NAME
ansitize – translate Plan 9 C to ANSI C

SYNOPSIS
ansitize [ –c conf ] [ –I dir ]... [ –p preload ]... [ file ]

DESCRIPTION
Ansitize translates programs written in the Plan 9 C dialect into standard ANSI C programs, preserving comments and formatting.

The options are:
c conf
Read configuration information from the file conf. The format of the configuration file is discussed below.
I dirAdd dir to the list of directories searched for #include files. /386/include and /sys/include are added to the list after processing the –I options.
p preload
Before processing file, process the file preload, but do not print its translation. This option is useful mainly for translating header files. See the examples below.

Ansitize translates many constructs from Plan 9 C, described below. It does not translate types or other features present in the Plan 9 C environment when those features can be provided by appropriate program context. For example, ansitize removes long character constants and strings but still assumes that Rune is a defined type.

Ansitize translates the following constructs.

anonymous structures or unions
Plan 9 C allows anonymous structures and unions. Ansitize gives these explicit names and translates references to reflect the new names. If a struct (or union) name is declared anonymously, ansitize uses _name in the new declaration. Otherwise, unions are named u, u2, etc., and structures are named _1, _2, etc. For example, by default ansitize translates the first structure definition into the second:
struct A {           struct A {           struct A {
union {              union {              union {
int x;               int x;               int x;
int y;               int y;               int y;
};                   } u;                 } au;
struct B;            struct B _B;          struct B b;
};                   };                   };

These default names can be overridden by a configuration line rename old new, where old is a single name or is tag.name, which restricts the renaming to the elements of struct (or union) tag. For example, using a configuration:
rename A.u au
rename _B b
(or rename A._b b)

would produce the third structure definition above.

anonymous structure promotions
Plan 9 C allows pointers to structures with anonymous elements to be passed to functions expecting pointers to the anonymous elements. For example, given the structure definition above, if a struct A *a is passed to a function expecting a struct B*, the C compiler instead passes a pointer to the B inside the A. Ansitize does the same transformation, in this case rewriting f(a) to f(&a–>b). The same conversion applies to simple assignment of struct A* to struct B*.

anonymous function parameters
Plan 9 C does not require unused function parameters to be named in the function definition. Ansitize names these parameters _1, _2, etc. For example, ansitize rewrites
void main(int, char**) { }

into
void main(int _1, char** _2) { }

structure displays
Plan 9 C allows casted initializer lists as structure values, as in (Point){1,2}. Ansitize can rewrite these into function calls, as in pt(1,2), but only does so if directed by a configuration line reconstruct struct–name function–name, as in reconstruct Point pt.

Unicode identifiers
Ansitize rewrites identifiers containing Unicode characters into ASCII equivalents, replacing Greek letters with their names and other Unicode characters with _xxxx, where xxxx is the hexadecimal value of the character.

long character constants
Ansitize rewrites long character constants like L'\n', L'a', or L'ÿ' into equivalent expressions like '\n', 'a', or (Rune)0x00FF.

long string constants
Ansitize replaces Rune string constants like L"abc" with references to statically declared arrays with names derived from the string data. It recognizes the special case where a Rune string is being used to initialize a Rune array and replaces the string in that case with an array. For example, ansitize rewrites the first program into the second:
Rune L_abc[] = {'a','b','c',0};
Rune *x    = L"abc";           Rune *x    = L_abc;
Rune y[] = L"def";           Rune y[] = {'d','e','f',0};

#pragma lines
Ansitize places #pragma lines inside /* */ comments. #pragma varargck lines are handled separately and are placed inside #ifdef VARARGCK / #endif pairs. (At least one compiler under development for Unix recognizes these #pragmas.)

integer/pointer casts
Some overeager Unix compilers complain about casts from integer to pointer, even when the pointer is as wide as or wider than the integer. Ansitize inserts an extra (uintptr) cast to silence these warnings: p=(void*)i becomes p=(void*)(uintptr)i.
<

ctype.h> casts
The macros defined in Plan 9's <ctype.h> cast their arguments to uchar so that either signed or unsigned character arguments can be passed to them. Unix's <ctype.h> requires the use of unsigned character arguments. Ansitize adds casts as necessary to the arguments of isalpha, isdigit, toupper, etc.

EXAMPLES
A configuration file for translating the regexp(2) library:
rename Resub.u s
rename Resub.u1 e
rename Reinst.u u1
rename Reinst.u1 u2

Translate the source files:
cd /sys/src/libregexp
for(i in *.c)
ansitize –c conf $i >$i.ansi

Translate the header file, reading <u.h> and <libc.h> first for context:
cd /sys/include
ansitize –p /386/include/u.h –p libc.h regexp.h >regexp.h.ansi

SOURCE
/sys/src/cmd/ansitize

SEE ALSO
8c(1), fortune(1)

Rob Pike, ``How to use the Plan 9 C Compiler''

BUGS
Ansitize stops short of full checking of the input program. Test that they compile using 8c(1) before running ansitize.

Ansitize ignores #ifdef and #define, limiting the kinds of macros that can be used. In particular, macros that introduce new control flow constructs will confuse the parser. (The parser contains extra grammar productions to accommodate the arg(2) macros and va_arg.)

Copyright © 2025 Plan 9 Foundation