Embedded configuration control information used by JEnable takes the form of Java
comment lines starting with "//#". This three-character sequence must be the first data
on the line in order to be recognized as configuration control information. If preceded by
anything else, even blanks or tabs, it will not be recognized.
Each embedded control line also specifies a token. This is a sequence made up of letters,
digits, and underscores ('_'), with the first character always a letter or underscore. A control
line must match one of the possible patterns at least as far as the first character of the token
in order to be recognized as a control line. The line "//#5", for instance, would
not be recognized
as a control line because the digit '5' is not a valid start of token character. Tokens are always
case sensitive, so "//#dbg" refers to a different token than "//#DBG".
Tokens may be specified as enabled or disabled (but the same token cannot be both) by the
JEnable command line. If a token is enabled, it means to activate the code
associated with that token. If the token is disabled, it means to deactivate the code
associated with that token. Tokens may also be indeterminant, if they have not be specified
as either enabled or disabled.
Several different formats of configuration control statements are usable in source files, with
different purposes. Some of the control statements use an additional character after the
"//#" start of line but before the token. Here's the complete list of formats:
//#token{ | start of optional code block; include this code if token is enabled,
exclude it if token is disabled |
//#!token{ | start of inverse optional code block; exclude this code if token is
enabled, include it if token is disabled |
//#}token{ | else optional code block; if optional code was being included, change
to excluding, if was being excluded, change to including |
//#token} | end of optional code block; ends
conditionally included code |
//#token* | optional file control, only valid as first line of a file with
extension "java" or "javx"; include this file in build (changing extension to "java" if currently
"javx") if token is enabled, exclude this file from build (changing extension to "javx" if
currently "java") if token is disabled |
//#!token* | inverse optional file control, only valid as first line of a file with
extension "java" or "javx"; include this file in build (changing extension to "java" if currently
"javx") if token is disabled, exclude this file from build (changing extension to "javx" if
currently "java") if token is enabled |
When a configuration change is made that excludes an optional code block from the build
each line within the block is prefixed with "//#token:". This converts all the lines to comments
and prevents processing by the Java compiler and related tools. When a configuration change
includes an optional code block in the build each line within the block has the
"//#token:" prefix removed.
For example, this original source code:
//#ATOK{
int i = 0;
//#ATOK}
int j = 1;
//#BTOK{
int k = 2;
//#}BTOK{
int l = 3;
//#BTOK}
When processed with ATOK enabled and BTOK disabled gets changed to:
//#ATOK{
int i = 0;
//#ATOK}
int j = 1;
//#BTOK{
//#BTOK: int k = 2;
//#}BTOK{
int l = 3;
//#BTOK}
If it's then processed again with BTOK enabled it becomes:
//#ATOK{
int i = 0;
//#ATOK}
int j = 1;
//#BTOK{
int k = 2;
//#}BTOK{
//#BTOK: int l = 3;
//#BTOK}
Nested optional blocks are allowed, but overlapping blocks are an error. For example, this
case is invalid because of overlap:
//#ATOK{
//#BTOK{
//#ATOK}
//#BTOK}
If a
configuration code change disables an outer optional block all contained blocks are ignored.
Enabling an outer block is a little more complicated. In order to ensure proper processing
of nested option blocks, the user should generally specify every token used for the
nested blocks as either enabled or disabled if any of them are either enabled or disabled
in a configuration change. It is an error if an indeterminant beginning of block token (one
with a token which is not on either list) is immediately contained within a block with an
enabled token. In other words, the case:
//#ATOK{
//#BTOK{
//#CTOK{
//#CTOK}
//#BTOK}
//#ATOK}
gives an error if ATOK is on the enabled list and BTOK is not on either
list, or if ATOK is not
on the disabled list, BTOK is on the enabled list, and CTOK is not on
either list.
The two forms of the file control statements (normal and inverted) do not in and of
themselves result in any changes to the source code in the file when the configuration changes.
Instead, these statements work on the file extension, changing it between "java" (which allows
the file to be included in the build) and "javx" (which excludes it from the build, using
standard Java compilers). This allows the source code for optional classes to be kept in the
same directories even when not included in the current configuration.
All the other control statements can be used within files with any desired extensions. The
file control statements are only allowed within files with "java" or "javx" extensions, and
only as the first line of these files.