Скриптер
Участник
Пользователь
- Сообщения
- 336
- Реакции
- 414
- Помог
- 7 раз(а)
Автор: Albertio
Первоисточники: Репозиторий Pawn на GitHub | Репозиторий AMX Mod X на GitHub | Директивы препроцессора | AMX ASM & Оператор #emit | Директива препроцессора - #pragma
Распространение данной статьи запрещено без указания ссылки на первоисточник.
Примечание: Все директивы должны быть первыми в строке и начинаться с символа "#", а полная инструкция не может занимать более одной строки - за исключением #define.
Выдает ошибку во время компиляции, если предоставленное постоянное выражение равно нулю. Директива #assert используется для защиты от определенных реализацией конструкций, от которых может зависеть программа, таких как размер ячейки в битах, или количество упакованных символов в ячейке.
Определяет макрос подстановки текста. Шаблон сопоставляется со всеми строками, считанными из исходных файлов; совпавшие участки заменяются текстами замены. Шаблон и тексты замены могут содержать параметры, обозначаемые от "%0" до "%9".
Директива #emit служит в качестве поточного ассемблера. По сути, это встроенный компилятор, если вы знаете AMX, вы можете использовать его для вставки опкодов AMX непосредственно в ваш код. Единственное ограничение - он допускает только один аргумент. Синтаксис: #emit <опкод> <операнд> может быть рациональным числом, целым числом или(локальным или глобальным) символом(переменные, функции и метки).
Основные инструкции:
Закрывает текущий файл и тем самым игнорирует весь текст, расположенный ниже директивы #endinput. Директива #endscript является синонимом #endinput.
Сигнализирует об "ошибке пользователя" с указанным сообщением. Ошибки пользователя являются фатальными ошибками, и они служат той же цели, что и директива #assert.
Части программы могут быть разобраны или проигнорированы в зависимости от определенных условий. PAWN парсер(компилятор или интерпретатор) генерирует код только для тех частей, для которых условие истинно.
За директивой #if должно следовать постоянное выражение. Чтобы проверить, определена ли переменная или константа, используйте оператор defined.
После начальной директивы #if может следовать ноль или более директив #elseif. Эти блоки пропускаются, если любой из предшествующих блоков #if или #elseif был разобран(т.е. не пропущен). Как и в случае с директивой #if, за выражением #elseif должно следовать постоянное выражение.
Директива #else заставляет парсер пропустить все строки до #endif, если предыдущая #if или любая из предыдущих директив #elseif были "истинными", и парсить эти строки, если все предыдущие блоки были пропущены. Директива #else может быть опущена; если она присутствует, то с каждым #if может быть связано только одно #else.
Директива #endif завершает часть программы, которая разбирается условно. Условные директивы могут быть вложенными, и каждая директива #if должна завершаться директивой #endif.
Вставляет содержимое указанного файла в текущую позицию внутри текущего файла. Имя файла в угловых скобках ("<" и ">") относится к системному файлу; PAWN парсер(компилятор или интерпретатор) будет искать такие файлы только в заданном списке каталогов, но не в "текущем" каталоге. Имена файлов без кавычек или в двойных кавычках - это обычные включаемые файлы, которые PAWN парсер будет искать сначала в текущем каталоге.
PAWN парсер сначала пытается открыть файл с указанным именем. Если это не удается, он пытается добавить к имени файла расширения ".inc", ".p" и ".pawn"(в таком порядке). Предлагаемое по умолчанию расширение включаемых файлов - ".inc".
Если файл может быть успешно открыт, директива #include определяет константу с именем "inc" плюс базовое имя файла(имя файла без пути и расширения) и значением 1. Если константа уже существует, директива #include пропускает открытие и включение файла, тем самым предотвращая двойное включение. Для принудительного двойного включения удалите определение константы с помощью директивы #undef перед вторым включением файла.
“pragma” - это крючок для парсера для указания дополнительных настроек, таких как уровни предупреждений или дополнительные возможности.
Устанавливает максимальный размер в байтах, до которого может вырасти скомпилированный скрипт. Эта прагма полезна для(встроенных) сред, где максимальный размер скрипта ограничен жестким верхним пределом. Если объем оперативной памяти для данных и стека не задан(см. #pragma amxram), это значение относится к общим требованиям к памяти; если объем оперативной памяти задан явно, это значение дает только объем памяти, необходимый для кода и статических данных.
PAWN парсер может переводить символы в символьных константах и в распакованных строках в "широкие" символы Unicode/UCS-4. Эта #pragma указывает кодовую страницу, которая должна быть использована для перевода.
Идентификаторы кодовой страницы
PAWN парсер может записывать сгенерированный P-код в компактной или обычной("некомпактной") кодировке. Значение по умолчанию зависит от конфигурации парсера(и, возможно, от настроек пользователя). Эта #pragma позволяет автору сценария отменить значение по умолчанию и принудительно использовать компактную кодировку(когда значение ненулевое) или принудительно использовать обычную кодировку(когда значение нулевое). Особенно полезно отключение компактного кодирования(принудительное использование обычного кодирования), поскольку PAWN парсер может оказаться не в состоянии скомпилировать определенный скрипт в режиме "компактного кодирования".
Определяет символ, который будет использоваться для обозначения начала "управляющей последовательности". По умолчанию управляющим символом является "\".
Пример: #pragma ctrlchar '$'
Вы можете задать новое значение управляющего символа в виде символьной константы(между одинарными кавычками) или в виде десятичного или шестнадцатеричного значения. Если вы опустите значение нового управляющего символа, парсер вернется к управляющему символу по умолчанию.
Последующий символ помечается как "устаревший". Если сценарий использует его, парсер выдает предупреждение.
Устанавливает размер в ячейках блока памяти для динамических данных(стека и кучи) на значение, заданное выражением. Размер блока динамических данных по умолчанию определяется реализацией. Реализация может также выбрать увеличение блока по мере необходимости.
Задает имя(динамически связанного) модуля расширения, в котором реализованы собственные функции. Эта #pragma должна появляться над объявлениями нативных функций, которые являются частью модуля расширения.
Параметр "название" может отсутствовать, в этом случае последующие объявления нативных функций не связаны ни с каким модулем расширения.
Область действия этой #pragma - от строки, в которой она появляется, до конца файла, в котором она появляется. При типичном использовании библиотечная строка #pragma появляется в верхней части включаемого файла, в котором объявляются собственные функции для модуля расширения, а область применения библиотечной "ссылки" заканчивается в конце этого включаемого файла.
Требует загрузки данной библиотеки.
Требует, чтобы данный библиотечный класс был загружен.
Автоматически пытается загрузить заданную библиотеку.
Если первая библиотека не загружена, будет сделана попытка загрузить вторую(не очень полезно).
Если ожидаемый класс не найден, будет сделана попытка загрузить заданную библиотеку. Это полезно для определения модуля по умолчанию, который будет загружаться с заданным классом модулей.
Аналогично #expclass, однако #defclasslib ждет, пока все ожидания не будут разрешены. Это позволяет подключаемым модулям отменять значения по умолчанию, добавляя свои собственные ожидания.
Если значение равно нулю, упакованные литеральные строки начинаются с "!"" (восклицательный знак + двойная кавычка), а распакованные литеральные строки - только с двойной кавычки """. Если значение ненулевое, синтаксис упакованных и неупакованных литеральных строк меняется местами: литеральные строки, начинающиеся с двойной кавычки, упаковываются, а литеральные строки, начинающиеся с "!"", распаковываются.
Включает поддержку рациональных чисел. tagname - это имя метки, которую будут иметь рациональные числа; обычно выбирают имена "Float:" или "Fixed:". Наличие значения в круглых скобках после tagname необязательно: если оно опущено, рациональное число хранится как значение с "плавающей точкой" в соответствии с нормой IEEE 754; если оно присутствует, рациональное число - это число фиксированной точности ("масштабированное целое число") с указанным количеством десятичных знаков.
Если значение равно нулю, то точка с запятой не требуется для завершения утверждения, если это утверждение является последним в строке. Точки с запятой по-прежнему необходимы для разделения нескольких утверждений на одной строке.
Когда точка с запятой необязательна(по умолчанию), постфиксный оператор(один из "++" и "--") не может быть первой лексемой в строке, поскольку они будут интерпретироваться как префиксные операторы.
Количество символов между двумя последовательными позициями TAB. Значение по умолчанию равно 8. Вам может понадобиться установить размер TAB, чтобы избежать предупреждения 217(свободный отступ), если в исходном коде отступы чередуются с пробелами и символами TAB. В качестве альтернативы, установив #pragma tabsize в ноль, парсер больше не будет выдавать предупреждение 217.
Помечает именованный символ как "используемый". Обычно PAWN парсер предупреждает о неиспользуемых переменных и неиспользуемых локальных константах. В большинстве ситуаций эти переменные и константы избыточны, и их лучше удалить ради ясности кода. Однако, особенно в случае локальных констант, может быть лучше(или требуется) сохранить определения констант. Эта #pragma позволяет пометить символ(переменную или константу) как "используемый" и избежать предупреждения парсера.
#pragma должна появляться после объявления символа - но не обязательно сразу после объявления.
В одной #pragma может быть несколько имен символов, разделенных запятыми.
Эта директива ведет себя так же, как директива #include, но она не выдает ошибку, если файл для включения не существует.
Удаляет макрос текстовой подстановки или числовую константу, объявленную с помощью const. Параметр "название" должен быть "префиксом" макроса - буквенно-цифровой частью макроса.
Первоисточники: Репозиторий Pawn на GitHub | Репозиторий AMX Mod X на GitHub | Директивы препроцессора | AMX ASM & Оператор #emit | Директива препроцессора - #pragma
Распространение данной статьи запрещено без указания ссылки на первоисточник.
Примечание: Все директивы должны быть первыми в строке и начинаться с символа "#", а полная инструкция не может занимать более одной строки - за исключением #define.
#assert постоянное выражение
Выдает ошибку во время компиляции, если предоставленное постоянное выражение равно нулю. Директива #assert используется для защиты от определенных реализацией конструкций, от которых может зависеть программа, таких как размер ячейки в битах, или количество упакованных символов в ячейке.
Код:
#define TEST 5
#assert TEST >= 3
// Успешная компиляция
#define TEST 1
#assert TEST >= 3
// fatal error 110: assertion failed: 1 >= 3
#define TEST
#if defined TEST
#assert "Variable TEST is defined"
#endif
// fatal error 110: assertion failed: "Variable TEST is defined"
#define TEST
#if defined TEST
#assert Variable Test is defined
#endif
// fatal error 110: assertion failed: Variable Test is defined
#define замена шаблона
Определяет макрос подстановки текста. Шаблон сопоставляется со всеми строками, считанными из исходных файлов; совпавшие участки заменяются текстами замены. Шаблон и тексты замены могут содержать параметры, обозначаемые от "%0" до "%9".
Код:
#define TEST
// Переменная TEST объявлена
#define TEST 5
// Переменная TEST равна 5
#define TEST "Testing"
// В переменной TEST хранится строка "Testing"
#define TEST(%0,%1,%2,%3) \
%0 + %1 * %2 / %3
// Макрос
#emit опкод операнд
Директива #emit служит в качестве поточного ассемблера. По сути, это встроенный компилятор, если вы знаете AMX, вы можете использовать его для вставки опкодов AMX непосредственно в ваш код. Единственное ограничение - он допускает только один аргумент. Синтаксис: #emit <опкод> <операнд> может быть рациональным числом, целым числом или(локальным или глобальным) символом(переменные, функции и метки).
Код:
new g_iInt1 = 1, g_iInt2 = 3;
public function()
{
new iInt1, iInt2;
#emit LOAD.pri g_iInt1 // Загрузка содержимого переменной "g_iInt1" в основной(pri) регистр.
#emit LOAD.alt g_iInt2 // Загрузка содержимого переменной "g_iInt2" в резервный/альтернативный(alt) регистр.
#emit XCHG // Замена местами значений оснвоного и резервного/альтернативного регистра.
// Теперь .pri-регистр хранит значение переменной "g_iInt2", а .alt-регистр - значение переменной "g_iInt1".
#emit STOR.S.pri iInt1 // Значение .pri-регистра теперь хранится в переменной iInt1.
// .S теперь используется в операциях с локальными переменными(которые заносятся в стек).
#emit LOAD.S.pri iInt1 // Загрузка содержимого переменной "iInt1" в основной(pri) регистр.
#emit LOAD.S.alt iInt2 // Загрузка содержимого переменной "iInt2" в резервный/альтернативный(alt) регистр.
// Обратите внимание, что .S должен использоваться во время загрузки содержимого локальных переменных.
#emit ADD // PRI = PRI + ALT = iInt1 + iInt2
#emit STOR.pri g_iInt1 // Значение .pri-регистра теперь хранится в переменной g_iInt1.
}
Код:
# мнемоника операнд семантика
1 LOAD.pri address PRI = [address]
2 LOAD.alt address ALT = [address]
3 LOAD.S.pri offset PRI = [FRM + offset]
4 LOAD.S.alt offset ALT = [FRM + offset]
5 LREF.pri address PRI = [[ address ]]
6 LREF.alt address ALT = [[ address ]]
7 LREF.S.pri offset PRI = [[FRM + offset]]
8 LREF.S.alt offset ALT = [[FRM + offset]]
9 LOAD.I PRI = [PRI]
11 CONST.pri value PRI = value
12 CONST.alt value ALT = value
13 ADDR.pri offset PRI = FRM + offset
14 ADDR.alt offset ALT = FRM + offset
15 STOR address [address] = PRI
16 STOR.S offset [FRM + offset] = PRI
19 SREF.pri address [[ address ]] = PRI
20 SREF.alt address [[address]] = ALT[\td]
21 SREF.S.pri offset [[FRM + offset]] = PRI
22 SREF.S.alt offset [[FRM + offset]] = ALT
23 STOR.I [ALT] = PRI (full cell)
25 LIDX PRI = [ ALT + (PRI ? cell size) ] (load what is there at calculated index)
27 IDXADDR PRI = ALT + (PRI ? cell size) (calculate indexed address)
39 PUSH.C value [STK] = value,STK = STK - cell size
31 LCTRL index PRI is set to the current value of any of the special registers. The index parameter must be: 0=COD, 1=DAT, 2=HEA,3=STP, 4=STK, 5=FRM, 6=CIP (of the next instruction)
32 SCTRL index Set the indexed special registers to the value in PRI.The index parameter must be: 2=HEA, 4=STK, 5=FRM, 6=CIP
33 MOVE.pri PRI = ALT
34 MOVE.alt ALT = PRI
35 XCHG Exchange contents of PRI and ALT
36 PUSH.pri [STK] = PRI and STK = STK - cell size
37 PUSH.alt [STK] = ALT and STK = STK - cell size
40 PUSH address [STK] = [address], STK = STK - cell size
41 PUSH.S offset [STK] = [FRM + offset], STK = STK - cell size
42 POP.pri PRI = [STK] and STK = STK + cell size
43 POP.alt ALT = [STK] and STK = STK + cell size
44 STACK value ALT = STK and STK = STK + value
47 RET STK = STK + cell size, FRM = [STK],STK = STK + cell size,CIP = [STK], The RET instruction cleans up the stack frame and returns from the function to the instruction after the call
48 RETN STK = STK + cell size, FRM = [STK],STK = STK + cell size, CIP = [STK], STK = STK + [STK]The RETN instruction removes a specifed number of bytes from the stack. The value to adjust STK with must be pushed prior to the call.
65 SHL PRI = PRI << ALT
66 SHR PRI = PRI >> ALT (without sign extension)
67 SSHR PRI = PRI >> ALT (with sign extension)
68 SHL.C.pri value PRI = PRI << value
69 SHL.C.alt value ALT = ALT << value
72 SMUL PRI = ALT * PRI (signed multiply)
73 SDIV PRI = ALT / PRI (signed divide),ALT = ALT mod PRI
78 ADD PRI = ALT + PRI
79 SUB PRI = ALT - PRI
81 AND PRI = ALT & PRI
82 OR PRI = ALT | PRI
83 XOR PRI = ALT?PRI
84 NOT PRI = !PRI
85 NEG PRI = -PRI
86 INVERT PRI = ~PRI
87 ADD.C value PRI = PRI + value
88 SMUL.C value PRI = PRI * value
107 INC.pri PRI = PRI + 1
108 INC.alt ALT = ALT + 1
109 INC [address] = [address] + 1
110 INC.S offset [FRM + offset] = [FRM + offset] + 1
112 DEC.pri PRI = PRI - 1
113 DEC.alt ALT = ALT - 1
116 DEC.I [PRI] = [PRI] - 1
119 FILL number Fill memory at [ALT] with value in [PRI]. The parameter specifes the number of bytes, which must be a multiple of the cell size.
123 SYSREQ.C address Used to call a system service or native functions
133 PUSH.ADR offset [STK] = FRM + ofset,STK = STK - cell size
#endinput/#endscript
Закрывает текущий файл и тем самым игнорирует весь текст, расположенный ниже директивы #endinput. Директива #endscript является синонимом #endinput.
Код:
#include <amxmodx>
public plugin_precache()
{
log_amx("Test 1");
}
#endinput
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
log_amx("Test 2");
}
// Весь код, который находится ниже #endinput - не сработает. #endinput может быть заменён #endscript.
#error сообщение
Сигнализирует об "ошибке пользователя" с указанным сообщением. Ошибки пользователя являются фатальными ошибками, и они служат той же цели, что и директива #assert.
Код:
#define TEST
#if defined TEST
#error "Variable TEST is defined"
#endif
// fatal error 111: user error: "Variable TEST is defined"
#define TEST
#if defined TEST
#error Variable TEST is defined
#endif
// fatal error 111: user error: Variable TEST is defined
#if/#elseif постоянное выражение, #else, #endif
Части программы могут быть разобраны или проигнорированы в зависимости от определенных условий. PAWN парсер(компилятор или интерпретатор) генерирует код только для тех частей, для которых условие истинно.
За директивой #if должно следовать постоянное выражение. Чтобы проверить, определена ли переменная или константа, используйте оператор defined.
После начальной директивы #if может следовать ноль или более директив #elseif. Эти блоки пропускаются, если любой из предшествующих блоков #if или #elseif был разобран(т.е. не пропущен). Как и в случае с директивой #if, за выражением #elseif должно следовать постоянное выражение.
Директива #else заставляет парсер пропустить все строки до #endif, если предыдущая #if или любая из предыдущих директив #elseif были "истинными", и парсить эти строки, если все предыдущие блоки были пропущены. Директива #else может быть опущена; если она присутствует, то с каждым #if может быть связано только одно #else.
Директива #endif завершает часть программы, которая разбирается условно. Условные директивы могут быть вложенными, и каждая директива #if должна завершаться директивой #endif.
Код:
#define TEST 1
#if TEST == 1
new g_iTest;
#endif
// Объявится переменная g_iTest
#define TEST 2
#if TEST == 1
new g_iTest1;
#elseif TEST == 2
new g_iTest2;
#endif
// Объявится переменная g_iTest2
#define TEST 3
#if TEST == 1
new g_iTest1;
#elseif TEST == 2
new g_iTest2;
#else
new g_iTest3;
#endif
// Объявится переменная g_iTest3
#include название файла или <название файла>
Вставляет содержимое указанного файла в текущую позицию внутри текущего файла. Имя файла в угловых скобках ("<" и ">") относится к системному файлу; PAWN парсер(компилятор или интерпретатор) будет искать такие файлы только в заданном списке каталогов, но не в "текущем" каталоге. Имена файлов без кавычек или в двойных кавычках - это обычные включаемые файлы, которые PAWN парсер будет искать сначала в текущем каталоге.
PAWN парсер сначала пытается открыть файл с указанным именем. Если это не удается, он пытается добавить к имени файла расширения ".inc", ".p" и ".pawn"(в таком порядке). Предлагаемое по умолчанию расширение включаемых файлов - ".inc".
Если файл может быть успешно открыт, директива #include определяет константу с именем "inc" плюс базовое имя файла(имя файла без пути и расширения) и значением 1. Если константа уже существует, директива #include пропускает открытие и включение файла, тем самым предотвращая двойное включение. Для принудительного двойного включения удалите определение константы с помощью директивы #undef перед вторым включением файла.
Код:
#include <amxmodx>
#include <amxmodx.inc>
#include amxmodx
#include amxmodx.inc
#include "amxmodx"
#include "amxmodx.inc"
#pragma дополнительная информация
“pragma” - это крючок для парсера для указания дополнительных настроек, таких как уровни предупреждений или дополнительные возможности.
#pragma amxlimit значение
Устанавливает максимальный размер в байтах, до которого может вырасти скомпилированный скрипт. Эта прагма полезна для(встроенных) сред, где максимальный размер скрипта ограничен жестким верхним пределом. Если объем оперативной памяти для данных и стека не задан(см. #pragma amxram), это значение относится к общим требованиям к памяти; если объем оперативной памяти задан явно, это значение дает только объем памяти, необходимый для кода и статических данных.
Код:
#pragma amxlimit 1000
// Если конеченый размер файла будет больше, чем 1000 КБ, то выдаст ошибку, но скомпилируется
#pragma codepage название/значение
PAWN парсер может переводить символы в символьных константах и в распакованных строках в "широкие" символы Unicode/UCS-4. Эта #pragma указывает кодовую страницу, которая должна быть использована для перевода.
Код:
#pragma codepage 65001
// Выставит кодировку utf-8
#pragma compress значение
PAWN парсер может записывать сгенерированный P-код в компактной или обычной("некомпактной") кодировке. Значение по умолчанию зависит от конфигурации парсера(и, возможно, от настроек пользователя). Эта #pragma позволяет автору сценария отменить значение по умолчанию и принудительно использовать компактную кодировку(когда значение ненулевое) или принудительно использовать обычную кодировку(когда значение нулевое). Особенно полезно отключение компактного кодирования(принудительное использование обычного кодирования), поскольку PAWN парсер может оказаться не в состоянии скомпилировать определенный скрипт в режиме "компактного кодирования".
Код:
#pragma compress 1
// Включение компактного кодирования
#pragma ctrlchar символ
Определяет символ, который будет использоваться для обозначения начала "управляющей последовательности". По умолчанию управляющим символом является "\".
Пример: #pragma ctrlchar '$'
Вы можете задать новое значение управляющего символа в виде символьной константы(между одинарными кавычками) или в виде десятичного или шестнадцатеричного значения. Если вы опустите значение нового управляющего символа, парсер вернется к управляющему символу по умолчанию.
Код:
#include <amxmodx>
#pragma ctrlchar '$'
// Изменяем стандартный escape-символ "^" на "$".
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
log_amx("TEST$tTEST");
// Выведет в лог "TEST TEST"
}
#pragma deprecated значение
Последующий символ помечается как "устаревший". Если сценарий использует его, парсер выдает предупреждение.
Код:
#include <amxmodx>
#define TEST "Testing"
#pragma deprecated TEST
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
log_amx("%s", TEST);
// warning 233: symbol "plugin_init" is marked as deprecated: TEST
}
#pragma dynamic значение
Устанавливает размер в ячейках блока памяти для динамических данных(стека и кучи) на значение, заданное выражением. Размер блока динамических данных по умолчанию определяется реализацией. Реализация может также выбрать увеличение блока по мере необходимости.
Код:
#include <amxmodx>
#pragma dynamic 16404
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
new szString[16384];
// Без использования "#pragma dynamic 16404" в консоли будет ошибка [AMXX] Run time error 3: stack error
}
#pragma library название
Задает имя(динамически связанного) модуля расширения, в котором реализованы собственные функции. Эта #pragma должна появляться над объявлениями нативных функций, которые являются частью модуля расширения.
Параметр "название" может отсутствовать, в этом случае последующие объявления нативных функций не связаны ни с каким модулем расширения.
Область действия этой #pragma - от строки, в которой она появляется, до конца файла, в котором она появляется. При типичном использовании библиотечная строка #pragma появляется в верхней части включаемого файла, в котором объявляются собственные функции для модуля расширения, а область применения библиотечной "ссылки" заканчивается в конце этого включаемого файла.
Код:
// Уставший вариант, рекомендуется использовать #pragma reqlib
#pragma reqlib <название файла>
Требует загрузки данной библиотеки.
test.inc
Код:
#pragma reqlib test
#if !defined AMXMODX_NOAUTOLOAD
#pragma loadlib test
#endif
test.sma
Код:
#include <amxmodx>
public plugin_natives()
{
register_library("test");
}
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma reqclass класс
Требует, чтобы данный библиотечный класс был загружен.
Код:
#include <amxmodx>
#pragma reqclass test1
#if !defined AMXMODX_NOAUTOLOAD
#pragma defclasslib test1 test2
#endif
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma loadlib <название файла>
Автоматически пытается загрузить заданную библиотеку.
test.inc
Код:
#pragma reqlib test
#if !defined AMXMODX_NOAUTOLOAD
#pragma loadlib test
#endif
test.sma
Код:
#include <amxmodx>
public plugin_natives()
{
register_library("test");
}
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma explib <название файла> <название файла>
Если первая библиотека не загружена, будет сделана попытка загрузить вторую(не очень полезно).
Код:
#include <amxmodx>
#pragma explib <test1> <test2>
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma expclass класс <название файла>
Если ожидаемый класс не найден, будет сделана попытка загрузить заданную библиотеку. Это полезно для определения модуля по умолчанию, который будет загружаться с заданным классом модулей.
Код:
#include <amxmodx>
#pragma reqclass test1 <test2>
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma defclasslib класс <название файла>
Аналогично #expclass, однако #defclasslib ждет, пока все ожидания не будут разрешены. Это позволяет подключаемым модулям отменять значения по умолчанию, добавляя свои собственные ожидания.
Код:
#include <amxmodx>
#pragma reqclass test1
#if !defined AMXMODX_NOAUTOLOAD
#pragma defclasslib test1 test2
#endif
public plugin_init()
{
register_plugin("Test Directives", "0.0.1", "Albertio");
}
#pragma pack значение
Если значение равно нулю, упакованные литеральные строки начинаются с "!"" (восклицательный знак + двойная кавычка), а распакованные литеральные строки - только с двойной кавычки """. Если значение ненулевое, синтаксис упакованных и неупакованных литеральных строк меняется местами: литеральные строки, начинающиеся с двойной кавычки, упаковываются, а литеральные строки, начинающиеся с "!"", распаковываются.
Код:
#pragma pack 1
// Если заданное значение равно нулю, упакованные строки объявляются знаком "!",
// а не запакованные двойными кавычками (""), без знака. Если значение равно единице,
// то литеральность строк объявляется в обратном порядке.
#pragma rational tagname(значение)
Включает поддержку рациональных чисел. tagname - это имя метки, которую будут иметь рациональные числа; обычно выбирают имена "Float:" или "Fixed:". Наличие значения в круглых скобках после tagname необязательно: если оно опущено, рациональное число хранится как значение с "плавающей точкой" в соответствии с нормой IEEE 754; если оно присутствует, рациональное число - это число фиксированной точности ("масштабированное целое число") с указанным количеством десятичных знаков.
Код:
#pragma rational Float /* формат плавающей точки */
#pragma rational Fixed(3) /* фиксированная точка, с 3 десятичными знаками */
// В float.inc уже заранее использовано "#pragma rational Float"
#pragma semicolon значение
Если значение равно нулю, то точка с запятой не требуется для завершения утверждения, если это утверждение является последним в строке. Точки с запятой по-прежнему необходимы для разделения нескольких утверждений на одной строке.
Когда точка с запятой необязательна(по умолчанию), постфиксный оператор(один из "++" и "--") не может быть первой лексемой в строке, поскольку они будут интерпретироваться как префиксные операторы.
Код:
#pragma semicolon 1
// Теперь компилятор будет ждать, что в конце каждого выражения должен стоять символ ";"
#pragma tabsize значение
Количество символов между двумя последовательными позициями TAB. Значение по умолчанию равно 8. Вам может понадобиться установить размер TAB, чтобы избежать предупреждения 217(свободный отступ), если в исходном коде отступы чередуются с пробелами и символами TAB. В качестве альтернативы, установив #pragma tabsize в ноль, парсер больше не будет выдавать предупреждение 217.
Код:
#pragma tabsize 0
// Убирает табуляцию
#pragma tabsize 2
// Выставляет табуляцию в 2 отступа
#pragma unused символ, ...
Помечает именованный символ как "используемый". Обычно PAWN парсер предупреждает о неиспользуемых переменных и неиспользуемых локальных константах. В большинстве ситуаций эти переменные и константы избыточны, и их лучше удалить ради ясности кода. Однако, особенно в случае локальных констант, может быть лучше(или требуется) сохранить определения констант. Эта #pragma позволяет пометить символ(переменную или константу) как "используемый" и избежать предупреждения парсера.
#pragma должна появляться после объявления символа - но не обязательно сразу после объявления.
В одной #pragma может быть несколько имен символов, разделенных запятыми.
Код:
public function()
{
static const TEST[] = "STEAM_0:0:000000000";
new iLen = sizeof(TEST);
#pragma unused TEST
// Компилятор не выдаст ошибку 203, что переменная TEST не используется.
}
#tryinclude название файла или <название файла>
Эта директива ведет себя так же, как директива #include, но она не выдает ошибку, если файл для включения не существует.
Код:
#tryinclude <amxmodx>
#tryinclude <amxmodx.inc>
#tryinclude amxmodx
#tryinclude amxmodx.inc
#tryinclude "amxmodx"
#tryinclude "amxmodx.inc"
// Если не будет инклюда "amxmodx", то ошибку не напишет при компиляции.
#undef название
Удаляет макрос текстовой подстановки или числовую константу, объявленную с помощью const. Параметр "название" должен быть "префиксом" макроса - буквенно-цифровой частью макроса.
Код:
public function()
{
#define TEST "Testing"
log_amx("%s", TEST);
// Объявляем переменную TEST. Можем вывести в лог.
#undef TEST
log_amx("%s", TEST);
// Удаляем переменную TEST. На этапе компиляции будет ошибка, т.к. пытаемся
// использовать несуществующую переменную, но если не использовать, то всё будет ок.
}
Последнее редактирование: