p2c(1) CLIX p2c(1)
NAME
p2c - Translates PASCAL programs to C programs
SYNOPSIS
p2c [flags] [file [module]]
FLAGS
-o cfile Uses cfile in place of file.c or module.c as the primary
output file. A single dash (-o -) writes the C code to
stdout.
-h hfile Uses hfile in place of module.h as the output file for
interface text. This flag only has effect if the input is
an HP Pascal module or a Turbo Pascal unit.
-s sfile Reads 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 interface text
without needing any -s flags.) If there are several -s
flags in the command, the list of sfiles are read from left
to right.
-p n Displays the progress of translation in the form of a line
number to file name display. The display is refreshed
every n lines. The default value of n is 25.
-c rcfile Reads 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.) Does not read from the system configuration
file /usr/lib/p2c/p2crc. Since some of the parameters in
this file are required, the local configuration file must
include those parameters instead. This flag also suppresses
the file named by the P2CRC environment variable.
-H homedir Uses homedir instead of /usr/lib/p2c as the p2c home
directory. The system p2crc file will be searched for in
this directory.
-I pattern Adds 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
2/94 - Intergraph Corporation 1
p2c(1) CLIX p2c(1)
of the current directory.
-i Copies the system configuration file /usr/lib/p2c/p2crc to
stdout in its entirety. This special flag must be the only
flag on the command line if it is used. The flag may be
used with -H, but -i is most useful when the location of
the home directory is not known.
-q (Quiet.) Suppresses output of status messages during
translation.
-E n Aborts translation after n errors. The default value for n
is 0, which means unlimited errors are allowed. Use the -
E1 flag to make p2c halt after the first error.
-e Echoes the PASCAL source into the output file, surrounded
by #ifdefs statements. This is the same as the CopySource
parameter in the p2crc file.
-a Produces modern ANSI C. This is a convenient override for
the AnsiC parameter in the p2crc file.
-L language Selects input language name, such as VAX or TURBO. This is
a convenient override for the Language parameter.
-V (Verbose.) Causes p2c to generate an additional .log file
with further details of the translation, such as a list of
warnings and notes, including those which are suppressed in
the regular output.
-M0 Disables 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 on the
output of p2c.
-d n Sets the debugging 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 the value of
n, the more information is printed.
-t Prints debugging information at every PASCAL token.
-B n Enables line-breaker debugging.
-C n Enables comment placement debugging.
DESCRIPTION
2 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
The p2c command translates PASCAL programs into C programs. The input
consists of a set of source files in any of the following 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 PASCAL programs are converted into fully functional C which will
compile and run with no further modifications, although p2c sometimes
generates readable code at the expense of generality.
The p2c command tries to insert notes and warning messages into the output
code to point out areas which may require 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 acceptable as the new source files for a program. In a pinch,
p2c also serves 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.
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, the command 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 nomenclature), or it may just contain a number of
procedures and declarations.
The p2c command is designed to work for correct input programs. That is,
it will accept partial programs but may halt if the input refers to
undefined symbols.
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 omitted. If the program or module has
included files, these may cause additional .c files to be generated,
depending on the value of the ExpandIncludes parameter.
If no file name is given, p2c reads PASCAL from the stdin and writes the
resulting C to stdout (though a .h file may still be produced). If a file
2/94 - Intergraph Corporation 3
p2c(1) CLIX p2c(1)
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. The p2c never
translates more than one module per run.
Before starting, p2c reads the file /usr/lib/p2c/p2crc for a number of
configuration parameters. (The actual path used may vary. The -i flag
may be used 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 for further configuration. If this
file does not exist, p2c looks for .p2crc instead.
Choice of Source Language
The Language configuration parameter or -L command-line flag tells p2c
which PASCAL dialect to expect in the input file. Any language features
which do not overlap between dialects are supported. The Language
parameter 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 Pascal The default language. All features of HP Standard Pascal, the
Pascal Workstation version, are supported except as noted in
the CAUTIONS section. Some features of MODCAL, HP's extended
PASCAL, are also supported. This is a superset of ISO
standard PASCAL, including conformant arrays and procedural
parameters.
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. (The Turbo and HP dialects use 16 and 32 bit integers,
respectively.)
UCSD UCSD Pascal. Similar to Turbo.
MPW Macintosh Programmer's Workshop Pascal 2.0. Works well with
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 language features are
supported. This has not yet been tested on large programs.
Oregon Oregon Software Pascal/2. All features implemented.
4 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
Berk Berkeley Pascal with Sun extensions.
Modula Modula-2. Based on Wirth's Programming in Modula-2, 3rd
Edition. Proper setting of the Language parameter is not
optional. Translation will be incomplete in most cases, is
still useful. Structure of local sub-modules is essentially
ignored; like-named identifiers may be confused. The type
WORD is translated as an integer, but the 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. For
example, two files 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 translates the
implementation part into file 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 manual modification may
be required.
Configuration Parameters
The p2c utility is configurable. The defaults are suitable for most
applications, but customizing these parameters will help to get the best
possible translation. Since the output of p2c is intended to be used as
maintainable source code, there are many parameters for describing the
coding style and conventions. Other parameters give hints about the
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 flag for 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 file, 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 numerous or minimal parentheses in expressions, with the
default being a compromise intended to be best for readers with an average
2/94 - Intergraph Corporation 5
p2c(1) CLIX p2c(1)
knowledge of C operator precedences.
Configuration options may also be embedded in the source file in the form
of PASCAL comments, as shown here.
{ShortOpt=0} {AvoidName=fred}
{FuncMacro slope(x,y)=atan2(y,x)*RadDeg}
This example disables automatic shortening of and and or expressions, 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 defined in the program.
White space is generally not allowed in embedded parameters. The equals
sign (=) is required for embedded parameters, though it is optional in
p2crc files. Comments within embedded parameters are delimited by ##.
Numeric parameters may replace = with + or - to increase or decrease 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. The following examples illustrates this:
{VarFiles=0 ## Pass FILE *'s params by value even if VAR}
some declarations
{VarFiles ## Back to original FILE * passing}
This example 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. For example:
{IncludeFrom strings=<p2c/strings.h>}
{*ExportSymbol=pascal_%s}
module strings;
This example records 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 flag. This
list contains 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
6 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
file being scanned for interface text. But HP Pascal allows
several modules per file, so this method will not work. The
ImportAll option overrides the default behavior for the
PASCAL dialect.
AnsiC Selects which dialect of C to use. If set to 1, all
conventions of ANSI C such as prototypes, void * pointers,
and so on, are used. If set to 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. A number of other parameters may be used to
control the individual features if setting AnsiC does not
produce the desired effects.
C++ The p2c utility 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 for
example, uses the declaration int foo;, and all others use
the declaration extern int foo;. The p2c utility
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 UseVExtern is
set to 0, p2c instead declares 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. The p2c utility uses
special capitalized names for these words; these names are
defined as macros in the file p2c.h which all translated
programs include. UseAnyptrMacros may be set to 0 to
disable the use of these macros. Note that the functions of
many of these macros can also be had directly using other
parameters.
For example, UseConsts specifies whether the target language
recognizes the word const in constant declarations. The
default is to use the Const macro instead, so that the 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;
2/94 - Intergraph Corporation 7
p2c(1) CLIX p2c(1)
lowercase char is used when the desired meaning is ``byte,''
not ``character.''
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 static is used for static local variables. Static
can be redefined to be null 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 type definition 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 the
following:
Void foo (int x, int y, Char *z);
Char *bar (void);
However, if only old-style declarations are supported, the
following will result:
Void foo ();
Char *bar ();
By default, p2c uses these macros for all function
declarations, but function definitions are written in old-
style C. The UsePPMacros 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 function. (This is
accomplished by preceding each old-style definition with a
PP-style declaration.) If the code will always be compiled
on systems that support prototyping, set Prototypes=1 or
AnsiC=1 to get true function 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]; this identifier may be
added to the EatNotes list to suppress that message.
8 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
Another useful form is to use a variable name or other
identifier to suppress warnings about that variable. The
strings are a list separated by spaces, and thus may not
contain embedded spaces. For example, to suppress notes
around a section of code, use {EatNotes+[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 set to 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 error messages
appear, do not use this option. By combining this option
with StaticFunctions=0 and editing the result, a pseudo-
modular PASCAL program can be converted 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
there are ``if false'' segments that should be retained in
C, this variable may have to set to ElimDeadCode=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
references like a[i] changed to a[i-2]. If SkipIndices is
set to a value of 2 or higher, this array would instead be
translated to a[11] with the first two elements never used.
This arrangement may generate incorrect code, though, for
some source programs.
FoldConstants PASCAL non-structured constants generally translate to
#define statements in C. When this variable is set to 1,
constants are inserted directly into the code. This may be
turned on or off around specific constant declarations.
Setting FoldConstants to 0 forces p2c to make no assumptions
about the constant's value in generated code, so the
constant can be changed later in the C code without
invalidating the translation. The default is to allow p2c
to use its knowledge of a constant's value, such as by
generating code that assumes the constant is positive.
CharConsts Governs whether single-character string literals in PASCAL
const declarations should be interpreted as characters or
2/94 - Intergraph Corporation 9
p2c(1) CLIX p2c(1)
strings. For example, const a='x'; translates to #define a
'x' if CharConsts=1 (the default), or to #define a "x" if
CharConsts=0.
Note that if p2c does not interpret the declarations
correctly, the generated code will not be wrong, but more
cluttered. For example, if a is written as a character
constant but is to be used as a string, p2c will have to
write character-to-string conversion code each time the
constant is used.
VarStrings In HP Pascal, a parameter of the form var s : string matches
a string variable of any size; a hidden size parameter is
passed which may be accessed by the PASCAL strmax function.
To prevent p2c from creating a hidden size parameter, set
VarString to 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 Controls whether ANSI C function prototypes are used. The
default is according to the AnsiC variable setting. The
Prototypes parameter also controls whether to include
parameter names or just the types in situations where names
are optional. The FullPrototyping parameter allows
prototypes to be generated for declarations but not for
definitions. In using a mixture of prototypes and old-style
definitions, types like short and float will be promoted to
int and double as required by the ANSI standard, unless the
PromoteArgs parameter 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, though with somewhat
different syntaxes. The p2c utility recognizes both
notational styles. Another difference is that HP's
procedure pointers can point to nested procedures, while
Turbo's pointers can point only to global procedures.
In HP Pascal, a procedure pointer must be stored as a
structure containing both a pure C function pointer and a
``static link,'' which is a pointer to the parent
procedure's locals. (The static link is NULL for global
procedures.) This notation can be forced by setting
StaticLinks to 1.
In Turbo, the default (StaticLinks=0) is to use plain C
function pointers with no static links.
10 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
A third option (StaticLinks=2) uses structures with static
links, but assumes the links are always NULL when calling
through a pointer (This is used when compatibility with the
HP format is necessary but the procedures are global.)
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 single 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 type long is used. The s[0]
element contains the number of succeeding array elements
which are in use. Set elements in the range 0..31 are
stored in the s[1] array element, and so on. Sets are
normalized 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 parameters take the form of a printf string
containing a %s sequence where the relevant information is
placed. In the case of the ReturnValueName parameter, the
%s sequence refers to a function 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 assignments to its return value embedded
in the program, so that return statements cannot
conveniently be used. Some parameters (ReturnValueName
included) do not require the %s sequence 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 The p2c utility 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 programs or
routines that are hidden from each other by PASCAL's scoping
rules, but must be declared globally in C. In these
situations, p2c uses the parameter AlternateName1 to
generate an alternative name for the symbol. The default is
to add an underscore to the name. There is also an
AlternateName2 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
sequence, in either order.) If these latter parameters are
2/94 - Intergraph Corporation 11
p2c(1) CLIX p2c(1)
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, that is, no special treatment for
exported symbols. If the Export_Symbol parameter is also
defined, that format is used instead for exported symbols
which contain an underscore character. If the %S sequence
(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 sequence, it is
a format string applied to the names of external functions
or variables. If the value does not contain a %s sequence,
it becomes the name of the next external symbol which is
declared (after which the parameter is cleared).
Synonym Creates a synonym for another PASCAL symbol or keyword. The
format is as follows:
Synonym
old_name = new_name
All occurrences of old_name in the input text 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 the user
to skip over a keyword in a dialect of PASCAL that is not
understood by p2c, or to simulate a keyword or predefined
identifier of a dialect with a similar one that p2c
recognizes. Note that all predefined functions are
available at all times; if a library routine behaves like
Turbo Pascal's getmem procedure, for example, the routine
can be made a synonym for getmem even if the user is not
translating in Turbo mode.
NameOf Defines the name to use in C for a specific symbol. The
parameter 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 as follows:
NameOf
pascal_name = C_name
By default, PASCAL names map directly onto C names with no
12 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
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 procedure. Otherwise, it applies to all
usages of the name.
VarMacro This parameter is analogous to the NameOf parameter, but is
specifically for use with PASCAL variables. The righthand
side can be most any C expression; all references to the
variable are expanded into that C expression. Names used in
the C expression are taken verbatim. There is also a
ConstMacro parameter for translating constants as arbitrary
expressions. Note that the variable 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 expression. For example, if the user asks to replace i
with i+1, the variable i will still be declared but its
value will be shifted accordingly. Note that if i appears
on the lefthand side of an assignment, p2c will use algebra
to ``solve'' for the value of i.
In all cases where p2c parses C expressions, all C operators
are recognized except compound assignments like `+='.
(Increment and decrement operators are allowed.) All
variable 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
introduced; 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
definition 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 the macro is used in situations where the exact
type of the expression must be known (say, as the argument
to a writeln command).
FieldMacro In this parameter, 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 ``dotted.'' The following is an
example definition.
FieldMacro Rect.topLeft = topLeft(Rect)
This translates a[i].topLeft into topLeft(a[i]), where a is
2/94 - Intergraph Corporation 13
p2c(1) CLIX p2c(1)
an array of Rect.
FuncMacro In this parameter, 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 expression on the righthand side. The following is an
example.
FuncMacro PtInRect(p,r) = PtInRect(p,&r)
This causes the second argument of PtInRect to be passed by
reference, even though the declaration says it is not. If
the function is actually defined in the program or module
being translated, the FuncMacro parameter will not affect
the definition but it will affect all calls to the function
elsewhere in the module. The FuncMacros parameter can also
be applied to predefined or never-defined functions.
IncludeFrom 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 generated for the
module.
ImportFrom 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 sequence, which expands to the name of the
module. The default path looks for %s.pas and %s.text in
the current directory, then for /usr/lib/p2c/%s.imp (where
/usr/lib/p2c is the p2c home directory).
StructFunction
Lists functions which follow the p2c semantics for
structure-valued functions (functions returning arrays,
sets, and strings, and structures 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 function strcpy is an
example of this concept. The sprintf function 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 the optimizer of
p2c will know how to manipulate them.
14 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
StrlapFunction
Functions on this parameter's list are structured functions
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.
Deterministic Functions on this parameter's 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. The p2c utility can make use of
this knowledge when optimizing code for efficiency 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 parameter's 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 automatically into calls to a C
writeln() function, rather than being translated into
equivalent printf calls. The built-in translation is also
suppressed if the function has a FuncMacro parameter.
BufferedFile The p2c utility normally assumes binary files will use the
read/write and not the 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 the
BufferedFile parameter's list to force p2c to allocate
buffers for them; do this if a warning message appears
stating that it is necessary to do this. Set the
BufferedFile parameter equal to 1 to buffer all files, in
which case the UnBufferedFile parameter allows the user to
force certain files not to have buffers.
StructFiles If p2c still cannot translate the file operations correctly,
set the StructFiles parameter equal to 1 to cause PASCAL
files to translate into structures which include the usual C
FILE pointer, as well as file buffer and filename fields.
While the resulting code does not look as much like native
C, the file structures will allow p2c to do a correct
translation in many more cases.
CheckFileEOF Normally, only file-open operations are checked for errors.
Additional error checking, such as read-past-end-of-file,
can be enabled with parameters like CheckFileEOF. These
checks can make the code very difficult to read. If I/O
checking is enabled by the program ("$iocheck on$" in HP
Pascal, or {$I+} in Turbo; this is always the default
2/94 - Intergraph Corporation 15
p2c(1) CLIX p2c(1)
state), these checks will generate fatal errors unless
enclosed in an HP Pascal try - recover construct. If I/O
checking is disabled, these will cause the global variable
P_ioresult to be set zero or nonzero according to the
outcome. The default for most of these options is to check
only when I/O checking is disabled.
Issues
Integer size.
The p2c utility normally generates code to work with either 16 or 32
bit integers. If the C integers will be 16 or 32 bits, set the
IntSize parameter 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 prototypes are available. To disable int/long
casting, set CastLongArgs=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 characters.
PASCAL characters are normally interpreted as unsigned; this is
controlled by the UnsignedChar variable. The default is either, so
that C's native char type may be used even if its sign is unknown.
Code that uses characters outside of the range 0-127 may need a
different setting. Alternatively, the types {SIGNED} char and
{UNSIGNED} char may be used. 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. (The 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.
The p2c utility understands the following predefined PASCAL type
names:
integer signed integers depending on the Integer16 parameter
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
16 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
c_uint unsigned native C integers
sbyte signed 8-bit integers
byte unsigned 8-bit integers
real floating-point numbers depending on the DoubleReals
parameter setting
single single-precision floats
longreal
double
extended double-precision floats
pointer
anyptr generic pointers (assignment-compatible with any pointer
type)
string generic string of length StringDefault (normally 255)
In addition, the usual PASCAL types of char, boolean, and text are
also understood. (If the user's version of PASCAL uses different
names for these concepts, the Synonym parameter may be useful.)
Embedded code.
It is possible to write a PASCAL comment containing C code to be
embedded into the output. See the descriptions of the EmbedComment
parameter and its relatives in the system p2crc file. These
techniques are helpful to do repeated translations of code that is
still being maintained in PASCAL.
Comments and blank lines.
The p2c utility collects the comments in a procedure into a list. All
comments and statements are stamped with serial numbers which are used
to reattach comments 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 the usage of
blank lines. The user can disable comments with the EatComments
parameter or disable their being attached to code with the
SpitComments parameter.
Indentation.
The p2c utility has a number of parameters to govern indentation 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
2/94 - Intergraph Corporation 17
p2c(1) CLIX p2c(1)
code it is indenting. Indentation works by applying ``indentation
deltas,'' which are either absolute numbers (which override the
previous indentation), or signed relative numbers (which augment the
previous indentation). A delta of +0 specifies no change in
indentation. All of the indentation options are described in the
standard p2crc file.
Line breaking.
The p2c utility uses an algorithm similar to the TeX typesetter's
paragraph formatter for breaking long statements into multiple lines.
A ``penalty'' is assigned to various 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 penalties for overrunning the desired maximum line length
(default 78 columns), an infinite penalty for overrunning the absolute
maximum line length (default 90), and progressively greater penalties
for breaking at operators deeply nested in expressions. Parameters
such as OpBreakPenalty control the relative weights of various
choices. The BreakArith parameter and its neighbors control whether
the operator at a line break should be placed at the end of the
previous line or at the beginning of the next. To prevent any
oversize lines, set the MaxLineWidth paramenter to 78.
Unlike TeX, the line breaker of p2c must actually try all possible
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 rounded up to zero. This allows p2c to
eliminate obviously undesirable alternatives in advance. The
MaxLineBreakTries parameter (its default is 5000) controls how many
alternatives to try.
PASCAL_MAIN.
The p2c utility 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, because in both HP Pascal and Turbo Pascal these
are accessed as global variables. To disable this feature, define the
ArgCName parameter to be argc, the ArgVName parameter to be argv, and
MainName (normally PASCAL_MAIN) to be blank. This will work if argc
and argv are never accessed outside of the main program.
EXAMPLES
1. The following example converts the contents of the Pascal module
example.pas to a C module. The resulting C module will be named
example.c.
p2c example.pas
2. This example converts all files with a .p extension in the current
directory, generating corresponding .c files which contain C code. A
18 Intergraph Corporation - 2/94
p2c(1) CLIX p2c(1)
file named .log is created and contains infomation about the
conversion.
f2c -V *.f
FILES
file.xxx PASCAL source files.
file.c Resulting C source file.
module.h Resulting C header file.
p2crc Local configuration file.
.p2crc Alternate local configuration file.
/usr/lib/p2c/p2crc System-wide configuration file.
/usr/lib/p2c/system.imp Declarations for predefined functions.
/usr/lib/p2c/system.m2 Analogous declarations for Modula-2.
/usr/lib/p2c/*.imp Interface text for standard modules.
/usr/include/p2c/p2c.h Header file for translated programs.
/usr/lib/libp2c.a Run-time library.
CAUTIONS
Certain kinds of conformant array parameters (including multi-dimensional
conformant arrays) produce code that declares variable-length arrays in C.
Only a few C compilers, 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
command 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 commands and try - recover statements are each implemented,
but may conflict if both are used at once. Non-local GOTO commands are
fairly careful about closing files that go out of scope, but may fail to
do so in the presence of recursion.
Arrays containing files are not initialized to NULL as other files are.
2/94 - Intergraph Corporation 19
p2c(1) CLIX p2c(1)
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 happens, 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 will be optimized 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 computational 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 supported. 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 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 solution is to use copy in the PASCAL source to truncate the strings
explicitly.
EXIT VALUES
The p2c command exits with a value of 0 if successful. Otherwise, it exits
with a value of 1.
RELATED INFORMATION
Commands: acc(1), cc(1), pc(1), ld(1)
20 Intergraph Corporation - 2/94