previous next top contents index framed top this page unframed
When subcommand mode is entered, the subcommand prompt “>” is displayed. Any number of subcommands may be entered at this point, one per line. Subcommand mode is exited by typing <eol> to the > prompt.
Multiline subcommands may be entered by terminating each line except the last with a backslash (\). The backspace and following end-of-line are discarded, and all the lines entered are concatenated to form the subcommand.
File names in subcommands cannot contain space characters.
Valid subcommands are listed in Table 4–1. In this table, commands that do not have “(nonsticky)” in their description remain in effect for all subsequently compiled MODULEs until either another subcommand turns it off or the compiler exits (commands that perform a single, one-time-only action, such as ABORT and REDEFINE, are also nonsticky). Nonsticky subcommands apply only to the next MODULE compiled.
Any sticky subcommand may be made temporarily nonsticky by immediately following the subcommand (before any arguments) with an asterisk; e.g., NOGENCODE * indicates that object MODULE generation is to be omitted only for the next compilation.
XIDAK reserves the right to create compiler subcommands for internal use only. Such subcommands are not documented here and are subject to change and/or removal without notice. You should not use undocumented subcommands; their effects are undefined.
Compiler subcommands may change from release to release of MAINSAIL.
Mixed case is used in the subcommands to show the minimum permitted abbreviation of compiler subcommands. The uppercase portion of each compiler subcommand in mixed case is a sufficient abbreviation for that subcommand (as if the upperCase bit were given to cmdMatch).
Table 4–1. MAINSAIL Compiler Subcommands
| Subcommand | Description |
|---|---|
| ABORT | Abort this compilation |
| ACheck | Set default to emit code to catch arithmetic overflow, etc. |
| ACHECKALL | ACHECK unconditionally |
| ALIST | Allow disassembly |
| BROWSE | Allow code browsing |
| Check | Set default to emit code to catch subscript errors, etc. |
| CHECKALL | CHECK unconditionally |
| CMDLINE s | Add s to the end of the cmdLine list (nonsticky) |
| DATETIMECHECK | Check date/time match when used as supporting intmod |
| DEBUG | Make this MODULE debuggable, and turn on INCREMENTAL |
| FLDXREF {f} | Write field cross reference {to file f (nonsticky)} |
| FLI s | Generate code for foreign interface s |
| GENcode | Generate code (i.e., produce objmod) |
| GENINLINES | Generate bodies for inline PROCEDUREs |
| INCREMENTAL | Allow output to be incrementally recompiled |
| ININTLIB f | Input intmod is in library f |
| INOBJFILE f | Input objmod is in file f (nonsticky) |
| INOBJLIB f | Input objmod is in library f |
| ITFXREF {f} | Write interface cross reference {to file f (nonsticky)} |
| LOG | Show log info |
| MODTIME | Measure time spent in this MODULE |
| MONITOR | Turn on PER{MOD,PROC,STMT} and {MOD,PROC}TIME |
| OPtimize | Set default to optimize all PROCEDUREs |
| OPtimize pi | Optimize PROCEDUREs pi = p1 p2 ... pn (nonsticky) |
| OPTIMIZEALL | Optimize all PROCEDUREs |
| OUTINTFILE f | Output intmod to file f (nonsticky) |
| OUTINTLIB f | Output intmod to library file f |
| OUTOBJFILE f | Output objmod to file f (nonsticky) |
| OUTOBJLIB f | Output objmod to library file f |
| PERMOD | Count total statements executed in the MODULE |
| PERPROC | Count total statements executed in each PROCEDURE |
| PERSTMT | Count times each statement is executed |
| PLIST {f} | Write parse tree listing {to file f (nonsticky if f specified)} |
| PROCCALLS {f} | Write procedure calls {to file f (nonsticky)} |
| PROCS | Show names of PROCEDUREs as they are parsed and generated |
| PROCTIME | Measure time spent in each PROCEDURE |
| RECOMPILE pi | Recompile PROCEDUREs pi = p1 p2 ... pn (nonsticky) |
| REDEFINE x y | Do $GLOBALREDEFINE x = [y]; |
| RESPONSE | Get user response to error messages |
| RPC {C} | generate code for remote PROCEDURE call {in C} |
| SAVEON {f} | Create intmod containing all compiler info {save on file f} |
| SLIST {f} | Write source listing {to file f (nonsticky)} |
| STRICTCLASSES | Enforce strict class compatibility |
| SUBCOMMAND s | Execute MAINEX subcommand s |
| TARGET s | Generate for target system s |
| UCHECK | Set default to catch uninitialized locals |
| UNBOUND | Nonbound-invocation MODULE |
| # s | A comment (s is ignored) |
| NOACheck | Turn off ACHECK |
| NOACHECKALL | Turn off ACHECKALL |
| NOALIST | Turn off ALIST |
| NOBROWSE | Turn off BROWSE |
| NOCheck | Turn off CHECK |
| NOCHECKALL | Turn off CHECKALL |
| NODATETIMECHECK | Turn off DATETIMECHECK |
| NODEBUG | Turn off DEBUG and INCREMENTAL |
| NOFLDXREF | Turn off FLDXREF |
| NOGENcode | Turn off GENCODE |
| NOGENINLINES | Turn off GENINLINES |
| NOINCREMENTAL | Turn off INCREMENTAL |
| NOININTLIB | Turn off ININTLIB |
| NOINOBJLIB | Turn off INOBJLIB |
| NOITFXREF | Turn off ITFXREF |
| NOLOG | Turn off LOG |
| NOMONITOR | Turn off PER{MOD,PROC,STMT} and {MOD,PROC}TIME |
| NOOPtimize | Turn off OPTIMIZE |
| NOOPtimize pi | Do not optimize PROCEDURE(s) pi = p1 ... pn |
| NOOPTIMIZEALL | Turn off NOOPTIMIZEALL |
| NOOUTINTLIB | Turn off OUTINTLIB |
| NOOUTOBJLIB | Turn off OUTOBJLIB |
| NOPLIST | Turn off PLIST |
| NOPROCCALLS | Turn off PROCCALLS |
| NOPROCS | Turn off PROCS |
| NOREDEFINE | Remove all global definitions |
| NOREDEFINE xi | Remove global definition(s) of xi = x1 ... xn |
| NORESPONSE | Turn off RESPONSE |
| NORPC | Turn off RPC |
| NOSAVEON | Turn off SAVEON |
| NOSLIST | Turn off SLIST |
| NOSTRICTCLASSES | Turn off STRICTCLASSES |
| NOUCHECK | Turn off UCHECK |
| NOUNBOUND | Turn off UNBOUND |
| Synonyms for compatibility with older versions of the compiler: | |
| LIBRARY f | Same as GENCODE, OUTOBJLIB f |
| OUTPUT {f} | Same as GENCODE {, OUTOBJFILE f} |
| NOLIBRARY | Same as NOOUTOBJLIB |
| NOOUTPUT | Same as NOGENCODE |
All of the compiler subcommands except the following may be invoked from MAINSAIL source text with the $DIRECTIVE directive, as described in Chapter 16 of the MAINSAIL Language Manual:
FLDXREF FLI ININTLIB ITFXREF PLIST PROCCALLS RECOMPILE RPC SLIST TARGET
NOFLDXREF NOININTLIB NOITFXREF NOPLIST NOPROCCALLS NOSLIST
The $DIRECTIVE directive is never sticky, i.e., never applies to more than one MODULE, even in the same compiler session.
4.1. Subcommands in Parameters File
The compiler can read default
subcommands from the standard
parameter file (e.g., in Version
16.20, v1620.prm).
The subcommands go in the parameter group, $COMPIL. For example, to set the default compiler subcommands to be DEBUG, ACHECK, and UCHECK (all of which are otherwise turned off by default), specify:
$GROUP $COMPIL
DEBUG
ACHECK
UCHECK
The parameters file mechanism is described in detail in Chapter 28 of the MAINSAIL Language Manual.
ABORT aborts the current
compilation while in subcommand mode.
This is useful if you have given
subcommands that you realize to be
incorrect for the current compilation.
It is also useful as a $DIRECTIVE
directive if a condition occurs at
compiletime that requires that a
compilation be aborted (a similar
effect can be achieved by using the
MESSAGE directive with the
error option; see Section 16.1 of the MAINSAIL Language Manual.
4.3. ACHECK/NOACHECK, ACHECKALL/NOACHECKALL
The ACHECK option enables the generation of extra code to detect arithmetic overflow in (LONG) INTEGER and (LONG) REAL operations. On some processors, no extra code is required to detect certain kinds of arithmetic overflow; on such machines, an overflow exception may be generated whether or not the ACHECK subcommand was in effect when the overflowing code was compiled. Where extra instructions are required to detect overflow, ACHECKed code may be significantly larger and slower.
NOACHECK turns the ACHECK option off. It suppresses the generation of extra instructions; it does not necessarily mean that arithmetic exceptions are not caught.
ACHECKALL and NOACHECKALL
override ACHECK and NOACHECK
directives in the source text of a
MODULE. Arithmetic checking, and
the subcommands and directives used to
control it, are described in more
detail in Chapter 16 of the MAINSAIL Language Manual.
4.4. ALIST/NOALIST
ALIST causes the compiler to put information into the intmod required if the disassembler is to be used to generate an intermixed source/code listing. The objmod is not affected.
NOALIST turns off ALIST.
4.5. BROWSE/NOBROWSE
The BROWSE subcommand causes the compiler to generate an intmod that contains a subset of the information generated by the DEBUG subcommand. The information is sufficient to allow the debugger to examine symbol declarations, but not enough to allow to it to step through the generated code.
Intmods produced with the BROWSE
subcommand are sufficient for the
debugger command !D (show where an
identifier was declared); see
Section 4.8 of the MAINDEBUG User's Guide for details.
4.6. CHECK/NOCHECK, CHECKALL/NOCHECKALL
CHECK causes the compiler to generate code that checks for runtime errors (the list of errors checked for is the same as the list governed by the MAINSAIL language CHECK directive; consult Section 16.3 of the MAINSAIL Language Manual for details). This option should be used when debugging and testing programs. Once a program is debugged, it can be compiled NOCHECK to reduce code size and increase execution speed.
NOCHECK turns off CHECK.
CHECKALL and NOCHECKALL override CHECK and NOCHECK directives in the source text of a MODULE. The rules for checking, and the subcommands and directives used to control it, are described in more detail in Section 16.3 of the MAINSAIL Language Manual.
CMDLINE s concatenates the STRING:
s & eol
to the end of the current cmdLine STRING.
Whenever the compiler
needs to read a line from file
cmdFile, it first checks whether
cmdLine is non-Zero, and if so, it
reads the line from cmdLine rather
than cmdFile. For example, interactive
defines may use cmdLine. Thus,
responses to interactive defines can
be specified in CMDLINE
subcommands. This is sometimes useful
in compilation scripts; e.g., if a
compilation may or may not do a single
interactive define (based on
compiletime evaluation), the response
can be put in a CMDLINE subcommand
so that the compilation will complete
correctly even if the interactive
define does not occur.
4.8. DATETIMECHECK/NODATETIMECHECK
The DATETIMECHECK subcommand controls whether MAINSAIL checks the date and time of compilation recorded in a supporting intmod when it opens the intmod.
DATETIMECHECK is mainly intended
to be used as a compiler directive in
a MODULE's source code, rather
than interactively as a compiler
subcommand. It is described in more
detail in Section 16.4.2 of the MAINSAIL Language Manual.
4.9. DEBUG/NODEBUG
DEBUG causes the compiler to put information into the intmod that is used by the MAINSAIL debugger. A MODULE that is to take part in debugging must be compiled with this option; see Section 2.1 of the MAINDEBUG User's Guide for more information. DEBUG slightly increases the size and execution time of the objmod.
PROCEDUREs declared INLINE (but not $ALWAYSINLINE) are not expanded inline if DEBUG is in effect. PROCEDUREs declared $ALWAYSINLINE are expanded inline even if DEBUG is in effect. Thus, a MODULE that uses INLINE PROCEDUREs may be larger and slower for this reason also.
NODEBUG turns off DEBUG.
As a side effect, DEBUG sets the INCREMENTAL and GENINLINES options, and NODEBUG clears them. DEBUG * has no effect on the current sticky subcommand setting values used in subsequent compilations, and may therefore be more suitable for compilation scripts in which both debuggable and non-debuggable MODULEs are compiled.
4.10. FLDXREF/FLDXREF f/NOFLDXREF
The FLDXREF and FLDXREF f options are similar to the corresponding ITFXREF options, except that they cause field references of the form p.f, where p is a POINTER or ADDRESS variable, to be listed (ITFXREF is for m.f only where m is a MODULE name). CLASS names enclosed in angle brackets are listed in place of the MODULE names for the ITFXREF option. Both ITFXREF and FLDXREF can be specified; the output goes to the same listing file if no output file is specified for either (.xrf file), or if the same output file is specified for both.
The interface cross-reference merger, XRFMRG, is used in conjunction with the ITFXREF and FLDXREF compiler subcommands. It is described in Chapter 6.
Figure 4–2. FLDXREF Sample Output
| Field Cross-Reference for MODULE TOPCMP <$DEVICECLS>.$DEVNEWBUF (m:syslib) SFWRITE 13.13 <$MICONF>.$CONFBITS (m:tops20) STTYWRITE 4.8 <FILE>.$DEVICE (m:syslib) SFWRITE 13.11 13.13 .$REMSIZE (m:syslib) SFWRITE 13.13 13.16* .$STATUSBITS (m:syslib) SFWRITE 13.8 13.16* <SYMBOL>.LINK (miscPF) COMPILE 5.96 5.100 <TEXTFILE>.$NEXTTEXT (m:syslib) SFWRITE 13.15* |
The FLI s subcommand specifies the direction and calling conventions of a foreign MODULE interface compilation. The STRING s has the form xy, where x is a character indicating the direction of the FLI compilation and y is a character indicating the foreign language. FLI ? displays a list of valid xy combinations. The supported values for x and y are shown in Table 4–3 (undocumented values are not supported).
Table 4–3. The Format of Arguments to the Compiler FLI Subcommand
| x | Description | y | Description |
|---|---|---|---|
| T | To foreignLanguage | C | the language C |
| F | From foreignLanguage | S | Solaris C |
Thus, TC means “To C (from MAINSAIL)”; FS means “From Solaris C (to MAINSAIL)”.
The C calling convention indicator is used for the C calling convention on most platforms. On operating systems where more than one C calling convention is supported, however, an alternative letter must be used to specify the convention in question.
You must specify the TARGET subcommand in conjunction with the FLI subcommand if the target is different than the host. Not every calling convention is implemented for every target. If a nonexistent or unavailable combination is selected, the compiler issues an error message to the effect that it cannot open the FLI code generator MODULE, the name of which is formed from the target, x, and y. Details on supported FLIs may be found in the relevant sections of the appropriate system-specific MAINSAIL documentation. If you need a complete, up-to-date list of the FLI code generators that have been implemented, please contact XIDAK.
FLI<eol> (i.e., no argument
specified) turns off the FLI
subcommand.
4.12. GENCODE/NOGENCODE
GENCODE specifies that an objmod is to be generated.
NOGENCODE specifies that no objmod
is to be generated. This is useful for
verifying that the syntax of a
MODULE is correct, or for a
MODULE for which just the intmod
is desired.
4.13. GENINLINES/NOGENINLINES
GENINLINES specifies that bodies are to be generated for each INLINE PROCEDURE, though calls to INLINE PROCEDUREs are still expanded inline. This option is useful when debugging to make PROCEDUREs declared $ALWAYSINLINE callable from the debugger.
If some additional PROCEDURE bodies are generated due to this option, the objmod is larger.
DEBUG sets this option, and NODEBUG clears it, so it is rarely useful to use GENINLINES and NOGENINLINES explicitly (though they could be used to force code to be generated for an INLINE PROCEDURE for which a disassembly was to be obtained in order to examine the generated code).
NOGENINLINES turns off
GENINLINES.
4.14. INCREMENTAL/NOINCREMENTAL
INCREMENTAL specifies that the intmod is to contain all the information required to support incremental recompilation. This subcommand must be given if the MODULE is ever to be incrementally recompiled. The objmod is not affected.
DEBUG sets this option, and NODEBUG clears it.
NOINCREMENTAL turns off
INCREMENTAL.
4.15. ININTLIB f/NOININTLIB
ININTLIB f specifies that the input intmod is in the intlib f. This information is used during an incremental recompilation where just the MODULE name, say FOO, is given to the compiler prompt, and FOO resides in the intlib f. As a side effect, the intlib f remains open for further intmod searches.
NOININTLIB turns the ININTLIB
option off, so that the default intmod
search rules are subsequently
followed.
4.16. INOBJFILE f
INOBJFILE f specifies that the object MODULE being recompiled is in the file f. This option is useful only when recompiling, since the compiler must then find the objmod for the MODULE being recompiled. This option need not be given if the objmod is in a file with the default objmod file name, or is in an open objmod library.
There is no corresponding
ININTFILE subcommand, since the
name of the input intmod file can be
specified in response to the compiler
prompt. If the intmod file has the
default name, then the MODULE name
can be given in response to the
compiler prompt, and the compiler
automatically finds the intmod file
(and the objmod file if it also has
the default name or is in an open
objmod library).
4.17. INOBJLIB f/NOINOBJLIB
INOBJLIB f specifies that the input objmod is in the objmod library f. This information is used during an incremental recompilation, since the compiler must locate the objmod for the MODULE being recompiled. As a side effect, the objmod library f remains open for further objmod searches.
NOINOBJLIB turns the INOBJLIB option off, so that the default objmod search rules are subsequently followed.
4.18. ITFXREF/ITFXREF f/NOITFXREF
ITFXREF and ITFXREF f cause the compiler to generate an interface field cross-reference listing that gives the file, name of containing PROCEDURE, page, and line of every occurrence of an interface field referenced (both implicitly and explicitly) by the MODULE being compiled. In addition, an asterisk (*) indicates that a reference alters the (data) field. PROCEDURE and data fields as well as the MODULE's references to its own interface fields are reported. A field f referenced using p.f, where p is a POINTER variable rather than a MODULE name, is not included in the listing. Use the FLDXREF option, described in Section 4.10, to include such references.
If the file name for the cross-reference listing is not specified, the output is written to a file m.xrf, where m is the name of the MODULE being compiled.
Once the ITFXREF option is specified, it remains in effect until either the NOITFXREF option is specified or the compiler is exited. The ITFXREF f option does not remain in effect for subsequently compiled MODULEs.
Figure 4–4 is a sample cross-reference listing. At the left is an alphabetic list of module.field, where module is the name of the referenced MODULE and field is the name of the referenced field. The module part is specified only the first time so that references to the same MODULE stand out as a group.
At the right are the source file, name of the containing PROCEDURE, page and line occurrences of each reference to the corresponding field, and asterisk if the field is altered (e.g., assigned to) by the reference. The source file name is enclosed in parentheses and given before all references in that file. References are listed in the order encountered by the compiler. The name of the containing PROCEDURE is repeated only as often as necessary; i.e., it applies to all following items up to the next time a PROCEDURE name is given. SOURCEFILE directives and implicit sourcefiles due to FORWARD PROCEDUREs can cause more than one source file to appear in the right-hand column.
Figure 4–4. ITFXREF Sample Output
| Interface Cross-Reference for MODULE TOPCMP COMPIL.COMPILEBITS (miscPF) COMPILE 5.13 5.24* 5.25 5.53 5.54 5.60* SUBCOMMAND 41.43 41.47* 41.49* 41.50* 41.51* 41.54* 41.55* 41.56* 41.57* 41.60* 41.61* 41.62* 41.63* .COMPVERSIONBITS (miscPF) COMPILE 5.15 5.16 .SYSVERSIONBITS (miscPF) COMPILE 5.18 5.19 .TARGETSYSTEM (miscPF) COMPILE 5.56 5.57 PASS1.FIRSTPASS (miscPF) COMPILE 5.63 PASS2.SECONDPASS (miscPF) COMPILE 5.75 TOPCMP.COMMANDSTRING (miscPF) CMPREAD 3.8* PROGCOMPILE 35.8* .DISPOSEDSYMLIST (miscPF) COMPILE 5.47* 5.95 .ENCODELIST (miscPF) COMPILE 5.44* 5.99 5.100* 5.100 .ERRFILE (miscPF) COMPILE 5.30 5.30* .ERRS (miscPF) COMPILE 5.31* 5.68 5.76* PROGCOMPILE 35.12 |
LIBRARY f is equivalent to the two options GENCODE and OUTOBJLIB f.
NOLIBRARY is equivalent to
NOOUTOBJLIB.
4.20. LOG/NOLOG
The LOG option causes the compiler to display file names, pages, and PROCEDURE names (for FORWARD PROCEDUREs) during compilation.
NOLOG turns off LOG.
4.21. MODTIME
MODTIME specifies that the objmod be configured so that it can monitor the total (deep and shallow) time spent in the MODULE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored value (see Table 3–2 of the MAINPM User's Guide).
NOMONITOR turns off all monitor
options.
4.22. MONITOR/NOMONITOR
MONITOR is a quick way to specify all the performance monitoring subcommands: PERMOD, PERPROC, PERSTMT, MODTIME, and PROCTIME.
NOMONITOR turns off all monitor
options.
4.23. OPTIMIZE/NOOPTIMIZE,
OPTIMIZE procedurei/NOOPTIMZE
procedurei,
and OPTIMIZEALL/NOOPTIMIZEALL
OPTIMIZE tells the compiler to produce code that executes faster in many situations. The exact optimizations performed are machine-dependent. In some cases, optimized code may be identical to unoptimized code; in other cases, it may run substantially faster.
OPTIMIZE may take an argument list of PROCEDURE names, i.e., OPTIMIZE procedure1 procedure2 ... proceduren. In this form, the specified PROCEDUREs are optimized whether or not the rest of the MODULE is optimized. This form is non-sticky.
NOOPTIMIZE turns off the OPTIMIZE option. NOOPTIMIZE may also take a list of PROCEDUREs that are not to be optimized, whether or not the rest of the MODULE is optimized. If a PROCEDURE is specified in both OPTIMIZE and NOOPTIMIZE subcommands, the last reference takes precedence.
OPTIMIZEALL and NOOPTIMIZEALL
override OPTIMIZE and
NOOPTIMIZE directives in the
source text of a MODULE. The rules
for optimization, and the subcommands
and directives used to control it, are
described in more detail in
Chapter 17 of the MAINSAIL Language Manual.
4.24. OUTINTFILE f
OUTINTFILE f specifies that the
intmod is to be stored as the file f.
The intmod is by default stored in a
file the name of which is derived from
the MODULE name, unless an
OUTINTLIB subcommand is specified,
in which case the intmod is stored in
the specified intmod library.
OUTINTFILE overrides
NOOUTINTLIB for the current
compilation.
4.25. OUTINTLIB f/NOOUTINTLIB
OUTINTLIB f specifies that the intmod is to be stored in the intmod library f. The intlib subsequently remains open.
NOOUTINTLIB turns off OUTINTLIB.
4.26. OUTOBJFILE f
OUTOBJFILE f specifies that the objmod is to be stored as the file f. The objmod is by default stored in a file with a name derived from the MODULE name, unless an OUTOBJLIB subcommand is specified, in which case the objmod is stored in the specified objmod library.
4.26.1. OUTOBJFILE Command Can Specify RPC Output File Names
When the RPC subcommand is
specified, the compiler produces two
output files, the client stub and the
server stub. Since it would not make
sense for both to have the same name,
the compiler treats the OUTOBJFILE
command specially when RPC is in
effect.
When RPC is in effect, the name given to the OUTOBJFILE subcommand is decomposed into its parts. The name of the generated source file for the client stub is obtained by appending cli to the base of the given file name and then recomposing the file name; the name of the generated source file for the server stub is obtained by appending srv to the base and then recomposing the file name. This allows the OUTOBJFILE subcommand to be used, for example, to specify that the generated files be written to a different directory.
For example, if you compile a MODULE FOOBLE in a file fooble.ms, and want to have the output on blarkcli.ms and blarksrv.ms in the directory ../ranmod instead of the default (fooblecli.msl and fooblesrv.msl on the current directory), you would specify:
compile (? for help): fooble.ms<eol>,
> rpc<eol>
> outobjfile ../ranmod/blark.ms<eol>
> <eol>
OUTOBJLIB f specifies that the objmod is to be stored in the objmod library f.
If for any reason the MODULE cannot be added to the specified library, the compiler prompts for an output file name.
The compiler uses the current TARGET subcommand value to determine the format of the target MODULE library.
NOOUTOBJLIB turns off
OUTOBJLIB.
4.28. OUTPUT/OUTPUT f/NOOUTPUT
OUTPUT is the same as GENCODE,
OUTPUT f is the same as
GENCODE followed by OUTOBJFILE
f, and NOOUTPUT is the same as
NOGENCODE.
4.29. PERMOD
PERMOD specifies that the objmod be configured so that it can monitor the total number of statements executed in the MODULE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored value (see Table 3–2 of the MAINPM User's Guide).
NOMONITOR turns off all monitor
options.
4.30. PERPROC
PERPROC specifies that the objmod be configured so that it can monitor the total number of statements executed in each PROCEDURE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).
NOMONITOR turns off all monitor
options.
4.31. PERSTMT
PERSTMT specifies that the objmod be configured so that it can monitor the total number of times each statement is executed. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).
NOMONITOR turns off all monitor
options.
4.32. PLIST/PLIST f/NOPLIST
The PLIST subcommand causes a
parse tree listing to be written to
the specified file (in the PLIST f
form) or to a file formed from the
MODULE name and the extension
pls. The parse tree listing is a
“decompiled” form of each
PROCEDURE's body. This listing may
be useful for files that call
complicated macros or include
complicated conditional compilation;
the PLIST listing lets you see
just how they were processed at
compiletime to produce the
PROCEDURE bodies the compiler
actually compiled.
Some users have requested tools to
help analyze the static PROCEDURE
call structure of a MAINSAIL program.
The MAINSAIL compiler subcommand:
causes the compiler to create a
human-readable text file with name f
that contains, for each PROCEDURE
body parsed during the compilation, a
list of all the PROCEDUREs it
calls directly. If f is omitted, the
created file has the name
moduleName.prc, where
moduleName is the name of the
compiled MODULE.
The PROCCALLS subcommand is sticky if
f is omitted, but can be turned off
using the subcommand:
The output file is generated during
the compiler's first pass so that it
can be obtained even if code is not
generated, e.g., if a syntax error is
detected or if the compiler subcommand
NOGENCODE is in effect.
The output format described here is
subject to change based on user
feedback. Any program that parses this
output should be written so it can be
easily modified.
The intention of PROCCALLS files is to
support a program that reads all of
the PROCCALLS files for a “system”,
builds a data structure that
represents all the calls, then
displays or answers questions about
the static call chains. Such an
analysis program is not currently
provided by XIDAK.
At present, a PROCCALLS file consists
of:
The pages are separated by end-of-page
characters (ASCII form feed).
where m is the name of the compiled
MODULE. More lines may be added to
this page, so skip to end-of-page (or
end-of-file) to process the remainder
of the file.
A CLASS page consists of one or
more header lines, a blank line and
one or more CLASS names:
The first header line has the format
Module m prefix classes, where m
is the name of the compiled
MODULE. Additional header lines
may be added in the future.
c1 is the name of the immediate prefix
CLASS of the MODULE, e.g.,
cls in the example above. If c1
was declared with a prefix CLASS,
then the name of that CLASS is
given on the next line, and so forth,
until a CLASS cn is reached that
was not declared with a prefix
CLASS.
This CLASS information can be used
to determine which PROCEDUREs can
possibly be called from a
PROCEDURE call of the form
p.f, where p is a POINTER of
some CLASS c. As described below,
a p.f call is indicated on a call page
as <c>.f, where c is f's
CLASS. To determine all m.f's that
could be the actual target of such a
call, where m is a MODULE name,
examine all the PROCCALLS files of
interest to find those MODULEs
whose CLASS page indicates that c
is a prefix CLASS of the
MODULE. Note that this approach
can fail if two different interface
CLASSes are declared with the same
name.
Note that a MODULE can have an
interface PROCEDURE, but no prefix
CLASS, as in MODULE m
(PROCEDURE foo). Such a MODULE
cannot legitimately be the target of a
p.foo call where p is a
POINTER, since there is no legal
way to classify p as having m's
interface. The programmer could, in
the current version of MAINSAIL,
declare CLASS c (PROCEDURE foo)
and POINTER(c) p, then use p :=
new(m); p.foo, but this is not
supported and may not work in future
versions of MAINSAIL (MODULE(c) m
should have been used for m's
declaration). The <c>.foo in the
call page described below is not
helpful in detecting a potential call
to such an m.foo.
The first header line has one of the
following formats:
The second header line indicates where
the PROCEDURE body was declared.
It has the format Declared at fn
p.rl (ap), where fn is the file name,
p is the page number, rl is the
relative line number on the page, and
ap is the absolute line number.
A called PROCEDURE has one of the
following forms:
The called PROCEDUREs are listed
one per line in alphabetically
ascending order based on the entire
form just described. A PROCEDURE
call form is listed for a given
PROCEDURE just once even though
the PROCEDURE may have been called
many times. If an interface
PROCEDURE f is called both as
m.f and p.f for a MODULE m
and POINTER p, it is listed
twice, once as m.f and once as
<c>.f as described above. A call
to an {$ALWAYS}INLINE
PROCEDURE is treated just like any
other call; i.e., the fact that the
called PROCEDURE was declared as
{$ALWAYS}INLINE is ignored as far
as the listing file is concerned. If a
PROCEDURE calls itself, its call
list will contain an instance of
itself.
4.33. PROCCALLS/PROCCALLS f/NOPROCCALLS
Temporary feature: subject to change
PROCCALLS {f} write proc calls {to file f (nonsticky)}
NOPROCCALLS turn off PROCCALLS
4.33.1. Header Page
The header page is the first page of
the file. Its first line is:
ProcCalls for m
4.33.2. CLASS Page
The CLASS page is present if the
MODULE is declared with a prefix
CLASS, e.g., MODULE(cls) foo.
The CLASS page can occur as any
page after the header page; it is
output when the MODULE declaration
is encountered or when an intmod that
contains the MODULE's declaration
is made visible (e.g., using
RESTOREFROM). It will often be the
second page since a MODULE
declaration is usually given before
any PROCEDURE bodies.
Module m prefix classes
possible additional header lines
c1
...
cn
4.33.3. Call Page
A call page consists of one or more
header lines, a blank line, and a
possibly empty list of called
PROCEDUREs. An example of a call
page is:
Procedure INITIALPROC
Declared at pass1.msl 8.11 (1318)
$ERRMOD.ERRMSG
$KERMOD.$CLASSDSCRFOR
$KERMOD.$NEWAREA
$KERMOD.NEWRECORD
$KERMOD.SNEWDATASECTION
$SYS$$SEARCHCALLCHAIN
$UTYMOD.$SCANSET
<COMPILCLS>.ALLOCATEKEPTSCRATCHSPACE
<TREEIOCLS>.INITTREEIO
4.33.4. Example
An example of a short PROCCALLS file
follows:
-------------------- start of file ---------------------
ProcCalls for PASS1
------------------------- eop --------------------------
Module PASS1 prefix classes
PASS1CLS
------------------------- eop --------------------------
Procedure INITIALPROC
Declared at pass1-14-10.msl 8.11 (1318)
$ERRMOD.ERRMSG
$KERMOD.$CLASSDSCRFOR
$KERMOD.$NEWAREA
$KERMOD.NEWRECORD
$KERMOD.SNEWDATASECTION
$SYS$$SEARCHCALLCHAIN
$UTYMOD.$SCANSET
<COMPILCLS>.ALLOCATEKEPTSCRATCHSPACE
<TREEIOCLS>.INITTREEIO
------------------------- eop --------------------------
Procedure FINALPROC
Declared at pass1-14-10.msl 8.85 (1392)
$KERMOD.$DISPOSEAREA
$KERMOD.PDISPOSE
$UTYMOD.$ISCANREL
FINALSTRMATH
------------------------- eop --------------------------
Procedure ADDSYMTBLNODETOLIST
Declared at pass1-14-10.msl 9.5 (1406)
$KERMOD.NEWRECORD
<INTMGRCLS>.GETMODULEINDEX
<INTMGRCLS>.OPENSYMTBLNODE
CMPHDR$FINDFILENAME
CMPHDR$GETFILENUM
------------------------- eop --------------------------
Procedure APPENDTEXT
Declared at pass1-14-10.msl 10.1 (1448)
$SYS$$CSCAN
------------------------- eop --------------------------
Procedure CHECKFORTHISMODULEDCL
Declared at pass1-14-10.msl 11.1 (1456)
$TXTDIO.LISREAD
<INTMGRCLS>.GETMODULEINDEX
ERR
FINDSYMBOL
SETOWNERMODULE
------------------------- eop --------------------------
Procedure <PASS1CLS>.COMPILEDECLARATIONS
Declared at pass1-14-10.msl 12.1 (1489)
$KERMOD.$RAISE
DEINITCOMPILEDECLARATIONS
GETDCLS
INITCOMPILEDECLARATIONS
POSTCOMPILE
SCANNER
------------------------- eop --------------------------
Procedure POPLINE
Declared at pass1-14-10.msl 80.1 (4398)
--------------------- end of file ----------------------
4.34. PROCS/NOPROCS
PROCS causes the names of PROCEDUREs to be printed when their bodies are compiled. The PROCEDURE names are normally printed twice: once during the first pass, and once during code generation (unless the PROCEDURE has no body, as is typically the case for an INLINE PROCEDURE). During the first pass, the message Compiling PROCEDURE procedureName is written to logFile; during code generation, the message Generating code for PROCEDURE procedureName is written.
If the PROCS option is not given, there is normally no output to logFile from the compiler during the code generation phase. This option allows the user to monitor the progress of the code generator, which is useful when the compiler gets a fatal error (such as running out of memory) while compiling a MODULE. The MODULE can be compiled with the PROCS option to determine which PROCEDURE caused the problem.
NOPROCS turns off PROCS.
4.35. PROCTIME
PROCTIME specifies that the objmod be configured so that it can monitor the total (deep and shallow) time spent in each PROCEDURE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).
NOMONITOR turns off all monitor
options.
4.36. RECOMPILE procedure1 procedure2
... proceduren
RECOMPILE procedure1 procedure2 ... proceduren indicates that an incremental recompilation is to be done, and that the PROCEDUREs procedure1, procedure2, and so on through proceduren are to be recompiled. (initialProc and finalProc are the names of unnamed INITIAL and FINAL PROCEDUREs.) The effect is undefined if changes have been made to any of the MODULE's source text outside any of the specified PROCEDUREs procedurei.
The compiler finds the intmod for the MODULE being recompiled, and finds within it the file and starting position of each of the PROCEDUREs procedurei. It then compiles them in the order in which their bodies were originally encountered, automatically compensating for a change in the size of each PROCEDURE if it affects the location of another PROCEDURE later in the same file. The compiler complains if the expected PROCEDURE header(s) are not found at the expected position(s).
If code is being generated, it is generated just for the recompiled PROCEDUREs. The old objmod must be located. The newly generated code is appended to the end of the old objmod, and the replaced code becomes wasted space. Similarly, the new intmod information is appended to the end of the old intmod, and the replaced information becomes wasted space. Thus, the intmod and objmod are larger than if a full compilation were done, though the compilation takes less time.
As described more fully in
Chapter 3, many options
are restored from the old intmod, and
the presently specified settings
ignored. Options that do not affect
global attributes of the intmod or
objmod can be altered, e.g.,
LOG/NOLOG.
4.37. REDEFINE id def/NOREDEFINE/NOREDEFINE
defi
REDEFINE x y is equivalent to compiling the following global definition at the start of the compilation:
$GLOBALREDEFINE x = [y];
y is the text that remains (if any) after removing blank space after x and from the end of the command line. $GLOBALREDEFINE is described in Section 16.7 of the MAINSAIL Language Manual. It defines identifiers that can be referenced across all compilations in a given invocation of the compiler.
The first argument to the compiler's REDEFINE subcommand must be a simple macro identifier; the macro cannot have parameters. Thus, the subcommand:
> REDEFINE mac(parm) body<eol>
causes the compiler to issue an error message.
NOREDEFINE deletes all global definitions. NOREDEFINE x1 x2 ... xn deletes the global definitions for the identifiers x1, x2, ..., xn.
The nonsticky indicator (*) has no
effect on these subcommands; they are
inherently sticky.
4.38. RESPONSE/NORESPONSE
The NORESPONSE option means “Do not get a user response to error messages”. The message is reported and compilation continues (unless the error is fatal). This is especially useful for running the compiler in “batch” mode, i.e., when no user is present to respond to any error messages. If a fatal error occurs while NORESPONSE is in effect, a stack dump is written to logFile and MAINSAIL exits.
NORESPONSE turns off RESPONSE. “RESPONSE” is equivalent to “SUBCOMMAND RESPONSE”, “NORESPONSE” to “SUBCOMMAND NORESPONSE”.
These options apply to all errors, not
just those generated by the compiler,
and remain in effect after exiting the
compiler. Use the MAINEX
subcommands RESPONSE and
NORESPONSE outside the compiler to
restore the previous option, if
desired.
4.39. SAVEON/SAVEON f/NOSAVEON
SAVEON directs the compiler to put the information into the intmod that is needed to support the ability to open the MODULE during a later compilation, e.g., using the RESTOREFROM directive as described in Section 13.3 of the MAINSAIL Language Manual. Opening a MODULE makes the symbols and PROCEDURE bodies declared in the MODULE available.
SAVEON f is equivalent to SAVEON followed by OUTINTFILE f.
NOSAVEON turns off SAVEON.
4.40. SLIST/SLIST f/NOSLIST
SLIST f causes the compiler to generate a source listing on the file f in which macros are expanded and source text not compiled due to conditional compilation logic is omitted. f may be omitted, in which case the output file is formed from the MODULE name and the extension lst.
NOSLIST turns off SLIST.
4.41. STRICTCLASSES/NOSTRICTCLASSES
The compiler subcommand
STRICTCLASSES can be used to cause
the compiler to generate an error
message for:
No error message is generated if either of the two POINTERs in question is unclassified.
In each of the cases mentioned above, the compiler does not have sufficient information to determine that the assignment is safe. For example, given the following declarations:
CLASS c1 (INTEGER i);
CLASS(c1) c2 (INTEGER j);
POINTER(c1) c1p;
POINTER(c2) c2p;
then the assignment:
c1p := c2p;
is clearly safe, since a record of c2 will have all the fields of c1, but:
c2p := c1p;
is not necessarily safe, since c1p may legally point to a record of c1 instead of c2 (or to a record of any other CLASS derived from c1); in this case, the field j of c2 will not be present, but the compiler would permit the use of the field variable c2p.j.
It is this second kind of assignment that is flagged as an error when STRICTCLASSES is in effect.
Classification of POINTERs can still be specified by the programmer using the pointer:className syntax. Thus, to get the effect of the second assignment above when STRICTCLASSES is in effect, use:
c2p := c1p:c2; # I know c1p really points to a c2 record
NOSTRICTCLASSES, which turns off STRICTCLASSES, is the default.
STRICTCLASSES is useful in conjunction with the GENERIC mechanism where it is desirable to invoke different PROCEDURE for POINTERs to different CLASSes derived from a common prefix CLASS. This effect cannot be achieved when STRICTCLASSES is not in effect. For example, given the declarations above, and:
PROCEDURE c1Proc (POINTER(c1) c1p);
write(logFile,"c1Proc" & eol);
PROCEDURE c2Proc (POINTER(c2) c2p);
write(logFile,"c2Proc" & eol);
GENERIC PROCEDURE proc "c2Proc,c1Proc";
the following code:
proc(c1p);
proc(c2p);
prints:
c1proc
c2proc
under STRICTCLASSES, but:
c2proc
c2proc
under NOSTRICTCLASSES.
For this kind of GENERIC
PROCEDURE to work,
STRICTCLASSES must be in effect at
the point of call of the GENERIC
PROCEDURE; it is not sufficient
(or necessary) for it to be in effect
at the point of declaration of the
GENERIC PROCEDURE or any of
the GENERIC PROCEDURE's
instance PROCEDUREs. It may be
useful to specify STRICTCLASSES as
a $DIRECTIVE directive to ensure
that it is turned on at the point of
call of the GENERIC PROCEDURE.
4.42. SUBCOMMAND s
SUBCOMMAND s causes s to be
executed as a MAINEX subcommand. For
example, to open an intlib foo
during a compilation, issue the
subcommand SUBCOMMAND OPENINTLIB
foo.
TARGET s specifies that code is to be generated for the target system s, where s is a target system abbreviation (case is ignored). TARGET ? displays a summary of the system abbreviations. For example, to compile for PA-RISC UNIX (while running on some other operating system), use TARGET upa.
NOTARGET is the same as TARGET hostSystem; i.e., further compilations generate code for the host system.
Code generators for cross-compilation
are separate products not shipped with
a standard development system.
Attempting to cross-compile to a
system for which no code generator is
available generates an error message
saying that the required code
generator cannot be found. Code
generators for any system on which
MAINSAIL is supported may be purchased
from XIDAK.
4.44. UCHECK/NOUCHECK
The UCHECK command performs uninitialized variable checking.
The MAINSAIL compiler can detect at compiletime some cases where a local variable is certainly uninitialized when used. By default, the compiler issues a message at compiletime for such variables even when UCHECK is not in effect. In addition, if UCHECK is in effect, the compiler issues compiletime messages for all variables that might possibly be uninitialized when used.
The UCHECK and NOUCHECK subcommands also govern the generation of extra code to check for uses of uninitialized local variables (the compiler generates the checking code whether it is certain that the variable is uninitialized, or whether it just thinks it might be uninitialized). If a local variable is used before having been initialized, the extra code causes a runtime error to occur at the point the variable is used. The text of the error message includes the uninitialized variable's name.
The runtime error for uninitialized variables is not fatal, so that you may continue from such errors. The uninitialized variable is initialized to Zero before the error is reported, so that future references to the variable within the same PROCEDURE activation will not cause more errors. However, future references to the variable in subsequent PROCEDURE activations will cause more errors, one for each activation that uses the variable when it is uninitialized.
If your program was compiled debuggable, then you can set the uninitialized variable to any arbitrary value, not just Zero, by invoking the debugger and using the debugger's xs command. However, you must do this manually at each error.
UCHECK causes the compiler to generate the extra compiletime warnings and/or checking code, and NOUCHECK turns off UCHECK. The most recently specified UCHECK or NOUCHECK subcommand during a MODULE's compilation governs the generation of checking code for the entire MODULE. UCHECK may be specified only at the MODULE level; there is no way to turn it on or off for individual PROCEDUREs.
4.44.1. UCHECK Details
Occasionally, the compiler is unable
to determine whether or not a local
variable has been initialized when it
is used at a particular place. In
practice, most such local variables
are, in fact, initialized, but the
compiler's analysis is too primitive
to detect this. For example, in the
following code, the compiler would
consider the local variable x to be
possibly uninitialized when it was
used in the statement x .+ n, even
though the logic of the code is such
that x will have always been
initialized by the time it is used:
firstTime := TRUE;
DO IF firstTime THENB x := 0; firstTime := FALSE END
EL x .+ n
UNTIL n .- 1 LEQ 0;
Despite its primitive nature, the compiler's analysis is sufficient to allow it to omit the extra UCHECK code for most local variables, since the compiler usually determines that most variables have been previously initialized everywhere they are used.
If UCHECK is in effect, the compiler reports at compiletime all local variables that are used when they are possibly uninitialized. It does this by writing messages to logFile, similar to the way it generates messages about local variables that it is sure are uninitialized when they are used. The extra variables are reported in order to inform the user of the variables for which extra checking code was generated, so that the user can modify the program so as to eliminate any chance of the errors actually occurring.
If NOUCHECK is in effect, the compiler does not report the local variables that are used when they are possibly uninitialized, because the list could, for some MODULEs, contain dozens of variables, most of which would always be initialized by the time they were used.
Except for USES and MODIFIES parameters, all local variables of data types other than POINTER, STRING, $PROCVAR, and inplace record and ARRAY are assumed to be uninitialized at the start of a PROCEDURE. A variable is officially considered to be initialized only by means of MAINSAIL constructs that are documented as having the effect of modifying a variable's value. Such constructs include assignments and passing a variable as a PRODUCES argument in a PROCEDURE call. In fact, the compiler may sometimes generate code at the start of a PROCEDURE to assign Zero to certain local variables, but the circumstances under which this occurs are unspecified and subject to change. Consequently, local variables implicitly assigned values by the compiler are still considered to be uninitialized.
A local variable is considered to be used anywhere its value is examined. This includes being passed as a USES or MODIFIES argument in a PROCEDURE call and being returned as a PRODUCES parameter.
Note that the definition of “use”
for PRODUCES parameters can cause
seemingly innocent programs to blow up
with an “uninitialized variable”
error if they are compiled with
UCHECK in effect. For example,
consider a BOOLEAN PROCEDURE
with a PRODUCES parameter where
the parameter has meaning only if the
PROCEDURE's result is TRUE. If
the PROCEDURE result is FALSE,
then the PRODUCES argument has no
meaning and should not be used by the
caller. The implementer of the
PROCEDURE may choose to initialize
the PRODUCES parameter only in
those cases where the PROCEDURE
will return TRUE as its result; in
all other cases, the PRODUCES
argument would be uninitialized upon
return to the PROCEDURE's caller.
In these cases, if UCHECK were in
effect, an “uninitialized
PRODUCES parameter” error would
occur just before the PROCEDURE
returned, because of the parameter's
implicit use at that point, even
though the corresponding uninitialized
argument may not actually be used by
the caller. To avoid the error, the
PRODUCES parameter should always
be initialized, even if it is known
that the PROCEDURE's caller will
not actually use the value returned.
UNBOUND specifies that
subsequently compiled MODULEs are
nonbound-invocation MODULEs, i.e.,
always allocated as nonbound data
sections by $invokeModule.
Nonbound-invocation MODULEs are
further described as temporary
features in the Section 11.16 of the MAINSAIL Language Manual.
4.45. UNBOUND/NOUNBOUND
Temporary feature: subject to change
4.46. # s
The # character in compiler
subcommand mode introduces a comment.
It is especially useful in command
files.
MAINSAIL Compiler User's Guide, Chapter 4