Design Goals ------------ - Must run independent of signal semantics, i.e. run on BSD systems where handlers remain installed as well as on System V systems where handlers are zapped and must be reinstalled. - Conciseness: use write() instead of putchar/fflush Why I think this is obfuscated ------------------------------ -The source is lint clean -It is even lclint clean. -Macro definitions, code and #includes appear intermixed. -The program is short: a file scope variable definition, a one line function definition and a main() function consisting only of a variable initialization, a loop statement and a return expression. -I have tried to avoid obfuscation by eliminating arbitrary constants other than 0 and 1. (I failed, there is a 2, 6 and 10 remaining -- the exceptions to the rule.) -Ever seen a 'do for ... while' loop? -I avoided 'int' like the plague. Instead I used storage class specifiers (register, auto) to get implicit int. Where this is impossible, like in the 'int main' declaration I have int split across two lines. All indent programs I use insert space at the beginning of the continuation line and thereby introduce a syntax error. -occasional use of trigraphs, not too excessive -occasional use of digraphs (each is used at least once) -static volatile sig_atomic_t, heavy wizardry! -Even if you know how the program works, you just can't predict the output. -Chained use of token pasting operators ## with shuffled arguments -Use of stringizing operator # -So you think you can't assign to __LINE__ and __FILE__? Not so. The #line preprocessor directive does the trick. But saying '#line 10 "01\n"' is a little lame and I came up with '??=line 10 ONE(O(1,1,2,6,0,6))' -__LINE__ is used as the signal number argument to signal(). If indenting or other editing changes the number of lines the program is likely to be killed after one second... Thanks to POSIX for specifying SIGALRM as 14. You're SOL if your system does not conform. Get a real OS. -All strings (or characters) needed are crammed into __FILE__ using octal notation and then extracted using pointer + offset notation. -The O macro looks quite similar to my statement of account... -Use of a # (null) preprocessor directive (hidden as a %: digraph) Delete this line and prepare for a core dump. -Identifiers reused with different capitalization: one, One, ONE, zero, Zero -Carefully commented source Portability ----------- The source should compile and run on any POSIX conforming implementation. If your C compiler is a little outdated and doesn't understand trigraphs and digraphs, preprocess the source with this little perl script. It reads stdin and writes to stdout. #!/usr/bin/perl -pw # # subgraph - substitute ISO C 9899:1990 digraphs and trigraphs # Caveat: simpleminded -- substitutes digraphs in strings. # # digraphs s/<:/[/g; s/:>/]/g; s/<%/{/g; s/%>/}/g; s/%:/#/g; # trigraphs s/\?\?=/#/g; s/\?\?\(/[/g; s,\?\?/,\\,g; s/\?\?\)/]/g; s/\?\?'/^/g; s/\?\?/}/g; s/\?\?-/~/g; The last character printed is '\012' which is a newline on systems with ascii as the execution character set. If your system doesn't use ascii the output may not be newline terminated. Change the second and third arg to the O macro call (these are used to build the second and third octal digit) in the #line directive to suit your needs.