UDN
Search public documentation:

UnrealScriptPreprocessor
日本語訳
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 Home > UnrealScript > UnrealScript Preprocessor (UPP)

UnrealScript Preprocessor (UPP)


Overview


In the Unreal Engine 3, the UnrealScript compiler now supports a preprocessor. The preprocessor works much like the C++ preprocessor and is perfect for supporting conditional compilation via macros.

The Basics


Macro processing happens before UnrealScript compilation. Since it is a separate phase it is not connected to the lexical conventions of UnrealScript.

Scope


Macros are file-scope, meaning a macro defined on line X of the script class (.uc) file is only usable on lines X+n in that file and not in any other files (unless it is included in another .uc file). However, you can create a Globals.uci file in your project's root folder (i.e. Development\Src\MyProject\Globals.uci), and those macros will be automatically available to all classes in the package.

Using Macros


A macro is invited using the ` (backtick character) before the name of the macro. So, to expand the hello macro with no parameters, the following line would work:

`hello

Equivalently, the name of the macro can be enclosed in { } after the tick as in:

`{hello}

This makes it possible to "insert" the expansion of a macro into the middle of text that does not have conveniently placed whitespace:

hippo`{hello}potamus

But how does the hello macro get defined? The built-in macro define works very similar to a C++ define:

  1. the `define keyword, followed by at least one whitespace character
  2. the name of the new macro (and optionally a function parameter list), followed by at least one whitespace character
  3. the definition of the body of the macro

So hello is defined with:

`define   hello   "Hello, World!"

Thereafter, `hello is replaced with "Hello, World!" (complete with quotes). All results of macro expansion are, again, scanned for opportunities to expand macros. Macro expansions can include macros that will, in turn, be expanded; also means that "infinitely recursive" macros can be written.

You may embed new lines into macro expansions by using the "\n" notation, which can be helpful for debugging your preprocessor macros, and is essential for working with macros intended to be used in DefaultProperties. Example:

`define EndComboBox(Name) \
    End Object \n\
    MenuObjects.Add(`Name)

Macro Parameters


Macro parameters are passed positionally, in a comma separated list between parentheses right after the name of the macro. The opening parenthesis of this list MUST come immediately after the macro name in order to be recognized as part of the macro call. See the notes below regarding the built-in macro define for more details about macro parameters.

Built-in Macros


define

`define <macroname>[<(paramA[,paramB...])>] [<macrodefinition>]

Defines the named macro to expand to the given definition. If no definition is provided, the macro is defined but expands to the empty string.

Parameters for the macro are specified in a typeless function parameter list immediately after the name of the macro. In the macro definition, the parameters are referenced by name and prefixed with a backtick. For example:

`define DeclareInt(x) var int `x;

The special macro `# repesents the number of parameters specified and can be referenced only within the macro definition.

if / else / endif

`if(<value>)
`else
`endif

These three macros together support conditional compilation. The <value> parameter is processed and if it is expanded to a non-empty string, the if-check evaluates to true; otherwise it is considered to be false.

The text between `if and either `else (if present) or `endif are emitted into the processed output if the condition is true; if the condition is not true, only the end-of-line characters are emitted so that the line numbers in the processed text match up with those in the original text.

The text between the (optional) `else and `endif are emitted if the original condition is false.

Note that macros in non-emitted code are not evaluated (except for `if groupings which are processed only for tracking nesting levels).

include

`include(<filename>)

Includes the text of the file <filename> at the current location. By default, <filename> is relative to the directory specified by the EditPackagesInPath of the Editor.EditorEngine section of your game's .ini file. If you specify only the filename (i.e. no directory), it will search for the include file in the classes directory for the package currently being compiled.

isdefined

`isdefined(<macroname>)
`notdefined(<macroname>)

Evaluate to the string "1" if the macro is (is not) defined, regardless of the definition. Useful with conditional compilation.

undefine

`undefine(<macroname>)

Remove the current definition of <macroname>. Will not work for macro parameter names (`cond, `txt, `#, etc).

log / warn

`log(string OutputString, optional bool bRequiredCondition, optional name LogTag);
`warn(string OutputString, optional bool bRequiredCondition);

Wrapper macros for the LogInternal and WarnInternal functions declared in Object.uc. If bRequiredCondition is specified, the message will only be logged if the condition is true.

Both macros are disabled if scripts are compiled with the -final_release switch.

logd

`logd(string OutputString, optional bool bRequiredCondition, optional name LogTag);

Identical to the `log macro, except that it is only enabled if scripts are compiled in debug mode.

This macro is disabled if scripts are compiled with the -final_release switch.

assert

`assert(bool bCondition);

Wrapper macro for the Assert intrinsic expression.

This macro is disabled if scripts are compiled with the -final_release switch.

Command-line Interactions


There are a number of switches that can be passed to make which will affect the script preprocessor.

debug
causes UPP to define the macro `debug
final_release
causes UPP to define the macro `final_release, as well as disable all wrapper macros (`log, `logd, `warn, `assert).
nopreprocess
turns off all macro and comment preprocessing, passing the exact text from the input file to the class factory. This is primarily for timing and speed testing but if some required text file contains the macro invitation character outside macros, it is possible to use this to compile that file.
intermediate
tells UPP to save the processed versions of the files it compiles. This can be time and space consuming for the entire source tree but it can be invaluable when tracking down macro errors. The files are stored in:
GameDirectory/PreprocessedFiles/<PackageName>/<ClassName>.uc