blocks

It can be a humbling experience to revist old code. And I’m not talking about the dynamic simulation stuff, which is obviously a hack on top of a pile of hacks. No, this week I returned to my old pal ansiconv, the program that converts text files to images of the text file, rendering it as if you had ANSI.SYS loaded and typed TYPE KOOL.ANS at the cee colon backslash prompt. This program had achieved a modicum of success in its heyday but lately various alternatives have popped up written in languages such as C# and PHP. Being the C bigot that I am (one who writes Java for a living), I thought I would update this one great program, slap a PHP module interface on it, and unleash it upon the world.

Stylistically, the program was a mess: 2-space indentations, curly braces on the same line as the function definition, spaces (( after the )) parentheses, seemingly no rhyme or reason to naming of typedefs, and, horror of horrors, extensive use of studlyCaps. Oh, how I had strayed from the Unix flock. Even worse, I found an obvious bug in TAB character handling; a memleak or two in the error paths; infrequent to non-existent use of the static keyword; global variables aplenty, in one place documented “to ease calling into functions” (had I some phobia of struct?); and even a case of a function returning a pointer to a global variable. Take that ctime(3). All this in the space of some 2 KLOC.

The good news is, a few hours with vim and the codebase is much better: no more globals, no more leaks, no more uglyNamingConventions. I changed the build to create a library with a single entry point, which the ansiconv binary uses to work its magic. All the CGI support code was ripped out, and I wrote a small PHP module that utilizes libansiconv to do stuff on the web. Finally, I borrowed an enhancement from our friends who wrote the newer ansi converters, which is to emit 4 bits-per-pixel images when we can to reduce their size.

The other ansi converters are more full-featured, but C still wins in speed, hands down. A rough test shows ansiconv converts around 2500 ansis/minute, compared with 270 ansis/min for another popular PHP converter (both tests include the overhead of starting the PHP interpreter).

If you have no freakin clue what this post is on about, visit Doug’s great page, 16c.

3 Replies to “blocks”

  1. Well, certainly it’s a matter of taste. And once upon a time I thought all of these ideas were wonderful. Apparently, at the time I had no taste and was stupid.

    Before, I would write something like:

    int crap;
    
    void frobTheBaz( int foo, int barQuux ) {
      xyzzy( foo, barQuux, barQuux + foo );
      crap = 2;
    }
    

    Which is horrible in C. Now, I tend more towards:

    static void frob_the_baz(context_t *x, int foo, int bar_quux)
    {
        xyzzy(foo, bar_quux, bar_quux + foo);
        x->crap = 2;
    }
    

    My Java code stillHasHumpsThough. One must stick with the language’s idioms.

    (static is used to mark a C function private to the module in which it is declared so that it doesn’t clutter the namespace.)

  2. Okay, ’cause I totally agree with you about the naming thing. Once upon a time in the ice channel Epoch was like youMustNameFunctionsLikeThis, youMUST, MUST! and everyone will love you. But those are so hard to read unless they are really short. Now I shall abuse my underscore more… must learn more new stuff…

Comments are closed.