P2C(1) USER COMMANDS P2C(1)
NAME
p2c - Pascal to C translator, version 1.20
SYNOPSIS
p2c [ options ] [ file [ module ] ]
DESCRIPTION
P2c is a tool for translating Pascal programs into C. The
input consists of a set of source files in any of the fol-
lowing Pascal dialects: HP Pascal, Turbo/UCSD Pascal, DEC
VAX Pascal, Oregon Software Pascal/2, Macintosh Programmer's
Workshop Pascal, Sun/Berkeley Pascal. Modula-2 syntax is
also supported. Output is a set of .c and .h files that
comprise an equivalent program in any of several dialects of
C. Output code may be kept machine- and dialect-
independent, or it may be targeted to a specific machine and
compiler. Most reasonable Pascal programs are converted
into fully functional C which will compile and run with no
further modifications, although p2c sometimes chooses to
generate readable code at the expense of absolute general-
ity. P2c endeavors to insert notes and warning messages into
the output code to point out areas which may require human
intervention. Output code is arranged to be readable and
efficient, and to make use of C idioms wherever possible.
The main goal of the translation is to produce C files which
are pleasant and "natural" enough to be acceptable as the
new source files for a program. In a pinch, p2c will also
serve as an ad hoc Pascal compiler.
Code generated by p2c normally does not assume characters
are signed or unsigned. Also, it assumes int is the same as
either short or long but does not depend on which. However,
if int is not the same as long it is best to use a modern C
compiler which supports prototypes. Generated code does not
require an ANSI-compatible compiler (unless ANSI-style code
is requested), but it does use various ANSI-standard library
routines.
All generated code includes the file <p2c/p2c.h> which in
turn includes <stdio.h> and various other common resources.
Also, many translated programs will need to be linked with
the run-time library, typically -lp2c.
Given a file name, p2c reads from the specified file and
outputs to a file with a .c suffix added or substituted.
For example,
p2c myfile.pas
reads from myfile.pas to produce the file myfile.c. The
input file may contain a Pascal main program or a single
Pascal module (or "unit" in Turbo and UCSD Pascal
Sun Release 4.1 Last change: local 1
P2C(1) USER COMMANDS P2C(1)
nomenclature), or it may just contain a number of procedures
and declarations. P2c is designed to work for correct input
programs. That is, it will accept partial programs but may
occasionally core dump if the input refers to undefined sym-
bols.
If the input is a module, the translator will also produce a
file module.h containing a translation of the module's
interface section. The implementation section may be omit-
ted in which case only the .h file will be interesting. If
the program or module has include files, these may cause
additional .c files to be generated depending on the value
of the ExpandIncludes option (see below).
If no file name is given, p2c reads Pascal from the standard
input and writes the resulting C to standard output (though
a .h file may still be produced). If a file name and module
name are given, the file may include several modules (or
units). The specified module is translated; any others are
skipped. The output files will be named module.c and
module.h. P2c never translates more than one module per
run.
Before starting, p2c reads the file /usr2/mbk/p2c-
1.20/home/p2crc for a number of configuration parameters.
(The actual path used on your system may vary. The -i
option is a handy way to examine this file.) If the P2CRC
environment variable is set, it gives the name of a file to
read instead of the system file; this file can start with
Include %H/p2crc to include the system file. Next, p2c
attempts to read the file p2crc in your directory for
further configuration. If this file does not exist, p2c
looks for .p2crc instead.
OPTIONS
-o cfile
Use cfile in place of file.c or module.c as the primary
output file. A single dash (`-o -') says to write the
C code to the standard output.
-h hfile
Use hfile in place of module.h as the output file for
interface text. This only has effect if the input is
an HP Pascal module or a Turbo Pascal unit.
-s sfile
Read interface text from sfile before beginning the
translation. This file typically contains one or more
modules, often with interface sections omitted for
speed, which the program or module being translated
will use. (Typically the ImportFrom and ImportDir
parameters in p2crc are set up to allow p2c to locate
Sun Release 4.1 Last change: local 2
P2C(1) USER COMMANDS P2C(1)
interface text without needing any -s options.) If
there are several -s options in the command, the sfiles
are read from left to right.
-pn Display progress of translation in the form of a line
number/file name display. This is refreshed every n
lines, 25 by default.
-c rcfile
Read local configuration commands from rcfile instead
of p2crc or .p2crc. A dash (`-c -') in place of rcfile
causes no local configuration file to be used.
-v ("Vanilla.") Do not read from the system configuration
file /usr2/mbk/p2c-1.20/home/p2crc. Since some of the
parameters in this file are required, your local confi-
guration file must include those parameters instead.
This also suppresses the file named by the P2CRC
environment variable.
-H homedir
Use homedir instead of /usr2/mbk/p2c-1.20/home as the
p2c home directory. The system p2crc file will be
searched for in this directory.
-Ipattern
Add pattern to the ImportDir search list of places to
find modules which are imported. The pattern should
include a %s to represent the module name, and should
evaluate to a potential file name for that module's
source code. For example, ../%s.pas looks for
modulename.pas in the parent of the current directory.
-i This special option (which must be the only argument on
the command line if used) simply copies the system con-
figuration file /usr2/mbk/p2c-1.20/home/p2crc to the
standard output in its entirety. (It may be used with
-H, but -i is most useful precisely when you don't know
the location of the home directory.)
-q Quiet mode. Suppresses output of status messages dur-
ing translation.
-En Abort translation after n errors. If n is omitted it
defaults to zero, which means unlimited errors are
allowed. Use -E1 to make p2c halt after the first
error.
-e Echo the Pascal source into the output file, surrounded
by #ifdefs. This is the same as the CopySource parame-
ter in the p2crc file.
Sun Release 4.1 Last change: local 3
P2C(1) USER COMMANDS P2C(1)
-a Produce modern ANSI C. This is a convenient override
for the AnsiC parameter in the p2crc file.
-L language
Select input language name, such as VAX or TURBO. This
is a convenient override for the Language parameter.
-V Verbose mode. This causes p2c to generate an addi-
tional ".log" file with further details of the transla-
tion, such as a list of warnings and notes including
those which are suppressed in the regular output.
-M0 Disable memory conservation. This prevents p2c from
freeing various data structures after translating each
function, in case this new conservation feature causes
unforseen problems.
-R Regression testing mode. Formats notes and warning
messages in a way that makes it easier to run diff(1)
on the output of p2c.
P2c also understands a few debugging options which may occa-
sionally be useful when tracking down translation problems.
The -dn option sets the "debug level" to n, a small integer
which is normally zero. Debugging output is written into
the regular output file along with the C code; the higher
your n, the more "wallpaper" you get. Also, -t prints
debugging information at every Pascal token, -Bn enables
line-breaker debugging, and -Cn enables comment placement
debugging.
CHOICE OF SOURCE LANGUAGE
The Language configuration parameter or -L command-line
option tells p2c which Pascal dialect to expect in the input
file. Any language features which do not overlap between
dialects are supported all of the time. The Language param-
eter is consulted when a syntax or usage is detected that
has different meanings in two different dialects, and also
to determine default values for various other translation
parameters as described below.
The following language words are supported by p2c. Names are
case-insensitive.
HP HP Pascal. This is the default language. All
features of HP Standard Pascal, the Pascal Worksta-
tion version, are supported except as noted in BUGS
below. Some features of MODCAL, HP's extended Pas-
cal, are also supported. This is a superset of ISO
standard Pascal, including conformant arrays and
procedural parameters.
Sun Release 4.1 Last change: local 4
P2C(1) USER COMMANDS P2C(1)
HP-UX HP Pascal, HP-UX version. Almost identical to the
"HP" dialect.
Turbo Turbo Pascal 5.0 for the IBM PC. Few conflicts with
HP Pascal, so the Language parameter is not often
needed for Turbo. (Most important is that the Turbo
and HP dialects use 16 and 32 bit integers, respec-
tively.)
UCSD UCSD Pascal. Similar to Turbo in many ways.
MPW Macintosh Programmer's Workshop Pascal 2.0. Should
also do a pretty good job for Lightspeed Pascal.
Object Pascal features are not supported, nor is the
fact that char variables are sometimes stored in 16
bits.
VAX VAX/VMS Pascal version 3.5. Most but not all
language features supported. This has not yet been
tested on large programs.
Oregon Oregon Software Pascal/2. All features implemented.
Berk Berkeley Pascal with Sun extensions.
Modula Modula-2. Based on Wirth's Programming in Modula-2,
3rd edition. Proper setting of the Language parame-
ter is not optional. Translation will be incomplete
in most cases, but should be good enough to work
with. Structure of local sub-modules is essentially
ignored; like-named identifiers may be confused.
Type WORD is translated as an integer, but type
ADDRESS is translated as char * or void *; this may
cause inconsistencies in the output code.
Modula-2 modules have two parts in separate files.
Suppose these are called foo.def (definition part)
and foo.mod (implementation part) for module foo.
Then a pattern like %s.def must be included in the
ImportDir list, and LibraryFile must be changed to
refer to system.m2 instead of system.imp. To
translate the definition part, give the command
p2c foo.def
to translate the definition part into files foo.h
and foo.c; the latter will usually be empty. The
command
p2c -s foo.def foo.mod
will translate the implementation part into file
Sun Release 4.1 Last change: local 5
P2C(1) USER COMMANDS P2C(1)
foo.c.
Even if all language features are supported for a dialect,
some predefined functions may be omitted. In these cases,
the function call will be translated literally into C with a
warning. Some hand modification may be required.
CONFIGURATION PARAMETERS
P2c is highly configurable. The defaults are suitable for
most applications, but customizing these parameters will
help you get the best possible translation. Since the out-
put of p2c is intended to be used as human-maintainable
source code, there are many parameters for describing the
coding style and conventions you prefer. Others give hints
about your program that help p2c to generate more correct,
efficient, or readable code.
The p2crc files contain a list of parameters, one per line.
The system configuration file, which may be viewed using the
-i option to p2c, serves as an example of the proper format.
Parameter names are case-insensitive. If a parameter name
occurs exactly once in the system p2crc, this indicates that
it must have a unique value and the last value given to it
by the configuration files is used. Other parameters are
written several times in a row; these are lists to which
each configuration line adds an entry.
Many p2crc options take a numeric value of 0 or 1, roughly
corresponding to "no" or "yes." Sometimes a blank value or
the value "def" corresponds to an intermediate "maybe"
state. For example, the stylistic option ExtraParens
switches between copious or minimal parentheses in expres-
sions, with the default being a nice compromise intended to
be best for readers with an average knowledge of C operator
precedences.
Configuration options may also be embedded in the source
file in the form of Pascal comments:
{ShortOpt=0} {AvoidName=fred}
{FuncMacro slope(x,y)=atan2(y,x)*RadDeg}
disables automatic short-circuiting of and and or expres-
sions, adds "fred" to the list of names to avoid using in
generated C code, and defines a special translation for the
Pascal program's slope function using the standard C atan2
function and a constant RadDeg presumably defined in the
program. Whitespace is generally not allowed in embedded
parameters. The `=' sign is required for embedded parame-
ters, though it is optional in p2crc files. Comments within
embedded parameters are delimited by `##'. Numeric parame-
ters may replace `=' with `+' or `-' to increase or decrease
Sun Release 4.1 Last change: local 6
P2C(1) USER COMMANDS P2C(1)
the parameter; list-based parameters may use `-' to remove a
name from a list rather than adding it. Also, the parameter
name by itself in comment braces means to restore the
parameter's value that was current before the last change:
{VarFiles=0 ## Pass FILE *'s params by value even if
VAR}
some declarations
{VarFiles ## Back to original FILE * passing}
causes the parameter VarFiles to have the value 0 for those
few declarations, without affecting the parameter's value
elsewhere in the file.
If an embedded parameter appears in an include file or in
interface text for a module, the effect of the assignment
normally carries over to any programs that included that
file. If the parameter name is preceded by a `*', then the
assignment is automatically undone after the source file
that contains it ends:
{IncludeFrom strings=<p2c/strings.h>}
{*ExportSymbol=pascal_%s}
module strings;
will record the location of the strings module's include
file for the rest of the translation, but the assignment of
ExportSymbol pertains only to the module itself.
For the complete list of p2crc parameters, run p2c with the
-i option. Here are some additional comments on selected
parameters:
ImportAll Because Turbo Pascal only allows one unit per
source file, p2c normally stops reading past
the word implementation in a file being
scanned for interface text. But HP Pascal
allows several modules per file and so this
would not be safe to do. The ImportAll
option lets you override the default behavior
for your Pascal dialect.
AnsiC This parameter selects which dialect of C to
use. If 1, all conventions of ANSI C such as
prototypes, void * pointers, etc. are used.
If 0, only strict K&R (first edition) C is
used. The default is to use "traditional
UNIX C," which includes enum and void but not
void * or prototypes. Once again there are a
number of other parameters which may be used
to control the individual features if just
setting AnsiC is not enough.
Sun Release 4.1 Last change: local 7
P2C(1) USER COMMANDS P2C(1)
C++ At present p2c does not use much of C++ at
all. The default action is to generate code
that will compile in either language.
UseVExtern Many non-UNIX linkers prohibit variables from
being defined (not declared) by more than one
source file. One module must declare, e.g.,
"int foo;", and all others must declare
"extern int foo;". P2c accomplishes this by
declaring public variables "vextern" in
header files, and arranging for the macro
vextern to expand to extern or to nothing
when appropriate. If you set UseVExtern=0
p2c will instead declare variables in a
simpler way that works only on UNIX-style
linkers.
UseAnyptrMacros
Certain C reserved words have meanings which
may vary from one C implementation to
another. P2c uses special capitalized names
for these words; these names are defined as
macros in the file p2c.h which all translated
programs include. You can set UseAnyptrMac-
ros=0 to disable the use of these macros.
Note that the functions of many of these mac-
ros can also be had directly using other
parameters; for example, UseConsts allows you
to specify whether your target language
recognizes the word const in constant
declarations. The default is to use the
Const macro instead, so that your code will
be portable to either kind of implementation.
Signed expands to the reserved word signed if
that word is available, otherwise it is given
a null definition. Similarly, Const expands
to const if that feature is available. The
words Volatile and Register are also defined
in p2c.h, although p2c does not use them at
present. The word Char expands to char by
default, but might need to be redefined to
signed char or unsigned char in a particular
implementation. This is used for the Pascal
character type; lowercase char is used when
the desired meaning is "byte," not "charac-
ter."
The word Static always expands to static by
default. This is used in situations where a
function or variable is declared static to
make it local to the source file; lowercase
Sun Release 4.1 Last change: local 8
P2C(1) USER COMMANDS P2C(1)
static is used for static local variables.
Thus you can redefine Static to be null if
you want to force private names to be public
for purposes of debugging.
The word Void expands to void in all cases;
it is used when declaring a function with no
return value. The word Anyptr is a typedef
for void * or char * as necessary; it
represents a generic pointer.
UsePPMacros The p2c.h header also declares two macros for
function prototyping, PP(x) and PV(). These
macros are used as follows:
Void foo PP( (int x, int y, Char *z) );
Char *bar PV( );
If prototypes are available, these macros
will expand to
Void foo (int x, int y, Char *z);
Char *bar (void);
but if only old-style declarations are sup-
ported, you instead get
Void foo ();
Char *bar ();
By default, p2c uses these macros for all
function declarations, but function defini-
tions are written in old-style C. The UsePP-
Macros parameter can be set to 0 to disable
all use of PP and PV, or it can be set to 1
to use the macros even when defining a func-
tion. (This is accomplished by preceding
each old-style definition with a PP-style
declaration.) If you know your code will
always be compiled on systems that support
prototyping, it is prettier to set Proto-
types=1 or simply AnsiC=1 to get true func-
tion prototypes.
EatNotes Notes and warning messages containing any of
these strings as sub-strings are not omitted.
Each type of message includes an identifier
like [145]; you can add this identifier to
the EatNotes list to suppress that message.
Another useful form is to use a variable name
or other identifier to suppress warnings
about that variable. The strings are a
Sun Release 4.1 Last change: local 9
P2C(1) USER COMMANDS P2C(1)
space-separated list, and thus may not con-
tain embedded spaces. To suppress notes
around a section of code, use, e.g., {Eat-
Notes+[145]} and {EatNotes-[145]}. Most notes
are generated during parsing, but to suppress
those generated during output the string may
need to remain in the list far beyond the
point where it appears to be generated. Use
the string "1" or "0" to disable or enable
all notes, respectively.
ExpandIncludes The default action is to expand Pascal
include files in-line. This may not be
desirable if include files are being used to
simulate modules. With ExpandIncludes=0, p2c
attempts to convert include files containing
only whole procedures and global declarations
into analogous C include files. This may not
always work, though; if you get error mes-
sages, don't use this option. By combining
this option with StaticFunctions=0, then
doing some fairly minor editing on the
result, you can convert a pseudo-modular Pas-
cal program into a truly modular collection
of C source files.
ElimDeadCode Some transformations that p2c does on the
program may result in unreachable or "dead"
code. By default p2c removes such code, but
sometimes it removes more than it should. If
you have "if false" segments which you wish
to retain in C, you may have to set ElimDead-
Code=0.
SkipIndices Normally Pascal arrays not based at zero are
"shifted" down for C, preserving the total
size of the array. A Pascal array a[2..10]
is translated to a C array a[9] with refer-
ences like "a[i]" changed to "a[i-2]" every-
where. If SkipIndices is set to a value of 2
or higher, this array would instead be
translated to a[11] with the first two ele-
ments never used. This arrangement may gen-
erate incorrect code, though, for tricky
source programs.
FoldConstants Pascal non-structured constants generally
translate to #define's in C. Set this to 1
to have constants instantiated directly into
the code. This may be turned on or off
around specific constant declarations. Set
this to 0 to force p2c to make absolutely no
Sun Release 4.1 Last change: local 10
P2C(1) USER COMMANDS P2C(1)
assumptions about the constant's value in
generated code, so that you can change the
constant later in the C code without invali-
dating the translation. The default is to
allow p2c to take advantage of its knowledge
of a constant's value, such as by generating
code that assumes the constant is positive.
CharConsts This governs whether single-character string
literals in Pascal const declarations should
be interpreted as characters or strings. In
other words, const a='x'; will translate to
#define a 'x' if CharConsts=1 (the default),
or to #define a x if CharConsts=0. Note that
if p2c guesses wrong, the generated code will
not be wrong, just uglier. For example, if a
is written as a character constant but it
turns out to be used as a string, p2c will
have to write char-to-string conversion code
each time the constant is used.
VarStrings In HP Pascal, a parameter of the form "var s
: string" will match a string variable of any
size; a hidden size parameter is passed which
may be accessed by the Pascal strmax func-
tion. You can prevent p2c from creating a
hidden size parameter by setting VarString=0.
(Note that each function uses the value of
VarStrings as of the first declaration of the
function that is parsed, which is often in
the interface section of a module.)
Prototypes Control whether ANSI C function prototypes
are used. Default is according to AnsiC.
This also controls whether to include parame-
ter names or just their types in situations
where names are optional. The FullPrototyp-
ing parameter allows prototypes to be gen-
erated for declarations but not for defini-
tions (older versions of Lightspeed C
required this). If you use a mixture of pro-
totypes and old-style definitions, types like
short and float will be promoted to int and
double as required by the ANSI standard,
unless PromoteArgs is used to override this.
The CastArgs parameter controls whether
type-casts are used in function arguments; by
default they are used only if prototypes are
not available.
StaticLinks HP Pascal and Turbo Pascal each include the
concept of procedure or function pointers,
Sun Release 4.1 Last change: local 11
P2C(1) USER COMMANDS P2C(1)
though with somewhat different syntaxes. P2c
recognizes both notational styles. Another
difference is that HP's procedure pointers
can point to nested procedures, while Turbo's
can point only to global procedures. In HP
Pascal a procedure pointer must be stored as
a struct containing both a pure C function
pointer and a "static link," a pointer to the
parent procedure's locals. (The static link
is NULL for global procedures.) This nota-
tion can be forced by setting StaticLinks=1.
In Turbo, the default (StaticLinks=0) is to
use plain C function pointers with no static
links. A third option (StaticLinks=2) uses
structures with static links, but assumes the
links are always NULL when calling through a
pointer (if you need compatibility with the
HP format but know your procedures are glo-
bal).
SmallSetConst Pascal sets are translated into one of two
formats, depending on the size of the set.
If all elements have ordinal values in the
range 0..31, the set is translated as a sin-
gle integer variable using bit operations.
(The SetBits parameter may be used to change
the upper limit of 31.) The SmallSetConst
parameter controls whether these small-sets
are used, and, if so, how constant sets
should be represented in C. For larger
sets, an array of long is used. The s[0]
element contains the number of succeeding
array elements which are in use. Set ele-
ments in the range 0..31 are stored in the
s[1] array element, and so on. Sets are nor-
malized so that s[s[0]] is nonzero for any
nonempty set. The standard run-time library
includes all the necessary procedures for
operating on sets.
ReturnValueName
This is one of many "naming conventions"
parameters. Most of these take the form of a
printf-like string containing a %s where the
relevant information should go. In the case
of ReturnValueName, the %s refers to a func-
tion name and the resulting string gives the
name of the variable to use to hold the
function's return value. Such a variable
will be made if a function contains assign-
ments to its return value buried within the
body, so that return statements cannot
Sun Release 4.1 Last change: local 12
P2C(1) USER COMMANDS P2C(1)
conveniently be used. Some parameters
(ReturnValueName included) do not require the
%s to be present in the format string; for
example, the standard p2crc file stores every
function's return value in a variable called
Result.
AlternateName P2c normally translates Pascal names into C
names verbatim, but occasionally this is not
possible. A Pascal name may be a C reserved
word or traditional C name like putc, or
there may be several like-named things that
are hidden from each other by Pascal's scop-
ing rules but must be global in C. In these
situations p2c uses the parameter Alterna-
teName1 to generate an alternative name for
the symbol. The default is to add an under-
score to the name. There is also an Alterna-
teName2 parameter for a second alternate
name, and an AlternateName parameter for the
nth alternate name. (The value for this
parameter should include both a %s and a %d,
in either order.) If these latter parameters
are not defined, p2c applies AlternateName1
many times over.
ExportSymbol Symbols in the interface section for a Pascal
module are formatted according to the value
of ExportSymbol, if any. It is not uncommon
to use modulename_%s for this symbol; the
default is %s, i.e., no special treatment for
exported symbols. If you also define the
Export_Symbol parameter, that format is used
instead for exported symbols which contain an
underscore character. If %S (with a capital
"S") appears in the format string it stands
for the current module name.
Alias If the value of this parameter contains a %s,
it is a format string applied to the names of
external functions or variables. If the
value does not contain a %s, it becomes the
name of the next external symbol which is
declared (after which the parameter is
cleared).
Synonym This creates a synonym for another Pascal
symbol or keyword. The format is
Synonym old-name = new-name
All occurrences of old-name in the input text
Sun Release 4.1 Last change: local 13
P2C(1) USER COMMANDS P2C(1)
are treated as if they were new-name by the
parser. If new-name is a keyword, old-name
will be an equivalent keyword. If new-name
is the name of a predefined function, old-
name will behave in the same way as that
function, and so on. If new-name is omitted,
then occurrences of old-name are entirely
ignored in the input file. Synonyms allow
you to skip over a keyword in your dialect of
Pascal that is not understood by p2c, or to
simulate a keyword or predefined identifier
of your dialect with a similar one that p2c
recognizes. Note that all predefined func-
tions are available at all times; if you have
a library routine that behaves like, e.g.,
Turbo Pascal's getmem procedure, you can make
your routine a synonym for getmem even if you
are not translating in Turbo mode.
NameOf This defines the name to use in C for a
specific symbol. It must appear before the
symbol is declared in the Pascal code; it is
usually placed in the local p2crc file for
the project. The format is
NameOf pascal-name = C-name
By default, Pascal names map directly onto C
names with no change (except for the various
kinds of formatting outlined above). If the
pascal-name is of the form module.name or
procedure.name then the command applies only
to the instance of the Pascal name that is
global to that module, or local to that pro-
cedure. Otherwise, it applies to all usages
of the name.
VarMacro This is analogous to NameOf, but specifically
for use with Pascal variables. The righthand
side can be most any C expression; all refer-
ences to the variable are expanded into that
C expression. Names used in the C expression
are taken verbatim. There is also a Const-
Macro parameter for translating constants as
arbitrary expressions. Note that the vari-
able on the lefthand side must actually be
declared in the program or in a module that
it uses. The declaration for the variable
will be omitted from the generated code
unless the Pascal-name appears in the expres-
sion: If you ask to replace i with i+1, the
variable i will still be declared but its
Sun Release 4.1 Last change: local 14
P2C(1) USER COMMANDS P2C(1)
value will be shifted accordingly. Note that
if i appears on the lefthand side of an
assignment, p2c will use algebra to "solve"
for i.
In all cases where p2c parses C expressions,
all C operators are recognized except com-
pound assignments like `+='. (Increment and
decrement operators are allowed.) All vari-
able and function names are assumed to have
integer type, even if they are names that
occur in the actual program. A type-
specification operator `::' has been intro-
duced; it has the same precedence as `.' or
`->' but the righthand side must be a Pascal
type identifier (built-in or defined by your
program previously to when the macro defini-
tion was parsed), or an arbitrary Pascal type
expression in parentheses. The lefthand
argument is then considered to have the
specified type. This may be necessary if
your macro is used in situations where the
exact type of the expression must be known
(say, as the argument to a writeln).
FieldMacro Here the lefthand side must have the form
record.field, where record is the Pascal type
or variable name for a record, and field is a
field in that record. The righthand side
must be a C expression generally including
the name record. All instances of that name
are replaced by the actual record being "dot-
ted." For example,
FieldMacro Rect.topLeft = topLeft(Rect)
translates a[i].topLeft into topLeft(a[i]),
where a is an array of Rect.
FuncMacro The lefthand side must be any Pascal function
or procedure name plus a parameter list. The
number of parameters must match the number in
the function's uses and declaration. Calls
to the function are replaced by the C expres-
sion on the righthand side. For example,
FuncMacro PtInRect(p,r) = PtInRect(p,&r)
causes the second argument of PtInRect to be
passed by reference, even though the declara-
tion says it's not. If the function in ques-
tion is actually defined in the program or
Sun Release 4.1 Last change: local 15
P2C(1) USER COMMANDS P2C(1)
module being translated, the FuncMacro will
not affect the definition but it will affect
all calls to the function elsewhere in the
module. FuncMacros can also be applied to
predefined or never-defined functions.
IncludeFrom This specifies that a given module's header
should be included from a given place. The
second argument may be surrounded by " " or
< > as necessary; if the second argument is
omitted, no include directive will be gen-
erated for the module.
ImportFrom This specifies that a given module's Pascal
interface text can be found in the given
file. The named file should be either the
source file for the module, or a specially
prepared file with the implementation section
removed for speed. If no ImportFrom entry is
found for a module, the path defined by the
ImportDir list is searched. Each entry in
the path may contain a %s, which expands to
the name of the module. The default path
looks for %s.pas and %s.text in the current
directory, then for /usr2/mbk/p2c-
1.20/home/%s.imp. (where /usr2/mbk/p2c-
1.20/home is the p2c home directory.)
StructFunction This parameter is a list of functions which
follow the p2c semantics for structure-valued
functions (functions returning arrays, sets,
and strings, and structs in primitive C
dialects). For these functions, a pointer to
a return-value area is passed to the function
as a special first parameter. The function
stores the result in this area, then returns
a copy of the pointer. (The standard C func-
tion strcpy is an example of this concept.
Sprintf also behaves this way in some
dialects; it always appears on the
StructFunction list regardless of the type of
implementation.) The system configuration
file includes a list of common structured
functions so that p2c's optimizer will know
how to manipulate them.
StrlapFunction Functions on this list are structured func-
tions as above, but with the ability to work
in-place; that is, the same pointer may be
passed as both the return value area and a
regular parameter.
Sun Release 4.1 Last change: local 16
P2C(1) USER COMMANDS P2C(1)
Deterministic Functions on this list have no side effects
or side dependencies. An example is the sin
function in the standard math library; two
calls with the same parameter values produce
the same result, and have no effects other
than returning a value. P2c can make use of
this knowledge when optimizing code for effi-
ciency or readability. Functions on this
list are also assumed to be relatively fast,
so that it is acceptable to duplicate a call
to the function.
LeaveAlone Functions on this list are not subjected to
the normal built-in translation rules that
p2c would otherwise use. For example, adding
writeln to this list would translate writeln
statements blindly into calls to a C wri-
teln() function, rather than being translated
into equivalent printf calls. The built-in
translation is also suppressed if the func-
tion has a FuncMacro.
BufferedFile P2c normally assumes binary files will use
read/write, not get/put/^ notation. A file
buffer variable will only be created for a
file if buffer notation is used for it. For
global file variables this may be detected
too late (a declaration without buffers may
already have been written). Such files can
be listed in BufferedFile to force p2c to
allocate buffers for them; do this if you get
a warning message that says it is necessary.
Set BufferedFile=1 to buffer all files, in
which case UnBufferedFile allows you to force
certain files not to have buffers.
StructFiles If p2c still can't translate your file opera-
tions correctly, you can set StructFiles=1 to
cause Pascal files to translate into structs
which include the usual C FILE pointer, as
well as file buffer and file name fields.
While the resulting code doesn't look as much
like native C, the file structs will allow
p2c to do a correct translation in many more
cases.
CheckFileEOF Normally only file-open operations are
checked for errors. Additional error check-
ing, such as read-past-end-of-file, can be
enabled with parameters like CheckFileEOF.
These checks can make the code very ugly! If
I/O checking is enabled by the program
Sun Release 4.1 Last change: local 17
P2C(1) USER COMMANDS P2C(1)
($iocheck on$ in HP Pascal; {$I+} in Turbo;
this is always the default state), these
checks will generate fatal errors unless
enclosed in an HP Pascal try-recover con-
struct. If I/O checking is disabled, these
will cause the global variable P_ioresult to
be set zero or nonzero according to the out-
come. The default for most of these options
is to check only when I/O checking is dis-
abled.
ISSUES
Integer size. P2c normally generates code to work with
either 16 or 32 bit ints. If you know your C integers will
be 16 or 32 bits, set IntSize appropriately. In particular
setting IntSize=32 will generate much cleaner code: p2c no
longer must carefully cast function arguments between int
and long. These casts also will be unnecessary if ANSI pro-
totypes are available. To disable int/long casting because
you know at least one of these cases will hold, set Cast-
LongArgs=0. (The CastArgs parameter similarly controls
other types of casts, such as between ints and doubles.) The
Integer16 parameter controls whether Pascal integers are
interpreted as 16 or 32 bits, or translated as native C
integers. The default value depends on the Language
selected.
Signed/unsigned chars. Pascal characters are normally
"weakly" interpreted as unsigned; this is controlled by
UnsignedChar. The default is "either," so that C's native
char type may be used even if its signed-ness is unknown.
Code that uses characters outside of the range 0-127 may
need a different setting. Alternatively, you can use the
types {SIGNED} char and {UNSIGNED} char in the few cases
where it really matters. These comments are controlled by
the SignedComment and UnsignedComment parameters. (The type
{UNSIGNED} integer is also recognized.) The SignedChar
parameter tells whether C characters are signed or unsigned
(default is "unknown"). The HasSignedChar parameter tells
whether the phrase "signed char" is legal in the output. If
it is not, p2c may have to translate Pascal signed bytes
into C shorts.
Special types. P2c understands the following predefined Pas-
cal type names: integer, signed integers depending on
Integer16; longint, signed 32-bit integers; unsigned,
unsigned 32-bit integers; sword, signed 16-bit integers;
word, unsigned 16-bit integers; c_int, signed native C
integers; c_uint, unsigned native C integers; sbyte, signed
8-bit integers; byte, unsigned 8-bit integers; real,
floating-point numbers depending on DoubleReals; single,
single-precision floats; longreal, double, and extended,
Sun Release 4.1 Last change: local 18
P2C(1) USER COMMANDS P2C(1)
double-precision floats; pointer and anyptr, generic
pointers (assignment-compatible with any pointer type);
string, generic string of length StringDefault (normally
255); also, the usual Pascal types char, boolean, and text.
(If your Pascal uses different names for these concepts, the
Synonym option will come in handy.)
Embedded code. It is possible to write a Pascal comment con-
taining C code to be embedded into the output. See the
descriptions of EmbedComment and its relatives in the system
p2crc file. These techniques are helpful if you plan to do
repeated translations of code that is still being maintained
in Pascal.
Comments and blank lines. P2c collects the comments in a
procedure into a list. All comments and statements are
stamped with serial numbers which are used to reattach com-
ments to statements even after code has been added, removed,
or rearranged during translation. "Orphan" comments
attached to statements that have been lost are attached to
nearby statements or emitted at the end of the procedure.
Blank lines are treated as a kind of comment, so p2c will
also reproduce your usage of blank lines. If the comment
mechanism goes awry, you can disable comments with EatCom-
ments or disable their being attached to code with SpitCom-
ments.
Indentation. P2c has a number of parameters to govern inden-
tation of code. The default values produce the GNU Emacs
standard indentation style, although p2c can do a better job
since it knows more about the code it is indenting. Inden-
tation works by applying "indentation deltas," which are
either absolute numbers (which override the previous inden-
tation), or signed relative numbers (which augment the pre-
vious indentation). A delta of "+0" specifies no change in
indentation. All of the indentation options are described
in the standard p2crc file.
Line breaking. P2c uses an algorithm similar to the TeX
typesetter's paragraph formatter for breaking long state-
ments into multiple lines. A "penalty" is assigned to vari-
ous undesirable aspects of all possible line breaks; the
"badness" of a set of line breaks is approximately the sum
of all the penalties. Chief among these are serious penal-
ties for overrunning the desired maximum line length
(default 78 columns), an infinite penalty for overrunning
the absolute maximum line length (default 90), and progres-
sively greater penalties for breaking at operators deeply
nested in expressions. Parameters such as OpBreakPenalty
control the relative weights of various choices. BreakArith
and its neighbors control whether the operator at a line
break should be placed at the end of the previous line or at
Sun Release 4.1 Last change: local 19
P2C(1) USER COMMANDS P2C(1)
the beginning of the next. If you don't want any oversize
lines, define MaxLineWidth=78.
Unlike TeX, p2c's line breaker must actually try all possi-
ble sets of break points. To avoid excessive computation,
the total penalty contributed at each decision point must
sum to a nonnegative value; negative values are clipped up
to zero. This allows p2c to prune away obviously undesir-
able alternatives in advance. The MaxLineBreakTries parame-
ter (default 5000) controls how many alternatives to try
before giving up and using the best so far.
PASCAL_MAIN. P2c generates a call to this function at the
front of the main program. In the (unmodified) run-time
library all this does is save argc and argv away because in
both HP and Turbo these are accessed as global variables.
If you do not wish to use this feature, define ArgCName to
be argc, ArgVName to be argv, and MainName (normally
"PASCAL_MAIN") to be blank. This will work if argc and argv
are never accessed outside of your main program.
BUGS
P2c was designed with the idea that clean, readable output
in most cases is worth more than guaranteed correct output
in extreme cases. P2c is not a compiler! However, ideally
the "extreme" cases would include only those which never
arise in real life. Thus if p2c actually generates
incorrect code I will consider it a bug, but I will not apo-
logize for it. :-) Below are the major remaining cases
where this is known to occur.
Certain kinds of conformant array parameters (including
multi-dimensional conformant arrays) produce code that
declares variable-length arrays in C. Only a few C com-
pilers, such as the GNU C compiler, support this language
extension. Otherwise some hand re-coding will be required.
HP Pascal try-recover structures are translated into calls
to TRY and RECOVER macros, which are defined to simulate the
construct using setjmp and longjmp. If this emulation does
not work, define the symbol FAKE_TRY to cause these macros
to become "inert." (In cases where the error is detected by
code physically within the body of the try statement, a C
goto to the recover section is always generated.) Also,
local file variables in scopes which are destroyed by an
escape are not closed.
Non-local GOTO's and try-recover statements are each imple-
mented, but may conflict if both are used at once. Non-
local GOTO's are fairly careful about closing files that go
out of scope but may fail to do so in the presence of recur-
sion.
Sun Release 4.1 Last change: local 20
P2C(1) USER COMMANDS P2C(1)
Arrays containing files are not initialized to NULL as other
files are. In some cases, such as file variables allocated
by NEW, the file is initialized but not automatically closed
by DISPOSE.
LINK variables allowing sub-procedures access to their
parents' variables are occasionally omitted by mistake, if
the access is too indirect for p2c to notice. If this hap-
pens, you can add an explicit reference to a parent variable
in the sub-procedure. A statement of the form "a:=a" will
count as a reference but then be optimized away by p2c.
Many aspects of Modula-2 are translated only superficially.
For example, the type-compatibility properties of the WORD
and ARRAY OF WORD types are only roughly modelled, as are
the scope rules concerning modules.
Parts of VAX Pascal are still untreated. In particular, the
[UNSAFE] attribute and a few others are not fully supported,
nor are the semantics of the OPEN procedure.
Turbo and VAX Pascal's double, quadruple, and extended real
types all translate to the C double type. Turbo's computa-
tional type is not supported at all.
Because Pascal strings (with length bytes) are translated
into C strings (with null terminators), certain Pascal
string tricks will not work in the translated code. For
example the assignment s[0]:=chr(x) is translated to s[x]=0
on the assumption that the string is being shortened. If x
is actually greater than the current length, but not of a
recognizable form like ord(s[0])+n, then the generated code
will not work. In VAX Pascal this corresponds to performing
arithmetic on the LENGTH field of a varying-length string.
Turbo Pascal's automatic clipping of strings is not sup-
ported. In Turbo, if a ten character string is assigned to
a string[8] variable, the last two characters are silently
removed. The code produced by p2c generally will overrun
the target string instead! The StringTruncLimit parameter
(80 by default if Language=Turbo) specifies a string size
which should be considered "short"; assignments of
potentially-long strings to short string variables will
cause a warning but will not automatically truncate. The
cure is to use copy in the Pascal source to truncate the
strings explicitly.
FILES
file.xxx Pascal source files
file.c resulting C source file
module.h resulting C header file
p2crc local configuration file
Sun Release 4.1 Last change: local 21
P2C(1) USER COMMANDS P2C(1)
.p2crc alternate local configura-
tion file
/usr2/mbk/p2c-1.20/home/p2crc system-wide configuration
file
/usr2/mbk/p2c-1.20/home/system.impdeclarations for prede-
fined functions
/usr2/mbk/p2c-1.20/home/system.m2 analogous declarations for
Modula-2
/usr2/mbk/p2c-1.20/home/*.imp interface text for stan-
dard modules
/usr2/mbk/p2c-1.20/home/p2c/p2c.h header file for translated
programs
/usr2/mbk/p2c-1.20/home/libp2c.a run-time library
AUTHOR
Dave Gillespie, daveg@csvax.cs.caltech.edu.
Many thanks to William Bader, Steven Levi, Rick Koshi, Eric
Raymond, Magne Haveraaen, Dirk Grunwald, David Barto, Paul
Fisher, Tom Schneider, and others whose suggestions and bug
reports have helped improve p2c in countless ways.
Sun Release 4.1 Last change: local 22