38.9. Директивы препроцессора
Препроцессор ecpg
поддерживает ряд директив, которые позволяют управлять разбором и обработкой исходных файлов.
38.9.1. Включение файлов
Для включения внешнего файла в программу со встраиваемым SQL, используется конструкция:
EXEC SQL INCLUDEимя_файла
; EXEC SQL INCLUDE <имя_файла
>; EXEC SQL INCLUDE "имя_файла
";
Встретив такую директиву, препроцессор встраиваемого SQL будет искать файл
, обрабатывать его и включать в выходной код C. В результате встраиваемые SQL-операторы во включённом таким образом файле будут обработаны корректно.имя_файла
.h
Препроцессор ecpg
будет искать указанный файл в нескольких каталогах в следующем порядке:
- текущий каталог
/usr/local/include
- каталог включаемых файлов Postgres Pro, определённый во время сборки (например,
/usr/local/pgsql/include
) /usr/include
Но когда используется форма EXEC SQL INCLUDE "
, просматривается только текущий каталог.имя_файла
"
В каждом каталоге препроцессор будет сначала искать файл с заданным именем, а если не обнаружит его, попытается найти файл с добавленным расширением .h
(если только заданное имя файла уже не содержит это расширение).
Заметьте, что команда EXEC SQL INCLUDE
не равнозначна включению:
#include <имя_файла
.h>
так как во втором случае включаемый файл не проходит через препроцессор SQL-команд. Естественно, директиву C #include
можно по-прежнему применять для включения других заголовочных файлов.
Примечание
Имя включаемого файла чувствительно к регистру, несмотря на то, что остальная команда EXEC SQL INCLUDE
подчиняется обычным правилам чувствительности к регистру SQL.
38.9.2. Директивы define и undef
Во встраиваемом SQL есть конструкция, подобная директиве #define
, известной в C:
EXEC SQL DEFINEимя
; EXEC SQL DEFINEимя
значение
;
Используя её, можно определить имя:
EXEC SQL DEFINE HAVE_FEATURE;
И также можно определить константы:
EXEC SQL DEFINE MYNUMBER 12; EXEC SQL DEFINE MYSTRING 'abc';
Удалить предыдущее определение позволяет команда undef
:
EXEC SQL UNDEF MYNUMBER;
Разумеется, в программе со встраиваемым SQL можно продолжать использовать версии #define
и #undef
языка C. Отличие состоит в том, когда вычисляются определяемые значения. Когда применяется команда EXEC SQL DEFINE
, вычислять определения и подставлять значения будет препроцессор ecpg
. Например, если написать:
EXEC SQL DEFINE MYNUMBER 12; ... EXEC SQL UPDATE Tbl SET col = MYNUMBER;
подстановку выполнит ecpg
и компилятор C никогда не увидит имени или идентификатора MYNUMBER
. Заметьте, что с другой стороны #define
не подходит для определения константы, которую вы хотите использовать во встраиваемом SQL, так как препроцессор встраиваемого SQL не сможет увидеть это определение.
Если в командной строке препроцессора ecpg
указано несколько входных файлов, EXEC SQL DEFINE
и EXEC SQL UNDEF
не влияют на них: каждый файл начинается только с символов, определённых ключами -D
в командной строке.
38.9.3. Директивы ifdef, ifndef, elif, else и endif
Для условной компиляции блоков кода можно использовать следующие указания:
EXEC SQL ifdef
имя
;Проверяет
имя
и обрабатывает последующие строки, еслиимя
было определено командойEXEC SQL define
.имя
EXEC SQL ifndef
имя
;Проверяет
имя
и обрабатывает последующие строки, еслиимя
не было определено командойEXEC SQL define
.имя
EXEC SQL elif
имя
;Начинает необязательный альтернативный блок после указания
EXEC SQL ifdef
илиимя
EXEC SQL ifndef
. Количество блоковимя
elif
может быть любым. Строки, следующие заelif
, будут обрабатываться, еслиимя
определено и при этом не был обработан ни один из блоков той же конструкцииifdef
/ifndef
...endif
.EXEC SQL else;
Начинает необязательный заключительный блок после указания EXEC SQL ifdef
имя
или EXEC SQL ifndefимя
. Последующие строки будут обрабатываться, если не был обработан ни один из блоков той же конструкцииifdef
/ifndef
...endif
.EXEC SQL endif;
Завершает конструкцию
ifdef
/ifndef
...endif
. Последующие строки обрабатываются обычным образом.
Конструкции ifdef
/ifndef
...endif
могут быть вложенными, на глубину до 127 уровней.
Так будет скомпилирована только одна из трёх команд SET TIMEZONE
:
EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; EXEC SQL elif TZNAME; EXEC SQL SET TIMEZONE TO TZNAME; EXEC SQL else; EXEC SQL SET TIMEZONE TO 'GMT'; EXEC SQL endif;