Merge pull request #1705 from xexyl/burton2
This commit is contained in:
27 files changed
+648
-400
No files matched your search
+31
-33
@@ -4,6 +4,10 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To use this entry requires, in some invocations, a sound processing program.
|
||||||
|
This can be ALSA or SoX but we recommend the latter. See [FAQ 3.10 - How do I
|
||||||
|
compile and use an IOCCC winner that requires sound?](/faq.md#faq3_10).
|
||||||
|
|
||||||
|
|
||||||
### Bugs and (Mis)features:
|
### Bugs and (Mis)features:
|
||||||
|
|
||||||
@@ -19,31 +23,16 @@ For more detailed information see [2018 algmyr in bugs.md](/bugs.md#2018-algmyr)
|
|||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cat prog.c | ./prog # Printing garbage might break your font
|
cat prog.c | ./prog # Print garbage: might mess up your terminal
|
||||||
./prog <file1> <file2> > out.raw
|
./prog <file1> <file2> > out.raw
|
||||||
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
|
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
|
||||||
```
|
```
|
||||||
|
|
||||||
NOTE: this entry will crash if a file specified cannot be opened.
|
|
||||||
|
|
||||||
|
|
||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog -h | ./prog -d 1 0
|
./try.sh
|
||||||
|
|
||||||
# Who needs cat?
|
|
||||||
./prog prog.c | ./prog -d 1 0
|
|
||||||
|
|
||||||
# Assuming ALSA:
|
|
||||||
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
|
|
||||||
./prog | aplay -c1 -fFLOAT_LE -r44100
|
|
||||||
|
|
||||||
# Assuming sox:
|
|
||||||
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |\
|
|
||||||
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
|
|
||||||
|
|
||||||
# now open spectrogram.png with a graphics viewer or editor
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -55,11 +44,13 @@ or at least a handy and well-tested volume knob.
|
|||||||
Pixels are numbered, amplitudes are weighed, frequencies are divided,
|
Pixels are numbered, amplitudes are weighed, frequencies are divided,
|
||||||
and the message can be displayed in fiery letters, but don't be alarmed.
|
and the message can be displayed in fiery letters, but don't be alarmed.
|
||||||
|
|
||||||
How does decoding of the waveform work? Can you encode an arbitrary text in a sound sample?
|
How does decoding of the waveform work? Can you encode an arbitrary text in a
|
||||||
|
sound sample?
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
|
|
||||||
### What is this?
|
### What is this?
|
||||||
|
|
||||||
To put it brief, this entry is akin to a sound based cat. It takes characters as
|
To put it brief, this entry is akin to a sound based cat. It takes characters as
|
||||||
@@ -67,18 +58,20 @@ input and outputs them into frequency space as audio. The entry also supports
|
|||||||
decoding the produced waveforms using the `-d` flag. Usage instructions is
|
decoding the produced waveforms using the `-d` flag. Usage instructions is
|
||||||
output if run with the `-h` flag, albeit not in an immediately legible format.
|
output if run with the `-h` flag, albeit not in an immediately legible format.
|
||||||
|
|
||||||
|
|
||||||
### Details
|
### Details
|
||||||
|
|
||||||
In normal operation, the entry reads characters from one or more sources. If the
|
In normal operation, the entry reads characters from one or more sources. If the
|
||||||
`-h` flag is given, usage instructions is used as a source. Else if file paths
|
`-h` flag is given, usage instructions is used as a source. Else if file paths
|
||||||
are present as arguments those will be used. Else stdin is used.
|
are present as arguments those will be used. Else `stdin` is used.
|
||||||
|
|
||||||
If a character is part of the supported subset of ASCII `{10, 32-126}` then that
|
If a character is part of the supported subset of ASCII `{10, 32-126}` then that
|
||||||
character is output into frequency space of an audio signal (44.1 kHz single
|
character is output into frequency space of an audio signal (44.1 kHz single
|
||||||
precision float, endianness should depend on system endianness) through `stdout`.
|
precision float, endianness should depend on system endianness) through `stdout`.
|
||||||
Any other character will be interpreted and outputted as a space.
|
Any other character will be interpreted and outputted as a space.
|
||||||
|
|
||||||
Characters are printed using a (slightly modified) pixel font based on [gohufont](https://github.com/hchargois/gohufont).
|
Characters are printed using a (slightly modified) pixel font based on
|
||||||
|
[gohufont](https://github.com/hchargois/gohufont).
|
||||||
Pixels are drawn using crosses in frequency space, achieved by simultaneous up
|
Pixels are drawn using crosses in frequency space, achieved by simultaneous up
|
||||||
and down chirps.
|
and down chirps.
|
||||||
|
|
||||||
@@ -93,12 +86,13 @@ characters.
|
|||||||
|
|
||||||
See image [spoiler.png](spoilers.png) for an example spectrogram.
|
See image [spoiler.png](spoilers.png) for an example spectrogram.
|
||||||
|
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
There is no error checking done when opening files, so expect segfaults if you
|
There is no error checking done when opening files, so expect segfaults if you
|
||||||
provide the wrong path to a file.
|
provide the wrong path to a file.
|
||||||
|
|
||||||
This program is bound to misbehave if int is less than 32 bits.
|
This program is bound to misbehave if `int` is less than 32 bits.
|
||||||
|
|
||||||
Flags will only be interpreted correctly if they are the first argument. Reading
|
Flags will only be interpreted correctly if they are the first argument. Reading
|
||||||
a file named `-d` or `-h` is fully possible if it is not the first file
|
a file named `-d` or `-h` is fully possible if it is not the first file
|
||||||
@@ -109,32 +103,32 @@ behavior. Some erroneous arguments cause segfaults (negative number of channels,
|
|||||||
channel id outside valid range). One argument in particular causes an infinite
|
channel id outside valid range). One argument in particular causes an infinite
|
||||||
loop printing whitespace.
|
loop printing whitespace.
|
||||||
|
|
||||||
#### Techniques:
|
|
||||||
|
|
||||||
##### Obfuscation:
|
### Obfuscation:
|
||||||
|
|
||||||
A lot of the obfuscations done came naturally from trying to appease the size
|
A lot of the obfuscations done came naturally from trying to appease the size
|
||||||
tool. To name some:
|
tool. To name some:
|
||||||
|
|
||||||
* One character names
|
* One character names.
|
||||||
* Merging of related (and not so related) arithmetic operations
|
* Merging of related (and not so related) arithmetic operations.
|
||||||
* Short circuiting for flow control to replace some `if`s
|
* Short circuiting for flow control to replace some `if`s.
|
||||||
* Some `#defines`, sadly
|
* Some `#defines`, sadly.
|
||||||
|
|
||||||
On the intersection of size and obfuscation is the data encoding, which was
|
On the intersection of size and obfuscation is the data encoding, which was
|
||||||
quite fun to design.
|
quite fun to design.
|
||||||
|
|
||||||
Some additional obfuscation was done to mathematical formulas. Somewhat known
|
Some additional obfuscation was done to mathematical formulas. Somewhat known
|
||||||
expressions was transformed into equivalent but less recognizable counterparts.
|
expressions were transformed into equivalent but less recognizable counterparts.
|
||||||
|
|
||||||
I have tried to avoid intentional red herrings in the code, although fishy
|
I have tried to avoid intentional red herrings in the code, although fishy
|
||||||
statements are plentiful.
|
statements are plentiful.
|
||||||
|
|
||||||
|
|
||||||
### Data encoding:
|
### Data encoding:
|
||||||
|
|
||||||
The large string in the beginning of the source file contains font data, encoded
|
The large string in the beginning of the source file contains font data, encoded
|
||||||
in base64 using characters in the range `' '` to `'_'`. The space was chosen as
|
in base64 using characters in the range `' '` to `'_'`. The space was chosen as
|
||||||
the zero because the data contains a lot of zeroes, and quite helpfully the size
|
zero because the data contains a lot of zeroes, and quite helpfully the size
|
||||||
tool ignores whitespace even in strings. Without this fact the program would
|
tool ignores whitespace even in strings. Without this fact the program would
|
||||||
have been too large and the decoding feature would have had to go. Fortunately
|
have been too large and the decoding feature would have had to go. Fortunately
|
||||||
this hole in the size spec was readily available. :)
|
this hole in the size spec was readily available. :)
|
||||||
@@ -142,9 +136,10 @@ this hole in the size spec was readily available. :)
|
|||||||
Characters in the font (5x8 pixels, 40 bits) are packed into 7 base64 digits
|
Characters in the font (5x8 pixels, 40 bits) are packed into 7 base64 digits
|
||||||
(which was a pain to decode in minimal code).
|
(which was a pain to decode in minimal code).
|
||||||
|
|
||||||
|
|
||||||
### Math:
|
### Math:
|
||||||
|
|
||||||
Note that even though floats are used for the waveforms, the standard math
|
Note that even though `float`s are used for the waveforms, the standard math
|
||||||
library is not used at all! Most arithmetic is done purely on integers. The only
|
library is not used at all! Most arithmetic is done purely on integers. The only
|
||||||
major exception is generating a table of sine values which are interpolated to
|
major exception is generating a table of sine values which are interpolated to
|
||||||
give high resolution waveforms. Can you see when the generation is triggered,
|
give high resolution waveforms. Can you see when the generation is triggered,
|
||||||
@@ -157,13 +152,15 @@ function was used. Although the one used is quite well known, it is not in a
|
|||||||
form that should be familiar to anyone. What looks like a polynomial and quacks
|
form that should be familiar to anyone. What looks like a polynomial and quacks
|
||||||
like a polynomial might not actually be a polynomial, at least not deep inside.
|
like a polynomial might not actually be a polynomial, at least not deep inside.
|
||||||
|
|
||||||
|
|
||||||
### Printing a string:
|
### Printing a string:
|
||||||
|
|
||||||
The program was written to deal exclusively with file descriptors, so how would
|
The program was written to deal exclusively with file descriptors, so how would
|
||||||
one go about printing a char array not from a file descriptor without adding
|
one go about printing a `char` array not from a file descriptor without adding
|
||||||
additional logic? Answer: `ungetc` into stdin, one char at a time (to be
|
additional logic? Answer: `ungetc(3)` into `stdin`, one `char` at a time (to be
|
||||||
standards compliant). This is used to print the usage instructions.
|
standards compliant). This is used to print the usage instructions.
|
||||||
|
|
||||||
|
|
||||||
### Compilation warnings
|
### Compilation warnings
|
||||||
|
|
||||||
Compiling using
|
Compiling using
|
||||||
@@ -179,7 +176,7 @@ clang -Wall -Wextra -pedantic
|
|||||||
```
|
```
|
||||||
|
|
||||||
is a bit more pessimistic and gives `-Wempty-body` (I like loops without
|
is a bit more pessimistic and gives `-Wempty-body` (I like loops without
|
||||||
bodies), `-Wstring-plus-int` (since apparently some people think string+int is a
|
bodies), `-Wstring-plus-int` (since apparently some people think string+`int` is a
|
||||||
concatenation) and one of the weirder warnings I have seen from me splitting a
|
concatenation) and one of the weirder warnings I have seen from me splitting a
|
||||||
negative constant with whitespace. Compiling using
|
negative constant with whitespace. Compiling using
|
||||||
|
|
||||||
@@ -190,6 +187,7 @@ clang -Wall -Wextra -pedantic -Weverything
|
|||||||
produces a few page faults of warnings and makes me feel generally bad about
|
produces a few page faults of warnings and makes me feel generally bad about
|
||||||
myself. :(
|
myself. :(
|
||||||
|
|
||||||
|
|
||||||
### Misc
|
### Misc
|
||||||
|
|
||||||
The reported size of the source code using the size tool is very intentionally
|
The reported size of the source code using the size tool is very intentionally
|
||||||
|
|||||||
Executable
+60
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/algmyr
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
echo "$ ./prog -h | ./prog -d 1 0" 1>&2
|
||||||
|
./prog -h | ./prog -d 1 0
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
# Who needs cat? Answer: more people than you think.
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog prog.c | ./prog -d 1 0 (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
./prog prog.c | ./prog -d 1 0 | less -EXF
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
APLAY="$(type -P aplay)"
|
||||||
|
SOX="$(type -P sox)"
|
||||||
|
|
||||||
|
if [[ -z "$SOX" && -z "$APLAY" ]]; then
|
||||||
|
echo "Missing both sox and aplay, cannot do this step."
|
||||||
|
elif [[ -n "$SOX" ]]; then
|
||||||
|
echo "$ echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog | \
|
||||||
|
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 \
|
||||||
|
- -n spectrogram -d 10 -X 300" 1>&2
|
||||||
|
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |\
|
||||||
|
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
|
||||||
|
|
||||||
|
echo "Now open spectrogram.png in an image viewer or editor." 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
echo "$ echo "IOCCC 2018" | ./prog | sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - ioccc.wav"
|
||||||
|
echo "IOCCC 2018" | ./prog | sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - ioccc.wav
|
||||||
|
echo "Now listen to ioccc.wav." 1>&2
|
||||||
|
|
||||||
|
else
|
||||||
|
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
|
||||||
|
./prog | aplay -c1 -fFLOAT_LE -r44100
|
||||||
|
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
|
||||||
|
./prog | aplay -c1 -fFLOAT_LE -r44100
|
||||||
|
|
||||||
|
echo "Now open spectrogram.png in an image viewer or editor." 1>&2
|
||||||
|
fi
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ echo "IOCCC 2018!" | ./prog | ./prog -d 1 0" 1>&2
|
||||||
|
echo "IOCCC 2018!" | ./prog | ./prog -d 1 0
|
||||||
|
|
||||||
|
|
||||||
+19
-14
@@ -4,6 +4,9 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
There is an alternate version of this entry. See [Alternate
|
||||||
|
code](#alternate-code) below for more details.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -15,32 +18,33 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < prog.c
|
./try.sh
|
||||||
./prog < prog.alt.c
|
|
||||||
./prog < README.md
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Alternate code:
|
## Alternate code:
|
||||||
|
|
||||||
An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided.
|
|
||||||
|
|
||||||
Compare [prog.c](prog.c) and [prog.alt.c](prog.alt.c) and find out why we had to
|
Compare [prog.c](prog.c) and [prog.alt.c](prog.alt.c) and find out why we had to
|
||||||
modify the entry, and what confused the author (see the author's remarks). No,
|
modify the entry, and what confused the author (see the author's remarks). No,
|
||||||
it was not the shape of the Roman V that we, or the compiler, didn't like.
|
it was not the shape of the Roman V that we, or the compiler, didn't like.
|
||||||
|
|
||||||
To compile this alternate version:
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make alt
|
make alt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
Use `prog.alt` as you would `prog` above.
|
Use `prog.alt` as you would `prog` above.
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
With this entry, you won't need to turn your monitor [upside down](http://en.wikipedia.org/wiki/River_%28typography%29)!
|
With this entry, you won't need to turn your monitor [upside
|
||||||
|
down](http://en.wikipedia.org/wiki/River_%28typography%29)!
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
@@ -52,12 +56,13 @@ cc -Wall -Wextra -Wpedantic -O3 -std=c11 prog.c -o prog
|
|||||||
```
|
```
|
||||||
|
|
||||||
Also works with a standard of C99, but C90/C89 will not compile due to
|
Also works with a standard of C99, but C90/C89 will not compile due to
|
||||||
for loop initial declarations, along with additional warnings about
|
`for` loop initial declarations, along with additional warnings about
|
||||||
variable length arrays and lack of a return statement.
|
variable length arrays and lack of a `return` statement.
|
||||||
|
|
||||||
|
|
||||||
### Additional info:
|
### Additional info:
|
||||||
|
|
||||||
This small program, when given text on stdin, will produce a pattern of
|
This small program, when given text on `stdin`, will produce a pattern of
|
||||||
squiggly lines. This pattern is deterministic, and it shouldn't be too
|
squiggly lines. This pattern is deterministic, and it shouldn't be too
|
||||||
difficult to determine from whence they come. There is even a comment
|
difficult to determine from whence they come. There is even a comment
|
||||||
that describes the highlighted phenomena in the source, for those that
|
that describes the highlighted phenomena in the source, for those that
|
||||||
@@ -74,14 +79,14 @@ such as proper handling of tabs are left as an exercise to the reader.
|
|||||||
In developing this program, the author found a potentially interesting
|
In developing this program, the author found a potentially interesting
|
||||||
bug. If the expression `(j=k,j)` (near the middle of the source) is
|
bug. If the expression `(j=k,j)` (near the middle of the source) is
|
||||||
changed to `(j=k,k)`, the program produces different output. The author
|
changed to `(j=k,k)`, the program produces different output. The author
|
||||||
used compiler gcc 5.4.0, compiled for x86_64-linux-gnu. Enabling or
|
used gcc 5.4.0, compiled for `x86_64-linux-gnu`. Enabling or
|
||||||
disabling optimization produces the same results. The author is not
|
disabling optimization produces the same results. The author is not
|
||||||
sure who is the culprit, but instead shrugged and moved on with life.
|
sure who is the culprit, but instead shrugged and moved on with life.
|
||||||
Of course, YMMV with your own environment.
|
Of course, YMMV with your own environment.
|
||||||
|
|
||||||
The structure of this program, as you may have deduced, is two for
|
The structure of this program, as you may have deduced, is two `for`
|
||||||
loops, one nested in the other. There is also a bunch of direct
|
loops, one nested in the other. There are also a bunch of direct
|
||||||
variable assignment, such as `j=k`. There is some filler fluff, such as
|
variable assignments, such as `j=k`. There is some filler fluff, such as
|
||||||
`0-0+0`, but all that sort should be rather easy to spot. It was mostly
|
`0-0+0`, but all that sort should be rather easy to spot. It was mostly
|
||||||
added for the purpose of making certain things line up right, and only
|
added for the purpose of making certain things line up right, and only
|
||||||
secondarily to obfuscate.
|
secondarily to obfuscate.
|
||||||
|
|||||||
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/anderson
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < prog.c: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < prog.alt.c: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < prog.alt.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < README.md (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < README.md | less -EXF
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < Makefile (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < Makefile | less -EXF
|
||||||
+41
-18
@@ -4,6 +4,9 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
There is an alternate version of this entry. See [Alternate
|
||||||
|
code](#alternate-code) below.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -15,8 +18,7 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < prog
|
./try.sh
|
||||||
./prog < prog.c
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -24,15 +26,23 @@ make
|
|||||||
|
|
||||||
An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided
|
An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided
|
||||||
This alternate code was supposed to compile without warnings, however
|
This alternate code was supposed to compile without warnings, however
|
||||||
with modern compilers this is no longer the case.
|
with modern compilers this is no longer the case so it will only cleanly compile
|
||||||
|
with `-Wno-` options.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
To compile this alternate version:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make alt
|
make alt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
|
Use `prog.alt` as you would `prog`.
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
One line, one array, one loop and one statement but it prints many bytes. It won.
|
One line, one array, one loop and one statement but it prints many bytes. It won.
|
||||||
@@ -40,9 +50,9 @@ One line, one array, one loop and one statement but it prints many bytes. It won
|
|||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
Feed this anything on stdin.
|
Feed this anything on `stdin`.
|
||||||
|
|
||||||
The [included script](scripthd) may be used as a driver program for this entry.
|
The [included script.sh](scripthd.sh) may be used as a driver program for this entry.
|
||||||
It adds several nice-to-have features, and allows salt-to-taste customizability.
|
It adds several nice-to-have features, and allows salt-to-taste customizability.
|
||||||
|
|
||||||
This code has been compiled and tested on:
|
This code has been compiled and tested on:
|
||||||
@@ -51,21 +61,24 @@ This code has been compiled and tested on:
|
|||||||
* X86-Linux, gcc 4.1.2 and 4.8.4, -O0 and -O3
|
* X86-Linux, gcc 4.1.2 and 4.8.4, -O0 and -O3
|
||||||
* ARM-QEMU, gcc 4.8.4, -O0 and -O3
|
* ARM-QEMU, gcc 4.8.4, -O0 and -O3
|
||||||
* X86-FreeBSD 10.3, clang 3.4.1, -O0 and -O3
|
* X86-FreeBSD 10.3, clang 3.4.1, -O0 and -O3
|
||||||
* TCC 0.9.26 (x86-64) (used as a proxy for [2001/bellard](http://ioccc.org/years.html#2001_bellard))
|
* TCC 0.9.26 (x86-64) (used as a proxy for [2001/bellard](/years.html#2001_bellard))
|
||||||
* UNIX V7 pcc (Johnson's C compiler) on a [simulated PDP-11/45](http://simh.trailing-edge.com/)
|
* UNIX V7 pcc (Johnson's C compiler) on a [simulated PDP-11/45](http://simh.trailing-edge.com/)
|
||||||
(see spoiler for further detail)
|
(see spoiler for further detail)
|
||||||
|
|
||||||
<div style="margin-bottom:60em;margin-top:4em"><strong>Spoiler below; scroll down.</strong></div>
|
<div style="margin-bottom:60em;margin-top:4em"><strong>Spoiler below; scroll down.</strong></div>
|
||||||
|
|
||||||
|
|
||||||
### SPOILER:
|
### SPOILER:
|
||||||
|
|
||||||
This started life as a personal challenge: write the shortest hex dump utility in C.
|
This started life as a personal challenge: write the shortest hex dump utility
|
||||||
|
in C.
|
||||||
|
|
||||||
The self-imposed ground rules in the hunt for shortest:
|
The self-imposed ground rules in the hunt for shortest:
|
||||||
|
|
||||||
- the code has to output correctly,
|
- The code has to output correctly.
|
||||||
- no extraneous newlines, the code must be portable,
|
- No extraneous newlines, the code must be portable,
|
||||||
and without bypassing the solution using execve(2), or functions built upon it (system(3), popen(3), etc).
|
and without bypassing the solution using `execve(2)`, or functions built upon it
|
||||||
|
(`system(3)`, `popen(3)`, etc).
|
||||||
|
|
||||||
E.g:
|
E.g:
|
||||||
|
|
||||||
@@ -155,8 +168,10 @@ $
|
|||||||
```
|
```
|
||||||
|
|
||||||
An obfuscated hex dump has been done before:
|
An obfuscated hex dump has been done before:
|
||||||
[1986/bright/bright.c](http://ioccc.org/1986/bright/bright.c) is similar in function,
|
[1986/bright](/1986/bright/README.md) is similar in function,
|
||||||
but it uses more characters in just setting up its obfuscation than this entire solution!
|
but it uses more characters in just setting up its obfuscation than this entire
|
||||||
|
solution!
|
||||||
|
|
||||||
|
|
||||||
### BIGGER SPOILER:
|
### BIGGER SPOILER:
|
||||||
|
|
||||||
@@ -165,12 +180,13 @@ replace the cryptic expression `4<(4^l>>5)?l:46` with `32>l|l>126?46:l`.
|
|||||||
Both take the same number of characters, but the former is a bit more interesting.
|
Both take the same number of characters, but the former is a bit more interesting.
|
||||||
Bonus question: how does the first expression work?
|
Bonus question: how does the first expression work?
|
||||||
|
|
||||||
|
|
||||||
### BIGGEST SPOILER (and some history):
|
### BIGGEST SPOILER (and some history):
|
||||||
|
|
||||||
Technically, `char o[0];` is illegal (SS 6.7.6.2) according to ISO (N1570). And
|
Technically, `char o[0];` is illegal (SS 6.7.6.2) according to ISO (N1570). And
|
||||||
`char o[];` is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
|
`char o[];` is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
|
||||||
However, it works in modern C implementations as an extension, including GCC,
|
However, it works in modern C implementations as an extension, including GCC,
|
||||||
Clang and TCC, for X86 and ARM, on multiple operating systems (Linux, OSX,
|
Clang and TCC, for X86 and ARM, on multiple operating systems (Linux, OSX/macOS,
|
||||||
FreeBSD), so it is _functionally_ correct. MicroSoft Visual C++ does not allow
|
FreeBSD), so it is _functionally_ correct. MicroSoft Visual C++ does not allow
|
||||||
`char o[]` or `char o[0]`, and implements its close relative `char o[1]` such
|
`char o[]` or `char o[0]`, and implements its close relative `char o[1]` such
|
||||||
that writing more than a single char will cause a fault, which is _technically_
|
that writing more than a single char will cause a fault, which is _technically_
|
||||||
@@ -185,7 +201,8 @@ bytes following `O`, addressed via `o`, and this code only needs 17. This is
|
|||||||
_undefined_ behavior, but as shown, it is widely available.
|
_undefined_ behavior, but as shown, it is widely available.
|
||||||
|
|
||||||
The [1979 Seventh Edition UNIX][1] (v7) system pre-dates the IOCCC by several years,
|
The [1979 Seventh Edition UNIX][1] (v7) system pre-dates the IOCCC by several years,
|
||||||
and the source code to `sh`(1) was a [significant inspiration for this contest][2].
|
and the source code to `sh`(1) was a [significant inspiration for this
|
||||||
|
contest](/all/README.md).
|
||||||
There are two C compilers present: `cc` written by Dennis Ritchie, and `pcc` written by Steven Johnson.
|
There are two C compilers present: `cc` written by Dennis Ritchie, and `pcc` written by Steven Johnson.
|
||||||
The nested conditional expressions in 116 and smaller are too complex for `cc` ("Illegal conditional")
|
The nested conditional expressions in 116 and smaller are too complex for `cc` ("Illegal conditional")
|
||||||
but `pcc` handles them correctly, and neither compiler accepts `char o[]` or
|
but `pcc` handles them correctly, and neither compiler accepts `char o[]` or
|
||||||
@@ -194,9 +211,9 @@ not yet written for UNIX).
|
|||||||
|
|
||||||
[1]: http://minnie.tuhs.org/cgi-bin/utree.pl
|
[1]: http://minnie.tuhs.org/cgi-bin/utree.pl
|
||||||
[2]: http://ioccc.org/all/README
|
[2]: http://ioccc.org/all/README
|
||||||
[3]: https://web.archive.org/web/20180521074522/http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4
|
[2]: https://web.archive.org/web/20180521074522/http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4
|
||||||
|
|
||||||
More significant is that v7 `printf`(3) does not report the number of characters
|
More significant is that v7 `printf(3)` does not report the number of characters
|
||||||
written, and therefore 111 compiles but does not work correctly; 113 is the
|
written, and therefore 111 compiles but does not work correctly; 113 is the
|
||||||
shortest code that compiles and runs correctly in Ancient UNIX.
|
shortest code that compiles and runs correctly in Ancient UNIX.
|
||||||
|
|
||||||
@@ -216,7 +233,7 @@ page 71, remarks:
|
|||||||
It is fascinating to explore the roots of C through the history of the operating
|
It is fascinating to explore the roots of C through the history of the operating
|
||||||
system it was birthed within. C is often criticized as a difficult, inscrutable
|
system it was birthed within. C is often criticized as a difficult, inscrutable
|
||||||
language, but as this contest demonstrates, this is in parody. _Shell-gol_ is
|
language, but as this contest demonstrates, this is in parody. _Shell-gol_ is
|
||||||
one of those instances where someone [preferred a different language][3], and
|
one of those instances where someone [preferred a different language][2], and
|
||||||
(ab)used the preprocessor to re-mold C into something they found comfortable.
|
(ab)used the preprocessor to re-mold C into something they found comfortable.
|
||||||
Most of the rest of the system, especially in the kernel, are models of clarity
|
Most of the rest of the system, especially in the kernel, are models of clarity
|
||||||
and efficient expression.
|
and efficient expression.
|
||||||
@@ -247,6 +264,12 @@ Try:
|
|||||||
cat prog.c prog.alt.c
|
cat prog.c prog.alt.c
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmp -b prog.c prog.alt.c
|
||||||
|
```
|
||||||
|
|
||||||
to compare the differences (`diff` is not helpful on a one-liner).
|
to compare the differences (`diff` is not helpful on a one-liner).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File renamed without changes.
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/burton1
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" everything >/dev/null || exit 1
|
||||||
|
|
||||||
|
for i in prog scripthd.sh; do
|
||||||
|
echo "$ ./$i < prog.c" 1>&2
|
||||||
|
./"$i" < prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./$i < prog (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
./"$i" < prog | less -EXF
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./$i < scripthd.sh (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
./"$i" < scripthd.sh | less -EXF
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: head $0 | ./$i: "
|
||||||
|
echo 1>&2
|
||||||
|
head "$0" | ./"$i"
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: tail -n 15 Makefile | ./$i: "
|
||||||
|
echo 1>&2
|
||||||
|
tail -n 15 Makefile | ./"$i"
|
||||||
|
done
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#
|
#
|
||||||
# sort with: sort -d -u
|
# sort with: sort -d -u
|
||||||
*.dSYM
|
*.dSYM
|
||||||
|
fixed_iocccsize
|
||||||
indent
|
indent
|
||||||
indent.c
|
indent.c
|
||||||
indent.o
|
indent.o
|
||||||
@@ -8,3 +9,4 @@ keywords
|
|||||||
manpage
|
manpage
|
||||||
prog
|
prog
|
||||||
prog.orig
|
prog.orig
|
||||||
|
tac
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"winners_text" : "field-by-field difference between iocccsize and ion"
|
"winners_text" : "field-by-field difference between iocccsize and ion"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "freqcount",
|
"file_path" : "freqcount.sh",
|
||||||
"winners_rank" : 100,
|
"winners_rank" : 100,
|
||||||
"created_by" : null,
|
"created_by" : null,
|
||||||
"prog" : null,
|
"prog" : null,
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
"winners_text" : "turns ASCII versions of man into real man pages"
|
"winners_text" : "turns ASCII versions of man into real man pages"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "mkkeywords",
|
"file_path" : "mkkeywords.sh",
|
||||||
"winners_rank" : 150,
|
"winners_rank" : 150,
|
||||||
"created_by" : null,
|
"created_by" : null,
|
||||||
"prog" : null,
|
"prog" : null,
|
||||||
@@ -500,7 +500,7 @@
|
|||||||
"winners_text" : "results without -k"
|
"winners_text" : "results without -k"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "runtest",
|
"file_path" : "runtest.sh",
|
||||||
"winners_rank" : 200,
|
"winners_rank" : 200,
|
||||||
"created_by" : null,
|
"created_by" : null,
|
||||||
"prog" : null,
|
"prog" : null,
|
||||||
@@ -510,7 +510,7 @@
|
|||||||
"winners_text" : "test suite"
|
"winners_text" : "test suite"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "spotcheck",
|
"file_path" : "spotcheck.sh",
|
||||||
"winners_rank" : 200,
|
"winners_rank" : 200,
|
||||||
"created_by" : null,
|
"created_by" : null,
|
||||||
"prog" : null,
|
"prog" : null,
|
||||||
@@ -530,14 +530,14 @@
|
|||||||
"winners_text" : "reserved words for a given C standard"
|
"winners_text" : "reserved words for a given C standard"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "spotdiff",
|
"file_path" : "spotdiff.sh",
|
||||||
"winners_rank" : 250,
|
"winners_rank" : 250,
|
||||||
"created_by" : null,
|
"created_by" : null,
|
||||||
"prog" : null,
|
"prog" : null,
|
||||||
"filetype" : "shellscript",
|
"filetype" : "shellscript",
|
||||||
"winners_show" : true,
|
"winners_show" : true,
|
||||||
"display_via" : "github",
|
"display_via" : "github",
|
||||||
"winners_text" : "summarize the results of spotcheck"
|
"winners_text" : "summarize the results of spotcheck.sh"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file_path" : "2018_burton2.tar.bz2",
|
"file_path" : "2018_burton2.tar.bz2",
|
||||||
|
|||||||
+10
-10
@@ -114,7 +114,7 @@ PROG= prog
|
|||||||
#
|
#
|
||||||
OBJ= ${PROG}.o
|
OBJ= ${PROG}.o
|
||||||
CSRC= ${PROG}.o
|
CSRC= ${PROG}.o
|
||||||
DATA= READ_ME.txt manpage java8 kandr kandr2 v7unix
|
DATA= author-README.txt manpage java8 kandr kandr2 v7unix
|
||||||
TARGET= ${PROG}
|
TARGET= ${PROG}
|
||||||
#
|
#
|
||||||
ALT_OBJ=
|
ALT_OBJ=
|
||||||
@@ -124,9 +124,9 @@ EXTRA_DATA= ansi c++11 c++14 c++98 c11 c99 discrepancies.md \
|
|||||||
test01.c test02.c test03.c test04.c test05.c test06.c test07.c \
|
test01.c test02.c test03.c test04.c test05.c test06.c test07.c \
|
||||||
test08.c test09.c test10.c test11.c test12.c test13.c test14.c \
|
test08.c test09.c test10.c test11.c test12.c test13.c test14.c \
|
||||||
iocccbug01.c iocccbug02.c iocccbug03.c iocccbug04.c iocccbug05.c \
|
iocccbug01.c iocccbug02.c iocccbug03.c iocccbug04.c iocccbug05.c \
|
||||||
iocccbug06.c results results.k src.doc.txt patch tac.man author-README.txt \
|
iocccbug06.c results results.k src.doc.txt patch tac.1 author-README.txt \
|
||||||
ioc_without_quote
|
ioc_without_quote
|
||||||
UTILITIES= unob.sh tokenfix spotcheck spotdiff freqcount
|
UTILITIES= unob.sh tokenfix.sh spotcheck.sh spotdiff.sh freqcount.sh
|
||||||
USAGE="\"prog [-tcksri] < file.c\ntokenize and count stdin\n\t-t\ttokens only\n\t-c\tcompatible counts\n\t-k\tkeep comments\n\t-s\tsuppress output\n\t-r\treserved words count as 1\n\t-i\tioccc count only\n\""
|
USAGE="\"prog [-tcksri] < file.c\ntokenize and count stdin\n\t-t\ttokens only\n\t-c\tcompatible counts\n\t-k\tkeep comments\n\t-s\tsuppress output\n\t-r\treserved words count as 1\n\t-i\tioccc count only\n\""
|
||||||
|
|
||||||
# this tool requires -trigraphs
|
# this tool requires -trigraphs
|
||||||
@@ -164,17 +164,17 @@ data: ${DATA} ${EXTRA_DATA}
|
|||||||
@${TRUE}
|
@${TRUE}
|
||||||
|
|
||||||
# keywords: c11
|
# keywords: c11
|
||||||
keywords: ioccc.kw.freq mkkeywords
|
keywords: ioccc.kw.freq mkkeywords.sh
|
||||||
./mkkeywords $< > keywords
|
./mkkeywords.sh $< > keywords
|
||||||
|
|
||||||
fixed_iocccsize: fixed_iocccsize.c
|
fixed_iocccsize: fixed_iocccsize.c
|
||||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||||
|
|
||||||
test: prog tac runtest fixed_iocccsize ${EXTRA_DATA}
|
test: prog tac runtest.sh fixed_iocccsize ${EXTRA_DATA}
|
||||||
-./runtest | diff - results
|
-./runtest.sh | diff - results
|
||||||
-opt=kcrs ./runtest | diff - results.k
|
-opt=kcrs ./runtest.sh | diff - results.k
|
||||||
-opt=rs prog=tac ./runtest | diff - results
|
-opt=rs prog=./tac ./runtest.sh | diff - results
|
||||||
-opt=rsk prog=tac ./runtest | diff - results.k
|
-opt=rsk prog=tac ./runtest.sh | diff - results.k
|
||||||
./fixed_iocccsize -rs < prog.c
|
./fixed_iocccsize -rs < prog.c
|
||||||
./tac -rs prog.c
|
./tac -rs prog.c
|
||||||
|
|
||||||
|
|||||||
+128
-122
@@ -15,117 +15,114 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog -i < prog.c
|
./try.sh
|
||||||
./prog -s < prog.c
|
|
||||||
./prog -sk < prog.c
|
|
||||||
```
|
|
||||||
|
|
||||||
If you get stuck, try:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you get really stuck, try:
|
If you get really stuck, try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
man ./tac.man
|
man ./tac.1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
They say size isn't everything, and in the case of IOCCC [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c)
|
They say size isn't everything, and in the case of IOCCC
|
||||||
that is saying something! What is this program weighing and how much does it weigh?
|
[iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) that is saying something!
|
||||||
|
What is this program weighing and how much does it weigh?
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
### tac - tokenize and count C and derivative languages:
|
### tac - tokenize and count C and derivative languages:
|
||||||
|
|
||||||
```
|
`tac` computes C program size\
|
||||||
tac computes C program size
|
(obfuscated / otherwise)\
|
||||||
(obfuscated / otherwise)
|
by splitting code as tokens small,\
|
||||||
by splitting code as tokens small,
|
ignoring space, then counting all.\
|
||||||
ignoring space, then counting all.
|
|
||||||
|
|
||||||
It tries quite hard to act the same
|
It tries quite hard to act the same\
|
||||||
as counting tool of I-OCCC fame.
|
as counting tool of I-OCCC fame.\
|
||||||
Some bugs were fixed, it's faster too,
|
Some bugs were fixed, it's faster too,\
|
||||||
and does more things, just add some glue!
|
and does more things, just add some glue!\
|
||||||
|
|
||||||
It does far more than print the size:
|
It does far more than print the size:\
|
||||||
the token part's a better prize!
|
the token part's a better prize!\
|
||||||
With each upon on a single line,
|
With each upon on a single line,\
|
||||||
how many things can you design?
|
how many things can you design?\
|
||||||
|
|
||||||
Included is a keyword sorter,
|
Included is a keyword sorter,\
|
||||||
de-obfuscator, freq reporter.
|
de-obfuscator, freq reporter.\
|
||||||
With code produced as little parts,
|
With code produced as little parts,\
|
||||||
just add your own creative arts.
|
just add your own creative arts.\
|
||||||
|
|
||||||
But first you have to figure out
|
But first you have to figure out\
|
||||||
the braces part, without a doubt!
|
the braces part, without a doubt!\
|
||||||
And then the code - it isn't easy:
|
And then the code - it isn't easy:\
|
||||||
for as else? That's rather cheesy!
|
for as else? That's rather cheesy!\
|
||||||
|
|
||||||
The rest of it is standard fare:
|
The rest of it is standard fare:\
|
||||||
expressions strange, the globals bare,
|
expressions strange, the globals bare,\
|
||||||
confusing symbols one and oh,
|
confusing symbols one and oh,\
|
||||||
and precedence you have to know.
|
and precedence you have to know.\
|
||||||
|
|
||||||
The keyword list was made external,
|
The keyword list was made external,\
|
||||||
because of standards change eternal.
|
because of standards change eternal.\
|
||||||
Thus other languages can now,
|
Thus other languages can now,\
|
||||||
be counted just like C, somehow!
|
be counted just like C, somehow!\
|
||||||
|
|
||||||
|
I hope you find this code obscure\
|
||||||
|
enough to win, and thus procure\
|
||||||
|
a public place for all to see\
|
||||||
|
how badly I can butcher C!\
|
||||||
|
|
||||||
I hope you find this code obscure
|
|
||||||
enough to win, and thus procure
|
|
||||||
a public place for all to see
|
|
||||||
how badly I can butcher C!
|
|
||||||
```
|
|
||||||
|
|
||||||
### Said another way....
|
### Said another way....
|
||||||
|
|
||||||
`tac` is the inverse of `cat`(1): it un-concatenates its input into C tokens,
|
`tac` is the inverse of `cat`(1): it un-concatenates its input into C tokens,
|
||||||
writing the token stream to `stdout`. There are options to suppress the token ids,
|
writing the token stream to `stdout`. There are options to suppress the token
|
||||||
summarize the token counts, and several options to allow it to be compatible
|
ids, summarize the token counts, and several options to allow it to be
|
||||||
with `iocccsize`.
|
compatible with `iocccsize`.
|
||||||
|
|
||||||
The token-based output is quite useful in analyzing source code (see below),
|
The token-based output is quite useful in analyzing source code (see below),
|
||||||
and the counter is more accurate than `iocccsize` (see below); but this can be
|
and the counter is more accurate than `iocccsize` (see below); but this can be
|
||||||
fixed by using the -c compatibility flag, restoring the following problems as
|
fixed by using the `-c` compatibility flag, restoring the following problems as
|
||||||
in the official tool:
|
in the official tool:
|
||||||
|
|
||||||
* whitespace **within** a string is **not** counted;
|
* Whitespace **within** a string is **not** counted;
|
||||||
this seems wrong, as these chars **are** significant
|
this seems wrong, as these chars **are** significant.
|
||||||
* "`{;}`" is not counted within a double-quoted string
|
* "`{;}`" is not counted within a double-quoted string.
|
||||||
* whitespace preceding a comment is char-counted, unless the comment starts a line
|
* Whitespace preceding a comment is `char`-counted, unless the comment starts a
|
||||||
* `-k` processes the reserved words within `//` comments(!), but not `/*`, changing the counts
|
line.
|
||||||
|
* `-k` processes the reserved words within `//` comments(!), but not `/*`,
|
||||||
|
changing the counts.
|
||||||
|
|
||||||
The following bugs are always corrected:
|
The following bugs are always corrected:
|
||||||
|
|
||||||
* treats `/*/` as a complete comment (`/*/int if for/*/` has three keywords)
|
* Treats `/*/` as a complete comment (`/*/int if for/*/` has three keywords)
|
||||||
* `-k` enables `//*` or within a line comment `/*` to initiate a comment block until following `*/`
|
* `-k` enables `//*` or within a line comment `/*` to initiate a comment block until following `*/`
|
||||||
* `-k` processes double quote characters in `//` comments - thus a solitary
|
* `-k` processes double quote characters in `//` comments - thus a solitary
|
||||||
quote consumes everything until the next quote
|
quote consumes everything until the next quote
|
||||||
* single quotes are not handled correctly (`'"'` starts a dquote in `iocccsize`)
|
* Single quotes are not handled correctly (`'"'` starts a double quote in `iocccsize`)
|
||||||
* `#ifndef` is omitted as a keyword (but `#ifdef` is allowed?)
|
* `#ifndef` is omitted as a keyword (but `#ifdef` is allowed?)
|
||||||
* `I` is not a reserved word.
|
* `I` is not a reserved word.
|
||||||
* `tac` correctly penetrates [23rd century cloaking technology][1]. ;-)
|
* `tac` correctly penetrates [23rd century cloaking technology][1]. ;-)
|
||||||
|
|
||||||
There is one (known) remaining problem with detection:
|
There is one (known) remaining problem with detection:
|
||||||
|
|
||||||
* comments between preprocessor hash and keyword are not replaced with whitespace;
|
* Comments between preprocessor hash and keyword are not replaced with whitespace;
|
||||||
the following counts #include as two tokens, `#` and `include` (not as a reserved word):
|
the following counts #include as two tokens, `#` and `include` (not as a reserved word):
|
||||||
|
|
||||||
#/*this will not be counted*/include/*correctly*/<stdio.h>
|
```c
|
||||||
|
#/*this will not be counted*/include/*correctly*/<stdio.h>
|
||||||
|
```
|
||||||
|
|
||||||
Fixing this properly hampers backwards compatibility in counting. This requires
|
Fixing this properly hampers backwards compatibility in counting. This requires
|
||||||
eliding comments during the translation phases (ISO 5.1.1.2, phase 3), and yet still
|
eliding comments during the translation phases (ISO 5.1.1.2, phase 3), and yet still
|
||||||
counting words correctly absent `-k`.
|
counting words correctly absent `-k`.
|
||||||
|
|
||||||
[1]: http://ioccc.org/2014/birken/hint.html "Best use of port 1701"
|
[1]: /2014/birken/README.md "Best use of port 1701"
|
||||||
|
|
||||||
|
|
||||||
### Backwards Compatibility:
|
### Backwards Compatibility:
|
||||||
|
|
||||||
@@ -135,10 +132,11 @@ counting words correctly absent `-k`.
|
|||||||
find ~/src/obc -type f -name \*.c | wc
|
find ~/src/obc -type f -name \*.c | wc
|
||||||
```
|
```
|
||||||
|
|
||||||
The discrepancies found are documented and explained in the file "discrepancies".
|
The discrepancies found are documented and explained in the file
|
||||||
|
[discrepancies.md](discrepancies.md).
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck ./prog | ./spotdiff |
|
find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck.sh ./prog | ./spotdiff.sh |
|
||||||
grep -v keep | diff -bw - discrep* | grep "[<>] cl "
|
grep -v keep | diff -bw - discrep* | grep "[<>] cl "
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -159,17 +157,17 @@ designed to allow exhaustive, hand-counted values for comparison with the tool v
|
|||||||
These test cases were vital in debugging and regression testing, and provided a way to
|
These test cases were vital in debugging and regression testing, and provided a way to
|
||||||
determine which tool was correct when there were differences.
|
determine which tool was correct when there were differences.
|
||||||
|
|
||||||
> A version of this tool in more clearly written C (tac.c)
|
> A version of this tool in more clearly written C ([tac.c](tac.c))
|
||||||
> is presented for the Judge's consideration as a more accurate replacement for `iocccsize`.
|
> is presented for the Judge's consideration as a more accurate replacement for `iocccsize`.
|
||||||
> This obfuscated entry is derived from (and compatible with) that code,
|
> This obfuscated entry is derived from (and compatible with) that code,
|
||||||
> but due to obfuscation, has had some significant, deep changes for the contest.
|
> but due to obfuscation, has had some significant, deep changes for the contest.
|
||||||
> Nevertheless, the more clearly written code remains a spoiler for this entry.
|
> Nevertheless, the more clearly written code remains a spoiler for this entry.
|
||||||
|
|
||||||
NB: `iocccsize` gets a different answer from `tac` on its own
|
NB: `iocccsize` gets a different answer from `tac` on its own
|
||||||
([iocccsize.c]([iocccsize.c](https://www.ioccc.org/2018/iocccsize.c)) source code;
|
([iocccsize.c](/2018/iocccsize.c)) source code;
|
||||||
`tac` gets the correct answer. This is due to the aforementioned bugs within `iocccsize`,
|
`tac` gets the correct answer. This is due to the aforementioned bugs within `iocccsize`,
|
||||||
proved by fixing
|
proved by fixing
|
||||||
[iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) with the included patch, so `iocccsize` reports
|
[iocccsize.c](/2018/iocccsize.c) with the included patch, so `iocccsize` reports
|
||||||
the correct answer for itself.
|
the correct answer for itself.
|
||||||
|
|
||||||
### But wait... There's More!
|
### But wait... There's More!
|
||||||
@@ -201,25 +199,27 @@ cat $* | ./prog -t | iskeyword | sort -k1nr
|
|||||||
This script was used to "optimize" the reserved word order so the most frequent IOCCC
|
This script was used to "optimize" the reserved word order so the most frequent IOCCC
|
||||||
winning entry keywords are checked first.
|
winning entry keywords are checked first.
|
||||||
|
|
||||||
> An interesting aside: as might be expected, obfuscation has changed the frequency of
|
An interesting aside: as might be expected, obfuscation has changed the frequency of
|
||||||
> keyword distribution over time. The top five for the decades:
|
keyword distribution over time. The top five for the decades:
|
||||||
>\
|
|
||||||
> 1980s 1990s 2000s 2010s
|
```
|
||||||
> ----- ----- ----- -----
|
1980s 1990s 2000s 2010s
|
||||||
> 94 if 532 char 375 if 254 int
|
----- ----- ----- -----
|
||||||
> 69 for 524 if 372 char 217 for
|
94 if 532 char 375 if 254 int
|
||||||
> 59 while 417 int 332 int 198 if
|
69 for 524 if 372 char 217 for
|
||||||
> 48 char 223 for 184 for 121 return
|
59 while 417 int 332 int 198 if
|
||||||
> 43 int 223 void 165 return 104 char
|
48 char 223 for 184 for 121 return
|
||||||
|
43 int 223 void 165 return 104 char
|
||||||
|
```
|
||||||
|
|
||||||
The keyword list is external to the program, and is easily changed, sorted, checked, verified.
|
The keyword list is external to the program, and is easily changed, sorted, checked, verified.
|
||||||
This allows such additional programs in concert with the tool's primary operation.
|
This allows such additional programs in concert with the tool's primary operation.
|
||||||
|
|
||||||
A poor-man's de-obfuscator can be based upon the output of `tac -t` and a handful of
|
A poor-man's de-obfuscator can be based upon the output of `tac -t` and a
|
||||||
simple rules (and another use of the external keyword file).
|
handful of simple rules (and another use of the external keyword file). A more
|
||||||
A more refined version of this is included in the file `unob.sh`,
|
refined version of this is included in the file [unob.sh](unob.sh), but the
|
||||||
but the simple code below is a serviceable obfuscated C de-obfuscator in a _scripting language_.
|
simple code below is a serviceable obfuscated C de-obfuscator in a _scripting
|
||||||
It really is this easy with `tac`:
|
language_. It really is this easy with `tac`:
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -277,22 +277,22 @@ sed 's/^# .*$//' | sed 's/^#//' |
|
|||||||
|
|
||||||
* Keywords follow the 2010s top five, without the `if`, for interesting flow control.
|
* Keywords follow the 2010s top five, without the `if`, for interesting flow control.
|
||||||
* Sometimes a `for` can be an `else` - [inconceivable][3]!
|
* Sometimes a `for` can be an `else` - [inconceivable][3]!
|
||||||
* I see the `getopt`. But "[where's the beef?][4]"
|
* I see the `getopt(3)`. But "[where's the beef?][4]"
|
||||||
* No character constants, several int constants, and one string
|
* No character constants, several `int` constants, and one string
|
||||||
(hint: which does not encode letters) -- how does this code parse code?
|
(hint: which does not encode letters) -- how does this code parse code?
|
||||||
> Interesting aside: how many is "several int constants"?
|
- Interesting aside: how many is "several `int` constants"?
|
||||||
>
|
|
||||||
> ./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}'
|
./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}'
|
||||||
> ... | wc
|
... | wc
|
||||||
>
|
|
||||||
> Which numbers are most often used?
|
Which numbers are most often used?
|
||||||
>
|
|
||||||
> ... | sort -k2nr | sed 5q
|
... | sort -k2nr | sed 5q
|
||||||
|
|
||||||
* The code describes its function by careful arrangement of variables up front...
|
* The code describes its function by careful arrangement of variables up front...
|
||||||
* ...coupled with a description of the typical IOCCC contestant, or at least the author
|
* ...coupled with a description of the typical IOCCC contestant, or at least the author
|
||||||
* Why shouldn't trigraph parsing be written in trigraph?
|
* Why shouldn't trigraph parsing be written in trigraph?
|
||||||
* Where [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) mocks, this code flaunts:
|
* Where [iocccsize.c](/2018/iocccsize.c) mocks, this code flaunts:
|
||||||
"_no matter how well you may think you understand this code, you don't, so don't mess with it. :-)_"
|
"_no matter how well you may think you understand this code, you don't, so don't mess with it. :-)_"
|
||||||
* `O,0,l,1` are used to confusing effect, local names obscure global names.
|
* `O,0,l,1` are used to confusing effect, local names obscure global names.
|
||||||
* Globals are used to pass information between routines: don't reorder "unrelated" statements....
|
* Globals are used to pass information between routines: don't reorder "unrelated" statements....
|
||||||
@@ -304,6 +304,7 @@ sed 's/^# .*$//' | sed 's/^#//' |
|
|||||||
[3]: https://www.youtube.com/watch?v=OHVjs4aobqs "Inconceivable"
|
[3]: https://www.youtube.com/watch?v=OHVjs4aobqs "Inconceivable"
|
||||||
[4]: https://www.youtube.com/watch?v=Ug75diEyiA0 "Where's the beef?"
|
[4]: https://www.youtube.com/watch?v=Ug75diEyiA0 "Where's the beef?"
|
||||||
|
|
||||||
|
|
||||||
### Rule 2:
|
### Rule 2:
|
||||||
|
|
||||||
The keyword list is externalized as an include file. This presents a useful
|
The keyword list is externalized as an include file. This presents a useful
|
||||||
@@ -312,27 +313,28 @@ produced, but the tool can be rebuilt with any set of reserved words, just by
|
|||||||
using a different list. For instance: removing all the secondary keywords;
|
using a different list. For instance: removing all the secondary keywords;
|
||||||
removing all the C11 keywords; trying just K&R C. Since C++ and Java share the
|
removing all the C11 keywords; trying just K&R C. Since C++ and Java share the
|
||||||
same operators as C, just change the keyword list and `tac` will correctly
|
same operators as C, just change the keyword list and `tac` will correctly
|
||||||
tokenize both of these; the tokens >>> and :: can be handled with a short
|
tokenize both of these; the tokens `>>>` and `::` can be handled with a short
|
||||||
post-filter ([tokenfix.sh](tokenfix.sh), included).
|
post-filter ([tokenfix.sh](tokenfix.sh), included).
|
||||||
|
|
||||||
I believe this entry may also satisfy the request for gratuitous use of all the C11 keywords?
|
I believe this entry may also satisfy the request for gratuitous use of all the
|
||||||
Whether this context satisfies "intended C language context" is a matter of interpretation. ;-)
|
C11 keywords? Whether this context satisfies "intended C language context" is a
|
||||||
And `tac` is ready for the IOCCC++ contest. And the IOJCC trashcan.
|
matter of interpretation. ;-) And `tac` is ready for the IOCCC++ contest. And
|
||||||
|
the IOJCC trash can.
|
||||||
|
|
||||||
The following reserved word files are included:
|
The following reserved word files are included:
|
||||||
|
|
||||||
|
|
||||||
kandr from my venerable 1978 18th printing "The C Programming Language"
|
* [kandr](kandr) from my venerable 1978 18th printing "The C Programming Language"
|
||||||
v7unix 7th edition Unix source code, extracted from c00.c
|
* [v7unix](v7unix) 7th edition Unix source code, extracted from c00.c
|
||||||
kandr2 from my 1988 1st printing "The C Programming Language", 2e
|
* [kandr2](kandr2) from my 1988 1st printing "The C Programming Language", 2e
|
||||||
ansi ANS X3.159-1989
|
* [ansi](ansi) ANSI X3.159-1989
|
||||||
c99 ISO/IEC 9899:1999(E)
|
* [c99](c99) ISO/IEC 9899:1999(E)
|
||||||
c11 ISO/IEC 9899:201x(E) N1570
|
* [c11](c11) ISO/IEC 9899:201x(E) N1570
|
||||||
c++98 http://en.cppreference.com/w/cpp/keyword
|
* [c++98](c++98) http://en.cppreference.com/w/cpp/keyword
|
||||||
c++11 ISO/IEC 14882:2011(E) N3337 2012-01-16
|
* [c++11](c++11) ISO/IEC 14882:2011(E) N3337 2012-01-16
|
||||||
c++14 ISO/IEC 14882:2014(E) N4296 2014-11-09
|
* [c++14](c++14) ISO/IEC 14882:2014(E) N4296 2014-11-09
|
||||||
java8 http://docs.oracle.com/javase/specs/index.html
|
* [java8](java8) <http://docs.oracle.com/javase/specs/index.html>
|
||||||
ioccc.kw.freq c11 + additional words, sorted on frequency of occurrence in ioccc winners
|
* [ioccc.kw.freq](ioccc.kw.freq) c11 + additional words, sorted on frequency of occurrence in IOCCC winners
|
||||||
|
|
||||||
|
|
||||||
NB: The keyword file used in this code is derived from the list in [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c),
|
NB: The keyword file used in this code is derived from the list in [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c),
|
||||||
@@ -354,11 +356,12 @@ This also allows the builder to configure the amount of help a utility should pr
|
|||||||
([you want a manpage? Because that's how you get a manpage.][5]) -- a rather
|
([you want a manpage? Because that's how you get a manpage.][5]) -- a rather
|
||||||
significant point of contention made moot.
|
significant point of contention made moot.
|
||||||
|
|
||||||
There is definitely abuse of the Rule2 counter, exploiting a "feature" of `iocccsize`:
|
There is definitely abuse of the Rule2 counter, exploiting a "feature" of
|
||||||
`iocccsize` does not Rule2 count {, } and ; when followed by whitespace -- even within a string!
|
`iocccsize`: `iocccsize` does not Rule2 count `{`, `}` and `;` when followed by
|
||||||
Thus: Freecode, a simple, uncounted, highly obfuscated encoding of a central part
|
whitespace -- even within a string! Thus: Freecode, a simple, uncounted, highly
|
||||||
of this program. (The reserved word list is not Freecoded, both because it is useful
|
obfuscated encoding of a central part of this program. (The reserved word list
|
||||||
apart from the program, and because Freecode is not entirely free.*)
|
is not Freecoded, both because it is useful apart from the program, and because
|
||||||
|
Freecode is not entirely free.)
|
||||||
|
|
||||||
* Some restrictions apply. Not approved for all uses. Some assembly required.
|
* Some restrictions apply. Not approved for all uses. Some assembly required.
|
||||||
|
|
||||||
@@ -370,12 +373,12 @@ The code is ANSI compliant, but it does have a string longer than 509 characters
|
|||||||
It has been tested on OSX and Linux, Clang and GCC.
|
It has been tested on OSX and Linux, Clang and GCC.
|
||||||
|
|
||||||
The code uses trigraphs, ironically: it parses trigraphs with trigraph code.
|
The code uses trigraphs, ironically: it parses trigraphs with trigraph code.
|
||||||
Because that's funny. And it remains obscure after, so trigraphs are not used for obfuscation.
|
Because that's funny. And it remains obscure after, so trigraphs are not used
|
||||||
Thus `-trigraphs -Wno-trigraphs` (which is also humorous).
|
for obfuscation. Thus `-trigraphs -Wno-trigraphs` (which is also humorous).
|
||||||
|
|
||||||
It's obfuscated C. Thus `-Wno-parentheses -Wno-empty-body -Wno-char-subscripts`.
|
It's obfuscated C. Thus `-Wno-parentheses -Wno-empty-body -Wno-char-subscripts`.
|
||||||
|
|
||||||
The code uses unsigned chars, but C strings are signed. Thus `-Wno-pointer-sign`.
|
The code uses `unsigned char`s, but C strings are `signed`. Thus `-Wno-pointer-sign`.
|
||||||
NB: This is *not* a portability concern, the one string holds only printable ASCII characters.
|
NB: This is *not* a portability concern, the one string holds only printable ASCII characters.
|
||||||
|
|
||||||
Thus:
|
Thus:
|
||||||
@@ -387,9 +390,9 @@ cc -ansi -Wall -trigraphs -Wno-trigraphs -Wno-parentheses -Wno-empty-body -Wno-c
|
|||||||
### Coda:
|
### Coda:
|
||||||
|
|
||||||
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) was relentless in his pursuit of bugs.
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) was relentless in his pursuit of bugs.
|
||||||
Thanks to his reports, the version of `unob.sh` is stronger,
|
Thanks to his reports, the version of [unob.sh](unob.sh) is stronger,
|
||||||
`tac` groks digraphs, `tokenfix` corrects for missing digraphs in `prog.c`,
|
`tac` groks digraphs, [tokenfix.sh](tokenfix.sh) corrects for missing digraphs
|
||||||
and the program `manpage` was added to the corpus.
|
in [prog.c](prog.c), and the program [manpage.sh](manpage.sh) was added to the corpus.
|
||||||
|
|
||||||
[manpage.sh](manpage.sh) is a useful program that turns ASCII versions of man
|
[manpage.sh](manpage.sh) is a useful program that turns ASCII versions of man
|
||||||
pages (e.g. [tac.man](tac.man)) into real man pages. It works for C and C-like
|
pages (e.g. [tac.man](tac.man)) into real man pages. It works for C and C-like
|
||||||
@@ -401,14 +404,17 @@ are not recognised when written as `-rs` in prose).
|
|||||||
Try:
|
Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./manpage tac
|
./manpage.sh tac
|
||||||
|
|
||||||
./manpage -h
|
./manpage.sh -h
|
||||||
./manpage -h | ./manpage
|
./manpage.sh -h | ./manpage.sh
|
||||||
./manpage -h | ./manpage -R | less
|
./manpage.sh -h | ./manpage.sh -R | less
|
||||||
./manpage -h | ./manpage -P | lpr
|
./manpage.sh -h | ./manpage.sh -P | lpr
|
||||||
```
|
```
|
||||||
|
|
||||||
|
NOTE: in 2023 the `tac.man` was updated to proper man format and renamed
|
||||||
|
[tac.1](tac.1).
|
||||||
|
|
||||||
|
|
||||||
## Copyright and CC BY-SA 4.0 License:
|
## Copyright and CC BY-SA 4.0 License:
|
||||||
|
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
tac comes with a small suite of support programs to test and validate against.
|
|
||||||
Untar tests and variations in the same dir as the sources,
|
|
||||||
or change runtest and unob.sh to look elsewhere for the keyword and test files.
|
|
||||||
|
|
||||||
keywords is a critical file, created from ioccc.kw.freq by mkkeywords.
|
|
||||||
Only ioccc.kw.freq produces results compatible with iocccsize.c;
|
|
||||||
however, any of the variations can be used instead:
|
|
||||||
|
|
||||||
mkkeywords c11 > keywords
|
|
||||||
|
|
||||||
unob.sh uses the same input file as mkkeywords to control spaces after keywords.
|
|
||||||
The script allows an environment variable, KW, to override this.
|
|
||||||
Use it simply:
|
|
||||||
|
|
||||||
unob.sh prog.c | less
|
|
||||||
unob.sh -p prog.c | less
|
|
||||||
KW=c11 unob.sh prog.c | less
|
|
||||||
|
|
||||||
To handle obscure command line defines, use the environment variable DEF:
|
|
||||||
|
|
||||||
DEF="-D'g(o)'='goto o;'" KW=c11 unob.sh -p prog.c | less
|
|
||||||
|
|
||||||
It does an amazingly good job for such a simple script.
|
|
||||||
|
|
||||||
Manifest
|
|
||||||
|
|
||||||
prog.c the reason for this README
|
|
||||||
keywords the file #included in prog.c, output of mkkeywords
|
|
||||||
mkkeywords reads one of the files from variations, produces string for prog.c
|
|
||||||
ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners
|
|
||||||
unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir
|
|
||||||
tokenfix patches up prog -t output for ::, >>>, ...
|
|
||||||
src.doc.txt the answers, or at least significant help
|
|
||||||
tac.c more clearly written code, offered as a replacement of iocccsize.c
|
|
||||||
patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I"
|
|
||||||
fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added
|
|
||||||
|
|
||||||
tests/*
|
|
||||||
runtest script to run the tests; ./runtest | diff results -
|
|
||||||
results results without -k
|
|
||||||
results.k results with -k; opt=kcrs ./runtest | diff results.k -
|
|
||||||
test*.c various test cases looking for compatability
|
|
||||||
iocccbug*.c various test cases demonstrating problems with iocccsize
|
|
||||||
spotcheck script to test a lot of files vs iocccsize
|
|
||||||
spotdiff summarize the results of spotcheck, showing only differences
|
|
||||||
discrepancies text file of the differences found using all the ioccc winning entries
|
|
||||||
|
|
||||||
to test prog:
|
|
||||||
|
|
||||||
runtest | diff - results
|
|
||||||
opt=kcrs runtest | diff - results.k
|
|
||||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck prog
|
|
||||||
[ | spotdiff | diff -bw - discrepancies ]
|
|
||||||
|
|
||||||
to test tac:
|
|
||||||
|
|
||||||
prog=tac runtest | diff - results
|
|
||||||
prog=tac opt=krs runtest | diff - results.k
|
|
||||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck tac
|
|
||||||
|
|
||||||
variations/* as described in the remarks, and in each file below
|
|
||||||
ansi
|
|
||||||
c++11
|
|
||||||
c++14
|
|
||||||
c++98
|
|
||||||
c11
|
|
||||||
c99
|
|
||||||
java8
|
|
||||||
kandr
|
|
||||||
kandr2
|
|
||||||
v7unix
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
tac comes with a small suite of support programs to test and validate against.
|
tac comes with a small suite of support programs to test and validate against.
|
||||||
Untar tests and variations in the same dir as the sources,
|
Untar tests and variations in the same dir as the sources,
|
||||||
or change runtest and unob.sh to look elsewhere for the keyword and test files.
|
or change runtest.sh and unob.sh to look elsewhere for the keyword and test files.
|
||||||
|
|
||||||
keywords is a critical file, created from ioccc.kw.freq by mkkeywords.
|
keywords is a critical file, created from ioccc.kw.freq by mkkeywords.sh.
|
||||||
Only ioccc.kw.freq produces results compatible with iocccsize.c;
|
Only ioccc.kw.freq produces results compatible with iocccsize.c;
|
||||||
however, any of the variations can be used instead:
|
however, any of the variations can be used instead:
|
||||||
|
|
||||||
mkkeywords c11 > keywords
|
mkkeywords.sh c11 > keywords
|
||||||
|
|
||||||
unob.sh uses the same input file as mkkeywords to control spaces after keywords.
|
unob.sh uses the same input file as mkkeywords.sh to control spaces after keywords.
|
||||||
The script allows an environment variable, KW, to override this.
|
The script allows an environment variable, KW, to override this.
|
||||||
Use it simply:
|
Use it simply:
|
||||||
|
|
||||||
@@ -25,38 +25,38 @@ It does an amazingly good job for such a simple script.
|
|||||||
Manifest
|
Manifest
|
||||||
|
|
||||||
prog.c the reason for this README
|
prog.c the reason for this README
|
||||||
keywords the file #included in prog.c, output of mkkeywords
|
keywords the file #included in prog.c, output of mkkeywords.sh
|
||||||
mkkeywords reads one of the files from variations, produces string for prog.c
|
mkkeywords.sh reads one of the files from variations, produces string for prog.c
|
||||||
ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners
|
ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners
|
||||||
unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir
|
unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir
|
||||||
tokenfix patches up prog -t output for ::, >>>, ...
|
tokenfix.sh patches up prog -t output for ::, >>>, ...
|
||||||
src.doc.txt the answers, or at least significant help
|
src.doc.txt the answers, or at least significant help
|
||||||
tac.c more clearly written code, offered as a replacement of iocccsize.c
|
tac.c more clearly written code, offered as a replacement of iocccsize.c
|
||||||
patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I"
|
patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I"
|
||||||
fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added
|
fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added
|
||||||
|
|
||||||
tests/*
|
tests/*
|
||||||
runtest script to run the tests; ./runtest | diff results -
|
runtest.sh script to run the tests; ./runtest.sh | diff results -
|
||||||
results results without -k
|
results results without -k
|
||||||
results.k results with -k; opt=kcrs ./runtest | diff results.k -
|
results.k results with -k; opt=kcrs ./runtest.sh | diff results.k -
|
||||||
test*.c various test cases looking for compatability
|
test*.c various test cases looking for compatibility
|
||||||
iocccbug*.c various test cases demonstrating problems with iocccsize
|
iocccbug*.c various test cases demonstrating problems with iocccsize
|
||||||
spotcheck script to test a lot of files vs iocccsize
|
spotcheck.sh script to test a lot of files vs iocccsize
|
||||||
spotdiff summarize the results of spotcheck, showing only differences
|
spotdiff.sh summarize the results of spotcheck.sh, showing only differences
|
||||||
discrepancies text file of the differences found using all the ioccc winning entries
|
discrepancies.md markdown file of the differences found using all the ioccc winning entries
|
||||||
|
|
||||||
to test prog:
|
to test prog:
|
||||||
|
|
||||||
runtest | diff - results
|
runtest.sh | diff - results
|
||||||
opt=kcrs runtest | diff - results.k
|
opt=kcrs runtest.sh | diff - results.k
|
||||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck prog
|
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck.sh prog
|
||||||
[ | spotdiff | diff -bw - discrepancies ]
|
[ | spotdiff.sh | diff -bw - discrepancies ]
|
||||||
|
|
||||||
to test tac:
|
to test tac:
|
||||||
|
|
||||||
prog=tac runtest | diff - results
|
prog=tac runtest.sh | diff - results
|
||||||
prog=tac opt=krs runtest | diff - results.k
|
prog=tac opt=krs runtest.sh | diff - results.k
|
||||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck tac
|
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck.sh tac
|
||||||
|
|
||||||
variations/* as described in the remarks, and in each file below
|
variations/* as described in the remarks, and in each file below
|
||||||
ansi
|
ansi
|
||||||
|
|||||||
File renamed without changes.
@@ -230,7 +230,7 @@ href="https://ioccc-src.github.io/temp-test-ioccc/2018/burton2/discrepancies.htm
|
|||||||
<tr class="odd">
|
<tr class="odd">
|
||||||
<td style="text-align: left;">frequency count utility</td>
|
<td style="text-align: left;">frequency count utility</td>
|
||||||
<td style="text-align: left;"><a
|
<td style="text-align: left;"><a
|
||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/freqcount">freqcount</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/freqcount.sh">freqcount.sh</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td style="text-align: left;">tokenize and count man page</td>
|
<td style="text-align: left;">tokenize and count man page</td>
|
||||||
@@ -299,7 +299,7 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/manp
|
|||||||
<td style="text-align: left;">reads a file from variations produces
|
<td style="text-align: left;">reads a file from variations produces
|
||||||
string for prog.c</td>
|
string for prog.c</td>
|
||||||
<td style="text-align: left;"><a
|
<td style="text-align: left;"><a
|
||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/mkkeywords">mkkeywords</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/mkkeywords.sh">mkkeywords.sh</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td style="text-align: left;">results with -k</td>
|
<td style="text-align: left;">results with -k</td>
|
||||||
@@ -454,13 +454,13 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/resu
|
|||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td style="text-align: left;">test suite</td>
|
<td style="text-align: left;">test suite</td>
|
||||||
<td style="text-align: left;"><a
|
<td style="text-align: left;"><a
|
||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/runtest">runtest</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/runtest.sh">runtest.sh</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="odd">
|
<tr class="odd">
|
||||||
<td style="text-align: left;">script to test a lot of files vs
|
<td style="text-align: left;">script to test a lot of files vs
|
||||||
iocccsize</td>
|
iocccsize</td>
|
||||||
<td style="text-align: left;"><a
|
<td style="text-align: left;"><a
|
||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotcheck">spotcheck</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotcheck.sh">spotcheck.sh</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td style="text-align: left;">reserved words for a given C standard</td>
|
<td style="text-align: left;">reserved words for a given C standard</td>
|
||||||
@@ -468,9 +468,9 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spot
|
|||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/v7unix">v7unix</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/v7unix">v7unix</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="odd">
|
<tr class="odd">
|
||||||
<td style="text-align: left;">summarize the results of spotcheck</td>
|
<td style="text-align: left;">summarize the results of spotcheck.sh</td>
|
||||||
<td style="text-align: left;"><a
|
<td style="text-align: left;"><a
|
||||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotdiff">spotdiff</a></td>
|
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotdiff.sh">spotdiff.sh</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="even">
|
<tr class="even">
|
||||||
<td style="text-align: left;">download winning source</td>
|
<td style="text-align: left;">download winning source</td>
|
||||||
|
|||||||
File renamed without changes.
Regular → Executable
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,139 @@
|
|||||||
|
.TH tac 1 "01 April 2018" "tac" "IOCCC 2018"
|
||||||
|
.SH NAME
|
||||||
|
tac \- tokenize and count C-like program source code
|
||||||
|
.SH SYNOPSIS
|
||||||
|
\fBtac\fP [\-t] [\-c] [\-k] [\-r] [\-s] [\-i] [file]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fBtac\fP reads C or C-like source code from \fBstdin\fP or file, breaking it into tokens (lexemes),
|
||||||
|
counting these according to the rules of the IOCCC, and outputting the tokens,
|
||||||
|
counts, or source code as directed by the command line options.
|
||||||
|
The default output is the source code with comments removed on \fBstdout\fP,
|
||||||
|
and the counts on \fBstderr\fP.
|
||||||
|
The count format is a set of integer values in the following order:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
.B lines
|
||||||
|
number of newlines
|
||||||
|
.TQ
|
||||||
|
.B words
|
||||||
|
number of words
|
||||||
|
.TQ
|
||||||
|
.B chars
|
||||||
|
number of characters
|
||||||
|
.TQ
|
||||||
|
.B ioccc
|
||||||
|
number of IOCCC countable tokens; the IOCCC rule 2 value
|
||||||
|
.TQ
|
||||||
|
.B saved
|
||||||
|
number of characters not counted due to rules and keywords
|
||||||
|
.TQ
|
||||||
|
.B kwcnt
|
||||||
|
number of keywords
|
||||||
|
.TQ
|
||||||
|
.B kwlen
|
||||||
|
number of characters saved by counting keyword length as 1
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
For the following code:
|
||||||
|
.sp
|
||||||
|
.RS 4
|
||||||
|
.nf
|
||||||
|
#include <stdio.h>
|
||||||
|
int main() {
|
||||||
|
/* example for loop */
|
||||||
|
for (int ac=1; ac<10; ++ac)
|
||||||
|
printf("%d\n", ac);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
\fBtac\fP prints the code to \fBstdout\fP, and to \fBstderr\fP: '6 15 96 71 25 5 0'
|
||||||
|
which means 6 lines, 15 words, 96 chars, 71 IOCCC counts, 25 chars saved,
|
||||||
|
5 \fBkwcnt\fP, and no characters saved from \fBkwlen\fP. (By default, comments are not
|
||||||
|
counted.)
|
||||||
|
.SH OPTIONS
|
||||||
|
The following options are supported:
|
||||||
|
.TP
|
||||||
|
.B \-t
|
||||||
|
Output just the token stream.
|
||||||
|
.TP
|
||||||
|
.B \-c
|
||||||
|
Correct the accounting bugs in \fBiocccsize(1)\fP, output the token id and the token.
|
||||||
|
.TP
|
||||||
|
.B \-k
|
||||||
|
Keep the comments.
|
||||||
|
.TP
|
||||||
|
.B \-r
|
||||||
|
Reserved words count as size 1.
|
||||||
|
.TP
|
||||||
|
.B \-s
|
||||||
|
Suppress the source code, summarize counts only.
|
||||||
|
.TP
|
||||||
|
.B \-i
|
||||||
|
Report only the official IOCCC rule 2 size: number of octets (implies \fB\-r\fP and \fB\-s\fP).
|
||||||
|
.PP
|
||||||
|
Counts are impacted by the \fB\-k\fP, \fB\-r\fP and \fB\-c\fP options.
|
||||||
|
By default, the counts do not include comments, words are counted as in \fBwc(1)\fP, and reserved words count in full.
|
||||||
|
Using the example code above, the options change the counts as follows:
|
||||||
|
.PP
|
||||||
|
.TP
|
||||||
|
\fB\-r\fP
|
||||||
|
6 15 96 53 25 5 18
|
||||||
|
.TQ
|
||||||
|
\fB\-k\fP
|
||||||
|
7 20 120 89 31 5 0
|
||||||
|
.TQ
|
||||||
|
\fB\-c\fP
|
||||||
|
7 36 98 71 27 5 0
|
||||||
|
.PP
|
||||||
|
The \fB\-c\fP option counts tokens instead of words, and is therefore more accurate for source code.
|
||||||
|
Note the aberration for line count with \fB\-r\fP; it is as\-if the comment never existed.
|
||||||
|
.PP
|
||||||
|
The \fB\-c\fP and \fB\-t\fP options change the output, instead writing a stream of tokens to \fBstdout\fP, one token per line.
|
||||||
|
The \fB\-t\fP option suppresses both the counts and the token ids, writing only the tokens.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.PP
|
||||||
|
Summarize the source code counts:
|
||||||
|
.sp
|
||||||
|
.RS
|
||||||
|
.ft B
|
||||||
|
tac -rs tac.c
|
||||||
|
.ft R
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
Count the 10 most frequently used unique tokens in the source code:
|
||||||
|
.sp
|
||||||
|
.RS
|
||||||
|
.ft B
|
||||||
|
tac -t tac.c 2>/dev/null | sort | uniq -c | sort -k1nr | sed 10q
|
||||||
|
.ft R
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
Count the unique constants in the source:
|
||||||
|
.sp
|
||||||
|
.RS
|
||||||
|
.ft B
|
||||||
|
tac -c tac.c 2>/dev/null | grep ^300 | sort | uniq -c | sort -k1nr | awk '{print $1,$3}'
|
||||||
|
.ft R
|
||||||
|
.RE
|
||||||
|
.SH BUGS
|
||||||
|
\fBtac\fP does not properly count preprocessor tokens with embedded space or comments as reserved words:
|
||||||
|
.sp
|
||||||
|
.RS
|
||||||
|
.ft B
|
||||||
|
echo '#/*comment*/include/*comment*/<stdio.h>' | tac -i
|
||||||
|
.br
|
||||||
|
echo '# include<stdio.h>' | tac -i
|
||||||
|
.br
|
||||||
|
echo '#include<stdio.h>' | tac -i
|
||||||
|
.ft R
|
||||||
|
.RE
|
||||||
|
.sp
|
||||||
|
report no reserved words on the first two inputs, and thus 17 as the IOCCC size, although 10 is the correct answer (as in the final example).
|
||||||
|
.PP
|
||||||
|
The original meaning of the \fB\-c\fP option was "become compatible with \fBiocccsize(1)\fP".
|
||||||
|
Its meaning was flipped so the default behavior is now compatible.
|
||||||
|
.SH SEE ALSO
|
||||||
|
\fBiocccsize(1)\fP, \fBwc(1)\fP
|
||||||
|
.br
|
||||||
|
\<https://ioccc.org/2015/rules.txt\>
|
||||||
+1
-1
@@ -37,7 +37,7 @@ awk '/^[^$]/{l=length;m=m>l?m:l;a[l]=a[l]$1}
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT the string kw; instead:
|
* DO NOT EDIT the string kw; instead:
|
||||||
*
|
*
|
||||||
* mkkeywords < my.list > my.keywords
|
* mkkeywords.sh < my.list > my.keywords
|
||||||
* cc -DW=\"my.keywords\" -o tac tac.c
|
* cc -DW=\"my.keywords\" -o tac tac.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
NAME
|
|
||||||
tac - tokenize and count C-like program source code
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
tac [-t] [-c] [-k] [-r] [-s] [-i] [file]
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
tac reads C or C-like source code from stdin or file, breaking it into tokens (lexemes),
|
|
||||||
counting these according to the rules of the IOCCC, and outputting the tokens,
|
|
||||||
counts, or source code as directed by the command line options.
|
|
||||||
The default output is the source code with comments removed on stdout,
|
|
||||||
and the counts on stderr.
|
|
||||||
|
|
||||||
The count format is a set of integer values in the following order:
|
|
||||||
|
|
||||||
lines number of newlines
|
|
||||||
words number of words
|
|
||||||
chars number of characters
|
|
||||||
ioccc number of IOCCC countable tokens; the IOCCC rule 2 value
|
|
||||||
saved number of characters not counted due to rules and keywords
|
|
||||||
kwcnt number of keywords
|
|
||||||
kwlen number of characters saved by counting keyword length as 1
|
|
||||||
|
|
||||||
For the following code:
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
int main() {
|
|
||||||
/* example for loop */
|
|
||||||
for (int ac=1; ac<10; ++ac)
|
|
||||||
printf("%d\n", ac);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tac prints the code to stdout, and to stderr:
|
|
||||||
|
|
||||||
6 15 96 71 25 5 0
|
|
||||||
|
|
||||||
which means 6 lines, 15 words, 96 chars, 71 IOCCC counts, 25 chars saved,
|
|
||||||
5 kwcnt, and no characters saved from kwlen. (By default, comments are not
|
|
||||||
counted.)
|
|
||||||
|
|
||||||
The following options are supported:
|
|
||||||
|
|
||||||
-t output just the token stream
|
|
||||||
-c correct the accounting bugs in iocccsize(1), output the token id and the token
|
|
||||||
-k keep the comments
|
|
||||||
-r reserved words count as size 1
|
|
||||||
-s suppress the source code, summarize counts only
|
|
||||||
-i report only the official IOCCC rule 2 size: number of octets (implies -r and -s)
|
|
||||||
|
|
||||||
Counts are impacted by the -k, -r and -c options.
|
|
||||||
By default, the counts do not include comments, words are counted as in wc(1),
|
|
||||||
and reserved words count in full.
|
|
||||||
Using the example code above, the options change the counts as follows:
|
|
||||||
|
|
||||||
-r 6 15 96 53 25 5 18
|
|
||||||
-k 7 20 120 89 31 5 0
|
|
||||||
-c 7 36 98 71 27 5 0
|
|
||||||
|
|
||||||
The -c option counts tokens instead of words, and is therefore more accurate for source code.
|
|
||||||
Note the aberration for line count with -r; it is as-if the comment never existed.
|
|
||||||
|
|
||||||
The -c and -t options change the output, instead writing a stream of tokens to stdout,
|
|
||||||
one token per line.
|
|
||||||
The -t option suppresses both the counts and the token ids, writing only the tokens.
|
|
||||||
|
|
||||||
EXAMPLES
|
|
||||||
Summarize the source code counts:
|
|
||||||
|
|
||||||
tac -rs tac.c
|
|
||||||
|
|
||||||
Count the 10 most frequently used unique tokens in the source code:
|
|
||||||
|
|
||||||
tac -t tac.c 2>/dev/null | sort | uniq -c | sort -k1nr | sed 10q
|
|
||||||
|
|
||||||
Count the unique constants in the source:
|
|
||||||
|
|
||||||
tac -c tac.c 2>/dev/null | grep ^300 | sort | uniq -c | sort -k1nr | awk '{print $1,$3}'
|
|
||||||
|
|
||||||
BUGS
|
|
||||||
tac does not properly count preprocessor tokens with embedded space or
|
|
||||||
comments as reserved words:
|
|
||||||
|
|
||||||
echo '#/*comment*/include/*comment*/<stdio.h>' | tac -i
|
|
||||||
echo '# include<stdio.h>' | tac -i
|
|
||||||
echo '#include<stdio.h>' | tac -i
|
|
||||||
|
|
||||||
reports no reserved words on the first two inputs, and thus 17 as the IOCCC size,
|
|
||||||
although 10 is the correct answer (as in the final example).
|
|
||||||
|
|
||||||
The original meaning of the -c option was "become compatible with iocccsize(1)".
|
|
||||||
Its meaning was flipped so the default behavior is now compatible.
|
|
||||||
|
|
||||||
SEE ALSO
|
|
||||||
iocccsize(1), wc(1)
|
|
||||||
http://ioccc.org/2015/rules.txt
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cat $* | ./prog -t | sort | uniq -c | sort -k1nr
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/burton2
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
|
||||||
|
echo "$ ./prog -i < prog.c" 1>&2
|
||||||
|
./prog -i < prog.c
|
||||||
|
|
||||||
|
echo "$ ./prog -s < prog.c" 1>&2
|
||||||
|
./prog -s < prog.c
|
||||||
|
|
||||||
|
echo "$ ./prog -sk < prog.c" 1>&2
|
||||||
|
./prog -sk < prog.c
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: make test (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
make test | less -EXF
|
||||||
@@ -108,4 +108,4 @@ tern && /^:/ { newline(); show($0); --tern; --n; next }
|
|||||||
{ show($0) }
|
{ show($0) }
|
||||||
'
|
'
|
||||||
|
|
||||||
pp $* | $PROG -t | ./tokenfix | awk "$script" # sed 's/""//g'
|
pp $* | $PROG -t | ./tokenfix.sh | awk "$script" # sed 's/""//g'
|
||||||
@@ -3151,8 +3151,19 @@ There was no IOCCC in 2017.
|
|||||||
### Source code: [2018/algmyr/algmyr.c](2018/algmyr/algmyr.c)
|
### Source code: [2018/algmyr/algmyr.c](2018/algmyr/algmyr.c)
|
||||||
### Information: [2018/algmyr/README.md](2018/algmyr/README.md)
|
### Information: [2018/algmyr/README.md](2018/algmyr/README.md)
|
||||||
|
|
||||||
This entry is known to crash if a file cannot be opened. This is noted by the
|
The author wrote:
|
||||||
author and is easy enough to fix but need not be.
|
|
||||||
|
* There is no error checking done when opening files, so expect segfaults if you
|
||||||
|
provide the wrong path to a file.
|
||||||
|
* This program is bound to misbehave if `int` is less than 32 bits.
|
||||||
|
* Flags will only be interpreted correctly if they are the first argument. Reading
|
||||||
|
a file named `-d` or `-h` is fully possible if it is not the first file
|
||||||
|
provided, even though I am not sure why you would want to do that.
|
||||||
|
* Providing invalid/unexpected arguments to the decode flag will result in odd
|
||||||
|
behavior. Some erroneous arguments cause segfaults (negative number of channels,
|
||||||
|
channel id outside valid range). One argument in particular causes an infinite
|
||||||
|
loop printing whitespace.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 2018 hou
|
## 2018 hou
|
||||||
@@ -3171,6 +3182,25 @@ Abort trap: 6
|
|||||||
|
|
||||||
but this is expected and the file `ioccc.html` will be generated properly.
|
but this is expected and the file `ioccc.html` will be generated properly.
|
||||||
|
|
||||||
|
|
||||||
|
## 2018 mills
|
||||||
|
|
||||||
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
### Source code: [2018/mills/prog.c](2018/mills/prog.c)
|
||||||
|
### Information: [2018/mills/README.md](2018/mills/README.md)
|
||||||
|
|
||||||
|
The author stated that if you make a typo it can happen that the boot loader can
|
||||||
|
crash and halt. If this is the case type ctrl-e to quit the emulator and try
|
||||||
|
again.
|
||||||
|
|
||||||
|
The author also stated that it is possible to corrupt the virtual disk. If you
|
||||||
|
do this you should type `make clobber all` and try again.
|
||||||
|
|
||||||
|
Cody caused a funny problem where it showed `ERROR` after each command. The
|
||||||
|
solution was to hit ctrl-e and start again. He does not know if this is what was
|
||||||
|
referred to by the author though he doesn't think he made a typo either.
|
||||||
|
|
||||||
|
|
||||||
## 2018 vokes
|
## 2018 vokes
|
||||||
|
|
||||||
### STATUS: INABIAF - please **DO NOT** fix
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
|||||||
@@ -3952,6 +3952,17 @@ He also added the [try.sh](/2015/yang/try.sh) script.
|
|||||||
# <a name="2018"></a>2018
|
# <a name="2018"></a>2018
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_anderson"></a>[2018/anderson](/2018/anderson/prog.c) ([README.md](/2018/anderson/README.md))
|
||||||
|
|
||||||
|
[Cody](#cody) added the [try.sh](/2018/anderson/try.sh) script.
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_algmyr"></a>[2018/algmyr](/2018/algmyr/prog.c) ([README.md](/2018/algmyr/README.md))
|
||||||
|
|
||||||
|
|
||||||
|
[Cody](#cody) added the [try.sh](/2018/algmyr/try.sh) script.
|
||||||
|
|
||||||
|
|
||||||
## <a name="2018_bellard"></a>[2018/bellard](/2018/bellard/prog.c) ([README.md](/2018/bellard/README.md))
|
## <a name="2018_bellard"></a>[2018/bellard](/2018/bellard/prog.c) ([README.md](/2018/bellard/README.md))
|
||||||
|
|
||||||
[Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this
|
[Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this
|
||||||
@@ -3961,6 +3972,40 @@ Cody also added [alt code](/2018/bellard/README.md#alternate-code) that should
|
|||||||
work for Windows, based on the author's remarks.
|
work for Windows, based on the author's remarks.
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_burton1"></a>[2018/burton1](/2018/burton1/prog.c) ([README.md](/2018/burton1/README.md))
|
||||||
|
|
||||||
|
[Cody](#cody) fixed the `scripthd` script (referred to `prog` not `./prog`) and
|
||||||
|
renamed it to [scripthd.sh](/2018/burton1/scripthd.sh) to help browsers and
|
||||||
|
GitHub as far as downloading/displaying goes.
|
||||||
|
|
||||||
|
Cody also added the [try.sh](/2018/burton1/try.sh) script which also uses
|
||||||
|
`scripthd.sh` to show how it differs from `prog` itself.
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_burton2"></a>[2018/burton2](/2018/burton2/prog.c) ([README.md](/2018/burton2/README.md))
|
||||||
|
|
||||||
|
[Cody](#cody) fixed the `make test` rule: it tried to run `tac(1)` (in systems
|
||||||
|
that have that command) rather than the entry itself which is called `tac` and
|
||||||
|
the `runtest` script (which he renamed to `runtest.sh` for download/browser
|
||||||
|
display purposes) was not executable.
|
||||||
|
|
||||||
|
Cody also renamed `manpage` to `manpage.sh` for download/browser purposes and he
|
||||||
|
did the same with `tokenfix` to `tokenfix.sh` as well as `spotcheck` to
|
||||||
|
`spotcheck.sh`, `spotdiff` to `spotdiff.sh`, `freqcount` to `freqcount.sh` and
|
||||||
|
`mkkeywords` to `mkkeywords.sh`.
|
||||||
|
|
||||||
|
Cody also made the man page properly formatted for `man(1)` and renamed it the
|
||||||
|
file `tac.1`.
|
||||||
|
|
||||||
|
Cody also renamed `discrepancies` to `discrepancies.md` and made it markdown
|
||||||
|
format.
|
||||||
|
|
||||||
|
Cody added the [tokcount.sh](/2018/burton2/tokcount.sh) script which was
|
||||||
|
included in the remarks of the author but not an included file.
|
||||||
|
|
||||||
|
Finally Cody added the [try.sh](/2018/burton2/try.sh) script.
|
||||||
|
|
||||||
|
|
||||||
## <a name="2018_ciura"></a>[2018/ciura](/2018/ciura/prog.c) ([README.md](/2018/ciura/README.md))
|
## <a name="2018_ciura"></a>[2018/ciura](/2018/ciura/prog.c) ([README.md](/2018/ciura/README.md))
|
||||||
|
|
||||||
[Cody](#cody) added the [try.sh](/2018/ciura/try.sh) script and the PDF file,
|
[Cody](#cody) added the [try.sh](/2018/ciura/try.sh) script and the PDF file,
|
||||||
|
|||||||
Reference in new issue
Block a user