--- parser3/operators.ru.txt 2002/06/10 14:37:35 1.42 +++ parser3/operators.ru.txt 2003/12/22 11:44:34 1.149 @@ -5,15 +5,19 @@ Xне сделано, видимо, не будет сделано операторы !^eval(выражение)[формат] выражение, кроме обычных функций:: + !допустимы #комментарии + работают до конца строки или закрывающейся круглой скобки + внутри комментария допустимы вложенные круглые скобки !из неочевидных операторов: - # побитный xor - ## логический xor + !| побитный xor + !|| логический xor ~ побитное отрицание \ целочисленное деление 10\3=3 !def для проверки defined, пустая строка не defined пустая таблица не defined пустой hash не defined + ^if(method $hash.delete){yes} !eq ne lt gt le ge для сравнения строк, !in "/dir/" для проверки ["внутри не допустимы, если надо сравнить со сложным, @@ -27,16 +31,17 @@ Xне сделано, видимо, не будет сделано !числовой литерал бывает 0xABC !приоритеты: /* logical */ - %left "##" + %left "!||" %left "||" %left "&&" %left '<' '>' "<=" ">=" "lt" "gt" "le" "ge" %left "==" "!=" "eq" "ne" %left "is" "def" "in" "-f" "-d" %left '!' + условие ? когдаДа: когдаНет /* bitwise */ - %left '#' + %left '!|' %left '|' %left '&' %left '~' @@ -45,6 +50,8 @@ Xне сделано, видимо, не будет сделано %left '-' '+' %left '*' '/' '%' '\\' %left NEG /* negation: unary - */ + + !^if(условие){когда да}{когда нет} !^switch[значение]{^case[вариант1[;вариант2...]]{действие}^case[DEFAULT]{действие по умолчанию}} !^while(условие){тело} @@ -79,19 +86,23 @@ Xне сделано, видимо, не будет сделано удобно сделать после выставления 401 ошибки ^return[результат] + - отваливает из выполнения метода, выдавая нестандартный результат - ^break[] + - обрывает цикл - ^continue[] + - обрывает итерацию цикла + X^break[] + - обрывает цикл + X^continue[] + - обрывает итерацию цикла !^untaint[[as-is|file-spec|http-header|mail-header|uri|table|sql|js|xml|html|optimized-html]]{код} default as-is !^taint[[lang]][код] default "just tainted, language unknown" - !^process{строка, которая будет process-ed, как код} + !^process[[$caller.CLASS|$object|$КЛАСС:CLASS]]{строка, которая будет process-ed, как код}[во что переименовать @main] + !^process..[путь][во что переименовать @main] + по умолчанию, методы компилируются в $self [в случае оператора, $self=$MAIN:CLASS] !^connect[protocol://строка соединения]]{код с ^sql[...]-ями} !mysql://user:pass@{host[:port]|[/unix/socket]}/database? charset=cp1251_koi8& timeout=3& compress=1& - named_pipe=1 + named_pipe=1& + autocommit=1 + autocommit если выставить в 0, будет делать commit/rollback !pgsql://user:pass@{host[:port]|[local]}/database? client_encoding=win,[to-find-out]& @@ -108,6 +119,7 @@ Xне сделано, видимо, не будет сделано NLS_ISO_CURRENCY ISO currency symbol NLS_SORT sort sequence ORA_ENCRYPT_LOGIN=TRUE + ClientCharset=parser-charset << charset in which parser thinks client works !odbc://DSN=dsn^;UID=user^;PWD=password @@ -140,10 +152,11 @@ odbc c:\drives\y\parser3project\odbc\ ставить такой префикс перед открывающим апострофом, впритык, везде без проблелов /**имя_поля**/'literal' !^rem{} - !^cache[файл](секунд){код} + !^cache[файл](секунд){код}[{catch код}] !относительное задание времени !скэшировать строку, которая получается при выполнении кода на 'секунд' секунд !если 0секунд, значит не кэшировать, а старый такой стереть + !в catch коде $exception.handled[cache] ^rem{флаг, что exception обработан} !^cache[файл][expires date]{код} !абсолютное задание времени X^cache[файл] удалить файл [не ругает, если его нет] // такое было, больше не будет, делать ^cache(0) @@ -160,8 +173,10 @@ odbc c:\drives\y\parser3project\odbc\ !и есть исключение: ^untaint[html]{код} не оптимизируется Xбезотностительно флажка - !у всех макросов есть локальная переменная $result, если в неё что положить, + !у всех методов есть локальная переменная $result, если в неё что положить, !то _это_ будет результатом макроса, а не его тело + !у всех методов есть локальная переменная $caller, в ней лежит родительский stack frame, + !если туда записать !use(^use или @USE) ищет файл... !1. ...если путь начинается с /, то считается, что это путь от корня веб пространства @@ -216,6 +231,10 @@ odbc c:\drives\y\parser3project\odbc\ !void + !^имя.length[] + 0 + !^имя.pos[...] + -1 !^имя.int[] (default) 0 или default !^имя.double[] (default) @@ -243,7 +262,7 @@ odbc c:\drives\y\parser3project\odbc\ пример: ^if(def $form:name) не пуста? ^if($user.isAlive) истина? [автопреобразование к числу, не ноль?] - !^string::sql{query}[[$.limit(2) $.offset(4) $.default{n/a}]] + !^string::sql{query}[[$.limit(1) $.offset(4) $.default{n/a}]] результат запроса должен быть один столбец/одна строка !^имя.int[] .int(default) целочисленное значение строки. если ломается преобразование, берётся default @@ -257,10 +276,17 @@ odbc c:\drives\y\parser3project\odbc\ s singleline = $ считается концом всего текста m multiline = $ считается концом строки[\n], не концом всего текста g найти все вхождения, а не одно + ' создавать столбцы prematch, match, postmatch !^строка.match[шаблон][опции поиска]{замена} опции поиска+= g заменить все вхождения, а не одно + !^строка.split[разделитель][[lrhv]] + l слева направо [default] + r справа налево + h nameless таблица + v таблица из столбца piece [default] !^строка.{l|r}split[разделитель] таблица из столбца $piece + оставлен для совместимости !^строка.upper|lower[] X^строка.truncate(предел терпенья) стиль :( !^строка.length[] @@ -272,21 +298,27 @@ odbc c:\drives\y\parser3project\odbc\ <0 = не найдено !^строка.replace[$таблица_подстановок_строка_на_строку] !^строка.save[[append;]путь] + !^строка.normalize[] выдает другую строку, в которой фрагменты на одном языке объединены + полезно делать перед сложными match операциями, если вы знаете, что входная строка + состоит из большого числа фрагментов !table в выражении логическое значение равно "не пуста?" числовое значение равно count[] !^table::create[[nameless]]{данные} старое имя "set" - !^table::create[table] - клонирует таблицу - !^table::load[[nameless;]путь] + !^table::create[table][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]] + клонирует таблицу + reverse << сзаду на перёд (работает пока только в locate, в table::create НЕ работает) + !^table::load[[nameless;]путь[;опции]] !если не nameless, названия колонок берутся из первой строки !пустые строки, и строки в первой колонке содержащие '#', игнорируются + !$.separator[^#09] + !$.encloser["] по-умолчанию, нет. !^table::sql{query}[[$.limit(2) $.offset(4) todo:$.default{ ^table::create[...] }]] - !^таблица.save[[nameless|append;]путь] + !^таблица.save[[nameless|append;]путь[;опции, см. load]] !$таблица.поле - !$таблица.fields+ из named таблицы выдаёт текущую запись как Hash + !$таблица.fields из named таблицы выдаёт текущую запись как Hash !^таблица.menu{тело}[разделитель] !^таблица.offset[[whence]](5) сдвигает; без параметра - печатает offset !whence=cur|set @@ -300,18 +332,22 @@ odbc c:\drives\y\parser3project\odbc\ X^таблица.remove(position[;count]) - стирает запись из текущей позиции [стирает запись из конкретной позиции] [стирает count записей] - !^таблица.join[таблица] - добавляет записи из таблицы. + !^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]] - добавляет записи из таблицы. таблицы должны иметь одинаковую структуру. !^таблица.flip[] выдаёт транспонированную, надо куда-то сложить, потом пользовать - !^таблица.locate[поле;значение] передвигает текущую строку, если найдёт. выдаёт bool - !^таблица.locate(логическое выражение) передвигает текущую строку, если найдёт. выдаёт bool - !^таблица.hash[поле, что будет ключом][[поле значений|table поля значений]]+ + !^таблица.locate[поле;значение][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]] + передвигает текущую строку, если найдёт. выдаёт bool + !^таблица.locate(логическое выражение)[[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]] + передвигает текущую строку, если найдёт. выдаёт bool + !^таблица.hash{[поле]|{код}|(выражение)}[[поле значений|table поля значений]][[$.distinct(1) $.distinct[tables]]] значением $hash.ключ будет hash в котором поля значений будут ключами поля значений могут быть не указаны, тогда ими будут все столбцы, включая ключевой + если distinct содержит true, то не будет ошибки при повторяющихся ключах + если distinct содержит tables, то будет создан hash из таблиц, содержащих строки с ключом !^таблица.columns[]+ таблица из одного столбца $column !$отобранное[^таблица.select(выражение)] = таблица из тех же столбцов и строк, у которых условие совпало - $adults[^man.select($man.age>=18)] - ^таблица.color[цвет1;цвет2] + $adults[^man.select($man.age>=18)] + ^таблица.color[цвет1;цвет2] !hash @@ -321,7 +357,8 @@ odbc c:\drives\y\parser3project\odbc\ !$hash.ключ !_default - специальный ключ, если задан, то при обращении по ключу, которому нет соответствия, выдаётся _default значение - !^hash::create[[!copy_from_hash|Xcopy_from_hashfile]] + !$hash.fields выдает $hash. чтобы класс hash был чуть больше похож на класс table + !^hash::create[[!copy_from_hash|copy_from_hashfile]] создаёт новый hash, копию старого !^hash.add[слагаемое] перезаписывает одноимённые @@ -331,7 +368,7 @@ odbc c:\drives\y\parser3project\odbc\ !^a.intersection[b] = пересечение значения a !^a.intersects[b] = bool - !^hash::sql{запрос}[[$.limit(2) $.offset(4) todo:$.default{$.field[]...}]] + !^hash::sql{запрос}[[$.distinct(1) $.limit(2) $.offset(4) todo:$.default{$.field[]...}]] получается hash(ключи=значения первая колонка ответа) of hash(ключи=названия остальных колонкок ответа) !^hash._keys[]+ таблица из одного столбца $key @@ -339,11 +376,37 @@ odbc c:\drives\y\parser3project\odbc\ !^foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}] !^delete[ключ] удалить ключ +!hashfile + !^hashfile::open[filename] + !^hashfile.clear[] забыть всё + !.ключ[значение] положить значение + !.ключ[$.value[значение] $.expires ЗНАЧЕНИЕ} + положить значение до expires + значение поля expires может быть date, или число дней(0дней=на вечно) + !.ключ достать + !^delete[ключ] удалить ключ + !^delete[] удалить файлы, содержащие данные + !^hash[] + преобразовать в обычный hash + попутно стирает устаревшие пары + !^foreach[key|value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}] + + пример: + $uids[^hashfile::open[/db/uids]] + + $random[23847387taduigh345XGHWElxjgdjg] + $uids.$random[$.value[$uid] $.expires(1)] + $uid[$persistent.logins.$random] + !form [берётся первый элемент из одноимённых из GET, потом первый из POST] !$form:поле = string/file + !$form:nameless = поле со значением поля без имени "?value&...", "...&value&...", "...&value" + !$form:qtail = строка со значением текста после второго "?xxxxx", если там не было ',' [imap] !$form:fields = hash со всеми полями формы !$form:tables.поле = table с одним столбцом "field" со значениями "поля" + !$form:imap = хэш с ключами 'x' и 'y' + со значением ?1,2 приписки при использовании server-site image map !env !$env:переменная @@ -351,11 +414,17 @@ odbc c:\drives\y\parser3project\odbc\ !cookie !$cookie:имя считать старое или свежезаданное !$cookie:имя[значение] на 90 дней - !$cookie:имя[$.value[значение] $.expires(дней, 0дней=session)] + !$cookie:имя[$.value[значение] $.expires ЗНАЧЕНИЕ ] + !значение поля expires может быть 'session', date, или число дней(0дней=session) + ! если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT" !request !$request:query + !$request:body unprocessed POST request body !$request:uri + !$request:document-root + каталог, относительно которого считаются пути в parser, по-умолчанию = $env:DOCUMENT_ROOT + можно изменить, если на hosting что-то неудобно настроено X!$request:browser это hash, поля: !$type = ie/nn и !$version = номер, скажем 5.5 X$request:user @@ -371,7 +440,11 @@ odbc c:\drives\y\parser3project\odbc\ !значение может быть string а может быть hash: ! $value[abc] field: {abc}<<часть ! $attribute[zzz] field: abc; {attribute=zzz}<<часть + !значение поля или атрибута может быть string или date + ! если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT" !$response:body[DATA] замещает стандартный ответ + !$response:download[DATA] замещает стандартный ответ, + выставляет флаг, заставляющий browser предложить download !$response:status !^response:clear[] забыть все заданные response поля !$response:charset @@ -383,47 +456,83 @@ odbc c:\drives\y\parser3project\odbc\ ПРЕДУПРЕЖДЕНИЕ: класс form получает свои поля после обработки всех auto класса MAIN поэтому необходимо задать $request/response:charset в одном из них. не после. -Xhashfile - !^hashfile::open[$DB_HOME;filename] - !^hashfile.clear[] - забыть всё - !.ключ[значение] положить значение навечно - !.ключ[$.value[значение] $.expires(секунд)} положить значение на expires секунд - !.ключ достать - !^cache[ключ](секунд){код} - !суть то же, что и "положить+достать", но за один раз и компактнее - !если 0секунд, значит не кэшировать, а старый такой стереть - !внутри {кода} может быть вызван ^delete[] - !^delete[[ключ]] удалить ключ - !буде вызван без параметра изнутри cache, отменяет кэширование блока: - !блок не будет скэширован, его старое значение будет стёрто - !^hash[] - преобразовать в обычный hash - !^foreach[key|value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}] - - - примеры: - $uids[^hashfile::assign[/db/uids]] - $code:clear[/db/cache]] - $code[^hashfile::assign[/db/cache]] - - $random[23847387taduigh345XGHWElxjgdjg] - $uids.$random[$.value[$uid] $.expires(60*30)] - $uid[$persistent.logins.$random] - - ^code.cache[заголовки новостей](35){....} - !mail + !$mail.received=MESSAGE: + .from + .reply-to + .subject + .date класса date + .message-id + .raw[ + .СЫРОЕ_ПОЛЬЗОВАТЕЛЬСКОЕ-ПОЛЕ-ЗАГОЛОВКА + ] + $.{text|html|file#}[ << нумеруется как и в mail:send (text, text2, ...) (file, file2, ...) + $.content-type[ + $.value[{text|...|x-unknown}/{plain|html|...|x-unknown}] + [$.charset[windows-1251]] << в каком пришло, сейчас уже перекодировано + $.ПОЛЬЗОВАТЕЛЬСКИЙ-ПАРАМЕТР-ЗАГОЛОВКА + ] + $.description + $.content-id + $.content-md5 + $.content-location + .raw[ + .СЫРОЕ_ПОЛЬЗОВАТЕЛЬСКОЕ-ПОЛЕ-ЗАГОЛОВКА + ] + $.value[строка|FILE] + ] + $.message#[MESSAGE] (message, message2, ...) + + !^mail:send[ + $.options[-odd] + unix: строка, которая будет добавлена к команде запуска sendmail + -odd означает "быстро поставь в очередь без проверки email" + win32: игнорируется + $.charset[кодировка заголовка и текстовых блоков] + $.any-header-field + $.text[string] + $.text[ + $.any-header-field + $.value[string] + ] + $.html{string} + $.html[ + $.any-header-field + $.value{string} + ] + $.file#[FILE] + $.file#[ + $.any-header-field + $value[FILE] + ] + ] + !если charset указан, письмо перекодируется в этот charset + !content-type.charset не влияет на перекодирование + !после имени части может идти # число + ^mail:send[ +# по-умолчанию, совпадает с source encoding. +# задаёт кодировку body + $.charset[windows-1251] +# нет умолчания + $.content-type[$.value[text/plain] $.charset[windows-1251]] + $.from["вася" ] + $.to["петя" ] + $.subject[пойдём пивка] + $.body[ + слова + ] + ] !:send[$.header-field[] $.charset[кодировка письма] $.body[когда body не строка, а hash, отсылается multipart письмо]] !если charset указан, письмо перекодируется в этот charset !content-type.charset не влияет на перекодирование + !после имени части может идти целое число, части пойдут в порядке чисел. !если body указан строкой, то это текст письма, никаких вложений. !если body указан hash, то это части, будут собраны текстовые блоки, затем вложения + !это старый формат, поддерживается для обратной совместимости !если имя части начинается со слова text, то это текстовый блок. !если имя части начинается со слова attach, то это вложение, формат задания:: !$attach[$.format[!uue|Xbase64] $.value[DATA] $.file-name[user-file-name]] - !после имени части может идти целое число, части пойдут в порядке чисел. !важно: при multipart не указывать content-type ^mail:send[ # по-умолчанию, совпадает с source encoding. @@ -475,6 +584,12 @@ Xhashfile !$картинка[^image::measure[DATA]] смотрит на .ext case insensitive, умеет мерить пока только .gif и .jpg .jpeg + !$image.exif << hash после measure jpeg с exif информацией + !$image.exif.DateTime & co + [полный список см. http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html] + !числа типа int/double, + !даты типа date + !перечисления в виде hash с ключами 0..count-1 !$картинка.src .width .height !$картинка.line-width число=ширина линий !$картинка.line-style строка=стиль линий '*** * '='*** * *** * *** * ' @@ -495,7 +610,8 @@ Xhashfile если указана ширина_символа, то monospaced, если 0, то ширина_символа = ширине gif !^картинка.text(x;y)[текст_надписи] AS_IS !^картинка.length[текст_надписи] AS_IS - !^картинка.gif[] -- кодирует в FILE с content-type=image/gif + !^картинка.gif[возможно, имя файла] -- кодирует в FILE с content-type=image/gif + имя файла будет использовано при $response:download !^картинка.arc(center x;center y;width;height;start in degrees;end in degrees;color) !^картинка.sector(center x;center y;width;height;start in degrees;end in degrees;color) !^картинка.circle(center x;center y;r;color) @@ -518,15 +634,17 @@ Xhashfile !^file:delete[имя файла] !^file:find[имя файла][{когда не нашли}] !^file:list[путь[;шаблон]] = table с колонкой name - !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip]] + !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip][;опции]] !$файл_который_был_loaded.size !^file::stat[имя файла] !$файл_который_был_stated.size !.adate !.mdate !.cdate - !^file::cgi[имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s]]]]]]] + !^file::cgi[имя файла[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]] возвращённый заголовок рассыпается на $поля $status $stderr !^file::exec[имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under win32 max 10 args]]]]]]] + options: + $.stdin[текст] если текст пуст, отключается автоматическое пересовывание данных HTTP-POST !^file:move[старое имя файла;новое имя файла] можно переименовывать и двигать каталоги[win32: но не через границу дисков] каталоги для dest создаются с правами 775 @@ -537,6 +655,13 @@ Xhashfile выполняется код разблокируется Xchmod[...] НЕТ И НЕ БУДЕТ, ЧТОБЫ НЕ МОГЛИ СДЕЛАТЬ executable и запустить, даже если ftp запрещает chmod. + !^file:dirname[/a/some.tar.gz]=/a + !^file:dirname[/a/b/]=/a + !^file:basename[/a/some.tar.gz]=some.tar.gz + !^file:justname[/a/some.tar.gz]=some.tar + !^file:justext[/a/some.tar.gz]=gz + !/some/page.html: ^file:fullpath[a.gif] => /some/a.gif + !math !$math:PI @@ -548,27 +673,50 @@ Xhashfile !^math:degrees radians !^math:pow sqrt !^math:random(ширина диапазона) + !^math:uuid[] + 22C0983C-E26E-4169-BD07-77ECE9405BA5 + win32: пользуется cryptapi + unix: пользуется /dev/urandom, + если нет, /dev/random, + если нет, rand + [на solaris /dev/random можно добавить] + !^math:uid64[] + BA39BAB6340BE370 + !^math:md5[string] + выдает digest строки, длиной 16 байт в виде строки, + где байты digest выданы в hex виде, впритык, в нижнем регистре + !^math:crypt[password;salt] + salt prefix $apr1$ вызывает встроенный MD5 алгоритм, + если нет тела salt, оно создаётся случайным + $1$ вызывает MD5 алгоритм функции OS 'crypt', если поддерживается [заведомо нет на solaris]. + другие salt читайте документацию по функции OS 'crypt'. !date !время типа time можно использовать в выражениях, подставляет количество дней с epoch [1 января 1970 (UTC)], дробное !всё происходит в localtime, !временная зона задаётся вне parser средствами OS + $date:UTC-offset сколько дней надо прибавить,чтобы попасть в local время + $date:TZ наш часовой пояс, дробное, в часах (где-то есть с точностью до получаса) !^date::now[] !^date::now(смещение в днях) выдаёт сейчас+смещение !^date::create(дней с epoch) // старое имя set !^date::create(year;month[;day[;hour[;minute[;second]]]]) // старое имя set - ^date::sql-create[дата в формате %Y-%m-%d %H:%M:%S] + !^date::create[дата в формате %Y-%m-%d %H:%M:%S] для удобного создания по значению из базы формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]] формат2: %H:%M[:%S] - !$date.year month day hour minute second weekday todo:yearday + !^date::unix-timestamp() + !^date.unix-timestamp[] + !$date.year month day hour minute second weekday yearday(0...) daylightsaving TZ read-only + TZ="" << локальная зона !^date.roll[year|month|day](+-смещение) сдвигает дату + !^date.roll[TZ;Новая зона] говорит, что дата в таком-то часовом поясе: влияет на .hour&co !^date.sql-string[] %Y-%m-%d %H:%M:%S where published='$дата.sql-string[]' !^date:calendar[rus|eng;год;месяц] выдаёт неименованную таблицу - столбцы: 0..6 + столбцы: 0..6, week, weekyear !^date:calendar[rus|eng;год;месяц;день] выдаёт именнованную таблицу столбцы: year, month, day, weekday @@ -600,10 +748,12 @@ xdoc(xnode) !равно текущей кодировке выходной страницы, $response:charset ::sql{...} - !::create{} старое имя 'set' - !::create[qualifiedName] - !::load[file.xml] - !.transform[rules.xsl][[params hash]] выдаёт dom + !::create[[URI]]{} старое имя 'set' + !::create[[URI]][qualifiedName] + URI default = disk path to requested document + для каталогов конечный / обязателен + !::load[file.xml[;опции]] + !.transform[rules.xsl|xdoc][[params hash]] выдаёт dom шаблон кэшируется, кэш обновляется при изменении даты файла шаблона, или изменении даты файла "имя шаблона.stamp"[проверка даты stamp приоритетнее] !параметры передаются как есть, не xpath выражения - !.string[output options] - !.save[file.xml;output options] с шапкой - !.file[output options] = file + !.string[[output options]] + !.save[file.xml[;output options]] с шапкой + !.file[[output options]] = file output options идентичны атрибутам xsl:output [исключение: игнорируется cdata-section-elements, нужно будет, сделаю] выдаёт media-type при подстановке $response:body[сюда] + !если на документ ссылаются так: + parser://method/param/to/that/method + то в качестве документа используется ^MAIN:method[/param/to/that/method] + [примечание: в параметр всегда приходит лидирующая /, даже, если параметров вообще не было] + !xnode DOM1 attributes: !$node.nodeName !$node.nodeValue + !read + !write !$node.nodeType = int ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 @@ -660,10 +817,15 @@ xdoc(xnode) true if the attribute received its value explicitly in the XML document, or if a value was assigned programatically with the setValue function. false if the attribute value came from the default value declared in the document's DTD. + !$attribute_node.name + !$attribute_node.value $text_node/cdata_node/comment_node.substringData !$pi_node.target = target of this processing instruction XML defines this as being the first token following the markup that begins the processing instruction. + !$pi_node.data = The content of this processing instruction + This is from the first non white space character after the target + to the character immediately preceding the ?>. document_node. readonly attribute DocumentType doctype readonly attribute DOMImplementation implementation @@ -690,7 +852,7 @@ xdoc(xnode) !void removeAttribute(in DOMString name) raises(DOMException) !Attr getAttributeNode(in DOMString name) !Attr setAttributeNode(in Attr newAttr) raises(DOMException) - !/*Attr*/ removeAttributeNode(in Attr oldAttr) raises(DOMException) + !Attr removeAttributeNode(in Attr oldAttr) raises(DOMException) !NodeList getElementsByTagName(in DOMString name) !void normalize() @@ -703,9 +865,9 @@ xdoc(xnode) !^node.select[xpath/query/expression] = array of nodes, empty array if nothing found !^node.selectSingle[xpath/query/expression] = first node if any - !^node.selectBool[xpath/query/expression] = bool if any - !^node.selectNumber[xpath/query/expression] = double if any - !^node.selectString[xpath/query/expression] = string if any + !^node.selectBool[xpath/query/expression] = bool if any or die + !^node.selectNumber[xpath/query/expression] = double if any or die + !^node.selectString[xpath/query/expression] = string if any or die !error codes(пока придут как текст в случае соответствующих ошибок): INDEX_SIZE_ERR @@ -729,7 +891,7 @@ xdoc(xnode) does not support data NO_MODIFICATION_ALLOWED_ERR If an attempt is made to modify an - object where modifications are not + object where modifications are not allowed NOT_FOUND_ERR If an attempt was made to reference a @@ -743,6 +905,11 @@ xdoc(xnode) attribute that is already inuse elsewhere +!memory + !^memory:compact[] собрать мусор, освободив место под новые данные + (предупреждение: память процесса никогда не освобождается) + полезно делать перед XSL transform. + !status !чтобы класс был доступен, в apache нужно сказать @@ -756,21 +923,11 @@ xdoc(xnode) url time url time url time - !$status:db hash - !cache hash db_home=>tables table - name time users - name time users - name time users !$status:stylesheet !cache table file time file time file time - !$status:charset hash - !cache table - file - file - file !$status:rusage hash !utime user time used @@ -779,6 +936,31 @@ xdoc(xnode) !ixrss integral shared text memory size !idrss integral unshared data size !isrss integral unshared stack size + !tv_sec + !tv_usec + $s[$status:rusage] + ^s.tv_sec.format[%.0f].^s.tv_usec.format[%06.0f] + + !$status:memory hash + !used + Includes some pages that were allocated but never written. + + !free + + !ever_allocated_since_compact + Return the number of bytes allocated since the last collection. + + !ever_allocated_since_start + Return the total number of bytes [EVER(c)PAF] allocated in this process. + Never decreases. + + !$status:pid process id + !$status:tid thread id + +console + $console:timeout + !$console:line + read/write строку !DATA::=string | file @@ -787,14 +969,11 @@ xdoc(xnode) кучи auto.p и запрашиваемого документа: !parser3.conf cgi: - 1. или полный путь из переменной окружения HTTP_PARSER_ROOT_CONFIG - или configure sysconfdir|windows directory - 2. или полный путь из переменной окружения HTTP_PARSER_SITE_CONFIG + 1. или полный путь из переменной окружения CGI_PARSER_SITE_CONFIG или рядом с бинарником parser'а isapi: windows directory apache module: - 1) ParserRootConfig [httpd.conf only] - 2) ParserSiteConfig [can be in .htaccess] + 1) ParserConfig [can be in .htaccess] !auto.p вниз от DOCUMENT_ROOT/ по дереву до каталога с обрабатываемым файлом включительно класс собирается из всех этих файлов, последующие становятся родителями предыдущих имя последнего загруженного MAIN, имён у предыдущих нет @@ -814,6 +993,25 @@ xdoc(xnode) там лежат в обратном порядке имена[name] и места вызовов[file line] операторов/методов, приведших к ошибке. +!при загрузке файла (file::load, table::load, xdoc::load) можно указать такое имя файла: + !http://domain/document?params + !а также, возможно, указать опции: + !$.method[GET|HEAD] + !$.timeout(3) << в секундах, по-умолчанию =2 + !$.headers[ + ! $поле[значение] << значение имеет формат, как $response:ЗАГОЛОВОК + !] + !по-умолчанию, user-agent=parser3 + !по-умолчанию, получение http status != 200 >> создает http.status ошибку, + !это можно отключить, передав + !$.any-status(1) + !$.charset[кодировка удалённых докуметов по-умолчанию] << если сервер вернёт content-type:charset=ОНА_ПЕРЕБИВАЕТ + !file::load в дополнительные поля записывает + !ПОЛЕ:значение (имена полей ответа заглавными буквами) + !tables << хеш их ПОЛЕ->table с единственным столбцом "value". + в таких таблицах можно брать повторяющиеся заголовки. например, несколько set-cookies + todo:сделать отдельный cookies + !системные типы ошибок: !parser.compile ^test[} компиляция (непарная скобка, ...) !parser.runtime ^if(0). параметры (больше/меньше, чем нужно, не тех типов, ...) @@ -822,14 +1020,25 @@ xdoc(xnode) !file.lock shared/exclusive lock error !file.missing ^file:delete[delme] not found !file.access ^table::load[.] no rights + !file.seek seek failed !image.format ^image::measure[index.html] not gif/jpg !sql.connect ^connect[mysql://baduser:pass@host/db]{} not found/timeout !sql.execute ^void:sql{select bad} syntax error + sql.duplicate + sql.access + sql.missing + sql.xxx [serge asked] !xml ^xdoc::create{} any error in xml/xslt libs !smtp.connect not found/timeout !smtp.execute communication error - - + !email.format hren tam@null.ru wrong email format(bad chars/empty) + !email.send $MAIL.sendmail[/shit] sendmail not executable + !http.host ^file::load[http://notfound/there] host not found + !http.connect ^file::load[http://not_accepting/there] host found, but do not accept connections + !http.timeout ^file::load[http://host/doc] whole load operation failed to complete in # seconds + !http.response ^file::load[http://ok/there] host found, connection accepted, bad answer + !http.status ^file::load[http://ok/there] host found, connection accepted, status!=200 + !нужно выключить русский apache: CharsetDisable on !если в MAIN будет определён флаг $ORIGINS(1) то вместо обычного вывода страницы будет