ПРЕПРОЦЕССОР

При компиляции процедуры, первым делом, осуществляется ее обработка препроцессором - специальной компонентой 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, в которой осуществляется компиляция 11 и выше, то при запуске скомпилированной процедуры будет выводится сообщение:

Hello New Progress World

При версии Progress ниже 11, процедура будет выводить сообщение:

Hello Progress World


ДИРЕКТИВА MESSAGE


Директива &MESSAGE осуществляет вывод сообщения во время компиляции.

&MESSAGE text-string

  • text-string - текс выводимого сообщения.
&IF OPSYS EQ "UNIX" &THEN
   &MESSAGE Данная процедура не предназначена для *NIX систем
&ELSE
   DISPLAY "Hello World".
&ENDIF

Если компиляция процедуры осуществляется в *NIX системе, то скомпилированная процедура не будет выполнять никаких действий.

Вы здесь: Главная Основы ABL ПРЕПРОЦЕССОР