Difference between revisions of "Precompiler definitions"
(beginning of work on #define/#undef) |
(more on #define) |
||
Line 5: | Line 5: | ||
Defines a precompiler define or macro.<br /> | Defines a precompiler define or macro.<br /> | ||
* <defname> contains the define name | * <defname> contains the define name | ||
− | * <macroparams> contains | + | * <macroparams> contains a list of parameters, seperated by commas, to use with a macro (optional) |
* <defvalue> contains the define value (optional) | * <defvalue> contains the define value (optional) | ||
− | After statement parsing, <defname> is considered defined. Then, FTEQCC encounters <defname> or #<defname> during parsing, it will be replaced with <defvalue>, or <defname> will be erased if <defvalue> is not defined. If <macroparams> are defined, FTEQCC will | + | After statement parsing, <defname> is considered defined. Then, FTEQCC encounters <defname> or #<defname> during parsing, it will be replaced with <defvalue>, or <defname> will be erased if <defvalue> is not defined. If <macroparams> are defined, FTEQCC will use <defvalue> in the following fashion: |
+ | * If a parameter in <macroparams> as an isolated token is found, it is replaced into the result. | ||
+ | * If a parameter in <macroparams> is found with a preceding #, it is surrounded in quotes, then placed into the result. | ||
+ | * If a parameter in <macroparams> is found with 2 preceding #, it is concatenated into the result. | ||
Examples: | Examples: | ||
Line 14: | Line 17: | ||
#define MONSTERS | #define MONSTERS | ||
#define NEWWEAPONS | #define NEWWEAPONS | ||
− | + | ||
// Use of defines as constants | // Use of defines as constants | ||
#define NEWWEAPONNAME "chainsaw with lasersight" | #define NEWWEAPONNAME "chainsaw with lasersight" | ||
string s; | string s; | ||
− | s = NEWWEAPONNAME; // | + | s = NEWWEAPONNAME; // Same as s = "chainsaw with lasersight"; |
− | s = #NEWWEAPONNAME; // | + | s = #NEWWEAPONNAME; // Also same as s = "chainsaw with lasersight"; |
− | + | ||
// Simple use of macros | // Simple use of macros | ||
#define ISEQUAL(a,b) (a == b) | #define ISEQUAL(a,b) (a == b) | ||
Line 28: | Line 31: | ||
if (ISEQUAL(float1, float2)) // Does the same thing as the previous if | if (ISEQUAL(float1, float2)) // Does the same thing as the previous if | ||
dosomething(); | dosomething(); | ||
+ | |||
+ | // Use of stringify with macros | ||
+ | #define OBJECT(a) #a | ||
+ | string s; | ||
+ | s = OBJECT(mouse); // Same as s = "mouse"; | ||
+ | |||
+ | // Use of concatenate with macros | ||
+ | #define SPECIALCLASS(a) float special_##a | ||
+ | SPECIALCLASS(thing); // same as float special_thing; | ||
+ | |||
+ | <font color=red>Warning</font>: Macros are not the same as functions. For example: | ||
+ | float x; | ||
+ | |||
+ | #define SQRT(x) (x*x) | ||
+ | float squareroot (float x) { return x * x; } | ||
+ | float subtract2fromx (void) { x = x - 2; return x; } | ||
+ | |||
+ | void testfunction (void) | ||
+ | { | ||
+ | x = 7; | ||
+ | y = squareroot(subtract2fromx()); // Results in (7-2) * (7-2) = 25 | ||
+ | |||
+ | x = 7; | ||
+ | z = SQRT(subtract2fromx()); // Results in (7-2) * ((7-2)-2) = 15 | ||
+ | } | ||
===#undef=== | ===#undef=== |
Revision as of 23:08, 30 October 2005
Contents
Definitions
#define
Syntax: #define <defname>[(<macroparams>)] [<defvalue>]
Defines a precompiler define or macro.
- <defname> contains the define name
- <macroparams> contains a list of parameters, seperated by commas, to use with a macro (optional)
- <defvalue> contains the define value (optional)
After statement parsing, <defname> is considered defined. Then, FTEQCC encounters <defname> or #<defname> during parsing, it will be replaced with <defvalue>, or <defname> will be erased if <defvalue> is not defined. If <macroparams> are defined, FTEQCC will use <defvalue> in the following fashion:
- If a parameter in <macroparams> as an isolated token is found, it is replaced into the result.
- If a parameter in <macroparams> is found with a preceding #, it is surrounded in quotes, then placed into the result.
- If a parameter in <macroparams> is found with 2 preceding #, it is concatenated into the result.
Examples:
// Simple defines for use in precompiler control logic later on #define MONSTERS #define NEWWEAPONS
// Use of defines as constants #define NEWWEAPONNAME "chainsaw with lasersight" string s; s = NEWWEAPONNAME; // Same as s = "chainsaw with lasersight"; s = #NEWWEAPONNAME; // Also same as s = "chainsaw with lasersight";
// Simple use of macros #define ISEQUAL(a,b) (a == b) float float1, float2; if (float1 == float2) dosomething(); if (ISEQUAL(float1, float2)) // Does the same thing as the previous if dosomething();
// Use of stringify with macros #define OBJECT(a) #a string s; s = OBJECT(mouse); // Same as s = "mouse";
// Use of concatenate with macros #define SPECIALCLASS(a) float special_##a SPECIALCLASS(thing); // same as float special_thing;
Warning: Macros are not the same as functions. For example:
float x; #define SQRT(x) (x*x) float squareroot (float x) { return x * x; } float subtract2fromx (void) { x = x - 2; return x; } void testfunction (void) { x = 7; y = squareroot(subtract2fromx()); // Results in (7-2) * (7-2) = 25 x = 7; z = SQRT(subtract2fromx()); // Results in (7-2) * ((7-2)-2) = 15 }
#undef
Syntax: #undef <defname>
After statement parsing, <defname> is considered undefined. FTEQCC will no longer parse <defname> or #<defname> when it is encountered.
Control Logic
#ifdef
#ifndef
#if
#else
#endif
Something
#message
Syntax: #message <message>
#warning
Syntax: #warning <message>
#error
Syntax: #error <message>
File things
#include
Syntax: #include <file>
#includelist
Syntax: #includelist
#endlist
Syntax: #endlist
#output
Depreciated, use #pragma PROGS_DAT instead.
Second file things
#eof
Syntax: #eof
#forcecrc
Syntax: #forcecrc <crc>
#copyright
Depreciated, use #pragma COPYRIGHT instead.
#datafile
Syntax: #datafile <file>
#pack
#packid
Pragma (#pragma)
#pragma is an extensive precompiler statement which controls many aspects of the compiler.
Note that all unknown #pragma statements encountered by FTEQCC are ignored (with a warning.)
#pragma DONT_COMPILE_THIS_FILE
This pragma is parsed but ignored by FTEQCC so PREQCC-using code can compile cleanly.
#pragma COPYRIGHT
Syntax: #pragma COPYRIGHT <message>
Changes the string to be embedded at the end of a compiled progs. <message> is the message to embed.
#pragma TARGET
Syntax: #pragma TARGET <target>
Switches compiled progs to a specific target type.
<target> can be the following:
- ID, STANDARD: standard Quake progs
- KK7: kkqwsv progs
- H2, HEXEN2: Hexen 2 progs
- FTE: FTE progs
- DEBUG, FTEDEBUG: FTE progs with debug information
It is not recommended to switch target types during compilation.
#pragma PROGS_SRC
This pragma is parsed but ignored by FTEQCC so PREQCC-using code can compile cleanly.
#pragma PROGS_DAT
Syntax: #pragma PROGS_DAT <progsfile>
Changes the destination file you wish to compile to. <progsfile> contains the new file name.
Example:
#ifdef MONSTERS #pragma PROGS_DAT monsters.dat #message FTEQCC will now compile to monsters.dat #else #pragma PROGS_DAT nomonsters.dat #message FTEQCC will now compile to nomonsters.dat #endif
#pragma keyword and #pragma flag
Syntax:
- #pragma keyword <onoroff> <keywordid>
- #pragma flag <onoroff> <keywordid>
#pragma warning
Syntax: #pragma warning <onoroff> <warningid>