|
|
| version 1.2, 2001/04/03 05:23:38 | version 1.4, 2001/04/26 14:55:22 |
|---|---|
| Line 1 | Line 1 |
| /** @mainpage | /** @mainpage |
| @test contents | |
| @section Targets Targets | |
| Parser, варианты сборки [/targets]: | |
| - apache 1.3 модуль [apache13/]; | |
| - CGI скрипт [cgi/]; | |
| - ISAPI extension [isapi/]. | |
| Каждый вариант реализует pure virtual static SAPI класс - интерфейс общения Parser'а с сервером, | |
| и функции выделения памяти Pool класса - задаёт способ выделения памяти. | |
| Сначала создаётся объект Request, ему передаётся Request::Info с параметрами запроса. | |
| После чего выполняется метод Request::core, выполняющий всю обработку. | |
| @section Pooled Pooled | |
| Работа с памятью происходит так: все выделения происходят через Pool::malloc и Pool::calloc, | |
| для удобства имеется Pooled родитель, инкапсулирующий класс Pool, и имеющий одноимённые обёртки: | |
| Pooled::malloc и Pooled::calloc, а также функцию Pooled::pool() для доступа к самому pool'у. | |
| Когда освобождается память зависит от варианта сборки: | |
| - apache: делает это за модуля; | |
| - CGI: вообще ничего не освобождает, смерть процесса всё списывает; | |
| - ISAPI extension: освобождается в Pooled:~Pooled(). | |
| Работа с исключениями происходит через класс Exception, инкапсулированный в Pooled. | |
| Для доступа к нему имеется функция Pooled::exception(). | |
| Если возникает проблема, её следует THROW. И где-то CATCH. | |
| @section String String | |
| В памяти строки[String] хранятся в виде списка фрагментов[String::Chunk::Row .item], | |
| каждый помнит язык, на котором написан фрагмент. | |
| Фрагменты, полученные из скриптов считаются чистыми(String::Untaint_lang ::UL_CLEAN), | |
| а от пользователя - из environment, из form, с диска[table:load] или из sql сервера[table:sql] | |
| считаются испачканными(String::Untaint_lang ::UL_TAINTED), | |
| при операциях со строкой её могут расделять на части, но получающиеся части по-прежнему помнят свой язык. | |
| Строку могут записать в Request.wcontext, задав ей язык. | |
| При этом язык задаётся всем её испачканным частям, они становятся не неопределённо грязными[UL_TAINTED], | |
| а "грязными, но известно, что нужно с ними сделать, чтобы стали чистыми, т.е. известен их язык". | |
| скажем | |
| @verbatim | |
| ^table:sql{insert into news (title) values ('$form:title')] | |
| @endverbatim | |
| при обработке параметра посредством Temp_lang выставляется "текущий язык"[Request::flang], | |
| и при записи[Request::write_assign_lang] UL_TAINTED строки из $form:title фрагмента параметра | |
| метода sql, находящегося в кавычках, получает язык UL_SQL. | |
| String можно преобразовать в обычную С-строку, используя String::cstr(). | |
| При этом будут учтены языки фрагментов и произведены соответствующие вычищения. | |
| Также можно воспользоваться String::cstr(String::Untaint_lang), при этом будет все фрагменты строки | |
| насильно будути считаться написаннами на этом языке. Безотносительно к указанному во фрагменте языку. | |
| Такое используется, например, для работы с именами файлов: | |
| @verbatim | |
| ^table:load[$form:file_name] | |
| @endverbatim | |
| здесь при обычной обработке $form:file_name вышел бы UL_USER_HTML, а нужен UL_FILE_NAME, | |
| при этом глупо всё время подобное делать, как для table:sql, настаивая на {} параметрах. | |
| Обычным языком вывода является String::Untaint_lang::UL_USER_HTML, | |
| исключение составляет CGI скрипт, который запускают вне веб-сервера, | |
| в этом случае используется язык UL_AS_IS. | |
| @section Compiler Compiler | @section Compiler Compiler |
| Входной код предварительно компилируется во внутренний формат. | |
| Это происходит с каждым запросом, результат компиляции не кэшируется. | |
| На выходе получается \b класс, который складывается в Hash Request.classes(). | |
| @see compile.y, compile.C, compile_tools.h, compile_tools.C | |
| @section Executor Executor | @section Executor Executor |
| Код во внутреннем формате затем исполняется. | |
| Методы[Method] могут быть | |
| - native: добавляются VStateless_class::add_native_method, и имеют непустой Method::native_code | |
| - parser: добавляются VStateless_class::add_method, и имеют непустой Method::parser_code | |
| @see execute.C | |
| @section module module | @section module module |
| Все исходные файлы называются модулями, и имеют синтаксис: | |
| @verbatim | |
| @CLASS | |
| Имя_класса | |
| @BASE | |
| Имя_базового_класса | |
| @USE | |
| Список | |
| Модулей | |
| Которые | |
| Нужны | |
| В | |
| Этом | |
| Модуле | |
| @метод1[параметр1;параметр2][локальная_переменная1;локальная_переменная2] комментарий | |
| тело метода | |
| @endverbatim | |
| при этом CLASS, BASE, USE части необязательны. | |
| Запрашиваемый пользователем документ, компилируется в класс с предопределённым названием "MAIN", и его имя сменить нельзя. | |
| Файл с именем auto.p, найденный в том же каталоге, где и запрошенный пользователем документ, | |
| компилируется в безымянный[на деле, тоже в имя "MAIN"] класс, и становится родителем класса, в который скомпилировался | |
| запрошенный пользователем документ. | |
| Файл auto.p из ../ каталога, компилируется в родителя следующего уровня, и так далее. | |
| Дополнительно: | |
| - apache: файл auto.p из каталога, | |
| задаваемого директивой parser_site_auto_path[допустима в любом месте], | |
| а затем, parser_root_auto_path[допустима только в конфиге сервера] | |
| - CGI: файл auto.p из каталога, рядом с бинарником скрипта[обычно cgi-bin], | |
| а затем из windows directory [c:\winnt] под windows и из $HOME под unix. | |
| - ISAPI: файл auto.p из windows directory [c:\winnt] | |
| @section Value Value | @section Value Value |
| Значения, которыми оперирует Parser, есть экземпляры классов, производных от Value. | |
| Value знает своё имя [Value::name] и тип [Value::type], которые используются для выводов сообщений об ошибках. | |
| Тип также можно проверить в | |
| @verbatim | |
| ^if($variable is hash){когда в переменной hash}{когда не hash} | |
| @endverbatim | |
| Value может хранить элементы [Value::get_element, Value::put_element]. | |
| Самый простой случай - hash[VHash]. | |
| @section Class Class | @section Class Class |
| Класс хранит | |
| - родителя: VStateless_class::base(); | |
| - ворох методов: VStateless_class::fmethods, Method. | |
| - поля: VClass::ffields | |
| в VStateless_class::get_element отдаётся метод+self[VJunction]. | |
| в VClass_class::get_element отдаются статические поля | |
| @section Object Object | @section Object Object |
| Объект[VObject], это экземпляр Класса. | |
| Хранит поля: VObject::ffields (динамические, не статические - тех хранит Класс). | |
| @section Aliased Aliased | |
| При выполнении метода Объекта или Класса, бывает так, что | |
| управление попадает вверх к методу родительского класса, | |
| и потом вниз, к методу производного класса. | |
| При этом необходимо искать всякий раз в разных таблицах методов, | |
| если, конечно, не пытаться объединить таблицу методов в один общий Hash. | |
| Было решено не объединять, для упрощения конструкции, чтобы "каждый за себя". | |
| Соответственно, в какой-то момент необходимо "переключить текущий набор методов/статических переменных", | |
| т.е. работать с текущим классом, как будто он - другой класс (родитель текущего, затем ребёнок того родителя). | |
| Так появился VAliased, прародитель Классов/Объектов, | |
| который хранит "текущий используемый класс", назовём его "псевдоним"[Valiased::fclass_alias]. | |
| Изначально VClass/VObject устанавливает alias в "мой_класс"/this. | |
| А затем, при переходе управления от метода ребёнка к методу родителя, псевдоним меняется[Temp_alias]. | |
| */ | */ |