The ANSI C to PCC C Translator (topcc)
--------------------------------------


About topcc
...........

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 prototypes (whether declarations or definitions).

Translation is done prior to the C preprocessing phase of  any following 
compilation and is oblivious of preprocessor flag settings. 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.


Command Line Options
....................

 The command format for <topcc> is:

    topcc <options> [<infile> [<outfile>]]

<infile> and <outfile> default to <stdin> and <stdout> respectively.

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(type1 a1, type2 a2) {...}

are rewritten as:

    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 
argument).

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 rewritten 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 compilation options. 
This is quite deliberate: it converts all conditionally compilable variants in 
parallel.

A price to be paid is that braces must be nested reasonably 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 concatenate adjacent 
string literals. In practice, all important uses of ANSI-style implicit 
concatenation involve some mix of literals and preprocessor variables (of which 
<topcc> is oblivious). <topcc> could easily concatenate adjacent string 
literals - but then these can just as easily 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 
declarations. If necessary, most of <topcc>'s other transliterations can be 
inhibited (see "<Command Line Options>") to make these 
principal changes more visible.

 

