PreProcessor Commands: Difference between revisions
m ('recognised' is correct as original author is not US American) |
(attempt to improve readability, requires technical proof reading) |
||
Line 1: | Line 1: | ||
=Introduction = | =Introduction = | ||
Preprocessor commands refer to the C(++) syntax used by the engine to 'pre process' the text inside a config.cpp, mission.sqm, or description.ext file. In fact, preprocessor commands apply to '''any''' BI game text file containing class statements, since these statements are 'scrunched' by the engine's internal C processor. The majority use however is in addons, and specifically, the config.cpp of the addon. | |||
Preprocessor commands refer to the C(++) syntax used by the engine to | |||
In fact, preprocessor commands | |||
The majority use however is in addons, and specifically, the config.cpp of the addon. | |||
There are six preprocessor commands recognised by the OFP and ArmA engine: | There are six preprocessor commands recognised by the OFP and ArmA engine: | ||
Line 16: | Line 11: | ||
#ifndef | #ifndef | ||
#endif | #endif | ||
==Note for experienced users== | ==Note for experienced users== | ||
The preprocessor mimics a subset of [http://en.wikipedia.org/wiki/C_preprocessor C preprocessor]. While basic functionality is similar, the preprocessor is not fully C-conformant, as order of substitution of arguments in macro invocation is different than in C, which means some intricate nested macro constructs, | The preprocessor mimics a subset of [http://en.wikipedia.org/wiki/C_preprocessor C preprocessor]. While basic functionality is similar, the preprocessor is not fully C-conformant, as order of substitution of arguments in macro invocation is different than in C, which means some intricate nested macro constructs, especially when using token concatenation operator, may produce different results than in C. | ||
= Preprocessor commands = | = Preprocessor commands = | ||
Line 27: | Line 20: | ||
==#include== | ==#include== | ||
Syntax | '''Syntax:''' | ||
#include <PathAndFileName> | |||
#include <PathAndFileName> | #include "PathAndFileName" | ||
#include "PathAndFileName" | |||
The purpose of an include statement is to wedge in further statements into the current body of text. The reason for doing so, in BI games at least, is artistry. To break up one large confusing text many pages long into smaller, more manageable chunks. | |||
The number of 'chunks' (ie, the number of included files) is solely at the author's discretion. In general, they will put similar elements together. For example, all icons will be in one file, all buildings in another, all cars in another, and so on. It is particularly common in the case of veteran authors to put base characteristics of similar 'models' into a single 'base' file, and then include this file into multiple variations of that base model. For example, a base file may define a soldier with khaki trousers. A second soldier class could include this standard base, and then define specific variations (which may change the trousers to pink, and so on). The base characteristics of the model do not need to be repeated in the main body of the text for the second soldier, as it's duplicating work and contains no new information. | |||
From the perspective of the game engine, the use of #include files is of <u>no consequence</u>, since the engine effectively processes all files as one file. All of the 'chunks' (the #included files) are merged into a single file for the purpose of compiling. Irrespective of how many #included files are used, the result is a single config.bin (config.bin is the resultant output of all this processing). | |||
Processing continues at the beginning of the included file until it's end, at which point, processing continues at the statement after the initial #include. Thus, anything required by that included file (if anything at all), must have 'appeared' before the #include statement. It is quite common for included files to have #include statement(s) of their own, under which circumstance, processing continues at the beginning of that included file, and so on. | |||
Example: | |||
#include "someAddon\somePathInTheAddon\someFile.someExtension" | |||
Note that the #include syntax string does not use a preceding backslash, unlike other file references (such as icons or models, etc.) used in BI game files. Also note, that there is no default file extension, and no trailing semi-colon. | |||
==#define== | ==#define== | ||
'''Syntax:''' | |||
#define NAME VALUE | |||
Within defines arguments, the token 'concatenation operator' ##, and 'stringize operator' # may be used. | |||
Define statements may be referred to by the term 'macro'. It is a macro in the same way macros are used in Microsoft Word - one macro can expand into a (very large) sequence of keystrokes. You can effectively understand #defines as | |||
#define THIS = THAT | |||
For example: | |||
#define true 1 | #define true 1 | ||
#define false 0 | #define false 0 | ||
Macros can be expanded to the following example: | |||
#define ICONS(icn) icon=\SomeAddon\icons\##icn; \ | #define ICONS(icn) icon=\SomeAddon\icons\##icn; \ | ||
model=\SomeAddon\##icn.p3d; \ | model=\SomeAddon\##icn.p3d; \ | ||
picture=\SomeAddon\##icn.paa | picture=\SomeAddon\##icn.paa | ||
Then, using: | |||
Then, using | |||
ICON(Peter); | ICON(Peter); | ||
ICON(Fred); | ICON(Fred); | ||
will be expanded during processing into: | |||
will | |||
icon=\SomeAddon\icons\Peter; | icon=\SomeAddon\icons\Peter; | ||
model=\SomeAddon\Peter.p3d; | model=\SomeAddon\Peter.p3d; | ||
Line 96: | Line 64: | ||
picture=\SomeAddon\Fred.paa; | picture=\SomeAddon\Fred.paa; | ||
The | The purpose of expanded macros as illustrated above is to allow simplified syntax, and to reduce typing load (and the likelihood of typos). In the case of the first example above, the #define macro creates more explicit, legible files, at the expense of increased typing. | ||
==#undef== | ==#undef== | ||
'''Syntax:''' | |||
Syntax | |||
#undef NAME | #undef NAME | ||
This will undefine (delete) a macro previously set by the use of #define. | |||
==#ifdef== | ==#ifdef== | ||
Syntax | '''Syntax:''' | ||
#ifdef NAME | #ifdef NAME | ||
...text that will be used if NAME is defined... | ...text that will be used if NAME is defined... | ||
Line 120: | Line 82: | ||
==#ifndef== | ==#ifndef== | ||
Syntax | '''Syntax:''' | ||
#ifndef NAME | #ifndef NAME | ||
...text that will be used if NAME ''isn't'' defined... | ...text that will be used if NAME ''isn't'' defined... | ||
#endif | #endif | ||
==#endif== | ==#endif== |
Revision as of 14:36, 5 September 2008
Introduction
Preprocessor commands refer to the C(++) syntax used by the engine to 'pre process' the text inside a config.cpp, mission.sqm, or description.ext file. In fact, preprocessor commands apply to any BI game text file containing class statements, since these statements are 'scrunched' by the engine's internal C processor. The majority use however is in addons, and specifically, the config.cpp of the addon.
There are six preprocessor commands recognised by the OFP and ArmA engine:
#include #define #undef #ifdef #ifndef #endif
Note for experienced users
The preprocessor mimics a subset of C preprocessor. While basic functionality is similar, the preprocessor is not fully C-conformant, as order of substitution of arguments in macro invocation is different than in C, which means some intricate nested macro constructs, especially when using token concatenation operator, may produce different results than in C.
Preprocessor commands
#include
Syntax:
#include <PathAndFileName> #include "PathAndFileName"
The purpose of an include statement is to wedge in further statements into the current body of text. The reason for doing so, in BI games at least, is artistry. To break up one large confusing text many pages long into smaller, more manageable chunks.
The number of 'chunks' (ie, the number of included files) is solely at the author's discretion. In general, they will put similar elements together. For example, all icons will be in one file, all buildings in another, all cars in another, and so on. It is particularly common in the case of veteran authors to put base characteristics of similar 'models' into a single 'base' file, and then include this file into multiple variations of that base model. For example, a base file may define a soldier with khaki trousers. A second soldier class could include this standard base, and then define specific variations (which may change the trousers to pink, and so on). The base characteristics of the model do not need to be repeated in the main body of the text for the second soldier, as it's duplicating work and contains no new information.
From the perspective of the game engine, the use of #include files is of no consequence, since the engine effectively processes all files as one file. All of the 'chunks' (the #included files) are merged into a single file for the purpose of compiling. Irrespective of how many #included files are used, the result is a single config.bin (config.bin is the resultant output of all this processing).
Processing continues at the beginning of the included file until it's end, at which point, processing continues at the statement after the initial #include. Thus, anything required by that included file (if anything at all), must have 'appeared' before the #include statement. It is quite common for included files to have #include statement(s) of their own, under which circumstance, processing continues at the beginning of that included file, and so on.
Example:
#include "someAddon\somePathInTheAddon\someFile.someExtension"
Note that the #include syntax string does not use a preceding backslash, unlike other file references (such as icons or models, etc.) used in BI game files. Also note, that there is no default file extension, and no trailing semi-colon.
#define
Syntax:
#define NAME VALUE
Within defines arguments, the token 'concatenation operator' ##, and 'stringize operator' # may be used.
Define statements may be referred to by the term 'macro'. It is a macro in the same way macros are used in Microsoft Word - one macro can expand into a (very large) sequence of keystrokes. You can effectively understand #defines as
#define THIS = THAT
For example:
#define true 1 #define false 0
Macros can be expanded to the following example:
#define ICONS(icn) icon=\SomeAddon\icons\##icn; \ model=\SomeAddon\##icn.p3d; \ picture=\SomeAddon\##icn.paa
Then, using:
ICON(Peter); ICON(Fred);
will be expanded during processing into:
icon=\SomeAddon\icons\Peter; model=\SomeAddon\Peter.p3d; picture=\SomeAddon\Peter.paa; icon=\SomeAddon\icons\Fred; model=\SomeAddon\Fred.p3d; picture=\SomeAddon\Fred.paa;
The purpose of expanded macros as illustrated above is to allow simplified syntax, and to reduce typing load (and the likelihood of typos). In the case of the first example above, the #define macro creates more explicit, legible files, at the expense of increased typing.
#undef
Syntax:
#undef NAME
This will undefine (delete) a macro previously set by the use of #define.
#ifdef
Syntax:
#ifdef NAME ...text that will be used if NAME is defined... #endif
#ifndef
Syntax:
#ifndef NAME ...text that will be used if NAME isn't defined... #endif
#endif
This ends a conditional block as shown in the descriptions of #ifdef and #ifndef above.