--- parser3/operators.ru.txt 2002/10/15 09:42:40 1.88 +++ parser3/operators.ru.txt 2003/11/03 13:20:30 1.123 @@ -6,8 +6,8 @@ Xне сделано, видимо, не будет сделано операторы !^eval(выражение)[формат] выражение, кроме обычных функций:: !допустимы #комментарии - работают до конца строки или закрывающейся круглой скобки - внутри комментария допустимы вложенные круглые скобки + работают до конца строки или закрывающейся круглой скобки + внутри комментария допустимы вложенные круглые скобки !из неочевидных операторов: !| побитный xor !|| логический xor @@ -92,7 +92,8 @@ Xне сделано, видимо, не будет сделано default as-is !^taint[[lang]][код] default "just tainted, language unknown" - !^process[[$caller.CLASS|$object|$КЛАСС:CLASS]]{строка, которая будет 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? @@ -227,7 +228,7 @@ odbc c:\drives\y\parser3project\odbc\ !void !^имя.length[] - 0 + 0 !^имя.pos[...] -1 !^имя.int[] (default) @@ -257,7 +258,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 @@ -271,16 +272,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 слева направо [default] + r справа налево + h nameless таблица + v таблица из столбца piece [default] !^строка.{l|r}split[разделитель] таблица из столбца $piece - оставлен для совместимости + оставлен для совместимости !^строка.upper|lower[] X^строка.truncate(предел терпенья) стиль :( !^строка.length[] @@ -301,15 +303,18 @@ odbc c:\drives\y\parser3project\odbc\ логическое значение равно "не пуста?" числовое значение равно count[] !^table::create[[nameless]]{данные} старое имя "set" - !^table::create[table][[$.limit(1) $.offset(5) $.offset[cur]]] + !^table::create[table][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]] клонирует таблицу - !^table::load[[nameless;]путь] + reverse << сзаду на перёд (работает пока только в locate, в table::create НЕ работает) + !^table::load[[nameless;]путь[;опции]] !если не nameless, названия колонок берутся из первой строки !пустые строки, и строки в первой колонке содержащие '#', игнорируются + !$.column-separator[^#09] + !$.column-encloser["] !^table::sql{query}[[$.limit(2) $.offset(4) todo:$.default{ ^table::create[...] }]] !^таблица.save[[nameless|append;]путь] !$таблица.поле - !$таблица.fields+ из named таблицы выдаёт текущую запись как Hash + !$таблица.fields из named таблицы выдаёт текущую запись как Hash !^таблица.menu{тело}[разделитель] !^таблица.offset[[whence]](5) сдвигает; без параметра - печатает offset !whence=cur|set @@ -326,11 +331,15 @@ odbc c:\drives\y\parser3project\odbc\ !^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]] - добавляет записи из таблицы. таблицы должны иметь одинаковую структуру. !^таблица.flip[] выдаёт транспонированную, надо куда-то сложить, потом пользовать - !^таблица.locate[поле;значение] передвигает текущую строку, если найдёт. выдаёт bool - !^таблица.locate(логическое выражение) передвигает текущую строку, если найдёт. выдаёт bool - !^таблица.hash[поле, что будет ключом][[поле значений|table поля значений]][[$.distinct(1)]] + !^таблица.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)] @@ -344,6 +353,7 @@ odbc c:\drives\y\parser3project\odbc\ !$hash.ключ !_default - специальный ключ, если задан, то при обращении по ключу, которому нет соответствия, выдаётся _default значение + !$hash.fields выдает $hash. чтобы класс hash был чуть больше похож на класс table !^hash::create[[!copy_from_hash|Xcopy_from_hashfile]] создаёт новый hash, копию старого !^hash.add[слагаемое] @@ -365,8 +375,12 @@ odbc c:\drives\y\parser3project\odbc\ !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:переменная @@ -374,12 +388,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 @@ -398,6 +417,8 @@ odbc c:\drives\y\parser3project\odbc\ !значение поля или атрибута может быть 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 @@ -563,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 строка=стиль линий '*** * '='*** * *** * *** * ' @@ -583,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) @@ -606,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 $.stdin[текст][;1cmd[;2line[;3ar[;4g[;5s;...under win32 max 10 args]]]]]]] + !^file::exec[имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under win32 max 10 args]]]]]]] + options: + $.stdin[текст] если текст пуст, отключается автоматическое пересовывание данных HTTP-POST !^file:move[старое имя файла;новое имя файла] можно переименовывать и двигать каталоги[win32: но не через границу дисков] каталоги для dest создаются с правами 775 @@ -630,8 +660,10 @@ Xhashfile !^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 !$math:PI !^math:round floor ceiling !^math:trunc frac @@ -641,7 +673,18 @@ math !^math:degrees radians !^math:pow sqrt !^math:random(ширина диапазона) - ^math:GUID {C2C0983C-E26E-4169-BD07-77ECE9405BA5} + !^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, оно создаётся случайным @@ -663,9 +706,13 @@ math для удобного создания по значению из базы формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]] формат2: %H:%M[:%S] - !$date.year month day hour minute second weekday yearday(0...) daylightsaving + !^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;год;месяц] выдаёт неименованную таблицу @@ -705,7 +752,7 @@ xdoc(xnode) !::create[[URI]][qualifiedName] URI default = disk path to requested document для каталогов конечный / обязателен - !::load[file.xml] + !::load[file.xml[;опции]] !.transform[rules.xsl|xdoc][[params hash]] выдаёт dom шаблон кэшируется, кэш обновляется при изменении даты файла шаблона, или изменении даты файла "имя шаблона.stamp"[проверка даты stamp приоритетнее] @@ -851,6 +898,11 @@ xdoc(xnode) attribute that is already inuse elsewhere +!memory + !^memory:compact[] собрать мусор, освободив место под новые данные + (предупреждение: память процесса никогда не освобождается) + полезно делать перед XSL transform. + !status !чтобы класс был доступен, в apache нужно сказать @@ -864,11 +916,6 @@ 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 @@ -892,6 +939,19 @@ xdoc(xnode) $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. + !DATA::=string | file @@ -924,6 +984,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). параметры (больше/меньше, чем нужно, не тех типов, ...) @@ -932,6 +1011,7 @@ 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 @@ -944,6 +1024,11 @@ xdoc(xnode) !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