Most preprocessing is controlled by preprocessor
directives. Directives are specified
within the source code by creating a commented line that starts with the //#
character
sequence, immediately followed by the directive. For example, //#ifdef
.
Like the XML language, preprocessor directives must be well-formed.
That is, they must have a beginning directive and an ending directive. For
example,
when a block is started with one of
the //#if
directives,
it must be closed by an //#endif
directive. Blocks can be nested,
which means that inside an if/elif/else/endif
block can
be any number of additional if/elif/else/endif
blocks.
Directives define actions and conditions. The preprocessor decides upon whether to comment or uncomment the block of code. Symbols in directive expressions can be either defined or not defined. Identifiers and variables, however, must always contain a value that can be used or compared during preprocessing. The preprocessor supports three types of variables: strings, integers, and booleans.
Variable names must start with characters/tokens which are same as start characters/tokens of valid Java
identifiers but in addition, consequentive characters can also be '.' '\' and '/'. . You can compare different variable
types using common comparison syntax (<=, <, >=, >
and ==
).
You can also use boolean operations, such as &&, ||, !
and ^
. You can also
use <variable name>:defined or defined(<variable name>) functions to check for variable defintions. This
is not neccessary and should not be used when creating new code blocks but is built in for easy imports from J2ME Polish.
For more information, see Comparing Preprocessor
Variables.
The following example shows If/Else
block with a nested elif
directive.
//#if mmedia //#if nokia //#if s60_ver=="1.0" import com.nokia.mmapi.v1 //#elif s60_ver=="2.0" import com.nokia.mmapi.v2 //#else import com.nokia.mmapi.def //#endif //#else import javax.microedition.mmapi //#endif //#endif
See the following table for a description of preprocessor directives.
Directive |
Description |
#ifdef [identifier] |
The identifier represents a variable of any type (boolean,
string, or integer) and checks whether or not the variable is defined.
If true (the variable is defined), the code that
follows is processed. Nested blocks are processed as well.
If false (the variable is not defined),
the
code
that follows
is commented and nested blocks are not evaluated. The directive
must be closed with #endif . |
#ifndef [identifier] |
Works in the same manner as ifdef, but returns "True"
if the variable is not defined. The directive must be closed with #endif . |
#elifdef [identifier] |
Works as a standard else if statement, but automatically
checks whether or not the identifier is defined. The directive can only
complement inside blocks started
by ifdef/ifndef . |
#elifndef [identifier] |
Works as a standard else if statement but automatically
checks whether the identifier is not defined. The directive can only complement
inside blocks started
by ifdef/ifndef. |
#if [expression] |
Evaluates an expression passed to it and fires the appropriate action.
The directive must be closed with
endif . |
#elif [expression] |
Works as a standard else if statement and can complement
only in blocks started by an if statement. The directive preprocesses
the code that follows based on the result of the expression. |
#else |
Works as a standard else statement only preprocesses
the code that follows when none of the previous conditions in the defining
block
were true. Complements
inside any block started with the if/ifdef/ifndef directive. |
#endif |
This directive must be used to close any block started with if/ifdef/ifndef . |
#condition [expression] |
Must be on the first line in a file. This directive determines if the file should be included in the build based on the result of the expression. |
#debug [level] |
Determines if the line following the directive should be commented or
uncommented based on the debug level set in Compiling
page of the project
properties. If the debug level is omitted and the debug level is not set
to "Off" in
the project properties, the preprocessor will automatically debug the line
in question. Used
for debugging
purposes
with expressions such as System.out.println ,
for example. This directive can be nested. |
#mdebug [level] |
Behaves the same as #debug, but instead comments or uncomments
a whole block of lines following the line it is on until it reaches #enddebug .
This directive is used for debugging purposes with expressions
such as System.out.println ,
for example. This directive can be nested. If the mdebug block
partially intersects an if/ifdef/ifndef block (for example,
enddebug is outside a closed if block in which mdebug is
called) the preprocessor will generate errors. |
#enddebug |
Must terminate #mdebug block. |
#define [identifier] #define [identifier=value] #define [identifier value] |
Adds temporary abilities or variables to the preprocessor memory. Can not be used in nested blocks. Global variables defined in the project configuration properties override these temporary variables. |
#undefine [identifier] | Removes temporary abilities/variables from the memory. This declaration can also be used to remove global variables defined in the project configuration properties from the preprocessor memory, but will not remove the variables from the list of project or configuration variables. |