File:  [parser3project] / parser3 / src / doc / Attic / doxygen.txt
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Thu Apr 26 14:55:22 2001 UTC (25 years, 2 months ago) by paf
Branches: MAIN
CVS tags: HEAD
code documentation ++

/** @mainpage


@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

Входной код предварительно компилируется во внутренний формат.
Это происходит с каждым запросом, результат компиляции не кэшируется.
На выходе получается \b класс, который складывается в Hash Request.classes().

@see compile.y, compile.C, compile_tools.h, compile_tools.C


@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

Все исходные файлы называются модулями, и имеют синтаксис:
@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

Значения, которыми оперирует 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

Класс хранит
- родителя: VStateless_class::base();
- ворох методов: VStateless_class::fmethods, Method.
- поля: VClass::ffields

в VStateless_class::get_element отдаётся метод+self[VJunction].
в VClass_class::get_element отдаются статические поля


@section Object Object

Объект[VObject], это экземпляр Класса.
Хранит поля: VObject::ffields (динамические, не статические - тех хранит Класс).


@section Aliased Aliased

При выполнении метода Объекта или Класса, бывает так, что 
управление попадает вверх к методу родительского класса,
и потом вниз, к методу производного класса.
При этом необходимо искать всякий раз в разных таблицах методов,
если, конечно, не пытаться объединить таблицу методов в один общий Hash.
Было решено не объединять, для упрощения конструкции, чтобы "каждый за себя".
Соответственно, в какой-то момент необходимо "переключить текущий набор методов/статических переменных",
т.е. работать с текущим классом, как будто он - другой класс (родитель текущего, затем ребёнок того родителя).
Так появился VAliased, прародитель Классов/Объектов, 
который хранит "текущий используемый класс", назовём его "псевдоним"[Valiased::fclass_alias].

Изначально  VClass/VObject устанавливает alias в "мой_класс"/this.
А затем, при переходе управления от метода ребёнка к методу родителя, псевдоним меняется[Temp_alias].

*/

E-mail: