ПРЕПРОЦЕССОР
При компиляции процедуры, первым делом, осуществляется ее обработка препроцессором - специальной компонентой OpenEdge и только после, осуществляется ее непосредственная компиляция. Другими словами, операция компиляции процедуры состоит из двух этапов:
- Обработка препроцессора;
- Компиляция.
Просматривая исходный текст процедуры, препроцессор обрабатывает специальные, понятные только ему, препроцессорные имена (константы) и директивы (специальные операторы), содержащиеся в нем. Отличительной особенностью препроцессорных имен и директив, является то, что все они начинаются с символа &.
Применение препроцессорных выражений позволяет создавать процедуры-шаблоны, компилируемый код которых может изменяться в зависимости от тех или иных условий.
ПРЕПРОЦЕССОРНЫЕ ИМЕНА
Препроцессорные имена являются текстовыми константами. Все препроцессорные имена для начала должны быть объявлены. Объявление препроцессорных имен осуществляется с помощью одной из двух препроцессорных директив:
&GLOBAL-DEFINE preprocessor-name definition
&SCOPE-DEFINE preprocessor-name definition
- preprocessor-name - идентификатор препроцессорного имени;
- definition - текстовая строка, значение препроцессорного имени.
Препроцессорные имена, объявленные с помощью директивы &GLOBAL-DEFINE, являются глобальными и доступны всем процедурам, компилируемым вместе.
&SCOPE-DEFINE объявляет локальные препроцессорные имена, область видимости которых ограничивается областью процедуры, в которой они объявлены.
При использовании в тексте процедуры препроцессорные имена необходимо указывать в фигурных скобках.
{&preprocessor-name}
При компиляции, препроцессор осуществляет замену всех используемых препроцессорных имен их значениями.
&SCOPE-DEFINE TABLE-NAME acct
FIND FIRST {&TABLE-NAME} WHERE RECID({&TABLE-NAME}) EQ tmprecid.id
NO-LOCK NO-ERROR.
После обработки препроцессором, компилируемый код будет выглядеть следующим образом:
&SCOPE-DEFINE TABLE-NAME acct
FIND FIRST acct WHERE RECID(accy) EQ tmprecid.id NO-LOCK NO-ERROR
Директива &UNDEFINE удаляет объявленное ранее препроцессорное имя.
&UNDEFINE preprocessor-name
После того, как препроцессорное имя было удалено, оно может быть повторно объявлено с новым значением.
Помимо объявляемых разработчиком препроцессорных имен, существуют стандартные, доступные для использования:
- {&BATCH-MODE} - значение YES для batch-mode (стартовый параметр -b), иначе значение - NO;
- {&FILE-NAME} - имя компилируемого файла;
- {&LINE-NUMBER} - номер текущей строки в компилируемом файле;
- {&OPSYS} - имя операционной системы;
- {&SEQUENCE} - целочисленное значение, изначально равное 0 и увеличивающееся на единицу при каждом обращении к нему;
- {&WINDOWS-SYSTEM} - Windows-система.
УПРАВЛЯЮЩИЕ ПРЕПРОЦЕССОРНЫЕ ДИРЕКТИВЫ
Управляющими являются директивы: &IF, &THEN, &ELSEIF, &ELSE и &ENDIF. Данные директивы аналогичны ABL-операторами IF...THEN...ELSE.
&IF expression &THEN
block
[&ELSEIF expression &THEN
block] ...
[&ELSE
block]
&ENDIF
Выражения expression могут состоять только из препроцессорных имен, констант, операций (арифметических, логических и операций сравнения), а также ABL-функций:
ABSOLUTE | ASC | AUDIT-ENABLED |
DATE | DAY | DBTYPE |
DECIMAL | ENCODE | ENTRY |
ETIME | EXP | FILL |
INDEX | INT64 | INTEGER |
KEYWORD | KEYWORD-ALL | LC |
LEFT-TRIM | LENGTH | LIBRARY |
LOG | LOOKUP | MATCHES |
MAXIMUM | MEMBER | MINIMUM |
MODULO | MONTH | NUM-ENTRIES |
OPSYS | PROPATH | PROVERSION |
RANDOM | REPLACE | RIGHT-TRIM |
R-INDEX | ROUND | SQRT |
STRING | SUBSTITUTE | SUBSTING |
TIME | TODAY | TRIM |
TRUNCATE | WEEKDAY | YEAR |
Если значение выражения expression директивы &IF является истинным (TRUE), то скомпилирован будет код (block), следующий за директивой &THEN.
В противном случае, при указанной директиве &ELSEIF осуществляется вычисление его выражения expression и если оно истино (TRUE), то скомпилирован будет код, следующий за директивой &THEN.
Если значение выражения директивы &ELSEIF является ложным (FALSE), или, если данная директива вовсе не указана, то при наличии директивы &ELSE будет скомпилирован код, следующий за ней.
Директива &ENDIF является закрывающей для директивы &IF.
&IF DEC(PROVERSION) >= 11 &THEN
DISPLAY "Hello, New Progress World".
&ELSE
DISPLAY "Hello, Progress World"
&ENDIF
Если версия Progress OpenEdge, в которой осуществляется компиляция 11 и выше, то при запуске скомпилированной процедуры будет выводится сообщение:
Hello, New Progress World
При версии Progress OpenEdge ниже 11, процедура будет выводить сообщение:
Hello, Progress World
ДИРЕКТИВА MESSAGE
Директива &MESSAGE осуществляет вывод сообщения во время компиляции.
&MESSAGE text-string
- text-string - текст выводимого сообщения.
&IF OPSYS EQ "UNIX" &THEN
&MESSAGE Данная процедура не предназначена для *NIX систем
&ELSE
DISPLAY "Hello World".
&ENDIF
Если компиляция процедуры осуществляется в *NIX системе, то скомпилированная процедура не будет выполнять никаких действий.