Version 0 of C code generators

Updated 2001-01-02 18:07:10

Richard Suchenwirth - A couple of holidays without work or family gave me the opportunity to install the Cygwin suite (gcc and lotsa Unix tools) on my W95/P200 box at home, and play with C. I soon noticed that some monotonous tasks could be better delegated to a program, and that would of course be in Tcl. So in a few days, I wrote three code generators with the following features:

  • All take some specifications from the user (C codelets) and use these, together with some constant text, to produce a complete C source file in a (temporary?) directory, and mostly call the compiler to produce an executable, and generate a Tcl "wrapper proc" that allows to call the new program from Tcl.
  • cproc (Outsourcing C helpers) looks almost like a Tcl proc - except that the body is in C... It makes a tiny main around the cbody, and the wrapper just says exec /path/name $args
 cproc strrev {s} {
        /* Revert a string */
        char *cp = s+strlen(s);
        while(cp > s) putchar(*--cp);
  }
  strrev "A man, a plan, a canal: Panama" ;#=> amanaP :lanac a ,nalp a ,nam A
  • cserver (Pipe servers in C from Tcl) allows to specify a more complex system with a number of "methods", including (optional) "constructors" and "destructors", that maintains state between calls (the example on that page is for a bitmap server that allows setting, unsetting, getting bits in a possibly large, densely packed array - one bit per bit ;-) . The C program is started as a bidirectional pipe and communicated with via gets and puts (again wrapped into a Tcl proc)
  • cxtend (Extending Tcl in C from Tcl) was the last in the series and the most fun: it produces an extended wish or tclsh that contains additional C functions - straight from the examples in Brent Welch's book. I only have to admit that this was late on New Years' day, and I could only get it to make a decent C source, but calling gcc from Tcl brought lib path specification problems that I haven't solved yet. The generated source linked flawlessly from inside bash, and the call there isn't that difficult:
 gcc mywish.c -o mywish -s -Wall -ltcl80 -ltk80

The -s switch strips all symbols from the executable, bringing it down from over 300k to just 3.5k - pretty amazing for a custom wish... Compilation time is 2..3 sec, starting up an executable from Tcl takes ~90 msec.

Here's how a wish extended with strrev (in a different implementation, swapping chars in place this time) is specified:

 cxtend -Tk 1 -name mywish -cc gcc -ccflags {-s -Wall} -cmd {
    strrev {char* s} {
            char *cp0, *cp1, t;
            for(cp0=s, cp1=s+strlen(s)-1; cp1>cp0; cp0++, cp1--) {
                    t=*cp0; *cp0=*cp1; *cp1=t;
            }
    } {char* s}
 }

Arts and crafts of Tcl-Tk programming