fix Makefile and README.md for 2001/westley
This commit is contained in:
1 parent
2706f3fc52
commit
768250a5f2
2 files changed
+138
-116
No files matched your search
@@ -63,14 +63,16 @@ X11_INCDIR= /opt/X11/include
|
|||||||
# Common C compiler warnings to silence
|
# Common C compiler warnings to silence
|
||||||
#
|
#
|
||||||
#CSILENCE=
|
#CSILENCE=
|
||||||
CSILENCE= -Wno-trigraphs -Wno-implicit-function-declaration -Wno-pedantic
|
CSILENCE= -Wno-empty-body -Wno-error -Wno-implicit-function-declaration \
|
||||||
|
-Wno-implicit-int -Wno-main -Wno-return-type -Wno-trigraphs \
|
||||||
|
-Wno-unused-parameter
|
||||||
|
|
||||||
# Common C compiler warning flags
|
# Common C compiler warning flags
|
||||||
#
|
#
|
||||||
#CWARN= ${CSILENCE}
|
#CWARN= ${CSILENCE}
|
||||||
#CWARN= -Wall ${CSILENCE}
|
#CWARN= -Wall ${CSILENCE}
|
||||||
#CWARN= -Wall -Wextra ${CSILENCE}
|
CWARN= -Wall -Wextra ${CSILENCE}
|
||||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
#CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||||
|
|
||||||
# Compiler standard
|
# Compiler standard
|
||||||
#
|
#
|
||||||
@@ -138,7 +140,9 @@ CC= cc
|
|||||||
#
|
#
|
||||||
ifeq ($(CC),clang)
|
ifeq ($(CC),clang)
|
||||||
#
|
#
|
||||||
CSILENCE+= -Wno-disabled-macro-expansion -Wno-poison-system-directories
|
CSILENCE+= -Wno-disabled-macro-expansion -Wno-extra-semi -Wno-missing-prototypes \
|
||||||
|
-Wno-missing-variable-declarations -Wno-pedantic \
|
||||||
|
-Wno-poison-system-directories -Wno-shadow -Wno-strict-prototypes
|
||||||
#
|
#
|
||||||
CWARN+= -Weverything
|
CWARN+= -Weverything
|
||||||
#
|
#
|
||||||
|
|||||||
+130
-112
@@ -1,4 +1,4 @@
|
|||||||
Best position-independent code:
|
# Best position-independent code:
|
||||||
|
|
||||||
Brian Westley
|
Brian Westley
|
||||||
Firesign Theatre webmaster
|
Firesign Theatre webmaster
|
||||||
@@ -8,25 +8,30 @@ Best position-independent code:
|
|||||||
|
|
||||||
http://www.westley.org
|
http://www.westley.org
|
||||||
|
|
||||||
|
# To build:
|
||||||
|
|
||||||
## To build:
|
```sh
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
make all
|
### To run:
|
||||||
|
|
||||||
### To run
|
```sh
|
||||||
|
././westley
|
||||||
./westley
|
```
|
||||||
|
|
||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
./westley < westley.c > westley2.c
|
```sh
|
||||||
make westley2
|
./westley < westley.c > westley2.c
|
||||||
echo 'Bozos, please deflate shoes before entering the bus!'| ./westley2
|
make westley2
|
||||||
sort -b < westley2.c > westley3.c
|
echo 'Bozos, please deflate shoes before entering the bus!'| ./westley2
|
||||||
make westley3
|
sort -b < westley2.c > westley3.c
|
||||||
./westley3 < westley.c | diff - westley.c
|
make westley3
|
||||||
./westley3 < westley.c | diff - westley2.c
|
./westley3 < westley.c | diff - westley.c
|
||||||
./westley3 < westley.c | diff - westley3.c
|
./westley3 < westley.c | diff - westley2.c
|
||||||
|
./westley3 < westley.c | diff - westley3.c
|
||||||
|
```
|
||||||
|
|
||||||
### Alternate code
|
### Alternate code
|
||||||
|
|
||||||
@@ -34,132 +39,145 @@ An alternate version of this entry, `westley.alt.c`, is provided. This alternat
|
|||||||
|
|
||||||
To compile this alternate version:
|
To compile this alternate version:
|
||||||
|
|
||||||
make alt
|
```sh
|
||||||
|
make alt
|
||||||
|
```
|
||||||
|
|
||||||
Use `westley.alt` as you would `westley` above.
|
Use `westley.alt` as you would `westley` above.
|
||||||
|
|
||||||
## Judges' comments
|
## Judges' comments
|
||||||
|
|
||||||
Try copying the source to a new file and changing around the
|
Try copying the source to a new file and changing around the
|
||||||
order of the lines. Does it produce the exact same output?
|
order of the lines. Does it produce the exact same output?
|
||||||
|
|
||||||
By changing the order of the source, figure out in how many different
|
By changing the order of the source, figure out in how many different
|
||||||
ways this program can transform input to output.
|
ways this program can transform input to output.
|
||||||
|
|
||||||
This assortment obfuscated lines takes position-independant code
|
This assortment obfuscated lines takes position-independant code
|
||||||
to a new level! :-)
|
to a new level! :-)
|
||||||
|
|
||||||
## Author's comments
|
## Author's comments
|
||||||
|
|
||||||
Punch cards, or Hollerith cards, were becoming obsolete just
|
Punch cards, or Hollerith cards, were becoming obsolete just
|
||||||
as C was becoming more popular*; this is rather unfortunate,
|
as C was becoming more popular*; this is rather unfortunate,
|
||||||
because C has an advantage over many other languages when it
|
because C has an advantage over many other languages when it
|
||||||
comes to punch cards - C programs can be written to be "drop
|
comes to punch cards - C programs can be written to be "drop
|
||||||
proof".
|
proof".
|
||||||
|
|
||||||
Consider the following C program:
|
Consider the following C program:
|
||||||
|
|
||||||
main(){a();b();c();}
|
```c
|
||||||
a(){printf("A");}
|
main(){a();b();c();}
|
||||||
b(){printf("B");}
|
a(){printf("A");}
|
||||||
c(){printf("C");}
|
b(){printf("B");}
|
||||||
|
c(){printf("C");}
|
||||||
|
```
|
||||||
|
|
||||||
This program will compile and run no matter what order the
|
This program will compile and run no matter what order the
|
||||||
lines are in. If you punch it on cards (one line of code per
|
lines are in. If you punch it on cards (one line of code per
|
||||||
card, naturally) and drop them, you don't need to put them in
|
card, naturally) and drop them, you don't need to put them in
|
||||||
any particular order**; it will always produce "ABC" as output.
|
any particular order**; it will always produce "ABC" as output.
|
||||||
|
|
||||||
You can also use global variables:
|
You can also use global variables:
|
||||||
|
|
||||||
char *greet = "Hello, world!";
|
```c
|
||||||
char *greet; main(){puts(greet);}
|
char *greet = "Hello, world!";
|
||||||
|
char *greet; main(){puts(greet);}
|
||||||
|
```
|
||||||
|
|
||||||
It would be trivial to write an entire C program that is
|
It would be trivial to write an entire C program that is
|
||||||
"drop proof" using the above techniques; surprisingly, it's
|
"drop proof" using the above techniques; surprisingly, it's
|
||||||
possible to write a program that will always compile but
|
possible to write a program that will always compile but
|
||||||
behave differently depending on the line order:
|
behave differently depending on the line order:
|
||||||
|
|
||||||
test(a,b){return a;}
|
```c
|
||||||
#define test(a,b) test(b,a)
|
test(a,b){return a;}
|
||||||
main(){if (test(0,1)) printf("T"); else printf("F");}
|
#define test(a,b) test(b,a)
|
||||||
|
main(){if (test(0,1)) printf("T"); else printf("F");}
|
||||||
|
```
|
||||||
|
|
||||||
This program will print out "T" if the #define statement
|
This program will print out "T" if the #define statement
|
||||||
falls between the declaration of test() and its use in
|
falls between the declaration of test() and its use in
|
||||||
main(), otherwise it will print out "F". Furthermore,
|
main(), otherwise it will print out "F". Furthermore,
|
||||||
you can use the same call to test() repeatedly in
|
you can use the same call to test() repeatedly in
|
||||||
different lines to return different values:
|
different lines to return different values:
|
||||||
|
|
||||||
#define test(x,y) test(y,x)
|
```c
|
||||||
main(){int i=0;a(&i);b(&i);c(&i);d(&i);printf("%d\n",i);}
|
#define test(x,y) test(y,x)
|
||||||
a(i)int*i;{if (test(0,1)) *i += 1;}
|
main(){int i=0;a(&i);b(&i);c(&i);d(&i);printf("%d\n",i);}
|
||||||
b(i)int*i;{if (test(0,1)) *i += 2;}
|
a(i)int*i;{if (test(0,1)) *i += 1;}
|
||||||
c(i)int*i;{if (test(0,1)) *i += 4;}
|
b(i)int*i;{if (test(0,1)) *i += 2;}
|
||||||
d(i)int*i;{if (test(0,1)) *i += 8;}
|
c(i)int*i;{if (test(0,1)) *i += 4;}
|
||||||
test(x,y){return x;}
|
d(i)int*i;{if (test(0,1)) *i += 8;}
|
||||||
|
test(x,y){return x;}
|
||||||
|
```
|
||||||
|
|
||||||
If you enter the above program on punch cards, throw them
|
If you enter the above program on punch cards, throw them
|
||||||
up in the air, gather them up, and run it, you will get
|
up in the air, gather them up, and run it, you will get
|
||||||
a number from 0 to 15 printed out. Now *that's* a random
|
a number from 0 to 15 printed out. Now *that's* a random
|
||||||
number generator...
|
number generator...
|
||||||
|
|
||||||
Of course, there are drawbacks to C programming on punch
|
Of course, there are drawbacks to C programming on punch
|
||||||
cards; an 80-character line limit can be restricting, and
|
cards; an 80-character line limit can be restricting, and
|
||||||
(to be maximally portable) you need to use trigraphs for
|
(to be maximally portable) you need to use trigraphs for
|
||||||
the characters "^[]{}\" (these aren't found on every
|
the characters "^[]{}\" (these aren't found on every
|
||||||
keypunch, and have various encodings).
|
keypunch, and have various encodings).
|
||||||
|
|
||||||
My C program entry does the following:
|
My C program entry does the following:
|
||||||
|
|
||||||
1) reads in lines
|
1) reads in lines
|
||||||
2) rearranges the lines, or not
|
2) rearranges the lines, or not
|
||||||
2a) if it rearranges the lines, they are sorted or scrambled
|
2a) if it rearranges the lines, they are sorted or scrambled
|
||||||
3) reverses the order of the lines, or not
|
3) reverses the order of the lines, or not
|
||||||
4) prints out the lines as either text or EBCDIC punch cards.
|
4) prints out the lines as either text or EBCDIC punch cards.
|
||||||
|
|
||||||
The code, as written, scrambles the input and prints it out
|
The code, as written, scrambles the input and prints it out
|
||||||
as normal text, so you can simulate 'dropping' the cards.
|
as normal text, so you can simulate 'dropping' the cards.
|
||||||
You can repeatedly scramble the code to get all 12 variants
|
You can repeatedly scramble the code to get all 12 variants
|
||||||
(but the scrambling isn't very random; it's just a bubble
|
(but the scrambling isn't very random; it's just a bubble
|
||||||
sort with a random number, so some variants are more common
|
sort with a random number, so some variants are more common
|
||||||
than others). You can also just swap the arguments in the
|
than others). You can also just swap the arguments in the
|
||||||
calls to t() in all combinations to get all the variations.
|
calls to t() in all combinations to get all the variations.
|
||||||
|
|
||||||
If you sort the lines, you will get the version that just
|
If you sort the lines, you will get the version that just
|
||||||
prints out the input as punch cards (you will need to display
|
prints out the input as punch cards (you will need to display
|
||||||
at least 82 columns of text, or clip the last few chars by
|
at least 82 columns of text, or clip the last few chars by
|
||||||
piping it through "sed s/...$//"). If you use this on the
|
piping it through "sed s/...$//"). If you use this on the
|
||||||
original code, you will see that it spells out "HOLLERITH"
|
original code, you will see that it spells out "HOLLERITH"
|
||||||
when punched on cards (you can see the tall, thin letters
|
when punched on cards (you can see the tall, thin letters
|
||||||
spelling out "HOLLERITH" if you turn the C code sideways).
|
spelling out "HOLLERITH" if you turn the C code sideways).
|
||||||
You will also see why "/KC 0000 K" is a "Hollerith emoticon".
|
You will also see why "/KC 0000 K" is a "Hollerith emoticon".
|
||||||
Unrecognized characters are punched as a lace column.
|
Unrecognized characters are punched as a lace column.
|
||||||
(You can see an ASCII simulation of the code as punch cards
|
(You can see an ASCII simulation of the code as punch cards
|
||||||
by looking at card.gif)
|
by looking at card.gif)
|
||||||
|
|
||||||
For a nice test pattern, try
|
For a nice test pattern, try
|
||||||
&-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#@'=".<(+|!$*);,%_>?abcmnoxyz^[]{}\
|
|
||||||
|
|
||||||
If you want to analyze the program, sorting the lines while
|
```
|
||||||
ignoring leading blanks works best (sort -b). This will
|
&-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#@'=".<(+|!$*);,%_>?abcmnoxyz^[]{}\
|
||||||
produce the version that just reverses the line order, and
|
```
|
||||||
the routines in the code are in a sensible order.
|
|
||||||
|
|
||||||
This program should work on EBCDIC computers. It assumes
|
If you want to analyze the program, sorting the lines while
|
||||||
that the time_t ptr param to time() will work with an int
|
ignoring leading blanks works best (sort -b). This will
|
||||||
ptr, and that "passing through" a char[][] array as a simple
|
produce the version that just reverses the line order, and
|
||||||
char* is ok. Your compiler MUST understand trigraphs, or it
|
the routines in the code are in a sensible order.
|
||||||
will miss the trigraph backslash before the double quote in
|
|
||||||
the K string and complain about a malformed string; for GNU
|
|
||||||
C, use -ansi or -trigraphs. Entering a line of more than 80
|
|
||||||
characters, or more than 81 lines, will jam the card reader.
|
|
||||||
|
|
||||||
I've used the a[b] ==> *(a+b) trick, because this is
|
This program should work on EBCDIC computers. It assumes
|
||||||
actually shorter than the trigraph version of a??(b??).
|
that the time_t ptr param to time() will work with an int
|
||||||
|
ptr, and that "passing through" a char[][] array as a simple
|
||||||
|
char* is ok. Your compiler MUST understand trigraphs, or it
|
||||||
|
will miss the trigraph backslash before the double quote in
|
||||||
|
the K string and complain about a malformed string; for GNU
|
||||||
|
C, use -ansi or -trigraphs. Entering a line of more than 80
|
||||||
|
characters, or more than 81 lines, will jam the card reader.
|
||||||
|
|
||||||
With 28 lines of code (not counting the blank lines or the
|
I've used the a[b] ==> *(a+b) trick, because this is
|
||||||
comment), there are technically 28! different programs, or
|
actually shorter than the trigraph version of a??(b??).
|
||||||
304,888,344,611,713,860,501,504,000,000 different versions,
|
|
||||||
all legal C.
|
|
||||||
|
|
||||||
*except in Florida voting machines
|
With 28 lines of code (not counting the blank lines or the
|
||||||
**all cards must be face down, nine-edge first, of course.
|
comment), there are technically 28! different programs, or
|
||||||
|
304,888,344,611,713,860,501,504,000,000 different versions,
|
||||||
|
all legal C.
|
||||||
|
|
||||||
|
*except in Florida voting machines
|
||||||
|
**all cards must be face down, nine-edge first, of course.
|
||||||
Reference in new issue
Block a user