michael@0: .. _preprocessor: michael@0: michael@0: ================= michael@0: Text Preprocessor michael@0: ================= michael@0: michael@0: The build system contains a text preprocessor similar to the C preprocessor, michael@0: meant for processing files which have no built-in preprocessor such as XUL michael@0: and JavaScript documents. It is implemented at ``python/mozbuild/mozbuild/preprocessor.py`` and michael@0: is typically invoked via :ref:`jar_manifests`. michael@0: michael@0: While used to preprocess CSS files, the directives are changed to begin with michael@0: ``%`` instead of ``#`` to avoid conflict of the id selectors. michael@0: michael@0: Directives michael@0: ========== michael@0: michael@0: Variable Definition michael@0: ------------------- michael@0: michael@0: define michael@0: ^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #define variable michael@0: #define variable value michael@0: michael@0: Defines a preprocessor variable. michael@0: michael@0: Note that, unlike the C preprocessor, instances of this variable later in the michael@0: source are not automatically replaced (see #filter). If value is not supplied, michael@0: it defaults to ``1``. michael@0: michael@0: Note that whitespace is significant, so ``"#define foo one"`` and michael@0: ``"#define foo one "`` is different (in the second case, ``foo`` is defined to michael@0: be a four-character string). michael@0: michael@0: undef michael@0: ^^^^^ michael@0: michael@0: :: michael@0: michael@0: #undef variable michael@0: michael@0: Undefines a preprocessor variable. michael@0: michael@0: Conditionals michael@0: ------------ michael@0: michael@0: if michael@0: ^^ michael@0: michael@0: :: michael@0: michael@0: #if variable michael@0: #if !variable michael@0: #if variable==string michael@0: #if variable!=string michael@0: michael@0: Disables output if the conditional is false. This can be nested to arbitrary michael@0: depths. Note that in the equality checks, the variable must come first, and michael@0: the comparison operator must not be surrounded by any whitespace. michael@0: michael@0: else michael@0: ^^^^ michael@0: michael@0: :: michael@0: michael@0: #else michael@0: michael@0: Reverses the state of the previous conditional block; for example, if the michael@0: last ``#if`` was true (output was enabled), an ``#else`` makes it off michael@0: (output gets disabled). michael@0: michael@0: .. warning:: An ``#else`` is relative to the last conditional block only, michael@0: unlike the C preprocessor. michael@0: michael@0: It does not matter whether any blocks before it were true. This behavior michael@0: changed on trunk (Gecko 1.9) on 2006-12-07; see Bug 277122 for details. michael@0: michael@0: :: michael@0: michael@0: #if 1 michael@0: always included michael@0: #elif 1 michael@0: never included michael@0: #else michael@0: always included michael@0: #endif michael@0: michael@0: endif michael@0: ^^^^^ michael@0: michael@0: :: michael@0: michael@0: #endif michael@0: michael@0: Ends the conditional block. michael@0: michael@0: ifdef / ifndef michael@0: ^^^^^^^^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #ifdef variable michael@0: #ifndef variable michael@0: michael@0: An ``#if`` conditional that is true only if the preprocessor variable michael@0: variable is defined (in the case of ``ifdef``) or not defined (``ifndef``). michael@0: michael@0: elif / elifdef / elifndef michael@0: ^^^^^^^^^^^^^^^^^^^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #elif variable michael@0: #elif !variable michael@0: #elif variable == string michael@0: #elif variable != string michael@0: #elifdef variable michael@0: #elifndef variable michael@0: michael@0: A shorthand to mean an ``#else`` combined with the relevant conditional. michael@0: The following two blocks are equivalent:: michael@0: michael@0: #ifdef foo michael@0: block 1 michael@0: #elifdef bar michael@0: block 2 michael@0: #endif michael@0: michael@0: :: michael@0: michael@0: #ifdef foo michael@0: block 1 michael@0: #else michael@0: #ifdef bar michael@0: block 2 michael@0: #endif michael@0: #endif michael@0: michael@0: .. warning:: An ``#elif``, ``#elifdef``, or ``#elifndef`` is relative to michael@0: the last conditional block only (as well as the condition it implies), michael@0: unlike the C preprocessor. It does not matter whether any blocks before michael@0: it were true. This behavior changed on trunk (Gecko 1.9) on 2006-12-07. michael@0: See Bug 277122 for details. michael@0: michael@0: File Inclusion michael@0: -------------- michael@0: michael@0: include michael@0: ^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #include filename michael@0: michael@0: The file specified by filename is processed as if the contents was placed michael@0: at this position. This also means that preprocessor conditionals can even michael@0: be started in one file and ended in another (but is highly discouraged). michael@0: There is no limit on depth of inclusion, or repeated inclusion of the same michael@0: file, or self inclusion; thus, care should be taken to avoid infinite loops. michael@0: michael@0: includesubst michael@0: ^^^^^^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #includesubst @variable@filename michael@0: michael@0: Same as a ``#include`` except that all instances of variable in the included michael@0: file is also expanded as in ``#filter`` substitution michael@0: michael@0: expand michael@0: ^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #expand string michael@0: michael@0: All variables wrapped in ``__`` are replaced with their value, for this line michael@0: only. If the variable is not defined, it expands to an empty string. For michael@0: example, if ``foo`` has the value ``bar``, and ``baz`` is not defined, then:: michael@0: michael@0: #expand This <__foo__> <__baz__> gets expanded michael@0: michael@0: Is expanded to:: michael@0: michael@0: This <> gets expanded michael@0: michael@0: filter / unfilter michael@0: ^^^^^^^^^^^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #filter filter1 filter2 ... filterN michael@0: #unfilter filter1 filter2 ... filterN michael@0: michael@0: ``#filter`` turns on the given filter. michael@0: michael@0: Filters are run in alphabetical order on a per-line basis. michael@0: michael@0: ``#unfilter`` turns off the given filter. Available filters are: michael@0: michael@0: emptyLines michael@0: strips blank lines from the output michael@0: slashslash michael@0: strips everything from the first two consecutive slash (``/``) michael@0: characters until the end of the line michael@0: spaces michael@0: collapses consecutive sequences of spaces into a single space, michael@0: and strips leading and trailing spaces michael@0: substitution michael@0: all variables wrapped in @ are replaced with their value. If the michael@0: variable is not defined, it is a fatal error. Similar to ``#expand`` michael@0: and ``#filter`` michael@0: attemptSubstitution michael@0: all variables wrapped in ``@`` are replaced with their value, or an michael@0: empty string if the variable is not defined. Similar to ``#expand``. michael@0: michael@0: literal michael@0: ^^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #literal string michael@0: michael@0: Output the string (i.e. the rest of the line) literally, with no other fixups. michael@0: This is useful to output lines starting with ``#``, or to temporarily michael@0: disable filters. michael@0: michael@0: Other michael@0: ----- michael@0: michael@0: #error michael@0: ^^^^^^ michael@0: michael@0: :: michael@0: michael@0: #error string michael@0: michael@0: Cause a fatal error at this point, with the error message being the michael@0: given string.