Add 1992/gson/try.sh, add note about optimiser
The optimiser must be disabled due to it otherwise crashing in macOS in some invocations. This has been added to the Makefile, the use of -O0 is forced and a note has been added to the README.md file. The bugs.md file has been updated on details of how it uses gets() and that text has been removed from the thanks file. Minor format fixes in README.md. The script added makes use of the author's script (that I added as mkdict.sh for easier use) after first trying to find a dictionary file. But one can override the dictionary file with the DICT environmental variable. This entry should now truly be done.
This commit is contained in:
1 parent
fed6b32f0a
commit
54c5271117
5 files changed
+158
-20
No files matched your search
+8
-3
@@ -42,7 +42,7 @@ CSILENCE= -Wno-bitwise-op-parentheses -Wno-char-subscripts \
|
||||
-Wno-deprecated-declarations -Wno-empty-body -Wno-error \
|
||||
-Wno-implicit-function-declaration -Wno-parentheses -Wno-pedantic \
|
||||
-Wno-return-type -Wno-unused-parameter -Wno-unused-value \
|
||||
-Wno-deprecated-non-prototype
|
||||
-Wno-deprecated-non-prototype -Wno-implicit-int
|
||||
|
||||
# Common C compiler warning flags
|
||||
#
|
||||
@@ -69,7 +69,9 @@ CINCLUDE=
|
||||
|
||||
# Optimization
|
||||
#
|
||||
OPT=
|
||||
# We DISABLE the optimiser because having it enabled will cause a crash in some
|
||||
# invocations in some systems.
|
||||
OPT= -O0
|
||||
|
||||
# Default flags for ANSI C compilation
|
||||
#
|
||||
@@ -133,8 +135,11 @@ all: data ${TARGET}
|
||||
clean clobber install love haste waste maker easter_egg \
|
||||
sandwich supernova deep_magic magic charon pluto
|
||||
|
||||
# We DISABLE THE OPTIMISER because when it's enabled in some conditions it
|
||||
# crashes.
|
||||
#
|
||||
${PROG}: ${PROG}.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
${CC} ${CFLAGS} -O0 $< -o $@ ${LDFLAGS}
|
||||
|
||||
ag: ${PROG}
|
||||
${RM} -f $@
|
||||
|
||||
+6
-1
@@ -4,6 +4,10 @@
|
||||
make all
|
||||
```
|
||||
|
||||
NOTE: we DISABLE the optimiser because having it enabled causes some invocations
|
||||
to crash in some systems.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
@@ -127,13 +131,14 @@ Instead, it tries to achieve both its speed and its obscurity through a
|
||||
careful choice of algorithms. Some of the finer points of those
|
||||
algorithms are outlined in the spoiler below.
|
||||
|
||||
|
||||
### How it works:
|
||||
|
||||
Here follows a description of some of the data structures and
|
||||
algorithms used by AG. It is by no means complete, but it may help
|
||||
you get an idea about the general principles.
|
||||
|
||||
--
|
||||
---
|
||||
|
||||
Internally, AG represents words and sentences as arrays of 32
|
||||
4-bit integer elements. Each element represents the number of
|
||||
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# try.sh - demonstrate IOCCC winner 1992/gson
|
||||
#
|
||||
|
||||
# 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
|
||||
|
||||
# attempt to find a dictionary file if DICT unset or not a regular readable file
|
||||
#
|
||||
if [[ -z "$DICT" || ! -f "$DICT" || ! -r "$DICT" ]]; then
|
||||
DICT="/usr/share/dict/words"
|
||||
|
||||
if [[ ! -r "$DICT" ]]; then
|
||||
DICT="/usr/share/lib/spell/words"
|
||||
|
||||
if [[ ! -r "$DICT" ]]; then
|
||||
DICT="/usr/ucblib/dict/words"
|
||||
|
||||
if [[ ! -r "$DICT" ]]; then
|
||||
DICT="/dev/null"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# safety check that DICT is not empty and is a readable file
|
||||
#
|
||||
if [[ -z "$DICT" || ! -f "$DICT" || ! -r "$DICT" ]]; then
|
||||
echo "No dictionary file found, try specifying one like:" 1>&2
|
||||
echo 1>&2
|
||||
echo " DICT=dict ./try.sh" 1>&2
|
||||
echo 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$ ./ag free software foundation < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag free software foundation < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag obfuscated c contest < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag obfuscated c contest < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag unix international < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag unix international < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag george bush < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag george bush < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag bill clinton < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag bill clinton < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag ross perot < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag ross perot < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag paul e tsongas < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag paul e tsongas < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
# now try making our own dictionary with mkdict.sh:
|
||||
#
|
||||
rm -f words
|
||||
cat README.md try.sh Makefile | ./mkdict.sh > words
|
||||
DICT="words"
|
||||
|
||||
read -r -n 1 -p "Press any key to use our own dict from mkdict.sh: "
|
||||
echo 1>&2
|
||||
|
||||
echo "$ ./ag free software foundation < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag free software foundation < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag obfuscated c contest < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag obfuscated c contest < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag unix international < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag unix international < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag george bush < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag george bush < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag bill clinton < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag bill clinton < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag ross perot < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag ross perot < "$DICT" 2>/dev/null | less -rEXF
|
||||
|
||||
echo "$ ./ag paul e tsongas < $DICT" 1>&2
|
||||
read -r -n 1 -p "Press any key to continue (space = next page, q = quit): "
|
||||
echo 1>&2
|
||||
./ag paul e tsongas < "$DICT" 2>/dev/null | less -rEXF
|
||||
@@ -893,7 +893,18 @@ problem of `gets()` being used in a more complex way.
|
||||
|
||||
It would be ideal if it were to use `fgets()` though. This will probably be
|
||||
looked at later but you're welcome to try and fix this too! A tip on how
|
||||
`gets()` is being used is in the [FAQ](/faq.md#gets) file.
|
||||
`gets()` is being used from Cody:
|
||||
|
||||
Previously it had a buffer size of 256 which could easily overflow. In this
|
||||
entry `gets(3)` is used in a more complicated way: first `m` is set to `*++p` in
|
||||
a for loop where `p` is argv. Later `m` is set to point to `h` which was of size
|
||||
256. `gets(3)` is called as `m = gets(m)`) but trying to change it to use
|
||||
`fgets(3)` proved more a problem. Since the input must come from the command
|
||||
line Cody changed the buffer size to `ARG_MAX+1` which should be enough (again
|
||||
theoretically) especially since the command expects redirecting a dictionary
|
||||
file as part of the command line. This also makes it possible for longer strings
|
||||
to be read (in case the `gets(3)` was not used in a loop).
|
||||
|
||||
|
||||
|
||||
## 1992 kivinen
|
||||
|
||||
+9
-15
@@ -1420,25 +1420,19 @@ commands that we suggested and some additional ones that provide for some fun.
|
||||
[Cody](#cody) fixed a crash that prevented this entry from working in some cases in some
|
||||
systems (like macOS) by disabling the optimiser in the Makefile.
|
||||
|
||||
Cody also changed the buffer size in such a way that `gets(3)` should be safe
|
||||
(theoretically) as it comes from the command line (though it can also read input
|
||||
from stdin after starting the program). Ideally `fgets(3)` would be used but this
|
||||
is a more problematic. Previously it had a buffer size of 256 which could
|
||||
easily overflow. In this entry `gets(3)` is used in a more complicated way:
|
||||
first `m` is set to `*++p` in a for loop where `p` is argv. Later `m` is set to
|
||||
point to `h` which was of size 256. `gets(3)` is called as `m = gets(m)`) but
|
||||
trying to change it to use `fgets(3)` proved more a problem. Since the input must
|
||||
come from the command line Cody changed the buffer size to `ARG_MAX+1` which
|
||||
should be enough (again theoretically) especially since the command expects
|
||||
redirecting a dictionary file as part of the command line. This also makes it
|
||||
possible for longer strings to be read (in case the `gets(3)` was not used in a
|
||||
loop).
|
||||
Cody also added the [try.sh](/1992/gson/try.sh) script.
|
||||
|
||||
Cody also added the [mkdict.sh](/1992/gson/mkdict.sh) script that the author
|
||||
included in their remarks. See the README.md for its purpose. It was NOT fixed
|
||||
for [ShellCheck](https://github.com/koalaman/shellcheck)
|
||||
because the author deliberately obfuscated it so **PLEASE DO NOT
|
||||
FIX THIS**.
|
||||
because the author deliberately obfuscated it so **PLEASE *DO NOT* FIX THIS OR
|
||||
MODERNISE IT**.
|
||||
|
||||
Cody also changed the buffer size in such a way that `gets(3)` should be safe
|
||||
(well, theoretically) as it comes from the command line (though it can also read input
|
||||
from `stdin` after starting the program). Ideally `fgets(3)` would be used but this
|
||||
is a more problematic. See [1992/gson in bugs.md](/bugs.md#1992-gson) for more
|
||||
details if you're interested in trying to understand it (or fix?).
|
||||
|
||||
|
||||
## <a name="1992_imc"></a>[1992/imc](/1992/imc/imc.c) ([README.md](/1992/imc/README.md]))
|
||||
|
||||
Reference in new issue
Block a user