ANSI C to PCC C Translator
topcc
SYNOPSIS
topcc [options] [infile [outfile]]
DESCRIPTION
The program topcc helps to translate (suitable) C programs
and headers from the ANSI dialect of C to the PCC dialect
of C, primarily by re-writing top-level function proto-
types (whether declarations or definitions). Translation
is done prior to the C preprocessing phase of any follow-
ing compilation and is oblivious of preprocessor flag set-
tings. Clearly, then, topcc cannot help to translate
sources in which function prototypes have been obscured
by, for example, preprocessor macros. The translation
performed is limited and other differences between the
ANSI and PCC dialects must be dealt with in the source
after or (preferably) before translation.
OPTIONS
infile and outfile default to stdin and stdout respec-
tively. The options are as follows:
-d describe what the program does
-c don't remove keyword 'const'
-e don't remove '#error...'
-p don't remove '#pragma...'
-s don't remove keyword 'signed'
-t don't remove 2nd argument to va_start()
-v don't remove keyword 'volatile'
-l don't add #line directives
Translation details
Primarily, topcc re-writes top-level function protoypes,
whether definitions or declarations. Top-level function
declarations are re-written with their argument lists
enclosed in /* and */. For example, declarations like:
type foo(argument-list);
are rewritten as:
type foo(/* argument-list */);
Any comment tokens /* or */ in the original argument list
are removed.
Function definition prototypes are re-written the pcc way.
For example, definitions like:
type foo(a1, a2)
type1 a1;
type2 a2;
{...}
and:
type foo(void)
{...
is rewritten as:
type foo()
{...
A '...' in a function definition is replaced by '<int
va_alist>', and the second argument to calls of the
va_start macro is removed, (varargs.h defines va_start as
a macro taking 1 argument; stdarg.h adds a second argu-
ment).
ANSI keywords const, signed, and volatile are removed
(with warnings), and enums are warned of (stricter usage
under pcc). Type '<void *>' is converted to '<VoidStar>',
which should be typedef'd to ' char *' to be compatible
with pcc.
ANSI C's unsigned and unsigned long constants are rewrit-
ten using the typecasts (unsigned) and (unsigned long).
(For example, 300ul becomes (unsigned long)300L).
After rewrites that change the number of lines in the
file, #line directives are included that re-synchronise
line numbering. These quote the source filename, so that
debugging tools then refer to the ANSI form of sources.
Issues with topcc
topcc takes no account of the setting of conditional com-
pilation options. This is quite deliberate: it converts
all conditionally compilable variants in parallel.
A price to be paid is that braces must be nested reason-
ably within conditionally compilable sections, or topcc
may lose track of the brace nesting depth, which is used
to determine whether it is within, or between top-level
definitions and declarations.
In principle, tracking brace nesting depth oblivious of
preprocessing, is impossible. In practice, topcc uses
heuristics to match conditionally compiled braces, usually
successfully. If topcc finds that it is lost it complains
of "mis-matched, conditionally included braces".
A second, niggling restriction is that topcc cannot con-
catenate adjacent string literals. In practice, all impor-
tant uses of ANSI-style implicit concatenation involve
some mix of literals and preprocessor variables (of which
ily be eliminated from the input program by the user.
The one disaster for topcc is to find an extra closing
brace and to start processing text prematurely as if it
were at the top level. This leads to damage to function
calls and macro invocations. In general it is a good idea
to compare the output of topcc with its input (using a
file difference utility), as a check that changes have
been reasonably localised to function headers and declara-
tions. If necessary, most of topcc's other translitera-
tions can be inhibited (see "Options") to make these prin-
cipal changes more visible.