помимо прочего выяснилось, что даже один несчастный существующий хук — и то нельзя обернуть своим. хотя бы сделайте все глобалы хуков в Dialog r/o, пожалуйста! у меня вот Dvcs делает файловую систему для гит-репозитория, там необходимо создавать свой локатор (потому что у стандартного метод `.This()` не подходит), и всё: без перекрытия хука FilesBrowser не в состоянии с ним работать. а если хук перекрыть — то в состоянии.
таки я склоняюсь к тому, что Поняш был прав: этими методами надо расширять сам интерфейс локатора. ну да, омики пытались спрятать пути. у них всё равно не вышло — так давайте уже стандартизуем тот факт, что у ЛЮБОГО локатора есть некое текстовое представление содержащегося в нём маршрута. оно не обязано совпадать с системным, но обязано быть, и как минимум локатор обязан:
1. уметь его парзить (хотя это дело дериктории, в принципе, но здесь неважно);
2. уметь его возвращать (также нужны функции для получения максимальной длины пути, и текущей длины, я пояснял тут зачем);
3. гарантировать, что элементы в пути разделены "/" (это требование уже есть в документации);
4. гарантировать, что префикс пути или не содержит двоеточия — и тогда отделяется от остального пути символом "/", или всегда отделяется от остальной части символами ":/". пустой префикс ("/" и ":/") — валиден. путь типа "PFX:path/to" —
может приниматься локатором на вход, но на выходе локатор
обязан тогда вернуть канонизированое "PFX:/path.to". короче, локатор
обязан всегда возвращать полную каноническую форму пути. финальный разделитель обязан присутствовать только для путей к корню.
опциональные методы для удобства можно уже кросс-платформенно реализовать поверх этих. трансляцию в системные пути (если надо) — скорее всего, лучше делать в соответствующих системно-зависимых модулях.
префиксы нужны для installable fs. они уже используются для получения относительных путей к USE и прочим — пусть так и дальше будет. я вот для гита сделал префикс "GIT:", например.
предлагаемый интерфейс:
Код:
PROCEDURE (l: Locator) This* (IN path: ARRAY OF CHAR): Locator, NEW, ABSTRACT;
PROCEDURE (l: Locator) MaxPathLen* (): INTEGER, NEW, ABSTRACT;
PROCEDURE (l: Locator) PathLen* (): INTEGER, NEW, ABSTRACT;
PROCEDURE (l: Locator) Path* (OUT path: ARRAY OF CHAR), NEW, ABSTRACT;
я не понял, зачем нужна `Dialog.CheckHostLoc()`: она используется ровно в одном месте, в самом модуле LinDialog — который системно-зависим, и может попросить соответствующий апи у другого системного модуля Lin напрямую.
процедура `This()` при ошибке возвращает локатор с неопределённым (но заведомо некорректным) путём и ненулевым res (НЕ допускается возвращать `l`, т.е. самого себя).
процедура `Path()` при нехватке места в `path` устанавливает поле `l.res` или в 80 (not enough memory), или в новый специальный код, но
НЕ ПАДАЕТ С ТРАПОМ out-of-bounds!
недостатки решения:
1. признаём тот факт, что текстовые пути в системе есть. я не уверен, что это недостаток, впрочем, и считаю скорее достоинством.
2. старый код, реализующий свои локаторы (т.е. какие-нибудь installable FS) сломается. но его не так много, и он всё равно сломается, потому что там наверняка используется Host. так что при переносе заодно и это починят.
достоинства решения:
1. форма текстовых пути в системе стандартизована.
2. упрощается реализация installable FS, убирается один хук (который всё равно реализуется в каждом системно-зависимом модуле конкретно для его локаторов).
3. благодаря п.1 вспомогательные инструменты типа FilesBrowser и подобные могут не заниматься больше определением Host OS.