31 July 2009

Going crazy in C

I have an application, written (by someone else) in C, running on SCO OpenServer 5 Unix, which I need to convince that Linux is a better thing to do — amongst other things, it is much easier to find people to maintain such a system, plus significantly easier to find matching hardware with drivers. Plus when SCO finally bites the dust, major support questions arise.

It is written, mostly, in very old-style C. No function protoypes at all.

It was compiled, it seems, with an ancient version of gcc, which should make things easier. The compile shell-scripts are a bit cumbersome, don’t refer to any particular breed of shell, have about zero error checking, use obsolete/defective options. Never mind.

Some definition files were copied in wholesale from the SCO Unix system files. Never mind about copyrights. Erase. We’ll use modern, intrinsic-to-system ones.

Terminal (text screen) handling is absolutely hard-wired into the code [printf("\33[%d;%dH", row, col);] for a VT-100 type terminal (but that at least is a bit modularised so can be readily converted to a more modern, portable style).

Some of the system definitions have been over-ridden by hand. Poorly. For example, NULL is #defined to be (0), in contrast to a void pointer to nothing.

C source files are canonically “whatever.c”; C include files (definitions) are supposed to be “whatever.h”; the binaries (compiled programs) are supposed to be just “whatever”... but both binaries & includes are quite cryptically named (what would you make of “dr3” or “clx?”) as just “whatever”. Some of the include files are prefixed “i_” — WTF?

Calling conventions are terribly arbitrary. They modify the supplied variables instead of returning a new one. They return the address of a static (one copy local to each procedure) variable instead of writing into a supplied one or creating a new one. A row number is supplied directly as an int, so is a column number but in one procedure it is supplied as a reference (indirect) to the number. No explanation. No comments within the code at all beyond a general/vague mention at the start of some files.

There are some unquestionable bugs; for example, one procedure prompts for & reads an integer from the keyboard, accepting a double * as an argument. In several places, it is passed an int *. Some things may mysteriously commence working after this compiles. (-:

The fact that it is working at all is a freakin’ miracle.

In amending it so that it will compile successfully on a modern C compiler, I am doing surgery which makes up many of those lacks, & emplaces default specifications & checks which will point out any obvious errors.


Anonymous said...

Pass by reference, especially for constants ala

int one = 1;
function (&one);

sounds a lot like you're calling, or have called in the past, Fortran functions (the Fortran ABI only handles pass by reference).

To be honest, I'd avoid changing your code too much, it's a great way to introduce subtle bugs (especially if Fortran is involved, Fortran enumerates arrays from 1, not 0)

Modern gcc still supports K&R style declarations, etc. So your source should still be compilable. Linux still supports VT100 terminal controls (set TERM=vt100).

Ideally, your only problem will be the use of library calls that aren't available on Linux, but for a terminal program it's usually just a matter of working out what #define turns that call on (assuming you're not touching threading, ioctls, IPv6, or a bunch of other areas).

Leon RJ Brooks said...

ForTran originally didn’s allow for recursion, either, due to having initially been written on a PDP-8. (-:

This is C (I have in the past used ForTran & even RatFor), but under gcc (later than the version used on SCO Unix) a straight compilation is warning city.

Gazing through many hundreds of warnings is a bit overwhelming, & I am planning for the future a bit, so if I get run down by the proverbial bus, the next programmer starts with at least an even chance...

AFAICT, library usage is very middle-of-the-road (the #includes physically copied into a local directory featured nothing bizarre).

Thanks for your comments...

Jenny said...

great post