Merge pull request #70 from xexyl/1989-westley
Get 1989/westley to compile with clang
This commit is contained in:
4 files changed
+116
-78
No files matched your search
@@ -1 +1,9 @@
|
|||||||
|
ver0
|
||||||
|
ver0.c
|
||||||
|
ver1
|
||||||
|
ver1.c
|
||||||
|
ver2
|
||||||
|
ver2.c
|
||||||
|
ver3
|
||||||
|
ver3.c
|
||||||
westley
|
westley
|
||||||
@@ -94,7 +94,7 @@ ARCH=
|
|||||||
# Defines that are needed to compile
|
# Defines that are needed to compile
|
||||||
#
|
#
|
||||||
#CDEFINE=
|
#CDEFINE=
|
||||||
CDEFINE= -Dtrgpune=putchar
|
CDEFINE= -Dtrgpune=putchar -Dpune=char -Dvag=int
|
||||||
|
|
||||||
# Include files that are needed to compile
|
# Include files that are needed to compile
|
||||||
#
|
#
|
||||||
|
|||||||
+104
-75
@@ -1,4 +1,4 @@
|
|||||||
Most algorithms in one program:
|
# Most algorithms in one program:
|
||||||
|
|
||||||
Merlyn LeRoy (Brian Westley)
|
Merlyn LeRoy (Brian Westley)
|
||||||
Starfire Consulting
|
Starfire Consulting
|
||||||
@@ -7,117 +7,146 @@ Most algorithms in one program:
|
|||||||
55104
|
55104
|
||||||
USA
|
USA
|
||||||
|
|
||||||
Judges notes:
|
## To build:
|
||||||
|
|
||||||
There is a secret way to get ONE of the versions to print out
|
make all
|
||||||
"Hello, world!\n". Can you find how to do it?
|
|
||||||
|
|
||||||
Try the following commands:
|
|
||||||
|
|
||||||
westley < westley.c > ver0.c
|
NOTE: [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) was able to get
|
||||||
westley 1 < westley.c > ver1.c
|
this to partially work with clang; clang requires that the second, third and
|
||||||
westley 1 2 < westley.c > ver2.c
|
fourth args to main() be `char **`. Only `westley.c` and `ver0.c` (see below) will
|
||||||
westley 1 2 3 < westley.c > ver3.c
|
compile with clang. It's possible to get ver1.c to compile too but this causes
|
||||||
|
problems with generating the output of the remaining files so we have opted, at
|
||||||
|
least for now, to not do that, as it does not have to output just source code.
|
||||||
|
He notes that the original source code sometimes segfaults with `ver2` which
|
||||||
|
also happens with the fix but it'll only compile with a compiler that
|
||||||
|
does not require the second, third and fourth args of main() to be a `char **`.
|
||||||
|
Thank you Cody for your help!
|
||||||
|
|
||||||
Try compiling and running the 4 resulting programs.
|
|
||||||
|
|
||||||
Selected notes from the author:
|
## Try:
|
||||||
|
|
||||||
This is a filter. If it is run with no arguments, it copies
|
|
||||||
stdin to stdout. With one argument, it ROT13's stdin to
|
|
||||||
stdout. With two arguments, it reverses stdin to stdout. With
|
|
||||||
three arguments, it does both. It requires the ASCII character
|
|
||||||
set, with all characters being in 0..255, and EOF must be -1.
|
|
||||||
Also requires two's complement (I think).
|
|
||||||
|
|
||||||
The source code will run if ROT13'ed and/or reversed, using a
|
./westley < westley.c > ver0.c
|
||||||
different algorithm for each version (hereafter referred to as
|
./westley 1 < westley.c > ver1.c
|
||||||
ver0 (original), ver1 (ROT13), ver2 (reversed), and ver3
|
./westley 1 2 < westley.c > ver2.c
|
||||||
(ROT13 and reversed)).
|
./westley 1 2 3 < westley.c > ver3.c
|
||||||
|
|
||||||
When compiling these versions, one needs to define 'trgpune'
|
|
||||||
in the compile line. Example:
|
Try compiling and running the 4 resulting programs. To compile try:
|
||||||
|
|
||||||
|
|
||||||
|
make ver0
|
||||||
|
make ver1
|
||||||
|
make ver2
|
||||||
|
make ver3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Judges notes:
|
||||||
|
|
||||||
|
|
||||||
|
There is a secret way to get ONE of the versions to print out
|
||||||
|
"Hello, world!\n". Can you find how to do it?
|
||||||
|
|
||||||
|
|
||||||
|
## Selected notes from the author:
|
||||||
|
|
||||||
|
This is a filter. If it is run with no arguments, it copies
|
||||||
|
stdin to stdout. With one argument, it ROT13's stdin to
|
||||||
|
stdout. With two arguments, it reverses stdin to stdout. With
|
||||||
|
three arguments, it does both. It requires the ASCII character
|
||||||
|
set, with all characters being in 0..255, and EOF must be -1.
|
||||||
|
Also requires two's complement (I think).
|
||||||
|
|
||||||
|
The source code will run if ROT13'ed and/or reversed, using a
|
||||||
|
different algorithm for each version (hereafter referred to as
|
||||||
|
ver0 (original), ver1 (ROT13), ver2 (reversed), and ver3
|
||||||
|
(ROT13 and reversed)).
|
||||||
|
|
||||||
|
When compiling these versions, one needs to define 'trgpune'
|
||||||
|
in the compile line (which the Makefile now has). Example:
|
||||||
|
|
||||||
cc -Dtrgpune=putchar ver3.c -o ver3
|
cc -Dtrgpune=putchar ver3.c -o ver3
|
||||||
|
|
||||||
"trgpune" is the ROT13 of getchar(), so getchar() and putchar()
|
"trgpune" is the ROT13 of getchar(), so getchar() and putchar()
|
||||||
are exchanged in the ROT13 counterpart. It is easy to see that
|
are exchanged in the ROT13 counterpart. It is easy to see that
|
||||||
this is unavoidable. I must have a #define for a library
|
this is unavoidable. I must have a #define for a library
|
||||||
function; otherwise I would have an unidentifed extern for the
|
function; otherwise I would have an unidentified extern for the
|
||||||
ROT13 version. If I then define this function, it won't link
|
ROT13 version. If I then define this function, it won't link
|
||||||
in the library version for the ORIGINAL code, since my
|
in the library version for the ORIGINAL code, since my
|
||||||
definition will supercede the library function. Hence, the
|
definition will supersede the library function. Hence, the
|
||||||
compiler option gives me putchar(), and allows me to use
|
compiler option gives me putchar(), and allows me to use
|
||||||
getchar(). I pass a dummy argument to getchar() to eliminate
|
getchar(). I pass a dummy argument to getchar() to eliminate
|
||||||
"variable number of args" from lint (unless it checks against
|
"variable number of args" from lint (unless it checks against
|
||||||
the library). Otherwise, all versions lint reasonably (main
|
the library). Otherwise, all versions lint reasonably (main
|
||||||
returns random value & constant in conditional context [when I
|
returns random value & constant in conditional context [when I
|
||||||
check for ROT13 version] is all it complains about).
|
check for ROT13 version] is all it complains about).
|
||||||
|
|
||||||
ver0 and ver1 use a range check and a calculation to do ROT13,
|
ver0 and ver1 use a range check and a calculation to do ROT13,
|
||||||
while ver2 and ver3 use table lookup. All versions contain
|
while ver2 and ver3 use table lookup. All versions contain
|
||||||
main() and it's ROT13 fn, znva(). ver0/ver1 [ver2/ver3] are
|
main() and it's ROT13 fn, znva(). ver0/ver1 [ver2/ver3] are
|
||||||
(of course) syntactically identical, since the syntax is in the
|
(of course) syntactically identical, since the syntax is in the
|
||||||
non-alphabetic characters. However, since one program starts
|
non-alphabetic characters. However, since one program starts
|
||||||
at main() while it's ROT13 counterpart starts at znva(), znva()
|
at main() while it's ROT13 counterpart starts at znva(), znva()
|
||||||
calls main (znva() is also used for output).
|
calls main (znva() is also used for output).
|
||||||
|
|
||||||
All versions use recursion to work. If the program is NOT
|
All versions use recursion to work. If the program is NOT
|
||||||
reversing it's output, it prints out the (possibly ROT13'd)
|
reversing it's output, it prints out the (possibly ROT13'd)
|
||||||
character before recursing, otherwise it prints it out
|
character before recursing, otherwise it prints it out
|
||||||
afterward (or doesn't recurse at all when EOF is reached).
|
afterward (or doesn't recurse at all when EOF is reached).
|
||||||
Since most of this code is identical, it is put into znva() and
|
Since most of this code is identical, it is put into znva() and
|
||||||
called with a first parameter of 0 as a flag (as "main()", it's
|
called with a first parameter of 0 as a flag (as "main()", it's
|
||||||
first argument (argc) must be at least one).
|
first argument (argc) must be at least one).
|
||||||
|
|
||||||
I can't use any flow control. If I used if(), I would have a
|
I can't use any flow control. If I used if(), I would have a
|
||||||
function vs() to define in the ROT13 version. But a function
|
function vs() to define in the ROT13 version. But a function
|
||||||
called vs() turns into a function called if() in the original,
|
called vs() turns into a function called if() in the original,
|
||||||
so it can't be done. Therefore, I do:
|
so it can't be done. Therefore, I do:
|
||||||
|
|
||||||
expr1 && expr2 && (expr3=etc);
|
expr1 && expr2 && (expr3=etc);
|
||||||
|
|
||||||
which is the same as:
|
which is the same as:
|
||||||
|
|
||||||
if (expr1 && expr2) expr3=etc;
|
if (expr1 && expr2) expr3=etc;
|
||||||
|
|
||||||
A/UX on the Macintosh doesn't get this right; it evaluates ALL
|
A/UX on the Macintosh doesn't get this right; it evaluates ALL
|
||||||
expressions if they aren't in an assignment or conditional
|
expressions if they aren't in an assignment or conditional
|
||||||
statement. This might warrant a warning, since other compilers
|
statement. This might warrant a warning, since other compilers
|
||||||
may do this. I found MANY compilers botched:
|
may do this. I found MANY compilers botched:
|
||||||
|
|
||||||
expr1 && (expr2,expr3);
|
expr1 && (expr2,expr3);
|
||||||
|
|
||||||
expr2 was OFTEN evaluated even if expr1 was false. I removed
|
expr2 was OFTEN evaluated even if expr1 was false. I removed
|
||||||
such statements to make it more portable.
|
such statements to make it more portable.
|
||||||
|
|
||||||
The variable names are worth noting:
|
The variable names are worth noting:
|
||||||
|
|
||||||
'irk' and 'vex' are ROT13 pairs and are synonyms.
|
'irk' and 'vex' are ROT13 pairs and are synonyms.
|
||||||
'Near' and 'Arne' are ROT13 pairs and are anagrams.
|
'Near' and 'Arne' are ROT13 pairs and are anagrams.
|
||||||
'NOON' and 'ABBA' are ROT13 pairs and are palindromes.
|
'NOON' and 'ABBA' are ROT13 pairs and are palindromes.
|
||||||
'tang' and 'gnat' are both ROT13 and palindrome pairs!
|
'tang' and 'gnat' are both ROT13 and palindrome pairs!
|
||||||
|
|
||||||
Normally (!), a reversible C program is done thus:
|
Normally (!), a reversible C program is done thus:
|
||||||
|
|
||||||
/**/ forward code /*/ edoc drawkcab /**/
|
/**/ forward code /*/ edoc drawkcab /**/
|
||||||
|
|
||||||
If your compiler nests comments, it will get this wrong.
|
If your compiler nests comments, it will get this wrong.
|
||||||
However, I have made some bits of the code palindromic,
|
However, I have made some bits of the code palindromic,
|
||||||
(or different, but reversible) so it is more like:
|
(or different, but reversible) so it is more like:
|
||||||
|
|
||||||
/**/forward/*//**/ palindromic /**//*/drawkcab/**/
|
/**/forward/*//**/ palindromic /**//*/drawkcab/**/
|
||||||
|
|
||||||
The code can therefore be interlaced. There are eight
|
The code can therefore be interlaced. There are eight
|
||||||
such palindromic bits. You can find them within the
|
such palindromic bits. You can find them within the
|
||||||
/*//**/ /**//*/ pairs.
|
`/*//**/ /**//*/` pairs.
|
||||||
|
|
||||||
The body of the code of ver0 and ver1 is a large lumpy 'K' (for
|
The body of the code of ver0 and ver1 is a large lumpy 'K' (for
|
||||||
Kernighan); the code of ver2 and ver3 is a flat-topped and
|
Kernighan); the code of ver2 and ver3 is a flat-topped and
|
||||||
lumpier 'R' (for Ritchie). Judicious use of spaces and tabs
|
lumpier 'R' (for Ritchie). Judicious use of spaces and tabs
|
||||||
helped here. It barely fits on an 80x24 screen. Squint. Note
|
helped here. It barely fits on an 80x24 screen. Squint. Note
|
||||||
that the code must start with a blank line, or the reversed version
|
that the code must start with a blank line, or the reversed version
|
||||||
will lack a terminating newline.
|
will lack a terminating newline.
|
||||||
|
|
||||||
Copyright (c) 1989, Landon Curt Noll & Larry Bassel.
|
Copyright (c) 1989, Landon Curt Noll & Larry Bassel.
|
||||||
All Rights Reserved. Permission for personal, educational or non-profit use is
|
All Rights Reserved. Permission for personal, educational or non-profit use is
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
/**//*/};)/**/main(/*//**/tang ,gnat/**//*/,ABBA~,0-0(avnz;)0-0,tang,raeN
|
/**//*/};)/**/main(/*//**/tang ,gnat/**//*/,ABBA~,0-0(avnz;)0-0,tang,raeN
|
||||||
,ABBA(niam&&)))2-]--tang-[kri - =raeN(&&0<)/*clerk*/,noon,raeN){(!tang&&
|
,ABBA(niam&&)))2-]--tang-[kri - =raeN(&&0<)/*clerk*/,noon,raeN)char
|
||||||
noon!=-1&&(gnat&2)&&((raeN&&( getchar(noon+0)))||(1-raeN&&(trgpune(noon
|
**gnat, **noon, **raeN;{int gn = gnat, ra = raeN, no = noon; (!tang&&
|
||||||
|
no!=-1&&(gn&2)&&((raeN&&( getchar(no+0)))||(1-ra&&(trgpune(no
|
||||||
)))))||tang&&znva(/*//**/tang ,tang,tang/**|**//*/((||)))0(enupgrt=raeN
|
)))))||tang&&znva(/*//**/tang ,tang,tang/**|**//*/((||)))0(enupgrt=raeN
|
||||||
(&&tang!(||)))0(rahcteg=raeN( &&1==tang((&&1-^)gnat=raeN(;;;)tang,gnat
|
(&&tang!(||)))0(rahcteg=raeN( &&1==tang((&&1-^)gnat=raeN(;;;)tang,gnat
|
||||||
,ABBA,0(avnz;)gnat:46+]552&)191+gnat([kri?0>]652%)191+gnat([kri=gnat
|
,ABBA,0(avnz;)gnat:46+]552&)191+gnat([kri?0>]652%)191+gnat([kri=gnat
|
||||||
|
|||||||
Reference in new issue
Block a user