--- parser3/operators.ru.txt 2017/02/15 23:45:14 1.251
+++ parser3/operators.ru.txt 2024/12/20 18:59:22 1.261
@@ -14,14 +14,12 @@
пустой hash не defined
eq ne lt gt le ge для сравнения строк,
in "/dir/" для проверки, находится ли текущий документ в каталоге
- ["внутри не допустимы выражения, если надо сравнить со сложным,
- пусть это будет переменная]
+ ["внутри не допустимы выражения, если надо сравнить со сложным, пусть это будет переменная]
is 'type' для проверки типа левого операнда,
можно проверить, "не hash ли параметр метода?"
-f для проверки существования файла на диске,
-d для проверки существования каталога на диске,
- строка в кавычках или апострофах - строка, без кавычек или апострофов строка до
- ближайшего whitespace
+ строка в кавычках или апострофах - строка, без кавычек или апострофов строка до ближайшего whitespace
числовой литерал бывает 0xABC
приоритеты:
/* logical */
@@ -33,22 +31,24 @@
%left "is" "def" "in" "-f" "-d"
%left '!'
- /* bitwise */
+ /* bitwise */
%left '!|'
%left '|'
%left '&'
%left '~'
- /* numerical */
+ /* numerical */
%left '-' '+'
%left '*' '/' '%' '\\'
%left '~' /* negation: unary */
- литералы
+
+ литералы:
true
false
^if(условие){когда да}{когда нет}
- ^if(условие1){да}[(условие2){да}[(условие2){да}[...]]]{нет} -- количество доп. условий не ограничено (в общем elseif это :)
+ ^if(условие1){да}[(условие2){да}[(условие2){да}[...]]]{нет}
+ количество доп. условий не ограничено (в общем elseif это :)
^switch[значение]{^case[вариант1[;вариант2...]]{действие}^case[DEFAULT]{действие по умолчанию}}
@@ -58,11 +58,11 @@
^try{
...
- ^throw[sql.connect[;вася[;болван]]] // был ^error[текст]
+ ^throw[sql.connect[;вася[;ошибся]]] // был ^error[текст]
^throw[
$.type[sql.connect]
$.source[вася]
- $.comment[болван]
+ $.comment[ошибся]
]
...
}{
@@ -77,7 +77,7 @@
$exception.type = sql.connect
$exception.file $exception.lineno $exception.colno [если не запрещены при компиляции]
$exception.source = вася
- $exception.comment = болван
+ $exception.comment = ошибся
}
^case[DEFAULT]{
код, обрабатывающий другую ошибку
@@ -86,14 +86,20 @@
}
}
- ^break[] - обрывает цикл
- ^break(true|false) - обрывает цикл, если true
-
- ^continue[] - обрывает итерацию цикла
- ^continue(true|false) - обрывает итерацию цикла, если true
-
- ^return[] - обрывает выполнение метода
- ^return[value] - присваивает $result значение value и обрывает выполнение метода
+ ^break[]
+ обрывает цикл
+ ^break(true|false)
+ обрывает цикл, если true
+
+ ^continue[]
+ обрывает итерацию цикла
+ ^continue(true|false)
+ обрывает итерацию цикла, если true
+
+ ^return[]
+ обрывает выполнение метода
+ ^return[value]
+ присваивает $result значение value и обрывает выполнение метода
^untaint[[as-is|file-spec|uri|http-header|mail-header|sql|js|json|parser-code|regex|xml|html|optimized-[as-is|xml|html]]]{код}
default as-is
@@ -107,19 +113,21 @@
^process[[$caller.CLASS|$object|$КЛАСС:CLASS]]{строка, которая будет process-ed, как код}[
$.main[во что переименовать @main]
$.file[имя файла из которого, якобы, данный текст]
- $.lineno(номер строки в файле, откуда данный текст. можно отрицательный)
+ $.lineno(номер строки в файле, откуда данный текст, можно отрицательный)
]
^process..[путь][во что переименовать @main]
по умолчанию, методы компилируются в $self [в случае оператора, $self=$MAIN:CLASS]
^connect[protocol://строка соединения]]{код с ^sql[...]-ями}
- mysql://user:pass@{host[:port]|[/unix/socket]}/database?
+ mysql://user:pass@{host[:port][, host[:port]]|[/unix/socket]}/database?
ClientCharset=parser-charset << charset in which parser thinks client works
charset=UTF-8&
timeout=3&
compress=0&
named_pipe=1&
- multi_statements=1& allow execute more then one query in one parser :sql{} request
+ multi_statements=1& allow execute more then one query in one parser :sql{} request
+ config_file=.my.cnf&
+ config_group=parser3& use group name from .my.cnf
autocommit=1
autocommit если выставить в 0, будет делать commit/rollback
@@ -128,19 +136,6 @@
&datestyle=ISO,SQL,Postgres,European,NonEuropean=US,German,DEFAULT=ISO
&ClientCharset=parser-charset << charset in which parser thinks client works
- oracle://user:pass@service?
- NLS_LANG=RUSSIAN_AMERICA.CL8MSWIN1251&
- NLS_LANGUAGE language-dependent conventions
- NLS_TERRITORY territory-dependent conventions
- NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS
- NLS_DATE_LANGUAGE language for day and month names
- NLS_NUMERIC_CHARACTERS decimal character and group separator
- NLS_CURRENCY local currency symbol
- 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^;ClientCharset=parser-charset
ClientCharset << charset in which parser thinks client works
@@ -148,36 +143,16 @@
ClientCharset=parser-charset& << charset in which parser thinks client works
autocommit=1
- для работы connect нужно, чтобы заранее(рекомендуется в системном конфигурационном auto.p)
- была определена таблица
+ для работы connect нужно, чтобы заранее (рекомендуется в системном конфигурационном auto.p) была определена таблица
#sql drivers
$SQL[
$.drivers[^table::create{protocol driver client
-mysql /www/parser3/libparser3mysql.so libmysqlclient.so
-pgsql /www/parser3/libparser3pgsql.so libpq.so
-oracle /www/parser3/libparser3oracle.so /u01/app/oracle/product/8.1.5/lib/libclntsh.so?ORACLE_HOME=/u01/app/oracle/product/8.1.5&ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data
-sqlite /www/parser3/libparser3sqlite.so sqlite3.so
-odbc c:\drives\y\parser3project\odbc\debug\parser3odbc.dll
+mysql $prefix/libparser3mysql.so libmysqlclient.so
+pgsql $prefix/libparser3pgsql.so libpq.so
+sqlite $prefix/libparser3sqlite.so sqlite3.so
+odbc parser3odbc.dll
}]
]
- в таблице у oracle в столбце клиентской библиотеки
- допустимо задать environment параметры инициализации(если они не заданы иначе заранее),
- допустимы имена, начинающиеся на NLS_ ORA_ и ORACLE_, или оканчивающиеся на +
- под win32
- необходим PATH+=^;C:\Oracle\Ora81\bin
- к сведению:
- ORA_NLS33 нужен для считывания файлика с клиентской кодировкой(задаваемой NLS_LANG)
- если кодировка не по-умолчанию, обязательно указать в .drivers,
- иначе будет сообщение про неправильный NLS параметр
- (имеют в виду, что не нашли кодировку из NLS_LANG)
- ORACLE_HOME нужен для считывания текстов сообщений об ошибках,
- можно указывать и в строке соединения, но глобален, и лучше вынести за скобки,
- в отличие от клиентской кодировки NLS_LANG, и прочего.
-
- ВНИМАНИЕ: при работе с большими текстовыми блоками в oracle&pgsql[а лучше всегда],
- ставить такой префикс перед открывающим апострофом, впритык, везде без проблелов
- /**имя_поля**/'literal'
-
^rem{}
комментарий, удаляется при компиляции
@@ -188,12 +163,14 @@ odbc c:\drives\y\parser3project\odbc\deb
в catch коде $exception.handled[cache] ^rem{флаг, что exception обработан}
^cache[файл][expires date]{код}[{catch код}]
абсолютное задание времени
- ^cache[файл] удалить файл [не ругает, если его нет]
+ ^cache[файл]
+ удалить файл [не ругает, если его нет]
^cache(секунд)
^cache[expires date]
сигнализирует вышестоящему ^cache "уменьши до стольких-то 'секунд'/'expires'"
в пределе: ^cache(0) отменить кеширование
- ^cache[] выдаёт текущую expires date
+ ^cache[]
+ выдаёт текущую expires date
у всех методов есть локальная переменная $result, если в неё что положить,
то это будет результатом метода, а не его тело
@@ -203,13 +180,13 @@ odbc c:\drives\y\parser3project\odbc\deb
use(^use или @USE) ищет и подключает файл:
1. если путь начинается с /, то считается, что это путь от корня веб пространства
- 2. относительно текущей директории.
- 3. относительно строк из table $MAIN:CLASS_PATH, снизу вверх.
+ 2. относительно текущей директории
+ 3. относительно строк из table $MAIN:CLASS_PATH, снизу вверх
$MAIN:CLASS_PATH - глобальная строка или таблица с путём или путями к каталогу
с классами (от корня веб пространства), задавайте её в конфигурационном auto.p
глобальная табличка $CHARSETS[$.название[имя файла]]
- задаёт какие буквы считаются какими(whitespace, letter, etc), а также их unicode
+ задаёт какие буквы считаются какими (whitespace, letter, etc), а также их unicode
формат: tab delimited файл, с заголовком:
char white-space digit hex-digit letter word lowercase unicode1 unicode2
A x x x a 0x0041 0xFF21
@@ -218,21 +195,22 @@ odbc c:\drives\y\parser3project\odbc\deb
всегда есть кодировка UTF-8, она является кодировкой по-умолчанию для request и response
ВНИМАНИЕ: имя кодировки case insensitive
+
синтаксис
$имя[новое значение]
$имя(математическое выражение нового значения)
$имя{код нового значения}
- $имя whitespace или ${имя}неважно подстановка значения
- ^имя параметры вызов
- $имя.CLASS класс значения
- $имя.CLASS_NAME имя класса
- $имя[$.key[] () {}] конструктор элемента переменной-хэша $имя.key
- ^method[$.key[] () {}] конструктор элемента параметра-хеша $parameter.key
+ $имя whitespace или ${имя}неважно - вывод значения переменой
+ ^имя параметры - вызов
+ $имя.CLASS - класс значения
+ $имя.CLASS_NAME - имя класса
+ $имя[$.key[] () {}] - конструктор переменной-хеша с элементом $имя.key
+ ^method[$.key[] () {}] - конструктор параметра-хеша с элементом $parameter.key
$CLASS.имя обращение к переменной класса
- имя заканчивается перед: пробел tab linefeed ; ] } ) " < > + * / % & | = ! ' , ? {уточнить}
+ имя заканчивается перед: пробел tab linefeed ; ] } ) " < > + * / % & | = ! ' , ?
т.е. можно $имя,aaaa
- но если нужно после имени букву, скажем -, то ${имя}-
+ но если нужно после имени символ, скажем -, то ${имя}-
в выражениях + и - являются дополнительными концами имени
@@ -241,23 +219,26 @@ odbc c:\drives\y\parser3project\odbc\deb
$переменная
строка$переменная
[код, вычисляющий строку]
- например: $хэш[$.возраст(88)] $достать[$.поле[возраст]] ^хэш.[$достать.поле].format{%05d}
+ например: $хеш[$.возраст(88)] $достать[$.поле[возраст]] ^хеш.[$достать.поле].format{%05d}
параметры := один или много параметров
параметр :=
(математическое выражение) вычисляется много раз внутри вызова,
| [код] вычисляется один раз перед вызовом,
| {код} вычисляется 0 или много раз внутри вызова,
- везде допустимы ; внутри - делает много параметров в одних скобках
+ допустимы ';' чтобы сделать много параметров в одних скобках
void
доступны все методы, присутствующие у объекта класса string, результат как у пустой строки
^void:sql{запрос без результата}{$.bind[см. table::sql]}
int,double
- ^имя.int[] целочисленное значение
- ^имя.double[] double значение
- ^имя.bool[] .bool(true|false) bool значение
+ ^имя.int[]
+ целочисленное значение
+ ^имя.double[]
+ double значение
+ ^имя.bool[] ^name.bool(true|false)
+ bool значение
^имя.inc(на сколько +)
^имя.dec(на сколько -)
^имя.mul(на сколько *)
@@ -275,21 +256,15 @@ string
пример:
^if(def $form:name) не пуста?
^if($user.isAlive) истина? [автопреобразование к числу, не ноль?]
-
^string:sql{query}[[$.limit(1) $.offset(4) $.default{n/a} $.bind[см. table::sql]]]
результат запроса должен быть один столбец/одна строка
-
- ^строка.int[] .int(default) целочисленное значение строки.
- если ломается преобразование, берётся default
-
- ^строка.double[] .double(default) double значение строки
- если ломается преобразование, берётся default
-
- ^строка.bool[] .bool(default) bool значение строки
- если ломается преобразование, берётся default
-
+ ^строка.int[] ^строка.int(default)
+ целочисленное значение строки, если ломается преобразование, берётся default
+ ^строка.double[] ^строка.double(default)
+ double значение строки, если ломается преобразование, берётся default
+ ^строка.bool[] ^строка.bool(default)
+ bool значение строки, если ломается преобразование, берётся default
^строка.format[формат] %d %.2f %02d...
-
^строка.match[шаблон-строка|шаблон-regex][[опции поиска]] $prematch $match $postmatch $1 $2...
опции поиска=
i CASELESS
@@ -300,68 +275,59 @@ string
' создавать столбцы prematch, match, postmatch
n вернуть цисло с количеством найденных совпадений, а не таблицу с результатами
U инвертировать смысл модификатора '?'
-
^строка.match[шаблон-строка|шаблон-regex][опции поиска]{замена}
опции поиска+=
g заменить все вхождения, а не одно
-
- ^строка.split[разделитель][[lrhv]][[название столбца для вертикального разбиения]]
+ ^строка.split[разделитель|regex][[lrhva]][[название столбца для вертикального разбиения]]
l слева направо [default]
r справа налево
h nameless таблица с ключами 0, 1, 2, ...
v таблица из 1 столбца 'piece' или как передадут [default]
-
+ a массив
^строка.{l|r}split[разделитель] таблица из столбца $piece
оставлен для совместимости
-
^строка.upper|lower[]
-
^строка.length[]
-
^строка.mid(P[;N])
без N - "до конца строки"
-
^строка.left(N), -1 выдает всю строку
-
^строка.right(N)
-
^строка.pos[подстрока]
-
^строка.pos[подстрока](позиция, с которой ищем)
<0 = не найдено
-
^строка.replace[$таблица_подстановок_строка_на_строку]
-
^строка.replace[$что;$на-что]
-
^строка.save[[append;]путь]
-
^строка.save[путь[;$.charset[в какой кодировке сохраняем] $.append(true)]]
-
- ^строка.trim[start|both|end|left|right[;chars]] выкидывает chars из начала/конца/и начала и конца
- default 'chars' -- whitespace chars
-
- ^строка.trim[chars] выкидывает chars из начала и конца
-
- ^строка.base64[] encode
- ^string:base64[encoded[;$.strict(true)]] decode
-
+ сохраняет строку в файл
+ ^строка.trim[start|both|end|left|right[;chars]]
+ выкидывает chars из начала/конца/и начала и конца
+ default 'chars' = whitespace chars
+ ^строка.trim[chars]
+ выкидывает chars из начала и конца
+ ^строка.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ] encode
+ ^string:base64[encoded[; $.pad(bool) $.strict(bool) $.url-safe(bool) ]] decode
^строка.idna[]
IDNA кодирование, поддержка кириллических доменов
-
^string:idna[encoded]
IDNA декодирование, поддержка кириллических доменов
-
- ^строка.js-escape[] кодирование для передачи в JS (%uXXXX)
-
- ^string:js-unescape[escaped] декодирование переданного из js
-
- ^string:unescape[js|uri;escaped; $.charset[] ] декодирование переданного из js или uri
+ ^строка.js-escape[]
+ кодирование для передачи в JS (%uXXXX)
+ ^string:js-unescape[escaped]
+ декодирование переданного из js
+ ^string:unescape[js|uri;escaped; $.charset[] ]
+ декодирование переданного из js или uri
+ ^строка.contains[ключ]
+ для совместимости с hash
table
в выражении
логическое значение равно "не пуста?"
числовое значение равно count[]
+ $таблица.поле
+ $таблица.поле[новое значение]
+ $таблица.fields
+ из named таблицы выдаёт текущую запись как Hash
^table::create[[nameless]]{данные}[[$.separator[^#09] $.encloser[]]]
^table::create[table][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
клонирует таблицу
@@ -370,34 +336,40 @@ table
если не nameless, названия колонок берутся из первой строки
пустые строки, и строки в первой колонке содержащие '#', игнорируются
$.separator[^#09]
- $.encloser["] по-умолчанию, нет.
+ $.encloser["] по-умолчанию, нет
^table::sql{query}[[$.limit(2) $.offset(4) $.bind[hash]]]
bind привязывает переменные в запросе к их значениям
пока реализован только для oracle
в запросе надо написать ":имя"
в параметре bind передать hash, из которого возьмётся (или куда запишется) значение
^таблица.save[[nameless|append;]путь[;опции, см. load]]
- $таблица.поле
- $таблица.поле[новое значение]
- $таблица.fields из named таблицы выдаёт текущую запись как Hash
+ сохраняет таблицу в файл
^таблица.menu{тело}[[разделитель]]
+ выполняет код тела для каждой строки таблицы
^таблица.foreach[позиция;значение]{тело}[[разделитель]]
- ^таблица.line[] 1-based offset
- ^таблица.offset[] печатает offset
- ^таблица.offset[[whence]](5) сдвигает
- whence=cur|set, без whence - это cur
- ^таблица.count[], ^таблица.count[rows] - количество строк в таблице
- ^таблица.count[columns] - количество столбцов таблицы
- ^таблица.count[cells] - количество ячеек в текущей строке таблицы
+ ^таблица.line[]
+ текущий ряд таблицы, начинается с 1
+ ^таблица.offset[]
+ смещение текущего ряда таблицы от начала, начинается с 0
+ ^таблица.offset[[whence]](5)
+ сдвигает whence=cur|set, без whence - это cur
+ ^таблица.count[], ^таблица.count[rows]
+ количество строк в таблице
+ ^таблица.count[columns]
+ количество столбцов таблицы
+ ^таблица.count[cells]
+ количество ячеек в текущей строке таблицы
^таблица.sort{{ключеделатель строка}|(ключеделатель число)}[{desc|asc}] default=asc
^таблица.append{данные}
^таблица.append[ $.имя столбца[значение столбца] ]
^таблица.insert{данные} добавить запись на текущую позицию
^таблица.insert[ $.имя столбца[значение столбца] ]
- ^таблица.delete[] - стирает запись с текущей позиции
- ^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]] - добавляет записи из таблицы.
- таблицы должны иметь одинаковую структуру.
- ^таблица.flip[] выдаёт транспонированную, надо куда-то сложить, потом пользовать
+ ^таблица.delete[]
+ стирает запись с текущей позиции
+ ^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]]
+ добавляет записи из таблицы, таблицы должны иметь одинаковую структуру
+ ^таблица.flip[]
+ выдаёт транспонированную
^таблица.locate[поле;значение][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
передвигает текущую строку, если найдёт. выдаёт bool
^таблица.locate(логическое выражение)[[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
@@ -408,183 +380,457 @@ table
если distinct содержит true, то не будет ошибки при повторяющихся ключах
если distinct содержит tables, то будет создан hash из таблиц, содержащих строки с ключом
$.type[string/table] поменять значение элемента на строку (указать одну колонку) или таблицу
- ^таблица.columns[[название столбца]] + таблица из одного столбца 'column' или как передадут
- $отобранное[^таблица.select(выражение)] = таблица из тех же столбцов и строк, у которых условие совпало
+ ^таблица.columns[[название столбца]]
+ таблица из одного столбца 'column' или как передадут
+ ^таблица.cells[], ^таблица.cells(лимит)
+ выдает массив ячеек текущей строки
+ ^таблица.array[]
+ возвращает массив, элементами которого являются хеши, отображающие данные каждой строки
+ ^таблица.array[колонка]
+ возвращает массив значений указанной колонки
+ ^таблица.array{код}
+ возвращает массив результатов выполнения переданного кода для каждой строки таблицы
+ ^таблица.rename[название столбца;новое навание столбца] ^таблица.rename[ $.название столбца[новое навание столбца] ]
+ переименовывает столбец или столбцы
+ $отобранное[^таблица.select(выражение)]
+ таблица из тех столбцов и строк, у которых условие совпало
$adults[^man.select($man.age>=18)]
^таблица.color[цвет1;цвет2]
-
+ чередует цвет1 и цвет2 последовательно для каждого ряда
hash
в выражении
логическое значение равно "не пуст?", хеш с _default уже не пуст
числовое значение равно count[]
$хеш.ключ
- !_default - специальный ключ, если задан,
+ _default - специальный ключ, если задан,
то при обращении по ключу, которому нет соответствия, выдаётся _default значение
- $хеш.fields выдает $hash. чтобы класс hash был чуть больше похож на класс table
+ $хеш.fields
+ выдает $hash, чтобы класс hash был чуть больше похож на класс table
^hash::create[[|copy_from_hash|copy_from_hashfile]]
создаёт новый hash, копию старого
^хеш.add[слагаемое]
перезаписывает одноимённые
^хеш.sub[вычитаемое]
- ^хеш.union[b] = объединение
- одноимённые остаются
- ^хеш.intersection[b] = пересечение
- значения хеш
+ ^хеш.union[b]
+ объединение, одноимённые остаются
+ ^хеш.intersection[b][[$.order[self|arg]]]
+ пересечение, новый хеш, order задает порядок элементов (как в исходном хеше или хеше-параметре)
^хеш.intersects[b] = bool
^hash::sql{запрос}[[$.distinct(1) $.limit(2) $.offset(4) $.type[hash|string|table]]]
получается hash(ключи=значения первая колонка ответа) of hash(ключи=названия остальных колонкок ответа) или
- string=значение каждого элемента - строка, при надо указать ровно два столбца или
+ string=значение каждого элемента - строка, при этом надо указать ровно два столбца или
table=значение каждого элемента - таблица
- ^хеш.keys[[название колонки с ключами]] + таблица из одного столбца key или как передадут
+ ^хеш.keys[[название колонки с ключами]]
+ таблица из одного столбца key или как передадут
^хеш.count[]
^хеш.foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- ^хеш.delete[ключ] удалить ключ
- ^хеш.contain[ключ] - существует ли в хеше ключ (bool)
- ^хэш.at[first|last][[key|value|hash]]
- ^хэш.at([-]N)[[key|value|hash]]
+ ^хеш.delete[ключ]
+ удалить ключ
+ ^хеш.contain[ключ]
+ существует ли в хеше ключ (bool)
+ ^хеш.at[first|last][[key|value|hash]]
+ ^хеш.at([-]N)[[key|value|hash]]
доступ к заданным элементам упорядоченного хеша
- ^хэш.sort[key;value]{{ключеделатель строка}|(ключеделатель число)}[[desc|asc]] default=asc
-
-!hashfile
- !^hashfile::open[filename]
- !^хешфайл.clear[] забыть всё
- !$хешфайл.ключ[значение] положить значение
- !$хешфайл.ключ[$.value[значение] $.expires[ЗНАЧЕНИЕ]}
- положить значение до expires
- значение поля expires может быть date, или число дней(0дней=на вечно)
- !$хешфайл.ключ достать
- !^хешфайл.delete[ключ] удалить ключ
- !^хешфайл.delete[] удалить файлы, содержащие данные
- !^хешфайл.hash[]
+ ^хеш.set[first|last;значение]
+ ^хеш.set([-+]N)[значение]
+ устанавливает значение заданного элемента упорядоченного хеша
+ ^хеш.rename[старый_ключ;новый_ключ]
+ ^хеш.rename[ $.старый_ключ[новый_ключ] ... ]
+ переименовывает заданные ключи хеша
+ ^хеш.sort[key;value]{{ключеделатель строка}|(ключеделатель число)}[[desc|asc]] default=asc
+ $обратный_хеш[^хеш.reverse[]]
+ $отобранное[^хеш.select[key;value](выражение)[ $.limit(N) $.reverse(bool) $.default(bool) ]]
+ хеш из ключей и значений, для которых условие истинно
+
+hashfile
+ ^hashfile::open[filename]
+ ^хешфайл.clear[]
+ забыть всё
+ $хешфайл.ключ[значение]
+ положить значение
+ $хешфайл.ключ[$.value[значение] $.expires[ЗНАЧЕНИЕ]}
+ положить значение до expires
+ значение поля expires может быть date, или число дней(0дней=на вечно)
+ $хешфайл.ключ достать
+ ^хешфайл.delete[ключ] удалить ключ
+ ^хешфайл.delete[] удалить файлы, содержащие данные
+ ^хешфайл.hash[]
преобразовать в обычный hash
попутно стирает устаревшие пары
- !^хешфайл.foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- !^хешфайл.release[]
- записать данные и снять блокировки.
- при повторном обращении к элементам откроется автоматически.
- !^хешфайл.cleanup[] пробежаться по всем элементам и удалить устаревшие.
+ ^хешфайл.foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
+ ^хешфайл.release[]
+ записать данные и снять блокировки
+ при повторном обращении к элементам откроется автоматически
+ ^хешфайл.cleanup[]
+ пробежаться по всем элементам и удалить устаревшие.
пример:
$sessions[^hashfile::open[/db/sessions]]
-
$sid[^math:uuid[]]
$sessions.$sid[$.value[$uid] $.expires(1)]
$uid[$sessions.$sid]
+array
+ в выражении
+ логическое значение равно "не пуст?"
+ числовое значение равно count[]
+ $массив.индекс, $массив.(выражение)
+ возврат значения по заданному индексу
+ $массив.индекс[значение], $массив.(выражение)[значение]
+ присваивание значения по индексу
+ $массив[значение;значение;...]
+ создание массива с заданными значениями
+ ^array::create[]
+ ^array::create[значение;значение;...]
+ создание массива с заданными значениями или пустого массива
+ ^array::copy[копируемый массив или хеш с цифровыми ключами]
+ копирование массива или хеша с цифровыми ключами
+ ^массив.add[добавляемый массив или хеш с цифровыми ключами]
+ добавление элементов из другого массива или хеша с перезаписью значений у совпадающих индексов
+ ^массив.join[добавляемый массив или произвольный хеш]
+ добавление элементов другого массива или хеша в конец массива
+ ^массив.append[значение;значение;...]
+ добавление элементов в конец массива
+ ^массив.insert(индекс)[значение;значение;...]
+ вставка элементов в указанную позицию массива
+ ^массив.left(n)
+ возвращает новый массив из n первых элементов массива
+ ^массив.right(n)
+ возвращает новый массив из n последних элементов массива
+ ^массив.mid(m;n)
+ возвращает новый массив, содержащий n инициализированных элементов массива, начиная с позиции m
+ ^массив.delete(index)
+ удаление элемента массива с оставлением пустого места
+ ^массив.remove(index)
+ удаление элемента со сдвигом последующих элементов на его место
+ ^массив.push[значение]
+ добавление элемента в конец массив
+ ^массив.pop[]
+ возвращает последний элемент и удаляет его из массива
+ ^массив.contain(индекс)
+ существует ли в массиве элемент по переданому индексу (bool)
+ ^array::sql{запрос}[[ $.sparse(false) $.distinct(false) $.limit(2) $.offset(4) $.type[hash|string|table]]]
+ создание массива на основе выборки из базы данных
+ $.sparse(false), по умолчанию - создать обычный массив. Значения строк выборки последовательно добавляются в массив
+ $.sparse(true) - создать разреженный массив. Первая колонка данных должна содержать индексы,
+ по которым будут размещены значения (аналогично ^hash::sql{})
+ получается array of hash (ключи=названия остальных колонкок ответа) или
+ string = значение каждого элемента - строка, при этом надо указать ровно два столбца или
+ table = значение каждого элемента - таблица
+ ^массив.keys[[название колонки с ключами]]
+ таблица из одного столбца key или переданного названия с индексами инициализированных элементов массива
+ ^массив.count[]
+ количество инициализированных элементов массива
+ ^массив.count[all]
+ общее количество элементов массива, включая неинициализированные
+ ^массив.foreach[index;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
+ перебирает все инициализированные элементы массива
+ ^массив.for[index;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
+ перебирает все элементы массива
+ ^массив.at[first|last][[key|value|hash]]
+ ^массив.at([-]число)[[key|value|hash]]
+ доступ к элементу массива по порядковому номеру
+ ^массив.set[first|last][значение]
+ ^массив.set([-]число)[значение]
+ установка значения элемента массива по порядковому номеру
+ ^массив.compact[]
+ удаление неинициализированных элементов массива
+ ^массив.compact[undef]
+ удаление неинициализированных и пустых элементов массива
+ ^массив.sort[key;value]{{ключеделатель строка}|(ключеделатель число)}[[desc|asc]] default=asc
+ сортировка массива
+ $обратный_массив[^массив.reverse[]]
+ возвращает новый массив из элементов исходного в обратном порядке
+ $отобранное[^массив.select[key;value](выражение)[ $.limit(N) $.reverse(bool) ]]
+ отбор элементов массива, для которых условие истинно
+
+date
+ время типа date можно использовать в выражениях, подставляет количество дней с epoch [1 января 1970 (UTC)], дробное
+ строковое значение в местном времени, численное в UTC, диапазон от 0000-00-00 00:00:00 до 9999-12-31 23:59:59
+ по умолчанию используется установленная средствами OS временная зона
+
+ ^date::now[]
+ ^date::now(смещение в днях)
+ выдаёт сейчас+смещение
+ ^date::today[]
+ дата на 00:00:00 текущего дня
+ ^date::today(целочисленное смещение в днях)
+ дата на 00:00:00 текущего дня+смещение
+ ^date::create(дней с epoch)
+ ^date::create(year;month[;day[;hour[;minute[;second[;TZ]]]]])
+ ^date::create[дата в формате %Y-%m-%d %H:%M:%S]
+ для удобного создания по значению из базы
+ формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
+ формат2: %H:%M[:%S]
+ ^date::create[дата в формате %Y-%m-%dT%H:%M[:%S]TZ]
+ для создания по значению в формате ISO 8601
+ формат TZ: Z(UTC) или +-hour[:minute] (смещение от UTC)
+ ^date::unix-timestamp()
+ ^дата.unix-timestamp[]
+ $дата.year month day hour minute second weekday yearday(0...) daylightsaving TZ weekyear
+ TZ="" << локальная зона
+ $дата.year month day hour minute second можно задать новое значение, остальные read only
+ ^дата.double[] ^дата.int[]
+ количество дней с epoch [1 января 1970 (UTC)], дробное или целое
+ ^дата.roll[year|month|day](+-смещение)
+ сдвигает дату
+ ^дата.roll[TZ;Новая зона]
+ говорит, что дата в таком-то часовом поясе: влияет на .hour & Co
+ ^date:roll[TZ;Новая зона]
+ говорит, что по умолчанию все даты в таком-то часовом поясе
+ ^дата.sql-string[[datetime|date|time]]
+ datetime или без параметра - %Y-%m-%d %H:%M:%S
+ date - %Y-%m-%d
+ time - %H:%M:%S
+ where published='^дата.sql-string[]'
+ ^date:calendar[rus|eng](год;месяц)
+ выдаёт неименованную таблицу, столбцы: 0..6, week, year
+ ^date:calendar[rus|eng](год;месяц;день)
+ выдаёт именнованную таблицу, столбцы: year, month, day, weekday
+ ^date:last-day(год;месяц)
+ вернёт последний день месяца
+ ^дата.last-day[]
+ вернёт последний день месяца $дата
+ ^дата.gmt-string[]
+ Fri, 23 Mar 2001 09:32:23 GMT
+ ^дата.iso-string[]
+ 2001-03-23T12:32:23+03
+
+file
+ $файл_из_post.name
+ $файл_из_post.size
+ $файлt_из_post.text
+ ^файл.save[text|binary;имя файла[;$.charset[в какой кодировке сохраняем]]]
+ ^file:delete[имя файла]
+ ^file:find[имя файла][{когда не нашли}]
+ ^file:list[путь[;шаблон-строка|шаблон-regex]]
+ table с колонками name dir
+ ^file:list[путь;$.filter[шаблон-строка|шаблон-regex] $.stat(true)]
+ table с колонками name dir size [mca]date
+ ^file::load[text|binary;big.zip[;domain_press_release_2001_03_01.zip][;опции]]
+ ^file::create[text|binary;имя;data]
+ ^file::create[text|binary;имя;data[;$.charset[кодировка букв в создаваемом файле] $.content-type[...]]]
+ ^file::create[string-or-file-content[;$.name[имя] $.mode[text|binary] $.content-type[...] $.charset[...]]]
+ $файл_который_был_loaded.size
+ $файл_который_был_loaded_или_created.mode = text/binary
+ ^file::stat[имя файла]
+ $файл_который_был_stated_или_loaded.size .adate .mdate .cdate
+ ^file::cgi[[text|binary;]имя файла[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
+ любой аргумент может быть строкой или массивом строк
+ возвращённый заголовок рассыпается на $поля
+ $status
+ $stderr
+ ^file::exec[[text|binary;]имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under unix max 50 args]]]]]]]
+ любой аргумент может быть строкой или массивом строк
+ options:
+ $.stdin[текст|файл] если пусто, отключается автоматическое пересовывание данных HTTP-POST
+ ^file:move[старое имя файла;новое имя файла]
+ можно переименовывать и двигать каталоги[win32: но не через границу дисков]
+ каталоги для dest создаются с правами 775
+ каталог старого файла стирается, если после move он остаётся пуст
+ ^file:copy[имя файла;имя копии файла[; $.append(1) ]]
+ можно копировать только файлы
+ ^file:lock[имя файла]{код}
+ файл при необходимости создаётся
+ блокируется
+ выполняется код
+ разблокируется
+ ^file:dirname[/a/some.tar.gz|file]=/a (работает аналогично комманде *nix)
+ ^file:dirname[/a/b/|file]=/a (работает аналогично комманде *nix)
+ ^file:basename[/a/some.tar.gz|file]=some.tar.gz (работает аналогично комманде *nix)
+ ^file:basename[/a/b/|file]=b (работает аналогично комманде *nix)
+ ^file:justname[/a/some.tar.gz|file]=some.tar
+ ^file:justext[/a/some.tar.gz|file]=gz
+ /some/page.html: ^file:fullpath[a.gif] => /some/a.gif
+ ^файл.sql-string[]
+ внутри ^connect даст правильно escaped строку, которую можно в запрос отдать
+ ^file::sql{query}[[ $.name[имя_файла_для_download] $.content-type[пользовательский content-type] ]]
+ результат запроса должен быть "одна строка".
+ колонки:
+ первая колонка - данные
+ если есть вторая - это имя файла
+ если есть третья - это content-type
+ ^файл.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ]
+ encode
+ ^file:base64[имя файла[; $.pad(bool) $.wrap(bool) $.url-safe(bool) ]]
+ encode
+ ^file::base64[encoded string[; $.pad(bool) $.strict(bool) url-safe(bool) ]]
+ decode
+ ^file::base64[mode;имя файла;encoded string[; $.content-type[...] $.pad(bool) $.strict(bool) url-safe(bool) ]]
+ decode
+ ^file:crc32[имя файла]
+ вычисляет crc32 файла с указанным именем
+ ^файл.crc32[]
+ вычисляет crc32 объекта
+ ^файл.md5[], ^file:md5[имя файла]
+ выдает digest файла, длиной 16 байт в виде строки,
+ где байты digest выданы в hex виде, впритык, в нижнем регистре
+
+image
+ $картинка[^image::measure[DATA[; $.exif(bool) $.xmp(bool) $.xmp-charset[] $.video(bool) ]]]
+ смотрит на .ext case insensitive,
+ умеет мерить gif, jpg, tiff, bmp, webp и mp4 (mov)
+ $картинка.exif << hash после measure jpeg с exif информацией и $.exif(true)
+ $image.exif.DateTime & co
+ [полный список см. https://exiftool.org/TagNames/EXIF.html]
+ числа типа int/double,
+ даты типа dateб
+ перечисления в виде hash с ключами 0..count-1
+ $картинка.src .width .height
+ $картинка.line-width число=ширина линий
+ $картинка.line-style строка=стиль линий '*** * '='*** * *** * *** * '
+ ^картинка.html[[hash]]
+
+ ^image::load[фон.gif]
+ только gif пока
+ ^image::create(размер X;размер Y[;цвет фона default белый]])
+ ^картинка.line(x0;y0;x1;y1;0xffFFff)
+ ^картинка.fill(x;y;0xffFFff)
+ ^картинка.rectangle(x0;y0;x1;y1;0xffFFff)
+ ^картинка.bar(x0;y0;x1;y1;0xffFFff)
+ ^картинка.replace(hex-цвет1;hex-цвет2)[table x:y вершины_многоугольника]
+ ^картинка.polyline(цвет)[table x:y точки]
+ ^картинка.polygon(цвет)[table x:y вершины_многоугольника]
+ ^картинка.polybar(цвет)[table x;y вершины_многоугольника]
+ ^картинка.font[набор_букв;имя_файла_шрифта.gif][(ширина_пробела[;ширина_символа])]
+ высота символа = высота картинки/количество букв в наборе
+ если указана ширина_символа, то monospaced, если 0, то ширина_символа = ширине gif
+ ^картинка.font[набор_букв;имя_файла_шрифта.gif;
+ $.space(ширина_пробела) // по умолчанию = ширине gif
+ $.width(ширина_символа) // см. выше, по умолчанию proportional
+ $.spacing(расстояние между буквами) // по умолчанию = 1
+ ]
+ ^картинка.text(x;y)[текст_надписи] AS_IS
+ ^картинка.length[текст_надписи] AS_IS
+ ^картинка.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)
+ ^картинка.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
+ при заданных dest_w/dest_h делает изменение размера кусочка
+ при уменьшении делает resample
+ годится только для уменьшения простой[малоцветной] дребедени вроде графиков/pie,
+ для thumbnais не годится
+ при не указанном dest_h сохраняет aspect ratio
+ tolerance - некое число[квадрат расстояния в RGB пространстве до искомого цвета],
+ определяющее прожорливость выделялки цветов из палитры [default=150]
+ меньше - точнее приближает цвета, но они быстро кончаются
+ больше - неточно приближает цвет, но большей части хватит
+ ^картинка.pixel(x;y)[(color)]
+ узнать или задать цвет пиксела
-!form
- [берётся первый элемент из одноимённых из GET, потом первый из POST]
- !$form:поле = string/file
- !$form:nameless = поле со значением поля без имени "?value&...", "...&value&...", "...&value"
- !$form:qtail = строка со значением текста после второго "?xxxxx", если там не было ',' [imap]
- !$form:fields = hash со всеми полями формы
- !$form:tables.поле = table с одним столбцом "field" со значениями "поля"
- !$form:files.поле = hash со значениями полей типа файл, ключи - 0, 1, ..., значение - файл
- !$form:imap = хэш с ключами 'x' и 'y'
- со значением ?1,2 приписки при использовании server-site image map
-
-
-!env
- !$env:переменная
- !$env:fields хэш с переменными окружения
- !$env:PARSER_VERSION версия парсера
-
-
-!cookie
- !$cookie:имя считать старое или свежезаданное
- !$cookie:имя[значение] на 90 дней
- !$cookie:имя[$.value[значение] $.expires[ЗНАЧЕНИЕ] $.secure(true)]
- !значение поля expires может быть 'session', date, или число дней(0дней=session)
- ! если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
- ! можно устанавливать bool свойства, например $.secure(true), $.httponly(true)
- !$cookie:fields = hash со всеми cookies
-
-
-!request
- !$request:query
- !$request:uri
- !$request:document-root
- каталог, относительно которого считаются пути в parser, по-умолчанию = $env:DOCUMENT_ROOT
- можно изменить, если на hosting что-то неудобно настроено
- !$request:argv = hash с параметрами коммандной строки. ключи 0, 1, ... [0 -- имя обрабатываемого файла].
- !$request:charset
- Кодировка исходного документа
- !используется при upper/lower и match[][i]
- ПРЕДУПРЕЖДЕНИЕ: класс form получает свои поля после обработки всех auto класса MAIN
- поэтому необходимо задать $request/response:charset в одном из них. не после.
- !$request:method метод запроса (GET|POST|PUT)
- !$request:body тело POST-запроса в виде текста
- !$request:body-file тело POST-запроса в виде файла
- !$request:body-charset кодировка POST-запроса
- !$request:headers хэш с заголовками запроса (без префикса HTTP_)
-
-
-!response
- !$response:поле[значение] и можно считать старое -- $response:поле
- !значение может быть string а может быть hash:
- ! $value[abc] field: {abc}<<часть
- ! $attribute[zzz] field: abc; {attribute=zzz}<<часть
- !значение поля или атрибута может быть string или date
- ! если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
- !$response:headers накопленные поля
- !$response:body[DATA] замещает стандартный ответ
- !$response:download[DATA] замещает стандартный ответ,
- выставляет флаг, заставляющий browser предложить download
- !$response:status
- !^response:clear[] забыть все заданные response поля
- !$response:charset
- кодировка клиента т.е. та,
- 1) из которой будут перекодированы $form:поля после забирания из browser'а
- 2) в которую документ будет перекодирован перед отдаванием в browser
- 3) в которую будет перекодирован текст языка uri
- не добавляет к content-type ничего, если хочется, это надо сделать вручную
- ПРЕДУПРЕЖДЕНИЕ: класс form получает свои поля после обработки всех auto класса MAIN
- поэтому необходимо задать $request/response:charset в одном из них. не после.
+regex
+ в выражении
+ логическое значение всегда равно true
+ числовое значение равно количеству байт скомпилированного шаблона
+ ^regex::create[шаблон-строка|regex][[опции поиска]]
+ ^шаблон.size[]
+ количество байт скомпилированного шаблона
+ если значение очень большое - стоит почитать документацию по pcre и, возможно, переписать шаблон
+ ^шаблон.study_size[]
+ размер study-структуры. если==0 - шаблон не может быть "изучен"
+ $шаблон.pattern
+ текст шаблона
+ $шаблон.options
+ строка с исходным текстом опций
+console
+ $console:timeout
+ $console:line
+ read/write строку
+
+cookie
+ $cookie:имя считать старое или свежезаданное
+ $cookie:имя[значение] на 90 дней
+ $cookie:имя[$.value[значение] $.expires[ЗНАЧЕНИЕ] $.secure(true) $.domain[имя домена] $.httponly(true)]
+ значение поля expires может быть 'session', date, или число дней (0дней=session)
+ если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
+ $cookie:fields
+ hash со всеми cookies
+
+env
+ $env:переменная
+ $env:fields хеш с переменными окружения
+ $env:PARSER_VERSION версия парсера
-!regex
- !в выражении
- !логическое значение всегда равно true
- !числовое значение равно количеству байт скомпилированного шаблона.
- !^regex::create[шаблон-строка][[опции поиска]]
- !^шаблон.size[] количество байт скомпилированного шаблона
- если значение очень большое -- стоит почитать документацию по pcre и, возможно, переписать шаблон.
- !^шаблон.study_size[] размер study-структуры. если==0 -- шаблон не может быть "изучен"
-
-
-!reflection
- !^reflection:create[класс;конструктор[;пара;[мет[;ры]]]] вызывает указанный конструктор класса (не более 100 параметров)
- !^reflection:classes[] хеш со всеми классами. ключ -- имя класса, значение бывает methoded (класс с методами) или void
- !^reflection:class[объект] класс переданного объекта
- !^reflection:class_name[объект] имя класса переданного объекта
- !^reflection:base[объект] родительский класс переданного объекта
- !^reflection:base_name[объект] имя родительского класса переданного объекта
- !^reflection:class_by_name[имя класса] получение класса по имени
- !^reflection:def[class;имя класса] проверка класса на существование
- !^reflection:methods[класс] хеш со списком методов указанного класса, значения -- строки 'native' или 'parser'
- !^reflection:method[класс или объект;имя метода] возвращает junction-method класса или объекта
- !^reflection:fields[класс или объект] хеш со списком статических полей указанного класса или динамических полей указанного объекта
- !^reflection:field[класс или объект;имя поля] возвращает значение указанного поля класса или объекта. getter-ы игнорируются.
- !^reflection:uid[класс или объект] возвращает идентификатор объекта или класса
- !^reflection:method_info[класс;метод] хеш с параметрами указанного метода класса
- $.inherited[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
- $.overridden[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
- для native классов возвращается хеш:
- .min_params(минимально необходимое число параметров)
- .max_params(максимально возможное число параметров)
- .call_type[dynamic|static|any]
- для parser классов возвращается хеш:
- ключ -- номер параметра (0, 1, ...), значение - имя параметра
- !^reflection:dynamical[[object or class, caller if absent]] возвращает true, если метод был вызван из динамического контекста
- при передаче параметра возвращает true, если передан динамический объект,
- false если класс
- !^reflection:delete[класс или объект;имя переменной] удаляет переменную с указанным именем в указанном классе или объекте
- !^reflection:is[имя элемента;имя класса][[контекст]] аналог оператора is, позволяющий определить, является ли элемент кодом.
+form
+ [берётся первый элемент из одноимённых из GET, потом первый из POST]
+ $form:поле
+ string/file
+ $form:nameless
+ поле со значением поля без имени "?value&...", "...&value&...", "...&value"
+ $form:qtail
+ строка со значением текста после второго "?xxxxx", если там не было ',' [imap]
+ $form:fields
+ hash со всеми полями формы
+ $form:elements.поле
+ array со всеми значениями поля - как строковыми, так и файловыми
+ $form:tables.поле
+ table с одним столбцом "field" со значениями "поля", для множественных значений
+ $form:files.поле
+ hash со значениями полей типа файл, ключи - 0, 1, ..., значение - файл
+ $form:imap
+ хеш с ключами 'x' и 'y' со значением ?1,2 приписки при использовании server-site image map
+
+inet
+ ^inet:ntoa(long)
+ ^inet:aton[IP]
+ ^inet:name2ip[name][[ $.ipv[4|6|any] $.table(true) ]]
+ прямое преобразование имени в IP адрес
+ ^inet:ip2name[ip][ $.ipv[4|6|any] ]]
+ обратное преобразование из IP адреса в имя
+ ^inet:hostname[]
+ имя хоста
+json
+ ^json:parse[-json-строка-[;
+ $.depth(максимальная глубина, default == 19)
+ $.double(false) отключить встроенный парсинг чисел с плавающей точкой (по умолчанию включен)
+ в этом случае они попадут в результирующий объект как строки
+ $.int(false) отключить встроенный парсинг целых чисел (по умолчанию включен)
+ в этом случае они попадут в результирующий объект как строки
+ $.distinct[first|last|all] как будет происходить разбор дублирующихся ключей у объектов
+ first - будет оставлен первый встретившийся элемент
+ last - будет оставлен последний встретившийся элемент
+ all - будут оставлены все элементы. при этом элементы, начиная со 2
+ получат числовые суффиксы (key_2 итд)
+ по умолчанию дублирующиеся ключи приведут к exception
+ $.object[method-junction] пользовательский метод[ключ;объект], которому будут передаваться все разобранные
+ объекты и ключи объекта, метод возвращает новый объект
+ $.array[method-junction] пользовательский метод, которому будут передаваться массивы
+ $.taint[язык преобразования] задаёт язык преобразования для всех строк результата
+ ]]
+ парсит json-строку в хеш
-!mail
- !$mail.received=MESSAGE:
+ ^json:string[system or user object[;
+ $.skip-unknown(false) отключить exception и выдавать 'null' при сериализации объектов с типами
+ отличных от void, bool, string, int, double, date, table, hash и file
+ $.indent(true) форматировать результирующую строку табуляциями по глубине вложенности
+ $.date[sql-string|gmt-string|iso-string|unix-timestamp]
+ формат вывода даты, по умолчанию -- sql-string
+ $.table[object|array|compact]
+ формат вывода таблицы, по умолчанию -- object
+ object: [{"c1":"v11","c2":"v12",...},{"c1":"v21","c2":"v22",...},...]
+ array: [["c1","c2",...] || null (for nameless),["v11","v12",...],...]
+ compact: ["v11" || ["v11","v12",...],...]
+ $.file[text|base64|stat] вывести тело файла в указанном виде (по умолчание тело файла
+ не попадает в output)
+ $.xdoc[hash] параметры преобразования xdoc в строку (как в ^xdoc.string[])
+ $.тип[method-junction] любой тип можно вывести с помощью пользовательского метода, который
+ должен принимать 3 параметра: ключ, объект данного типа и опции
+ вызова ^json:string[]
+ $._default[метод] пользовательский метод, будет вызываться для вывода всех объектов пользовательских
+ классов. Метод должен принимать 3 параметра: ключ, объект и опции вызова.
+ $._default[имя метода] имя пользователького метода, при его наличии он будет вызван для сериализации
+ $.void[null|string] неопределенное значение будет выдано в виде null (по умолчанию)
+ или пустой строки
+ ]]
+ сериализует системный или пользовательский объект в json-строку
+
+mail
+ $mail.received=MESSAGE:
.from
.reply-to
.subject
@@ -610,74 +856,77 @@ hash
]
$.message#[MESSAGE] (message, message2, ...)
- !^mail:send[
+ ^mail:send[
$.options[-odd]
unix: строка, которая будет добавлена к команде запуска sendmail
-odd означает "быстро поставь в очередь без проверки email"
win32: игнорируется
- $.charset[кодировка заголовка и текстовых блоков]
- $.any-header-field
+ $.charset[кодировка заголовка и текстовых блоков]
+ $.any-header-field
$.text[string]
$.text[
- $.any-header-field
+ $.any-header-field
$.value[string]
]
$.html{string}
$.html[
- $.any-header-field
+ $.any-header-field
$.value{string}
]
$.file#[FILE]
$.file#[
- $.any-header-field
+ $.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[
- слова
- ]
+ если 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, то это текстовый блок.
- !если имя части начинается со слова file, то это вложение, формат задания::
- !$file[$.format[!uue|!base64] $.value[DATA] $.name[user-file-name]]
- !важно: при multipart не указывать content-type
+ ]
+
+ ^mail:send[$.header-field[] $.charset[кодировка письма] $.body[когда body не строка, а hash, отсылается multipart письмо]]
+ если charset указан, письмо перекодируется в этот charset
+ content-type.charset не влияет на перекодирование
+ после имени части может идти целое число, части пойдут в порядке чисел.
+ если body указан строкой, то это текст письма, никаких вложений.
+ если body указан hash, то это части, будут собраны текстовые блоки, затем вложения
+ это старый формат, поддерживается для обратной совместимости
+ если имя части начинается со слова text, то это текстовый блок.
+ если имя части начинается со слова file, то это вложение, формат задания:
+ $file[$.format[uue|base64] $.value[DATA] $.name[user-file-name]]
+ важно: при multipart не указывать content-type
+
^mail:send[
-# по-умолчанию, совпадает с source encoding.
+# по-умолчанию, совпадает с source encoding
# задаёт кодировку body
- $.charset[windows-1251]
+ $.charset[windows-1251]
# нет умолчания
$.content-type[$.value[text/plain] $.charset[windows-1251]]
$.from["вася" ]
$.to["петя" ]
- $.subject[пойдём пивка]
+ $.subject[тема]
$.body[
слова
]
]
+
^mail:send[
$.from["вася" ]
$.to["петя" ]
- $.subject[пойдём пивка]
+ $.subject[тема]
$.body[
$.text[
# задаёт кодировку body
@@ -686,630 +935,465 @@ hash
$.content-type[$.value[text/plain] $.charset[windows-1251]]
$.body[слова]
]
-#для удобства скриптования можно указать только одну часть, при этом не будет multipart
+# для удобства можно указать только одну часть, при этом не будет multipart
$.file[
- $.value[^file::load[my beloved.doc]]
- $.name[мой любимый.doc]
- $.format[base64]
+ $.value[^file::load[my beloved.doc]]
+ $.name[my beloved.doc]
+ $.format[base64]
]
$.file2[
- $.value[^file::load[my beloved.doc]]
- $.name[мой любимый.doc]
- ]
+ $.value[^file::load[my beloved.doc]]
+ $.name[my beloved.doc]
+ ]
]
]
- !для отправки
- под unix используется программа с параметрами, задаваемая
+ для отправки под unix используется программа с параметрами, задаваемая
$MAIL.sendmail[команда]
- если не будет задана, проверяется, доступна ли
- /usr/sbin/sendmail или
- /usr/lib/sendmail
- и, если доступна, то запускается с параметром "-t".
- под win32 используется SMTP протокол, сервер задаётся
- $MAIL.SMTP[smtp.domain.ru]
-
-!image
- !$картинка[^image::measure[DATA]]
- смотрит на .ext case insensitive,
- умеет мерить пока только .gif и .jpg .jpeg
- !$картинка.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 строка=стиль линий '*** * '='*** * *** * *** * '
- !^картинка.html[[hash]] =
- !^image::load[фон.gif]
- только gif пока
- !^image::create(размер X;размер Y[;цвет фона default белый]])
- !^картинка.line(x0;y0;x1;y1;0xffFFff)
- !^картинка.fill(x;y;0xffFFff)
- !^картинка.rectangle(x0;y0;x1;y1;0xffFFff)
- !^картинка.bar(x0;y0;x1;y1;0xffFFff)
- !^картинка.replace(hex-цвет1;hex-цвет2)[table x:y вершины_многоугольника]
- !^картинка.polyline+(цвет)[table x:y точки]
- !^картинка.polygon(цвет)[table x:y вершины_многоугольника]
- !^картинка.polybar(цвет)[table x;y вершины_многоугольника]
- !^картинка.font[набор_букв;имя_файла_шрифта.gif][(ширина_пробела[;ширина_символа])]
- высота символа = высота картинки/количество букв в наборе
- если указана ширина_символа, то monospaced, если 0, то ширина_символа = ширине gif
- !^картинка.font[набор_букв;имя_файла_шрифта.gif;
- $.space(ширина_пробела) // по умолчанию = ширине gif
- $.width(ширина_символа) // см. выше, по умолчанию proportional
- $.spacing(расстояние между буквами) // по умолчанию = 1
- ]
- !^картинка.text(x;y)[текст_надписи] AS_IS
- !^картинка.length[текст_надписи] AS_IS
- !^картинка.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)
- !^картинка.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
- при заданных dest_w/dest_h делает изменение размера кусочка
- при уменьшении делает resample
- годится только для уменьшения простой[малоцветной] дребедени вроде графиков/pie,
- для thumbnais не годится.
- при не указанном dest_h сохраняет aspect ratio
- tolerance - некое число[квадрат расстояния в RGB пространстве до искомого цвета],
- определяющее прожорливость выделялки цветов из палитры [default=150]
- меньше - точнее приближает цвета, но они быстро кончаются
- больше - неточно приближает цвет, но бОльшей части хватит
- !^картинка.pixel(x;y)[(color)]
- узнать или задать цвет пиксела
-
-
-!file
- !$файл_из_post.name
- !$файл_из_post.size
- !$файлtиз_post.text
- !^файл.save[text|binary;имя файла[;$.charset[в какой кодировке сохраняем]]]
- !^file:delete[имя файла]
- !^file:find[имя файла][{когда не нашли}]
- !^file:list[путь[;шаблон-строка|шаблон-regex]] = table с колонками name dir
- !^file:list[путь;$.filter[шаблон-строка|шаблон-regex] $.stat(true)] = table с колонками name dir size [mca]date
- !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip][;опции]]
- !^file::create[text|binary;имя;data]
- !^file::create[text|binary;имя;data[;$.charset[кодировка букв в создаваемом файле] $.content-type[...]]]
- !^file::create[string-or-file-content[;$.name[имя] $.mode[text|binary] $.content-type[...] $.charset[...]]]
- !$файл_который_был_loaded.size
- !$файл_который_был_loaded_или_created.mode = text/binary
- !^file::stat[имя файла]
- !$файл_который_был_stated_или_loaded.size !.adate !.mdate !.cdate
- !^file::cgi[[text|binary;]имя файла[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
- возвращённый заголовок рассыпается на $поля
- $status
- $stderr
- !^file::exec[[text|binary;]имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under unix max 50 args]]]]]]]
- options:
- $.stdin[текст] если текст пуст, отключается автоматическое пересовывание данных HTTP-POST
- !^file:move[старое имя файла;новое имя файла]
- можно переименовывать и двигать каталоги[win32: но не через границу дисков]
- каталоги для dest создаются с правами 775
- каталог старого файла стирается, если после move он остаётся пуст
- !^file:copy[имя файла;имя копии файла]
- можно копировать только файлы
- !^file:lock[имя файла]{код}
- файл при необходимости создаётся
- блокируется
- выполняется код
- разблокируется
- Xchmod[...] НЕТ И НЕ БУДЕТ, ЧТОБЫ НЕ МОГЛИ СДЕЛАТЬ executable и запустить, даже если ftp запрещает chmod.
- !^file:dirname[/a/some.tar.gz]=/a (работает аналогично комманде *nix)
- !^file:dirname[/a/b/]=/a (работает аналогично комманде *nix)
- !^file:basename[/a/some.tar.gz]=some.tar.gz (работает аналогично комманде *nix)
- !^file:basename[/a/b/]=b (работает аналогично комманде *nix)
- !^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
- !^файл.sql-string[] внутри ^connect даст правильно escaped строку, которую можно в запрос отдать
- !^file::sql{query}[[
- $.name[имя_файла_для_download]
- $.content-type[пользовательский content-type]
- ]]
- результат запроса должен быть "одна строка".
- колонки:
- первая колонка - данные
- если есть вторая - это имя файла
- если есть третья - это content-type
- !^файл.base64[] encode
- !^file:base64[имя файла]
- encode
- !^file::base64[encoded string]
- !^file::base64[mode;имя файла;encoded string[;$.content-type[...]]]
- decode
- !^file:crc32[имя файла]
- вычисляет crc32 файла с указанным именем
- !^файл.crc32[]
- вычисляет crc32 объекта
- !^файл.md5[]
- !^file:md5[имя файла]
- выдает digest файла, длиной 16 байт в виде строки,
- где байты digest выданы в hex виде, впритык, в нижнем регистре
+ если не будет задана, проверяется, доступна ли /usr/sbin/sendmail или
+ /usr/lib/sendmail и, если доступна, то запускается с параметром "-t".
+ под Windows используется SMTP протокол, сервер задаётся
+ $MAIL.SMTP[smtp.domain.ru]
-!math
- !$math:PI
- !^math:round floor ceiling
- !^math:trunc frac
- !^math:abs sign
- !^math:exp log
- !^math:sin asin cos acos tan atan
- !^math:degrees radians
- !^math:pow sqrt
- !^math:random(ширина диапазона)
- !^math:uuid[]
+math
+ $math:PI
+ ^math:round floor ceiling
+ ^math:trunc frac
+ ^math:abs sign
+ ^math:exp log log10
+ ^math:sin asin cos acos tan atan atan2
+ ^math:degrees radians
+ ^math:pow sqrt
+ ^math:random(ширина диапазона)
+ ^math:convert[number|файл](base-from;base-to)[[ $.format[string|file] ]]
+ ^math:convert[number|файл][алфавит](base-to)[[ $.format[string|file] ]]
+ ^math:convert[number|файл](base-from)[алфавит][[ $.format[string|file] ]]
+ преобразует строку или файл с числом из одной системы исчисления в другую
+ система счисления может быть задана алфавитом, числом от 2 до 16 (эквивалентно алфавиту 0123456789ABCDEF), числом 256 (все ASCII символы)
+ ^math:uuid[ $.lower(bool) $.solid(bool) ]
22C0983C-E26E-4169-BD07-77ECE9405BA5
win32: пользуется cryptapi
- unix: пользуется /dev/urandom,
- если нет, /dev/random,
- если нет, rand
- [на solaris /dev/random можно добавить]
- !^math:uid64[]
- BA39BAB6340BE370
- !^math:md5[string]
+ unix: пользуется /dev/urandom,
+ если нет, /dev/random,
+ если нет, rand
+ ^math:uuid7[ $.lower(bool) $.solid(bool) ]
+ 0193CBF0-7898-7000-A391-AC513CC15658
+ https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7
+ ^math:uid64[ $.lower(bool) ]
+ 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'.
- !^math:crc32[string]
- вычисляет crc32 строки
- !^math:sha1[string]
- !^math:convert[number](base-from;base-to) преобразует строку с числом из одной системы исчисления в другую
- !^math:digest[[md5|sha1|sha256|sha512];строка или файл][[ $.format[hex|base64] $.hmac[ключ] ]]
- объединяет в себе возможность работы с разными алгоритмами криптографического хеширования.
- $.hmac[ключ] для проверки целостности переданных данных
-
-
-!inet
- !^inet:ntoa(long)
- !^inet:aton[IP]
- !^inet:name2ip[name][[ $.ipv[4|6|any] $.table(true) ]] прямое преобразование имени в IP адрес
- !^inet:ip2name[ip][ $.ipv[4|6|any] ]] обратное преобразование из IP адреса в имя
-
-
-!json
- !^json:parse[-json-строка-[;
- $.depth(максимальная глубина, default == 19)
- $.double(false) отключить встроенный парсинг чисел с плавающей точкой (по умолчанию включен)
- в этом случае они попадут в результирующий объект как строки
- $.int(false) отключить встроенный парсинг целых чисел (по умолчанию включен)
- в этом случае они попадут в результирующий объект как строки
- $.distinct[first|last|all] как будет происходить разбор дублирующихся ключей у объектов
- first -- будет оставлен первый встретившийся элемент
- last -- будет оставлен последний встретившийся элемент
- all -- будут оставлены все элементы. при этом элементы, начиная со 2
- получат числовые суффиксы (key_2 итд)
- по умолчанию дублирующиеся ключи приведут к exception
- $.object[method-junction] пользовательский метод[ключ;объект], которому будут передаваться все разобранные
- объекты и ключи объекта, метод возвращает новый объект
- $.array[method-junction] пользовательский метод, которому будут передаваться массивы
- ]]
- парсит json-строку в хэш
- !^json:string[system or user object[;
- $.skip-unknown(false) отключить exception и выдавать 'null' при сериализации объектов с типами
- отличных от void, bool, string, int, double, date, table, hash и file
- $.indent(true) форматировать результирующую строку табуляциями по глубине вложенности
- $.date[sql-string|gmt-string|iso-string|unix-timestamp] формат вывода даты, по умолчанию -- sql-string
- $.table[object|array|compact] формат вывода таблицы, по умолчанию -- object
- object: [{"c1":"v11","c2":"v12",...},{"c1":"v21","c2":"v22",...},...]
- array: [["c1","c2",...] || null (for nameless),["v11","v12",...],...]
- compact: ["v11" || ["v11","v12",...],...]
- $.file[text|base64|stat] вывести тело файла в указанном виде (по умолчание тело файла
- не попадает в output)
- $.xdoc[hash] параметры преобразования xdoc в строку (как в ^xdoc.string[])
- $.тип[method-junction] любой тип можно вывести с помощью пользовательского метода, который
- должен принимать 3 параметра: ключ, объект данного типа и опции
- вызова ^json:string[]
- $._default[имя метода] имя пользователького метода, при его наличии он будет вызван для
- сериализации
- $.void[null|string] неопределенное значение будет выдано в виде null (по умолчанию)
- или пустой строки
- ]]
- сериализует системный или пользовательский объект в json-строку
-
-
-!date
- !время типа time можно использовать в выражениях, подставляет
- количество дней с epoch [1 января 1970 (UTC)], дробное
- !строковое значение в местном времени, численное в UTC
- !по умолчанию используется установленная средствами OS временная зона
- !^date::now[]
- !^date::now(смещение в днях) выдаёт сейчас+смещение
- !^date::today[] дата на 00:00:00 текущего дня
- !^date::create(дней с epoch)
- !^date::create(year;month[;day[;hour[;minute[;second]]]])
- !^date::create[дата в формате %Y-%m-%d %H:%M:%S]
- для удобного создания по значению из базы
- формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
- формат2: %H:%M[:%S]
- !^date::create[дата в формате %Y-%m-%dT%H:%M[:%S]TZ]
- для создания по значению в формате ISO 8601
- формат TZ: Z(UTC) или +-hour[:minute] (смещение от UTC)
- !^date::unix-timestamp()
- !^дата.unix-timestamp[]
- !$дата.year month day hour minute second weekday yearday(0...) daylightsaving TZ weekyear
- read-only
- TZ="" << локальная зона
- !^дата.roll[year|month|day](+-смещение) сдвигает дату
- !^дата.roll[TZ;Новая зона] говорит, что дата в таком-то часовом поясе: влияет на .hour & Co
- !^date:roll[TZ;Новая зона] говорит, что по умолчанию все даты в таком-то часовом поясе
- !^дата.sql-string[[datetime|date|time]]
- datetime или без параметра -- %Y-%m-%d %H:%M:%S
- date -- %Y-%m-%d
- time -- %H:%M:%S
- where published='^дата.sql-string[]'
- !^date:calendar[rus|eng](год;месяц) выдаёт неименованную таблицу
- столбцы: 0..6, week, year
- !^date:calendar[rus|eng](год;месяц;день) выдаёт именнованную таблицу
- столбцы: year, month, day, weekday
- !^date:last-day(год;месяц) вернёт последний день месяца
- !^дата.last-day[] вернёт последний день месяца $дата
- !^дата.gmt-string[] Fri, 23 Mar 2001 09:32:23 GMT
- !^дата.iso-string[] 2001-03-23T12:32:23+3
+ ^math:crypt[password;salt]
+ salt prefix $apr1$ вызывает встроенный MD5 алгоритм,
+ если нет тела salt, оно создаётся случайным
+ $1$ вызывает MD5 алгоритм функции OS 'crypt', если поддерживается.
+ другие salt читайте документацию по функции OS 'crypt'.
+ ^math:crc32[string]
+ вычисляет crc32 строки
+ ^math:sha1[string]
+ ^math:digest[[md5|sha1|sha256|sha512];строка или файл][[ $.format[hex|base64|file] $.hmac[ключ строка|ключ файл] ]]
+ объединяет в себе возможность работы с разными алгоритмами криптографического хеширования.
+ $.hmac[ключ] для проверки целостности переданных данных
+
+memory
+ ^memory:compact[]
+ собрать мусор, освободив место под новые данные (предупреждение: память процесса никогда не освобождается)
+ полезно делать перед XSL transform
+ ^memory:auto-compact(частота сборки)
+ задает режим автоматической сборки мусора, от 0 (выключена) до 5 (максимальная)
+
+reflection
+ ^reflection:create[класс;конструктор[;пара[;мет[;ры]]]]
+ вызывает указанный конструктор класса (не более 100 параметров)
+ ^reflection:create[ $.class[name] $.constructor[name] $.arguments[ $.1[па] $.2[рам] $.3[етры] ] ]
+ вызывает указанный конструктор класса
+ ^reflection:classes[]
+ хеш со всеми классами. ключ = имя класса, значение бывает methoded (класс с методами) или void
+ ^reflection:class[объект]
+ класс переданного объекта
+ ^reflection:class_name[объект]
+ имя класса переданного объекта
+ ^reflection:base[объект]
+ родительский класс переданного объекта
+ ^reflection:base_name[объект]
+ имя родительского класса переданного объекта
+ ^reflection:class_by_name[имя класса]
+ получение класса по имени
+ ^reflection:class_alias[имя класса;новое имя класса]
+ задает псевдоним для указанного класса
+ ^reflection:def[class;имя класса]
+ проверка класса на существование
+ ^reflection:methods[класс]
+ хеш со списком методов указанного класса, значения - строки 'native' или 'parser'
+ ^reflection:method[класс или объект;имя метода]
+ возвращает junction-method класса или объекта
+ ^reflection:filename[объект или класс или метод]
+ возвращает имя файла, где определен объект, класс или метод
+ ^reflection:fields[класс или объект]
+ хеш со списком статических полей указанного класса или динамических полей указанного объекта
+ ^reflection:fields_reference[объект]
+ редактируемый хеш динамических полей указанного объекта
+ ^reflection:field[класс или объект;имя поля]
+ возвращает значение указанного поля класса или объекта. getter-ы игнорируются.
+ ^reflection:copy[источник;назначение]
+ копирует поля из одного объекта или класса в другой
+ ^reflection:uid[класс или объект]
+ возвращает идентификатор объекта или класса
+ ^reflection:method_info[класс;метод]
+ хеш с параметрами указанного метода класса
+ $.inherited[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
+ $.overridden[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
+ для native классов возвращается хеш:
+ .min_params(минимально необходимое число параметров)
+ .max_params(максимально возможное число параметров)
+ .call_type[dynamic|static|any]
+ для parser классов возвращается хеш:
+ ключ - номер параметра (0, 1, ...), значение - имя параметра
+ ^reflection:dynamical[[object or class, caller if absent]]
+ возвращает true, если метод был вызван из динамического контекста при передаче
+ параметра возвращает true, если передан динамический объект, false если класс
+ ^reflection:delete[класс или объект;имя переменной]
+ удаляет переменную с указанным именем в указанном классе или объекте
+ ^reflection:is[имя элемента;имя класса][[контекст]]
+ аналог оператора 'is', позволяющий определить, является ли элемент кодом.
+ ^reflection:tainting[[язык|tainted|optimized];строка]
+ строка, в которой каждому символу исходной строки соотвествует символ с кодом преобразования
+ ^reflection:stack[ $.args(false/true) $.locals(false/true) $.limit(n) $.offset(o)]
+ текущее состояние стека вызовов методов на парсере
+ ^reflection:mixin[источник; $.to[получатель] $.name[имя] $.methods(true/false) $.fields(true/false) $.overwrite(false/true) ]
+ копирует в класс методы и поля другого класса
+
+request
+ $request:query
+ $request:uri
+ $request:document-root
+ каталог, относительно которого считаются пути в parser, по-умолчанию = $env:DOCUMENT_ROOT
+ $request:argv
+ hash с параметрами коммандной строки. ключи 0, 1, ... [0 -- имя обрабатываемого файла]
+ $request:charset
+ кодировка исходного документа
+ используется при upper/lower и match[][i]
+ ПРЕДУПРЕЖДЕНИЕ: необходимо задать $request/response:charset до использования полей класса form
+ $request:method
+ метод запроса (GET|POST|PUT)
+ $request:body
+ тело POST-запроса в виде текста
+ $request:body-file
+ тело POST-запроса в виде файла
+ $request:body-charset
+ кодировка POST-запроса
+ $request:headers
+ хеш с заголовками запроса (без префикса HTTP_)
+
+response
+ $response:поле[значение] и можно считать старое - $response:поле
+ значение может быть string а может быть hash:
+ $value[abc] field: {abc}<<часть
+ $attribute[zzz] field: abc; {attribute=zzz}<<часть
+ значение поля или атрибута может быть string или date
+ если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
+ $response:headers
+ накопленные поля
+ $response:body[DATA]
+ замещает стандартный ответ
+ $response:download[DATA]
+ замещает стандартный ответ, выставляет флаг, заставляющий browser предложить download
+ $response:status
+ ^response:clear[] забыть все заданные response поля
+ $response:charset
+ кодировка клиента т.е. та,
+ 1) из которой будут перекодированы $form:поля после забирания из browser'а
+ 2) в которую документ будет перекодирован перед отдаванием в browser
+ 3) в которую будет перекодирован текст языка uri
+ не добавляет к content-type ничего, если хочется, это надо сделать вручную
+ ПРЕДУПРЕЖДЕНИЕ: необходимо задать $request/response:charset до использования полей класса form
+status
+ $status:sql
+ cache table
+ url time
+ url time
+ url time
+ $status:stylesheet
+ cache table
+ file time
+ file time
+ file time
+ $status:rusage hash
+ utime user time used
+ stime system time used
+ maxrss max resident set size
+ 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
+ $status:mode
+ режим работы, cgi|console|mail|httpd|apache|isapi
+ $status:log-filename
+ путь к журналу ошибок parser3.log
xdoc(xnode)
- !$xdoc.search-namespaces hash, where keys=prefixes, values=urls
-
+ $xdoc.search-namespaces hash, where keys=prefixes, values=urls
+
DOM1 attributes:
- !readonly attribute DocumentType doctype
- Xreadonly attribute DOMImplementation implementation
- !readonly attribute Element documentElement
+ readonly attribute DocumentType doctype
+ readonly attribute Element documentElement
DOM1 methods:
- !Element createElement(in DOMString tagName)
- !DocumentFragment createDocumentFragment()
- !Text createTextNode(in DOMString data)
- !Comment createComment(in DOMString data)
- !CDATASection createCDATASection(in DOMString data)
- !ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data)
- !Attr createAttribute(in DOMString name)
- !EntityReference createEntityReference(in DOMString name)
- !NodeList getElementsByTagName(in DOMString tagname)
+ Element createElement(in DOMString tagName)
+ DocumentFragment createDocumentFragment()
+ Text createTextNode(in DOMString data)
+ Comment createComment(in DOMString data)
+ CDATASection createCDATASection(in DOMString data)
+ ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data)
+ Attr createAttribute(in DOMString name)
+ EntityReference createEntityReference(in DOMString name)
+ NodeList getElementsByTagName(in DOMString tagname)
DOM2 some methods:
- !^.getElementById[elementId] = xnode
- The DOM implementation must have information that says which attributes are of type ID.
- Attributes with the name "ID" are not of type ID unless so defined.
- Implementations that do not know whether attributes are of type ID or not
+ ^.getElementById[elementId] = xnode
+ The DOM implementation must have information that says which attributes are of type ID.
+ Attributes with the name "ID" are not of type ID unless so defined.
+ Implementations that do not know whether attributes are of type ID or not
are expected to return null.
- !кодировка строк и умолчание для $.encoding
- !равно текущей кодировке выходной страницы,
- $response:charset
+ кодировка строк и умолчание для $.encoding равно текущей кодировке выходной страницы, $response:charset
+
::sql{...}
- !::create[[URI]]{} старое имя 'set'
- !::create[[URI]][qualifiedName]
+ ::create[[URI]]{} старое имя 'set'
+ ::create[[URI]][qualifiedName]
URI default = disk path to requested document
для каталогов конечный / обязателен
- !::create[file] can be usable:
- $f[^file::load[binary;http://;some HTTP options here...]]
- $x[^xdoc::create[$f]]
- !::load[file.xml[;опции]]
- !.transform[rules.xsl|xdoc][[params hash]] выдаёт dom
+ ::create[file] can be usable:
+ $f[^file::load[binary;http://;some HTTP options here...]]
+ $x[^xdoc::create[$f]]
+ ::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
- output options идентичны атрибутам xsl:output
+ method = "xml" | "html" | "text"
+ version = nmtoken
+ encoding = string
+ omit-xml-declaration = "yes" | "no"
+ standalone = "yes" | "no"
+ cdata-section-elements = qnames
+ indent = "yes" | "no"
+ media-type = string />
+ параметры передаются как есть, не xpath выражения
+
+ .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]
+ [примечание: в параметр всегда приходит лидирующая /, даже, если параметров вообще не было]
- !если на документ ссылаются так:
- parser://method/param/to/that/method
- то в качестве документа используется ^MAIN:method[/param/to/that/method]
- [примечание: в параметр всегда приходит лидирующая /, даже, если параметров вообще не было]
-
-!xnode
+xnode
DOM1 attributes:
- !$node.nodeName
- !$node.nodeValue
- !read
- !write
- !$node.nodeType = int
- ELEMENT_NODE = 1
- ATTRIBUTE_NODE = 2
- TEXT_NODE = 3
- CDATA_SECTION_NODE = 4
- ENTITY_REFERENCE_NODE = 5
- ENTITY_NODE = 6
- PROCESSING_INSTRUCTION_NODE = 7
- COMMENT_NODE = 8
- DOCUMENT_NODE = 9
- DOCUMENT_TYPE_NODE = 10
- DOCUMENT_FRAGMENT_NODE = 11
- NOTATION_NODE = 12
+ $node.nodeName
+ $node.nodeValue
+ read
+ write
+ $node.nodeType = int
+ ELEMENT_NODE = 1
+ ATTRIBUTE_NODE = 2
+ TEXT_NODE = 3
+ CDATA_SECTION_NODE = 4
+ ENTITY_REFERENCE_NODE = 5
+ ENTITY_NODE = 6
+ PROCESSING_INSTRUCTION_NODE = 7
+ COMMENT_NODE = 8
+ DOCUMENT_NODE = 9
+ DOCUMENT_TYPE_NODE = 10
+ DOCUMENT_FRAGMENT_NODE = 11
+ NOTATION_NODE = 12
$vasyaNode.type==$xnode:ELEMENT_NODE
- !$node.parentNode
- !$node.childNodes = array of nodes
- !$node.firstChild
- !$node.lastChild
- !$node.previousSibling
- !$node.nextSibling
- !$node.ownerDocument = xdoc
- !$node.prefix
- !$node.namespaceURI
- !$element_node.attributes = hash of xnodes
- !$element_node.tagName
- !$attribute_node.specified = boolean
- 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
+ $node.parentNode
+ $node.childNodes = array of nodes
+ $node.firstChild
+ $node.lastChild
+ $node.previousSibling
+ $node.nextSibling
+ $node.ownerDocument = xdoc
+ $node.prefix
+ $node.namespaceURI
+ $element_node.attributes = hash of xnodes
+ $element_node.tagName
+ $attribute_node.specified = boolean
+ true if the attribute received its value explicitly in the XML document,
+ or if a value was assigned programmatically 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
+ $pi_node.target = target of this processing instruction
+ XML defines this as 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 ?>.
+ $pi_node.data = The content of this processing instruction
+ From the first non-whitespace character after the target
+ to the character immediately preceding the ?>.
document_node.
readonly attribute DocumentType doctype
- readonly attribute DOMImplementation implementation
+ readonly attribute DOMImplementation implementation
readonly attribute Element documentElement
document_type_node.
- !readonly attribute DOMString name
+ readonly attribute DOMString name
readonly attribute NamedNodeMap entities
readonly attribute NamedNodeMap notations
- !notation_node.
- !readonly attribute DOMString publicId
- !readonly attribute DOMString systemId
-
- !DOM1 node methods:
- !Node insertBefore(in Node newChild,in Node refChild)
- !Node replaceChild(in Node newChild,in Node oldChild)
- !Node removeChild(in Node oldChild)
- !Node appendChild(in Node newChild)
- !boolean hasChildNodes()
- !Node cloneNode(in boolean deep)
-
- !DOM1 element methods:
- !DOMString getAttribute(in DOMString name)
- !void setAttribute(in DOMString name, in DOMString value) raises(DOMException)
- !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)
- !NodeList getElementsByTagName(in DOMString name)
- !void normalize()
-
-
- !Introduced in DOM Level 2:
- !Node importNode(in Node importedNode, in boolean deep) raises(DOMException)
- !NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName)
- !boolean hasAttributes()
+ notation_node.
+ readonly attribute DOMString publicId
+ readonly attribute DOMString systemId
+
+ DOM1 node methods:
+ Node insertBefore(in Node newChild,in Node refChild)
+ Node replaceChild(in Node newChild,in Node oldChild)
+ Node removeChild(in Node oldChild)
+ Node appendChild(in Node newChild)
+ boolean hasChildNodes()
+ Node cloneNode(in boolean deep)
+
+ DOM1 element methods:
+ DOMString getAttribute(in DOMString name)
+ void setAttribute(in DOMString name, in DOMString value) raises(DOMException)
+ 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)
+ NodeList getElementsByTagName(in DOMString name)
+ void normalize()
+
+ Introduced in DOM Level 2:
+ Node importNode(in Node importedNode, in boolean deep) raises(DOMException)
+ NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName)
+ boolean hasAttributes()
- !XPath:
- !^node.select[xpath/query/expression] = array of nodes,
+ XPath:
+ ^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 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
- If index or size is negative, or greater
- than the allowed value
- DOMSTRING_SIZE_ERR
- If the specified range of text does not
- fit into a DOMString
- HIERARCHY_REQUEST_ERR
- If any node is inserted somewhere it
- doesn't belong
- WRONG_DOCUMENT_ERR
- If a node is used in a different
- document than the one that created it
- (that doesn't support it)
- INVALID_CHARACTER_ERR
- If an invalid character is specified,
- such as in a name.
- NO_DATA_ALLOWED_ERR
- If data is specified for a node which
- does not support data
- NO_MODIFICATION_ALLOWED_ERR
- If an attempt is made to modify an
- object where modifications are not
- allowed
- NOT_FOUND_ERR
- If an attempt was made to reference a
- node in a context where it does not
- exist
- NOT_SUPPORTED_ERR
- If the implementation does not support
- the type of object requested
- INUSE_ATTRIBUTE_ERR
- If an attempt is made to add an
- attribute that is already inuse
- elsewhere
-
-!memory
- !^memory:compact[] собрать мусор, освободив место под новые данные
- (предупреждение: память процесса никогда не освобождается)
- полезно делать перед XSL transform.
-
-!status
- !чтобы класс был доступен, в apache нужно сказать
-
- ParserStatusAllowed
-
- !в cgi доступен везде
- !в isapi не доступен нигде
-
- !$status:sql hash
- !cache table
- url time
- url time
- url time
- !$status:stylesheet
- !cache table
- file time
- file time
- file time
-
- !$status:rusage hash
- !utime user time used
- !stime system time used
- !maxrss max resident set size
- !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 строку
+ ^node.selectSingle[xpath/query/expression] = first node 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
DATA::=string | file | hash
+ hash вида
+ [
+ $.file[имя файла на диске]
+ $.name[имя файла для пользователя]
+ $.mdate[date]
+ ]
-!hash вида
-[
- $.file[имя файла на диске]
- $.name[имя файла для пользователя]
- $.mdate[date]
-]
-
-!MAIN
- это класс, загружаемый на автомате из конфигурационного auto.p,
- кучи auto.p и запрашиваемого документа:
- !конфигурационный auto.p
- cgi:
- 1. или полный путь из переменной окружения CGI_PARSER_SITE_CONFIG
- или рядом с бинарником parser'а
+MAIN
+ это класс, загружаемый на автомате из конфигурационного auto.p, кучи auto.p и запрашиваемого документа:
+ конфигурационный auto.p
+ cgi:
+ 1. или полный путь из переменной окружения CGI_PARSER_SITE_CONFIG или рядом с бинарником parser'а
isapi: windows directory
- apache module:
+ apache module:
1) ParserConfig [can be in .htaccess]
- !auto.p вниз от DOCUMENT_ROOT/ по дереву до каталога с обрабатываемым файлом включительно
+ auto.p вниз от DOCUMENT_ROOT/ по дереву до каталога с обрабатываемым файлом включительно
класс собирается из всех этих файлов, последующие становятся родителями предыдущих
имя последнего загруженного MAIN, имён у предыдущих нет
-
- !после загрузки MAIN класса вызывается его @main[]
- !результат которого передаётся в его @postprocess[data] if($data is string) ...
- !результат которого отдаётся пользователю
-
-!если встречается ошибка и try не задан, её можно красиво сообщить пользователю,
- !определив
- !@unhandled_exception[exception;stack]
- !$exception.type строка "тип проблемы"
- !$exception.file $exception.lineno $exception.colno файл, строка и позиция, где случилась проблема [если не запрещены при компиляции]
- !$exception.source строка, из-за которой случилась проблема
- !$exception.comment комментарий english
- !stack табличка из колонок file line name,
- там лежат в обратном порядке имена[name] и места вызовов[file line]
- операторов/методов, приведших к ошибке.
-
-!при загрузке файла (file::load, table::load, xdoc::load) можно указать такое имя файла:
- !http://domain/document[?params<> создает http.status ошибку,
- !это можно отключить, передав
- !$.any-status(1)
- !$.charset[кодировка удалённых документов по-умолчанию], если сервер вернёт content-type:charset - ОНА_ПЕРЕБИВАЕТ
- !$.response-charset[кодировка удалённых документов], не перебиваеся content-type:charset
- !$.user[пользователь]
- !$.password[пароль]
- !file::load в дополнительные поля записывает
- !ПОЛЕ:значение (имена полей ответа заглавными буквами)
- !tables << хеш их ПОЛЕ->table с единственным столбцом "value".
+ $.body[string|file]
+ по-умолчанию, user-agent=parser3
+ по-умолчанию, получение http status != 200 >> создает http.status ошибку, это можно отключить, передав $.any-status(1)
+ $.charset[кодировка удалённых документов по-умолчанию], если сервер вернёт content-type:charset - ОНА ПЕРЕБИВАЕТ
+ $.response-charset[кодировка удалённых документов], не перебиваеся content-type:charset
+ $.user[пользователь]
+ $.password[пароль]
+ file::load в дополнительные поля записывает
+ ПОЛЕ:значение (имена полей ответа заглавными буквами)
+ tables << хеш их ПОЛЕ->table с единственным столбцом "value"
в таких таблицах можно брать повторяющиеся заголовки. например, несколько set-cookies
todo:сделать отдельный cookies
-!системные типы ошибок:
- !parser.compile ^test[} компиляция (непарная скобка, ...)
- !parser.runtime ^if(0). параметры (больше/меньше, чем нужно, не тех типов, ...)
- !number.zerodivision ^eval(1/0) ^eval(1%0)
- !number.format ^eval(abc*5)
- !file.lock shared/exclusive lock error
- !file.missing ^file:delete[delme] not found
- !file.access ^table::load[.] no rights
- !file.read ^file::load[...] error while reading file
- !file.seek seek failed
- !file.execute ^file::cgi[...] incorrect cgi header/can't execute
- !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
+системные типы ошибок:
+ parser.compile ^test[} компиляция (непарная скобка, ...)
+ parser.runtime ^if(0). параметры (больше/меньше, чем нужно, не тех типов, ...)
+ number.zerodivision ^eval(1/0) ^eval(1%0)
+ number.format ^eval(abc*5)
+ file.lock shared/exclusive lock error
+ file.missing ^file:delete[delme] not found
+ file.access ^table::load[.] no rights
+ file.read ^file::load[...] error while reading file
+ file.seek seek failed
+ file.execute ^file::cgi[...] incorrect cgi header/can't execute
+ 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
- !date.range ^date::create(1950;1;1) date out of valid range
+ 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 does not accept connections
+ http.timeout ^file::load[http://host/doc] 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
+ date.range ^date::create(10000;1;1) date out of valid range
если в MAIN определён $SIGPIPE(1) то в случае, если обработка была прервана пользователем, сообщение
- об этом будет записано в parser3.log (раньше оно всегда писалось)
+ об этом будет записано в parser3.log
-если описание метода содержит локальную переменную result в явном виде
- (есть и неявная переменная)
- то код вывода пробельных литералов не попадает в конечный байт-код.
+если описание метода содержит локальную переменную result в явном виде (есть и неявная переменная)
+ то код вывода пробельных литералов не попадает в конечный байт-код
+$Id: operators.ru.txt,v 1.261 2024/12/20 18:59:22 moko Exp $