home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
JRCPP.ZIP
/
USERS.DOC
< prev
Wrap
Text File
|
1990-03-27
|
70KB
|
1,444 lines
JRCPP USERS MANUAL (3/23/90)
Copyright (C) 1990 James Roskind, All rights reserved. Permission
is granted to copy and distribute this file as part any machine
readable archive containing the entire, unmodified, JRCPP PUBLIC
DISTRIBUTION PACKAGE (henceforth call the "Package"). The set of
files that form the Package are described in the README file that
is a part of the Package. Permission is granted to individual
users of the Package to copy individual portions of the Package
(i.e., component files) in any form (e.g.: printed, electronic,
electro-optical, etc.) desired for the purpose of supporting
users of the Package (i.e., providing online, or onshelf
documentation access; executing the binary JRCPP code, etc.).
Permission is not granted to distribute copies of individual
portions of the Package, unless a machine readable version of the
complete Package is also made available with such distribution.
Abstracting with credit is permitted. There is no charge or
royalty fee required for copies made in compliance with this
notice. To otherwise copy elements of this package requires
prior permission in writing from James Roskind.
James Roskind
516 Latania Palm Drive
Indialantic FL 32903
End of copyright notice
What the above copyright means is that you are free to use and
distribute (or even sell) the entire set of files in this Package,
but you can't split them up, and distribute them as separate files.
The notice also says that you cannot modify the copies that you
distribute, and this ESPECIALLY includes NOT REMOVING the any part of
the copyright notice in any file. JRCPP currently implements a C
Preprocessor, but the users of this Package do NOT surrender any
right of ownership or copyright to any source text that is processed
by JRCPP, either before or after processing. Similarly, there are no
royalty or fee requirements for using the post-preprocessed output of
JRCPP.
This Package is expected to be distributed by shareware and freeware
channels (including BBS sites), but the fees paid for "distribution"
costs are strictly exchanged between the distributor, and the
recipient, and James Roskind makes no express or implied warranties
about the quality or integrity of such indirectly acquired copies.
Distributors and users may obtain the Package (the Public
distribution form) directly from the author by following the ordering
procedures in the REGISTRATION file.
DISCLAIMER:
JAMES ROSKIND PROVIDES THIS FILE "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM AND DOCUMENTATION IS WITH YOU. Some states do not allow
disclaimer of express or implied warranties in certain transactions,
therefore, this statement may not apply to you.
UNIX is a registered trademark of AT&T Bell Laboratories.
_____________________________________________________________________
JRCPP USERS MANUAL (3/23/90)
Contents:
INTRODUCTION
USERS MANUAL- USER INTERFACE- INTRODUCTION
USERS MANUAL- USER INTERFACE- COMMAND LINE ARGUMENTS AND FLAGS
USERS MANUAL- USER INTERFACE- Environment variable control
USERS MANUAL- USER INTERFACE- Interactive interface (bug report support)
APPENDIX A PREDEFINED MACRO NAMES (compatibility guide)
APPENDIX B JRCPP STATIC LIMITS
INTRODUCTION
JRCPP is a full ANSI C compatible preprocessor, with customizable
extensions to assist in transitioning from less complete C
preprocessor standards. Among the customizations available from JRCPP
is support for preprocessing of C++ files (note: this does not
include "translation" of C++ source code to C code). The command
line interface is designed to be compatible with the UNIX command
line interface for cpp (the traditional UNIX C Preprocessor).
Major Features of JRCPP:
1) Full ANSI C standard support, with highly customizable options
to assist in porting, development, and training. Customization
can be used easily to support many special C preprocessing
needs (see #pragma for descriptions of options).
2) Full ANSI C macro definition and expansion capabilities. This
includes support for:
a) ANSI C defined recursive macros expansion;
b) ANSI C "##" paste operator;
c) ANSI C "#" stringize operator;
d) Special "macro expansion explanation" mode. Useful for
debugging, or as a tutorial/learning aid;
e) Output file has line directive that identifies the line
from which a token was derived, rather than ascribing the
results to the line containing the macro name invocation;
test
3) Full support of predefined ANSI C macros including __DATE__,
__TIME__, __LINE__, ,__FILE__, and __STDC__ (or __cplusplus in
C++ compatibility mode).
4) Extensive customizable diagnostic capabilities. This includes
170+ diagnostics which provide:
a) Identification of all non-ANSI C preprocessing constructs.
b) Production of all ANSI C suggested preprocessor warnings.
c) Typically hidden activity trace (such as where #include is
searching for a file).
d) Customizable diagnostic responses include:
1) Fine grain control over severity of EVERY diagnostic.
2) Coarse control over response to groups of diagnostics.
5) Full ANSI C preprocessor "if" construct support. This
includes:
a) Support for the ANSI C "#elif" construct
b) Traditional support for "#if", "#ifdef", "ifndef",
"#else", and "#endif"
c) Support for the "defined()" and "defined" operators.
d) ANSI C specified "#if" and "#elif" expression expansion
and evaluation.
6) Removal of common static limits on macro expansion (available
memory is the only constraint). This includes:
a) No limit on the number of macros defined;
b) No limit on the number of arguments for function-like
macros;
c) No limit on the size of macro definitions;
d) No limit on the size of macro expansions;
e) No limit on the depth of nested include files;
6) Support for very long identifier names, with all characters
considered significant. Optional support for identifiers
containing '$'.
7) Support for precomputation of header file inclusion. This
involves preprocessing a complex header-file-set in advance,
and constructing an "equivalent" single preprocessed file (see
#pragma descriptions).
8) Customizable C++ source compatibility. This includes:
a) optional support for // style comments
b) optional support for __cplusplus macro INSTEAD of __STDC__
c) optional support for "missing" macro arguments as
whitespace
d) optional support for allowing consecutive tokens to
"merge" after preprocessing (part of Classic C
preprocessor model).
e) optional support for various #include search schemes (re:
where to look for a file specified by a "...." style
#include directive).
f) support for C++ tokenization of "->*" and ".*".
USERS MANUAL- USER INTERFACE- INTRODUCTION
JRCPP has three main methods of acquiring information and commands
from a user, and one secondary method. The first and primary method
is via command line flags and arguments. The second method of
transferring information is via environment variables. The third
method makes use of the "#pragma" construct to pass precise
customization commands to the preprocessor. The final method is
actually a tool to assist in providing problem reports to the vendor,
and makes use of a simple interactive interface, instigated by
<cntrl><break>.
USERS MANUAL- USER INTERFACE- COMMAND LINE ARGUMENTS AND FLAGS
As mentioned, the command line interface is modeled after the UNIX
cpp command line interface. The most typical use of JRCPP would be:
jrcpp source.c procesed.i >source.err
where "source.c" is the user supplied input source file, "procesed.i"
is the file name for the post-preprocessed C text, and "source.err"
is the name of a file that will receive error messages.
The following is a synopsis of the command line interface:
Usage: jrcpp [option_list] [infile [outfile]]
'infile' defaults to stdin, 'outfile' to stdout
Options are read left to right, and enacted immediately.
-B Support // style comments
-Dname Define preprocessor symbol 'name' to be 1
-H Output pathnames of included files to stderr
-help display list of command line options
-helppragma display list of pragmas
-Idir Add directory to search path for "*.h" selected files
-P Don't produce #line directives in output
-Uname Undefine preprocessor symbol 'name'
-undef Undefine platform specific macros and __STDC__
-undefANSI Undefine macros: __FILE__, __LINE__, __DATE__, __TIME__
-Ydir Add directory to search path for <*.h> selected files
The following are detailed descriptions of the command line options:
----------------------------------------------
-B Support // style comments
If the -B option is selected, then // style comments, as are defined
in C++, are honored. A // style comment begins with the sequence
"//", and continues until the end of a line. Note that comments do
not nest. Hence, a "/*" encountered during a // style comment will
be ignored. Similarly, a "//" encountered within a "/*" style comment
will also be ignored. Finally, comments are NOT looked for within
lexical tokens such as string literals, or character constants.
(e.g.: the text "hello///***there" does not start a comment).
----------------------------------------------
-Dname Define preprocessor symbol 'name' to be 1
The -D command line option is used to define a macro in a manner
similar to what in achieved via:
#define name 1
Note that the macro defined my this mechanism is always a manifest
macro (i.e.:not a function like macro), and the default value of
decimal one (1) is provided. The slightly more complex form of the
command line:
-Dname=token
is also supported. In this form, the results are equivalent to:
#define name token
but there is the significant restriction that "token" be a single
lexical token. For example, the following is legal:
-Dversion=200 -Dbuffer_size=default_buffer_size
but the following is illegal because the text is NOT a single token:
-Dbuffer_size=2*default_buffer_size
The intent of support the -D option is to provide a simple way of
controlling the preprocessor. More complex control should be
provided by using #if constructs in the source to regulate complex
macro definitions.
----------------------------------------------
-H Output pathnames of included files to stderr
When this option is provided, the full path and file name for each
included file will be displayed on the screen (stderr). Each file
will be separated by a space from the next file. This option is most
useful for watching the progress the preprocessor, without slowing
down the computation. Note that the "#pragma display_progress" is a
more dramatic way to watch progress, and also much more detailed (and
computationally expensive).
----------------------------------------------
-help display list of command line options
The -help option displays a complete list of all options currently
supported. It is commonly used to avoid having to refer to
documentation for JRCPP. In addition, this option may reveal more
up-to-date information than even the documentation.
----------------------------------------------
-helppragma display list of pragmas
The -helppragma option displays a complete list of all pragmas
currently supported. It is commonly used to avoid having to refer to
documentation for JRCPP. In addition, this option may reveal more
up-to-date information than even the documentation.
----------------------------------------------
-Idir Add directory to search path for "*.h" selected files
The -I directory provides a mechanism for extending the application
include path. The application include path is used for searching for
files designated in a "...." style include directive. The text
provided with this option ("dir") is assumed to be a directory in
which some include files may be found. This command adds "dir" to
the end of the current applications search path, so that it is used
only if prior entries on the search path do not expose the desired
file (based on a #include "..." directive). This directory can be a
relative path name, but this complicates the search algorithm
slightly (see LANGUAGE REFERENCE MANUAL for details).
Note that the include file searching algorithm is based on two
distinct paths: the application include path; and the system include
path. When <...> style include directives are encountered, only the
system include path is consulted during the search procedure. In
contrast, when a "..." style include directive is encountered, a file
is searched for locally, then searched for using the application
include path, and finally using the system include path. For more
details on the exact algorithm used, see the LANGUAGE REFERENCE
MANUAL. Also note that the "#pragma include_search" provides for
customization of the actual search algorithm. See also the command
line option "-Ydir" in order to augment the system include path.
----------------------------------------------
-P Don't produce #line directives in output
When the -P option is selected, the output will not contain any #line
directives. Note that when #line directives are provided, that the
output for long lines is broken up using backslash newline
separators, and additional #line directives are added to compensate
for this "beautification". In addition, when #line directives are
provided, long series of blank lines are replaced by a single #line
directive. In contrast, when there are no #line directives, lines are
not wrapped using escaped newlines, and blank lines are actually
provided as such (this is very common when long block comments are
translated, during preprocessing, into blank lines).
----------------------------------------------
-Uname Undefine preprocessor symbol 'name'
This option is equivalent to the preprocessor directive "#undef
name". It is most commonly used to remove (selectively) the macro
definitions for platform specific macros (such as _JRCPP, or MSDOS),
but it CANNOT be used to undefine the special internal macros (such
as __DATE__, and __STDC__). It can also be used to undefine a macro
that was defined earlier on the command line. If it is necessary to
undefine any internal macros, the command line option -undefANSI can
be used, or the "#pragma undefine_macros ..." pragma can be invoked.
----------------------------------------------
-undef Undefine platform specific macros and __STDC__
The -undef option provides a convenient way to undefine all the
platform specific macros as well as __STDC__. Note that it does not
effect the other internal macros (__DATE__, __TIME__, __LINE__,
__FILE__), nor does it effect any macros defined on the command line.
This feature is commonly used during a porting operation, where the
target compiler is known not to be ANSI conformant, and hence it is
desirable to remove the __STDC__ macro definition along with the
platform specification.
----------------------------------------------
-undefANSI Undefine macros: __FILE__, __LINE__, __DATE__, __TIME__
The -undefANSI is only necessary when the above 4 standard ANSI macro
names are interfering with some source code that predates the ANSI
standard. Note that this functionality is also supported via
"#pragma undefine_macros ...". In addition, once these macros have
been undefined in this manner, they CAN be redefined by the user, but
they can never resume their special meaning. Note that this action
supports a very non-conforming porting operation, and is RARELY
necessary.
----------------------------------------------
-Ydir Add directory to search path for <*.h> selected files
The -Ydir option provides a mechanism for extending the system
include path. The system include path is used to search for files
designate by a <...> style include directive, and used as an
alternate path for finding files designated by a "..." style include
directive. The argument "dir" provided with this option is expected
to be a directory in which some include files can be found. The
argument is appended to the system include path, and hence is only
considered for use (as a prefix for a file) if all earlier
directories on the include path have failed to reveal the desired
file. Note that the directory provided is usually an absolute path
in a file system, but a relative path may be used (see LANGUAGE
REFERENCE MANUAL for detailed explanation of the use of this path).
Prior to examining the command line, the environment variable
"INCLUDE" is consulted and parsed to form an initial system search
path. With this environment variable set to identify the directory
containing the system include files, it is rarely necessary to use
this -Y option. This option can be useful if various versions of
system include files are being used (as is common during a cross
compilation). Note that for such use to be effective, the
environment variable "INCLUDE" must either not exist, or contain no
entries (Note that directory entries in the environment variable
INCLUDE are separated by semicolons, and spaces adjacent to the
semicolons are discarded).
USERS MANUAL- USER INTERFACE- Environment variable control
JRCPP consults the system environment at start up to provide some
default settings. Currently, only the environment variable INCLUDE
is consulted, and its contents are parsed into a list of directories.
These directories form the basis for the "system include path". See
the LANGUAGE REFERENCE MANUAL for details of the search algorithm
used to find #include files.
The "system include path" is a list of directories that are searched
when a <....> style #include directive is encountered. The "system
include path" is also used when a "...." style #include directive is
being processed, and neither local searching, nor searches in the
"application include path" have revealed the requested file.
The "system include path" is specified in the environment by a list
of absolute or relative paths, with semicolons to separate the
directories. For example, if the environment variable "INCLUDE"
contains:
/include ; /local/include
Then the initial value of the "system include path" would be the
directories "/include" and "/local/include". Additional directories
may also be added to this list using the command line option "-Ydir".
Under most DOS and UNIX operating systems, a value, such as was just
described, may be placed into the environment using the command:
set INCLUDE=/include;/local/include
See your operating system reference manual for more details of this
functionality.
Also note that relative paths may be used, but the user should
carefully understand the consequences of such path specifiers. For
example, if the environment variable "INCLUDE" contains:
/include ; ..
Then the initial value of the "system include path" would be the
directory "/include", and the relative directory "..". The methods
by which such relative directories are resolved (with the postfix
being the requested file name) can vary depending on whether
ancestral searching is permitted, and whether the current directory
is consulted. In addition to the LANGUAGE REFERENCE MANUAL, see also
the description of the "#pragma include_search ..." directive.
USERS MANUAL- USER INTERFACE- PRAGMA DIRECTIVES
This section describes the pragmas that are available. This section
begins with a concise listing of the available pragmas, and then
provides detailed explanation of the meanings of each pragma, and its
potential use.
CONCISE LIST OF PRAGMA DIRECTIVES
Each pragma has a base name that identifies the pragma (such as
"space_between_tokens"), and optionally some refining arguments. The
following is concise list of the pragmas that are currently supported
by JRCPP. Note that any pragmas that are encountered that do not
match a supported pragma format, are passed unchanged to the
post-preprocessed output file. Also note that the tokens on a line
with a pragma are NOT macro expanded, and are taken exactly as
supplied. Similarly, unrecognized pragmas are passed to the output
without undergoing macro expansion.
In the following descriptions, square brackets [] are used to
surround optional arguments. The "|" operator may be read as "or",
and is used to indicate that either of the arguments may be supplied.
Parentheses are used to group lists of alternative arguments.
DIAGNOSTIC_NUMBER is a number between 1001 and 9999 inclusive. All
other text is exactly what is allowed as an argument. A similar list
of supported pragmas can be obtained using the command line option
"-helppragma".
BASE NAME REFINING ARGUMENTS
after_output_dump [macros][profile]
cplusplus_comment [on|off]
cplusplus_mode
delayed_expansion [on|off]
describe_macro_expansions [on|off]
diagnostic_adjust DIAGNOSTIC_NUMBER (fatal|error|warning|hint|silent)
diagnostic_adjust (error|warning|hint|silent)
(fatal|error|warning|hint|silent)
display_progress [on|off]
include_search [current_directory] [only_eldest_ancestor|
only_youngest_ancestor|all_ancestors]
space_between_tokens [on|off]
undefine_macros [ANSI] [STDC] [platform] [command_line] [user]
The sections that follow describe the detailed interpretation of each
of the pragma directives listed above.
----------------------------------------------
#pragma after_output_dump [macros] [profile]
This pragma directs JRCPP to append some additional text to the
post-preprocessed output file. The two option are either a
performance profile of JRCPP, or a list of all the macros that were
defined at the end of the preprocessing action.
The performance profile is most useful to the author of JRCPP, as it
reveals details of both memory usage and of function call activity.
All the profile information is contained in a comment, and hence it
does not effect the quality of the post-processed output. Note that
the production version of JRCPP does not have the required calls to
the profiling system, and hence very little information is provided
when this option is exercised. In contrast, JRCPPSAF, and JRCPPTIM
perform detailed tracing of all function calls.
The distinction between JRCPPTIM and JRCPPSAF is that JRCPPTIM does
not have assertions, but does make use of an actual clock in order to
calculate time spent in each function. Consequently, the profiling
information gathered during a run of JRCPPTIM is very indicative of
the performance of the production version JRCPP, which also bypasses
assertion checking. The detailed timing provided by JRCPPTIM comes
at the cost of a severe decrease in overall execution time, as viewed
by the user (the careful maintenance of clock interval information is
very computationally expensive). JRCPPSAF is HEAVILY asserted (i.e.,
has massive redundant code, with extensive internal error checking).
In addition, in JRCPPSAF calls to the tracing system are made, but in
the interest of speed, a real time clock is not used. As a result,
it is very useful for providing problem reports (i.e., bug reports)
to the JRCPP author, but it is slightly less useful for identifying
execution bottlenecks in JRCPP. Note that JRCPP (the production
version) has neither assertions, nor profiling calls, and hence is
the smallest and fastest version available. Note that when an
assertion is violated in JRCPPSAF, a complete stack dump is provided,
and hence it is generally quite apparent (to the author of JRCPP)
what the problem was.
If you wish to complain about the performance (in terms of execution
time) of JRCPP with some specific source, you should use JRCPPTIM and
the "#pragma after_output_dump profile" to document the problem.
Note that your complaint need only include commented out profile, and
you will NOT have to submit your actual source code. Often complaints
that are documented in this way can actually be fixed! (although the
underlying hardware can sometimes be the actual source of the poor
performance). The information provided in this output identifies
where JRCPP is spending its time, and if your source program focuses
on an area that was not sufficiently optimized, poor performance can
result.
When "#pragma dump_after_output macros" is present in the source file
(or included file), then a complete dump of the macro database is
appended to the post-preprocessed output file. The format of this
output is a series of actual #define and #undef directives.
This particular pragma has two significant applications for users.
The first application is in debugging complex source files, in that
the user is able to easily see exactly what macros were defined, what
their definitions were, if they were ever undefined. The second
major application is in precalculating what the inclusion of a
complex set of include files would result in. From a users point of
view, including a single file that went on to include other files
which included ..., and contained extensive macro expansion activity,
may require a significant amount of time to process, and may be
repeated in many distinct source files. With this macro dump option,
the user can construct a single header file that is equivalent to a
complex set of nested include files. This resultant file is much
more than the simple concatenation of the files, as its initial
section contains the fully macro expanded contents of the set of
files, while the latter section provides all the macro definitions
that were active at the end of the complex set. After such a
"summarizing" header file has been created, it is possible to include
only this one header file, but achieve an equivalent result (in much
less time) to including the root of the complex nested include set.
Note that the macro definitions at the end of the header file cause
its inclusion to be IDENTICAL to including the original header file
sequence.
If the above method of precalculating resulting header file contents
is used, one slight warning must be observed. The repeated
preprocessing of the top section of a precalculated header file (when
it is used in lieu of the massive set of headers) will automatically
provide for macro expansions in that text. The user should be
certain that no macros are defined during this section of code, and
that all macros are defined only when the "macro dump" section is
encountered. In order to assist in this, the pragma:
#pragma undefine_macros platform command_line user
can be used prior to including the precomputed single header file.
See the description of the the undefine_macros pragma later in this
section for more details of its operation. Note that the macro
definitions at the end of the precomputed header file will reinstate
the desired platform specific macro definitions :-).
----------------------------------------------
#pragma cplusplus_comment [on|off]
This pragma may be used to allow or disallow the support for // style
comments. A // style comment begins with the character sequence
"//", and continues till the end of the line. Note that by default,
these comments (introduced in the C++ language) are not supported.
The command line option "-B" can be used to direct the compiler to
respect such comments, as can "#pragma cplusplus_comment on". Note
that if no argument is supplied, then "#pragma cplusplus_comment" is
by default equivalent to "#pragma cplusplus_comment on". This
support for C++ style comments is only provided AFTER the newline
that terminates the text of the pragma (with argument "on"), or
disallowed AFTER the terminating newline.
Neither // style comments nor /* style comments nest. In addition,
comment initiators are NOT scanned for during the tokenization of a
string literal or character constant. Hence the following are string
literals, and do NOT initiate a comment under any circumstances:
"comments begin with /* or // on a line"
Similarly, // style initiators are not scanned for during /* style
comments, and /* style initiators are not scanned for during // style
comments. For example, the following 3 lines are all considered
IDENTICAL after preprocessing:
i++;
/* note that // has no effect in /* style comment */ i++;
i++; // note that /* in this comment is ignored
i++; // and the initial text of this line is used */
This pragma is most useful for turning on acceptance of // style
comments in a small section of code, without having to allow it in
all of the source file, or similarly disallowing it in a small
section of code.
----------------------------------------------
#pragma cplusplus_mode
This pragma has two effects. The simplest element of its action is
to enable // style comments, in a manner identical to what is
provided by "#pragma cplusplus_comment on". The other action
performed by this pragma is that the ANSI C macro __STDC__ is
undefined, and no longer considered "special" in any way (i.e.: it
can now be the subject of macro definitions and undef actions). In
addition, the macro __cplusplus is defined as 1 (the digit one), and
it is considered a special internal macro (i.e.: it cannot be the
subject of standard #define or #undef activities).
This pragma is most useful when preprocessing C++ native code, which
may have dependency on __STDC__ NOT being defined, and/or the macro
__cplusplus being defined.
----------------------------------------------
#pragma delayed_expansion [on|off]
This option allows for the presence of directives, during the
scanning for arguments to a function like macro. Under default
operation (which is "off"), if an argument list is not complete by
the time a directive is encountered, the error "missing ')' in
argument list" is provided. Since some directives do not change the
macro database, the macro expansion of argument lists across
directives is possible. Note that this delayed expansion does NOT
allow for #define, #undef, or #pragma actions within an argument list.
For example, consider the following code segment:
#define F(x) a x 2
F(
#if expression
+
#else
-
#endif
)
Although this is not guaranteed to be understood by all ANSI
compatible preprocessors, the above will be acceptable if the
delayed_expansion option is set to "on". In contrast, none of the
following invocations of the macro "F" are legal, independent of the
setting of delayed_expansion:
#define F(x) a x 2
F(
#pragma anything
+)
F(
#define anything
*)
F(
#undef anything
-)
If no argument is provided, the default of "on" is assumed.
This pragma is most useful when porting code that used these features
on some other platform, which silently supported "delayed_expansion".
As clearly stated in the in the ANSI C Standard, and echoed in the
LANGUAGE REFERENCE MANUAL: if the results of macro expansion provide
sequences that COULD HAVE BEEN interpreted as directives, these
sequences are NOT processed as directives. Hence directives must be
located BEFORE the macro expansion process takes place, and the
directives cannot be usefully provided as arguments to macros.
----------------------------------------------
#pragma describe_macro_expansions [on|off]
This pragma causes an extensive amount of additional information to
be provided to the user when macro expansion takes place. The
information is provided in the diagnostics listings (via stdout), and
is self explanatory. Note that this option may be turned "on" and
"off" selectively during a source file in order to see the actual
macro expansion activity in only a small section of code.
The information that is supplied includes a printout of a token
sequence before and after each step of macro expansion. Also
included is a printout of the actual #define directive that is being
used in each step. In the case of function like macro invocations,
an explanation is provided of which arguments are themselves macro
expanded (or stringized), and what the results of such intermediate
goals are. Finally, whenever a macro is explicitly "skipped" and not
expanded (in compliance with the ANSI Standard specifications that
preclude self recursive macro expansion), a notification of this
activity is provided.
This pragma is most useful when debugging complex macros, and
understanding the derivation of expanded text. In this regard, it
may also be used as a tutorial explaining the underlying algorithm
(It can also be used to document errors in the preprocessor expansion
provided by bugs in JRCPP, if need be :-) ).
----------------------------------------------
#pragma diagnostic_adjust DIAGNOSTIC_NUMBER
(fatal|error|warning|hint|silent)
This pragma is used to adjust the severity level of a single
diagnostic. For a complete list of diagnostics and their meaning,
see DIAGNOSTIC MESSAGE REFERENCE MANUAL.
As an example, if the user wishes to ignore the presences of
diagnostic 4034 (which has a default severity level of "error", and
which would in turn preclude the production of any preprocessed
output), the directive:
#pragma diagnostic_adjust 4034 warning
would counsel JRCPP to emit only a "warning" when the diagnostic
inducing construct was identified. Moreover, since this diagnostic
is only a "warning" now, preprocessed output would be provided
(assuming no other errors were encountered).
Note that this pragma has priority over the alternate form of
diagnostic level adjustment, that controls an entire class of
diagnostics. For example, recall that the diagnostic message 4034 has
a default level of "error". Assume message 4034 is adjusted via the
pragma:
#pragma diagnostic_adjust 4034 silent
at the same time as the coarse adjustments:
#pragma diagnostic_adjust error fatal
were made. The fine grain diagnostic adjustment for 4034 would have
priority over the coarse adjustment (which makes all other default
"error" diagnostics into "fatal" level diagnostics). Hence diagnostic
4034 will receive an actual severity level of "silent".
This pragma is a fundamental part of the customization process for
JRCPP. Aside from the obvious concept of "silencing" a bothersome
message that dominates the diagnostic listings, several other
activities may be performed. The following lists common uses for
this pragma:
1) As mentioned above, a specific diagnostic that dominates the
diagnostic listing for a given source file may be TOTALLY silenced,
and hence made to never appear in the diagnostic list. A slightly
less drastic action is to change the level to "hint", whereby ONLY
the first occurrence of the offending construct would generate a
diagnostic.
2) If it is desirable to prevent header files or later source code
from further modifying the severity level of diagnostics, this pragma
can be used to "lock out any use of itself". In order to prevent any
further use of diagnostic_adjust, diagnostic 5007 ("diagnostic
display may be diminished") can be changed to "fatal". Since
diagnostic 5007 is provided BEFORE each change diagnostic_adjust
activity, any attempt at further modification of severity levels will
trigger this now "fatal" diagnostic, and terminate JRCPP.
3) If a single diagnostic has default severity level of "error", but
the user considers its presence acceptable, then the user can
downgrade the severity level and JRCPP will then produce preprocessed
output. Note that it is common to downgrade a specific message of
this sort to a "warning" so that the user will still be made aware of
the non-portable construct.
4) If a specific diagnostic has a default severity level of "silent",
but the user WANTS to see the information associated with that
diagnostic, then the severity level may be changed to "warning".
This is commonly done to follow some of the details of preprocessing
that are only illuminated via silent diagnostics (such as showing
what directories were searched and in what order, during the
processing of a #include directive). See the DIAGNOSTIC MESSAGE
REFERENCE MANUAL for complete descriptions of the diagnostics and
their explanation. The reference manual contains a separate list of
all of JRCPP's "silent" default diagnostics.
----------------------------------------------
#pragma diagnostic_adjust (error | warning | hint | silent)
(fatal | error | warning | hint | silent)
This pragma is used to manipulate a whole class of diagnostics to a
new severity level. Note that the first level indicates the default
severity level delineating a group of diagnostics, and the second
specifies the new level. Note that the DIAGNOSTIC MESSAGE REFERENCE
MANUAL contains a complete list of diagnostics, sorted by severity
levels. The meaning of the severity levels are summarized in that
manual as:
Fatal ==> stop immediately
Error ==> stop after complete error check of source
Warning==> continue, but notify user
Hint ==> continue, but notify the user the first time only
Silent ==> continue, and don't notify user
For example, if a user expects to receive absolutely no warnings,
then the following would enforce that fact:
#pragma diagnostic_adjust warning error
With this directive in place, any warning level diagnostics (not
adjusted by the aforementioned fine grain adjustment) would induce an
"error" in the diagnostic listing, and hence no preprocessed output
file would be produced.
As another example, a user with an interactive edit/compile cycle
might wish to stop the preprocessing at the first error that was
encountered. To accomplish this, the user would establish the
directive:
#pragma diagnostic_adjust error fatal
With this adjustment in place, any diagnostic that occurs with a
default level of "error" (and is not modified by a fine grain
adjustment) will be treated like a fatal error, and the preprocessing
will abort immediately after rendering the diagnostic message.
As a last example of the use of this pragma, some users prefer not to
get any warnings, and only desire a list actual errors. Such users
can direct JRCPP to support this philosophy via:
#pragma diagnostic_adjust warning silent
#pragma diagnostic_adjust hint silent
Notice that the above set of pragmas will direct JRCPP to produce no
messages when only a "warning" or "hint" level construct was
identified. Be advised that the first use of this pragma may trigger
a "hint" that that some diagnostic message may be obscured, and there
is no way to silence this message (which appears BEFORE the pragma
takes effect).
If a user is "just curious", then all the "silent" diagnostics can be
exposed via the directive:
#pragma diagnostic_adjust silent warning
and the resulting diagnostic listings will tend to be fairly
voluminous.
----------------------------------------------
#pragma display_progress [on|off]
This pragma causes the current line and file number that is being
scanned (lexically analysed) to be displayed on stderr. Note that
use is made of ANSI Terminal escape sequences to clear the remainder
of the line. If an ANSI Display driver is not installed, extraneous
characters may appear at the end of each line.
This feature is most useful for watching the progress of the
preprocessor, (it is nice to know something is being processed, and
that the system has not crashed).
----------------------------------------------
#pragma include_search [current_directory]
[only_eldest_ancestor|only_youngest_ancestor|all_ancestors]
The above pragma can be used to customize the search algorithm used
to find include files. A detailed discussion of the search strategy
is provided in the LANGUAGE REFERENCE manual. This pragma allows the
user to include or exclude searching in the current directory, as
well as restricting or eliminating searches in ancestral directories
(i.e.: directories that outer nested include-files were found in).
For example, if it is desirable that the search strategy have NO
dependence on where source files are located, and only make use of
the current directory and the directories listed on the
application/system include path, the the following pragma may be used:
#pragma include_search current_directory
In contrast, if the current directory should be disregarded, and only
the directory of the file that contains that #include directive in
question should be considered, then the following could be entered:
#pragma include_search youngest_ancestor_only
Alternatively, if the current directory, and/or the directory
associated with the original source file (the one listed on the
command line) should be used, then the following can be entered:
#pragma include_search eldest_ancestor_only current_directory
Note that at start up of the preprocessor, the default setting of:
#pragma include_search all_ancestors current_directory
is active. In contrast, the directive:
#pragma include_search
prevents the use of any directories that are not on the
application/system include paths. It also renders useless any
relative path entries in either of those include paths.
This pragma takes effect immediately, and remains in effect until
until another such directive is encountered. This pragma is very
useful in porting application from other platforms, wherein different
standards may exist. Usefulness of this pragma is generally limited
to projects that have source and header files spread across many
directories. See the LANGUAGE REFERENCE manual for more examples, as
well as comments on several other compiler standards in this area.
If a user is still confused about the details of the search
algorithm, there are several "silent" diagnostics that are triggered
by each step in the search process. Consult the DIAGNOSTIC MESSAGE
REFERENCE MANUAL listing of diagnostics by severity level, and
identify the "silent" messages relating to include file searching.
Each significant diagnostic can be made visible by changing its
diagnostic level using the "#pragma diagnostic_adjust NUMBER
warning", where NUMBER is the diagnostic number of interest. A
current list includes:
#pragma diagnostic_adjust 3027 warning
#pragma diagnostic_adjust 3028 warning
#pragma diagnostic_adjust 3029 warning
#pragma diagnostic_adjust 3030 warning
#pragma diagnostic_adjust 3041 warning
#pragma diagnostic_adjust 3042 warning
When the above list of directives have been supplied, it should be
very easy for a user to trace the actions of the underlying search
algorithm by simply examining the diagnostic listing.
----------------------------------------------
#pragma space_between_tokens [on|off]
This pragma concerns the placement of spaces between tokens that
might otherwise "flow together" in the post preprocessed output.
Consider the sample sequence:
#define BASE_TYPE(x) int
long BASE_TYPE(int)name;
If spaces were not added between tokens, then the above code would
expand to:
long intname;
and be "misinterpreted" during compilation. The default performance
of such sequences is to provide at least one space between every pair
of tokens, and hence guarantee that this "problem" cannot surface.
The default performance by JRCPP (and the performance associated with
turning this option "on") would be a preprocessed output of:
long int name ;
Since the preprocessed output is produced all at once at the end of
the entire preprocessing pass, it is not generally significant to
turn this feature on and off at different points in the source text.
It does however have an impact on the "#pragma
describe_macro_expansions", and may be useful for clarity and/or
brevity in such listings.
This option is most useful when a user actually WANTS such adjacent
tokens to "flow together". This performance is similar to what is
provided in several classical C compilers, and hence can be selected
for conformity. Note that space found in the source code is NOT
removed when this option is set to "off". Spaces are however added
regularly when this option is set to "on" (which is also the default
for this pragma).
Note that setting this option to "off" does not quite provided all
the conformance that might be desired with some classical (re:
non-ANSI) preprocessors. Specifically, even with this option set to
"off", tokens will NOT flow together during the preprocessor scan
(and hence would not be recognized as a macro name for example), but
they might flow together during output.
----------------------------------------------
#pragma undefine_macros [ANSI] [STDC] [platform]
[command_line] [user]
This pragma provides a mechanism to quickly and easily undefine a
large group of macros, without having to name them directly. In
addition, it provides a mechanism for undefining the ANSI standard
macros (which are protected from #define and #undef activity). Note
that the use of this pragma provides strictly NON-ANSI performance,
but may be very useful when porting non-ANSI code.
Each of the arguments specifies a group of macros. The "ANSI"
argument indicates that the macros __DATE__, __TIME__, __LINE__, and
__FILE__ should be undefined. The "STDC" argument means that
__STDC__ (or __cplusplus if we have enabled C++ mode) should be
undefined. The "platform" argument indicates that all platform
dependent macros (currently _JRCPP and MSDOS) be undefined. The
"command_line" argument directs the undefining of all macros given
definition via the "-D" command line option. Finally, the "user"
argument forced the removal of definitions of all macros that have
been defined via #define directives from with the source files.
Note that the "#pragma dump_after_output macros" pragma groups these
macros under their related headings. This dumping pragma should be
used if there is any question about what the target of the bulk
undefine pragma is. Moreover, by examining the dumps after trying
several distinct bulk undefined activities (re: #pragma
undefine_macros ....) it is trivial for a user to identify the exact
results of each bulk undefine.
USERS MANUAL- USER INTERFACE- Interactive interface (bug report
support)
The interactive interface to JRCPP is only intended as a support
feature when there is a problem (possible bug) within JRCPP. With
this thought in mind, this section will start by discussing the
procedure that should be followed prior to making use of the
interactive interface.
This interface was placed in JRCPP to facilitate several classes of
problem (bug) reports. The interface is activated by pressing
<cntrl><break> while JRCPP is running. If the version of JRCPP that
is executing is not tracing function calls (JRCPP does not trace, but
JRCPPSAF and JRCPPTIM do perform tracing) then it may be necessary to
press <cntrl><break> a second time in order to interrupt the
preprocessing. In any case, once the interrupt has been
acknowledged, the user will be provided with a simple menu of
options. These options are rather self explanatory, may prove useful
in diagnosing a problem in JRCPP.
The following are list of items that should be undertaken in order to
gather data for a bug report:
1) If you suspect that you are exercising a bug in JRCPP, try running
JRCPPSAF with the same input. If indeed you have provided input that
reveals a bug in JRCPP, there is a tremendous probability that
JRCPPSAF will diagnose the problem, and provide a listing of
information to send to the author of JRCPP. If JRCPPSAF is able to
diagnose the problem (it has a tremendous amount of internal error
checking and redundancy) then you will get a message indicating that
an "ASSERT FAILURE" has occurred. The output that is displayed on
the screen should be redirected to a file, and this information
should be sent in as part of (if not the entire) bug report. Please
submit such listings (which do NOT usually need to include your code)
to the author of JRCPP, and a fix will be provided.
Note that if ever JRCPPSAF produces an "ASSERT FAILURE" message, then
you have indeed found a bug in JRCPP. All the output provided by
this assertion should be submitted as part of the problem report.
There is a chance that the error was in the assertion, and not in the
actual code, but certainly there is an error.
2) If JRCPPSAF exhibits different performance from JRCPP (and in fact
JRCPPSAF works!), then you have a very interesting bug. Typically
such bugs have been caused by the development environment (read:
compiler) used to create JRCPP. These bugs tend to arise when
"overly optimistic", if not just plain "buggy", optimizers seek to
trade speed for correctness. Fortunately, the work around is to use
JRCPPSAF (which runs slower, but at least correctly). Please report
this bug, and an attempt will be made to provided a JRCPP that does
not exhibit erroneous performance. Unfortunately, a complete fix for
this sort of bug does require some source text that demonstrates that
JRCPP and JRCPPSAF behave differently. If you are unable to provided
this, at least the work around mentioned above will support you until
a new release (which hopefully will fix the problem) will arrive.
3) If both JRCPP and JRCPPSAF provide the same performance, then it
should be assumed that you have an "algorithmic" bug. If the problem
involves a point for which no subjective interpretation is involved
(such as: "the machine hangs"), then proceed to step 4. If the
problem is subjective, then please document a small example that
shows that JRCPP acts in opposition to the ANSI Standard. To submit
a bug report does not require that you quote chapter and verse from
the Standard, but you must document your complaint and submit it. A
response will either be a bug fix, a work around, or an argument
explaining why the JRCPP author does not believe there is a bug at
all.
To assist in gathering evidence to support your position you should
consider using the #pragma directives that report the activities of
the preprocessor. Specifically, the "#pragma describe_macro_expansion
on" can be useful when there is a disagreement about how a small area
of text is being macro expanded (note that this pragma can be turned
on immediately in front of the questionable area, and turned off
immediately after the area. Turning it on and then off around a
small area will GREATLY reduce the amount of diagnostic information
that is produced.
If the question involves the #include directive, and where/how it is
finding files, then the "silent" diagnostics that trace this activity
should be changed to "warnings". With this change, you should get a
very precise list of what JRCPP is doing as it searches for a file.
4) If you have reached this step, then both JRCPP and JRCPPSAF have
caused the same erroneous performance. The performance is so severe
that you can not provide simple documentation (as was suggested in
step 3), and you really wish you had something more like a symbolic
debugger to help you identify the problem. As a sanity check,
consider the following questions:
a) Are you running on an 8088 based machine? If you are,
are you using a special version that is compiled
for an 80286 instruction set by accident?
b) Are you using an MSDOS version 3.0 or later? Versions
2.0 and higher MIGHT work, but there has
been no formal testing.
c) Do you have at least 300K of free memory? This amount
of memory would not be enough to run much, but at least
you would get a diagnostic informing you of the problem.
d) Are you running any TSR (Terminate and Stay Resident)
programs in the background that **might** in some
way effect the running of JRCPP?
e) Do any of your other programs run?
f) etc.
Since both JRCPP and JRCPPSAF have exhibited the same problem, all
further examination should be performed using JRCPPSAF. The JRCPPSAF
code supports many aspects of introspection (re: identifying what
function is active) much better than JRCPP.
If you cannot get JRCPPSAF to correctly process even the simplest of
files, then there is some problem that goes well beyond what
"debugging" can do. Assuming you have answered the list of sanity
check questions given above, you may either contact JRCPP to obtain
support or a refund for your registration fee. The paragraphs that
follow discuss the scenario where JRCPPSAF works at least some of the
time (i.e., on some simple test programs).
The first line of defense for a hang (possibly an infinite loop in
JRCPP) is to add "#pragma display_progress" to the source code that
is causing the difficulty. Often the user can see with this option
that progress is actually being made. Note that a user can easily
cause an infinite loop by having a file include itself, but this
would be very visible once the user has activated the above pragma.
Assuming that the progress does stop at some point (the display stops
changing), then there is some more reason to believe that JRCPP is
acting incorrectly. Note that the line numbers may stop changing
momentarily as JRCPP expands a large block of lines that preceded the
scan point.
Assuming you are having a problem like "the machine hangs", the first
question is: what is being processed when the hang occurs? Hopefully
you will have the answer to this question based on turning on the
#pragma display_progress. Note that it is possible to provide a set
of macros that cause exponentially much time (read: a LONG...TIME) to
be needed to complete their expansion. One way to monitor this
activity is to activate "#pragma describe_macro_expansion". The
information provided by this option may be very massive, but it will
show progress at a granularity that cannot be seen simply by
observing the line number (re: display_progress).
Assuming you have seen the display_progress stop, and you believe
that an infinite loop is present, you should attempt the following
items. First you should turn "#pragma describe_macro_expansion" on
near the point at which JRCPP seems to hang. Note that if you place
this call too late in the source, then you will NOT get ANY extra
output. When it is placed prior to the offending code, then at least
some output will be produced. If output from both pragmas stop being
produced (and there is no use of the "off" options of these pragmas),
then you have indeed found an infinite loop in JRCPP.
Assuming you have isolated an infinite loop by the method given
above, the following steps can be used to obtain information for a
bug report. The goal here is to isolate the functions within JRCPP
that are were called to instigate this infinite loop. To start this
process, press <cntrl><break>. Pressing this once should cause a
prompt to appear. If you press this once, and the prompt does not
appear within a second or so, then there is probably an infinite loop
in some single function, but pressing <cntrl><break> a second time
should get the prompt. If you still don't get the prompt, then your
system has probably crashed beyond hope, and you will have to contact
customer service for support, or at least run the same source code
through JRCPPSAF under OS2 (which theoretically is more crash
resistant that DOS).
Assuming now that you have gained control of JRCPPSAF via
<cntrl><break>, select first the option that displays the ancestry of
include files. A user should confirm that the ancestry is as
expected (e.g.: not a list demonstrating an error in the user's code
by way of unlimited recursive inclusion). Next the user should
select the option to "output execution profile to stdout". This will
provide a list of the functions that are currently active, as well as
a list of all the functions that were called up to this point (the
user should be collecting all the output in a file for a bug report).
If possible, the option to "continue running main program" should
next be entered (if you had to press <cntrl><break> twice, then this
option will not be provided). If you were able to "continue", you
should again press <cntrl><break>, and obtain another listing of the
execution profile (this will very concisely verify that no progress
has been made). Finally, you should select the option to "terminate,
and return to operating system". The output gathered during this
brief encounter with the interactive interface should be supplied to
the authors of JRCPP as part of a bug report. It may be possible to
diagnose the bug without seeing the source code that induced it, but
it is commonly helpful for this sort of bug to see the problematic
source. Please send as much information as possible (in machine
readable form) in as part of your bug report.
APPENDIX A PREDEFINED MACRO NAMES
Users should note that many compilers surreptitiously define several
preprocessor macro names, and then rely on these definitions to cause
the related header files to act correctly. When a user is trying to
switch over to using JRCPP from an existing systems C preprocessor,
the user should first attempt to locate a list of exactly which macro
names need to be defined. Experience has shown that the
documentation provided by many vendors is often incomplete in this
area. In order to overcome such a lack of documentation, a user
should attempt to preprocess with the system supplied preprocessor,
and then compare the postpreprocessed text to what is produced by
JRCPP. Typically this comparisons identifies places in the header
files where such dependencies exist, and the appropriate definitions
can be added the command line for JRCPP. As a second approach, the
system header files can be searched for text (via utilities such as
"grep", or "ts") for the words "ifdef", "ifndef", and "defined".
These searches tend to uncover most macro dependencies in system
header files.
When JRCPP is processing a file, aside from the ANSI specified
internal macro definitions, definitions are given to "MSDOS" and
"_JRCPP". Is is rather straightforward (within JRCPP) to verify
exactly what macros are defined, as the "#pragma after_output_dump
macros" supplies exactly such a listing. During a transition from
some other preprocessor to JRCPP, it may prove desirable (in order to
cause the system header files to function correctly) to have some
specific macro names defined. The user has the option of simply
defining such identifiers on the command line (via the "-D" option),
or defining them within actual source files. The following lines of
code demonstrate how (for example) "foo" and "goo" can be
economically defined by adding just a few lines to a centralized
header file:
#ifdef JRCPP
#define foo 1
#define goo 1
#endif
The following are sections provide lists of macros that have appeared
on several platforms. In each case the actual macro name is enclosed
in double quotes, in order to clearly isolate the name that is being
discussed. For example, the fact that "MSDOS" is often defined on a
certain platform is equivalent to indicating that there is
effectively a definition of the form:
#define MSDOS 1
As individual vendors and/or users provided information in this area,
this document will grow to accommodate such inclusions.
MICROSOFT C COMPATIBILITY
When compiling with Microsoft C products for DOS and OS2, the
following are some common macro definitions:
"MSDOS" is always defined (by default this is also provided by JRCPP
when running on a DOS platform).
Depending on what memory model is used during compilation (Small,
Medium, Compact, Large, or Huge), one of the following will typically
be defined:
"M_I86SM" "M_I86MM" "M_I86CM" "M_I86LM" "M_I86HM"
One or more of the following may be defined based on what the
restrictions are for code generation (i.e., 8088 compatibility vs.
use of full 80286 instruction set):
"M_I86", "M_I8086", "M_I286"
"NO_EXT_KEYS" is defined when the Microsoft extensions are disabled.
Depending on the default for a plain "char" (it may be "unsigned
char" or "signed char"), the following may be defined:
"_CHAR_UNSIGNED"
SUN WORKSTATION COMPATIBILITY (RUNNING DEFAULT UNIX COMPILER)
When the compilation is for Sun computer, and the compiler used is
the default UNIX system compiler, the following may be defined:
"unix", "m68k", "sun", "mc68000"
On a Sun 2-nnn system, the following may be defined to indicate the
underlying processor:
"M68010", "mc68010"
On a Sun 3-nnn system, the following may be defined to specify the
underlying processor:
"M68020" and "mc68020"
GENERIC MACRO DEFINITIONS
On most systems, one of the following operating system specifiers is
predefined:
"ibm", "gcos", "os", "tss", "unix", "MSDOS"
One or more of the following hardware specifier macros may also be
defined:
"interdata",
"pdp11", "vax",
"u370",
"u3b", "u3b2", "u3b5", "u3b15", "u3b20d",
"m68k", "mc68000", "mc68010", "mc68020", "M68010", "M68020",
"ns32000",
"iAPX286", "i386", "M_I86", "M_I8086", "M_I286",
"RES",
"RT",
"sparc", "sun"
"Lint like" error checking is enhanced on some systems when the
following is defined:
"lint"
APPENDIX B JRCPP STATIC LIMITS
The following are the current static limits for JRCPP. Future
versions of JRCPP will use dynamic reallocation, and hence these
limits will vanish (subject to available memory in the system).
1) The level of nesting parenthesis within #if/elif expression
(approximately 50 levels). This limitation is based on a
restriction provided by the parsing engine implemented via YACC.
This restriction will vanish in future versions when dynamic
reallocation is installed into this engine.
2) The nesting of #if...#endif directive groups. (approximately 35
levels) This limitation is based on a restriction provided by the
parsing engine implementation via YACC. This restriction will
vanish in future versions when dynamic reallocation is installed
into this engine.
3) The length of a single token (e.g.: a long identifier, a long
string literal, a long section of a comment on a single line).
Note that a comment is broken into pieces as it crosses newline
boundaries (non-escaped newline boundaries), and hence the length
of each "piece" must stay below this limit, whereas the entire
comment may be MUCH longer. This limitation is based on a
restriction provided by the lexical analyser FLEX, and should
vanish in future versions as dynamic reallocation is supported in
the lexing engine.
4) The level of nested argument expansion in macros is bounded by the
size of the program stack. This should VERY rarely be a problem.
This will only appear of a function like macro has an argument
that must be expanded, and it in turn contains a function like
macro that has an argument that must be expanded, .... For
example, the macro definition: #define F(x) x with an invocation
construct of the form: F( F( F( F( F( F( F( F( F( F( F( F( F(...(
F( F(2)))...))))))))))))))) may exceed the stack limitation. The
stack size in a non-bound version of JRCPP (MSDOS only) can be
adjusted upwards to increase this limit on stack size. The OS/2
only version is compiled with the largest possible stack size, so
it can not be adjusted, but it is rarely a problem. The bound
version is a slight compromise, in that it cannot be adjust, and
it is not excessively large.
5) The levels of nested include files when one of the source files is
actually stdin. This limitation is only notable when JRCPP is
using stdin to provided the original source file. The mechanism
used to generally avoid ANY limit on nested include files requires
the ability to locate the current position within a file,
temporarily close the file, and later reopen the file at the
correct position. Unfortunately, stdin does not fit into this
general scheme, and the limit on the number of file handles
provided by the system will restrict the level of nested
inclusion. On a typical MSDOS/OS2 system, this limit should
typically be about 17 (a total of 20, minus one for each of stdin
stdout, and stderr). IF registered users complain about this
slight limitation, then it will be removed. Note that there is NO
LIMIT on the depth of nested include files when stdin is not being
used.