もっとも便利な難読化
xxxxxxxxxx
#define iv 4
#define v ;(void
#define XI(xi)int xi[iv*'V'];
#define L(c,l,i)c(){d(l);m(i);}
#include <stdio.h>
int*cc,c,i,ix='\t',exit(),X='\n'*'\d';XI(VI)XI(xi)extern(*vi[])(),(*
signal())();char*V,cm,D['x'],M='\n',I,*gets();L(MV,V,(c+='d',ix))m(x){v)
signal(X/'I',vi[x]);}d(x)char*x;{v)write(i,x,i);}L(MC,V,M+I)xv(){c>=i?m(
c/M/M+M):(d(&M),m(cm));}L(mi,V+cm,M)L(md,V,M)MM(){c=c*M%X;V-=cm;m(ix);}
LXX(){gets(D)||(vi[iv])();c=atoi(D);while(c>=X){c-=X;d("m");}V="ivxlcdm"
+iv;m(ix);}LV(){c-=c;while((i=cc[*D=getchar()])>-I)i?(c?(c<i&&l(-c-c,
"%d"),l(i,"+%d")):l(i,"(%d")):(c&&l(M,")"),l(*D,"%c")),c=i;c&&l(X,")"),l
(-i,"%c");m(iv-!(i&I));}L(ml,V,'\f')li(){m(cm+!isatty(i=I));}ii(){m(c=cm
= ++I)v)pipe(VI);cc=xi+cm++;for(V="jWYmDEnX";*V;V++)xi[*V^' ']=c,xi[*V++]
=c,c*=M,xi[*V^' ']=xi[*V]=c>>I;cc[-I]-=ix v)close(*VI);cc[M]-=M;}main(){
(*vi)();for(;v)write(VI[I],V,M));}l(xl,lx)char*lx;{v)printf(lx,xl)v)
fflush(stdout);}L(xx,V+I,(c-=X/cm,ix))int(*vi[])()={ii,li,LXX,LV,exit,l,
d,l,d,xv,MM,md,MC,ml,MV,xx,xx,xx,xx,MV,mi};
引用元:https://www.ioccc.org/1987/wall/wall.c
審査員・作者による説明:https://www.ioccc.org/1987/wall/hint.html
ローマ数字と10進数の相互変換ツール。 電卓コマンドのbcと組み合わせることで、次のようにローマ数字電卓として使える。
$ gcc -o wall wall.c
$ echo "xi * xi" | ./wall | bc | ./wall
cxxi
xi
はローマ数字で11、cxxi
はローマ数字で121。
このプログラムは出力がTTYのとき、10進数→ローマ数字の変換をする。
$ echo 1 | ./wall
i
$ echo 2 | ./wall
ii
$ echo 3 | ./wall
iii
$ echo 4 | ./wall
iv
$ echo 5 | ./wall
v
出力がTTYではないとき、ローマ数字→10進数の式の変換をする。
$ echo i | ./wall | cat
(1)
$ echo ii | ./wall | cat
(1+1)
$ echo iii | ./wall | cat
(1+1+1)
$ echo iv | ./wall | cat
(1-2+5)
$ echo v | ./wall | cat
(5)
./wall | bc | ./wall
とすると、ローマ数字での電卓のような挙動になる。
出力がTTYかどうかはisattyで判定できるが、単にこれで遊ぶだけでなく、ユースケースと結合しているところが良い。
hint.textには「直接呼び出されていない関数ポインタがあるが、どう呼び出されているかわかる?」と書いてある。 SIGPIPEのシグナルハンドラに関数ポインタを設定し、読み側をcloseしたパイプを作ってwriteし、わざとシグナルを起こすことで関数を呼び出している。 システムプログラミングの悪用のさきがけと言える?