This includes the thanks-for-fixes.md file where C code was actually in the form of a diff (which happened when I was looking for the differences to put in the file in the first place, forgetting to remove the [-+] at the time).
92 KiB
Thanks for all the fixes
.. and thanks for all the fish. :-)
Thank you honor roll
There are a number of people who have contributed to several thousand changes, fixes and important improvements and one who has literally (or numerically :-) ) contributed thousands, that we wish to thank.
We call out the extensive contributions of Cody Boone
Ferguson who is
responsible for many of the improvements including many very complicated bug
fixes like 1988/phillipps,
2001/anonymous and
2004/burley, making entries like
1986/wall not require -traditional-cpp (all very
complicated fixes), fixing entries to compile with clang, porting entries to
macOS, some being very complicated like
1998/schweikh1, fixing code like
2001/herrmann2 to work in both 32-bit/64-bit which
can be very complicated, providing alternate code where useful/necessary,
fixing where possible dead links or removing them, typo/consistency fixes,
improving ALL Makefiles and writing sgit
that we installed locally to easily run sed on files in the repo to help build
the website. Thank you very much for your extensive efforts in helping
improve the IOCCC presentation of past IOCCC winners and fixing almost all for
modern systems!
Yusuke Endoh supplied a number of important bug fixes to a number of past IOCCC winners. Some of those fixes were very technically challenging such as 1989/robison, 1990/cmills, 1992/lush and 2001/ctk. Thank you very much for your help!
A good number of the past winners of the IOCCC tested, identified and helped correct and/or improve the write-ups of fellow IOCCC winners for the year that they won. The list of those past winners is too long to mention: nevertheless the IOCCC judges very much appreciate those who helped improve the presentation of their fellow IOCCC winners.
Thank you list since 2021 Jan 01
To avoid having to change numerous "README.md" files to add thank you notes, we centralize them below.
The IOCCC judges wish to recognize the many important contributions to the IOCCC presentation of past IOCCC winners. We are pleased to note the many contributions, made since 2021 Jan 01, on a winner by winner basis.
Makefile fixes and improvements
Cody made a variety of changes in all Makefiles, sometimes to get an entry to work, all noted below, but he also improved them all in at least one or two ways.
For instance he changed the LIBS variable to LDFLAGS as that is the standard
variable. This simplifies compiling without having to modify the Makefile which
can be useful if something changes or if someone is trying to fix an entry but
forgets to change the Makefile or even if they don't want to make a change due
to a temporary test. These would of course depend on the compiler invocation but
since LDFLAGS is standard it is more likely to be used by default so no need
to check the Makefiles.
Sometimes there were bad characters or rules that caused the entry to fail to compile or not work in some way.
Where useful he added some notes to the Makefiles during compilation to let one know of certain problems or features that matter.
There were some other fixes as well including typos in the Makefiles.
1984/anonymous (README.md)
Cody fixed this to work for macOS.
The problem was to do with the way that the read(2) function was redefined.
With macOS the second arg needs to be a void * and this also necessitated some
casts to int (on the second arg) in the call to write(2) (in read()).
By request, the original code is provided as anonymous.alt.c so that one can look at it and the famous tattoo:
which was done in 2005 by Thomas Scovell.
1984/decot (README.md)
Cody fixed this to not require -traditional-cpp which some compilers like
clang do not support. Fixing -traditional-cpp is, as noted earlier, very
complicated, but we encourage you to look at the alternate code (which is the
original code with a minor modification made by the judges) and the fixed
code, to see what had to be done.
Clang is also more strict about the type of args in main() and this was also a
problem that Cody fixed, making it work with both clang and gcc.
These fixes worked fine in macOS but it turned out that in some cases with clang in linux it did not work so this had to be further fixed which Cody also did. It is no longer clear what the problem was as in fedora 38 with clang 16.0.6 the only difference is it causes additional warnings but it seems to work just fine. It seems unlikely that a fix was made just for warnings so it is presumed that there was another problem so the change is kept in place.
A note about the fix is that the #defined macros that were used still exist
but are not used; they are left in just to make it look more like the original
entry. Nevertheless they cannot be used.
Later on Cody improved the fix to make it look rather more like the original by
bringing back an extern declaration (slightly changing it to match the symbol
that it is i.e. extern double floor(double); instead of extern int floor;)
and double (x1, y1) b;, commenting out only the code:
char x {sizeof(
double(%s,%D)(*)())
and changing the type of k to be an int.
Additionally, because of the #define union static struct there is no need to
have in the code static struct as we can have it like the original code which
has it as union.
Originally Yusuke supplied a patch so that this entry would compile with gcc - but not clang - or at least some versions.
To see the difference from start to fixed:
diff 1984/decot/decot.orig.c 1984/decot/decot.c
1984/mullender (README.md)
Cody provided an alternate version, an improved version of the judges, so that everyone can enjoy it with systems that are not VAX/PDP. We also refer you to the FAQ as there are some winning entries that also let one enjoy it - with more to them of course!
Cody also added the gentab.c file, fixed to compile
and work with modern systems and so that it would create the proper array (it
had unbalanced '}'s), which the author noted in their remarks (which Cody also
found). As this file uses the old header file a.out.h that is not available in
all modern systems, Cody found a copy of it as to what it should have been at
the time, in the fabulous Unix History
Repo.
1985/applin (README.md)
Both Cody and Yusuke fixed this; Yusuke got this to not crash and Cody fixed it to work with macOS.
The crash was because it destructively rewrites string literals. However with
strdup() it's safe.
The problem with macOS is that although it didn't crash, it printed H???? in a
seemingly infinite loop, each time printing another ?, and it probably would
have until it runs out of memory.
The fix for macOS is that there was no prototype for execlp() and macOS has
problems with missing prototypes for some functions (this was also seen when
Cody fixed 1984/anonymous for macOS as well). As
this is a one-liner the include of unistd.h was done in the Makefile.
Ironically this fix was discovered through linux!
NOTE: originally this entry did not print a newline prior to returning to the
shell, after the output (despite having \n in the string - can you figure out
why?) but to make it more friendly to users Cody made it print a \n prior to
returning to the shell. The original version does not have this change.
1985/august (README.md)
Cody added the script primes.sh which allows one to check the output for the first N prime numbers of the output, where N is either the default or user specified. The inspiration was the previous 'try' command he gave to have fun with finding primes that might seem unusual in a way.
1985/lycklama (README.md)
Cody fixed this to compile with modern compilers. In the past one could get away
with defining some macro to #define and then use #foo to have the same
effect as using #define but this does not work in modern systems so Cody
changed the #o lines to #define. Also unistd.h had to be #included.
Yusuke provided some useful information that amounts to an alternate version that Cody added. See the README.md for details.
1985/sicherman (README.md)
Cody fixed this very twisted entry to not require -traditional-cpp. Fixing
-traditional-cpp is, as noted earlier, very complicated, but Cody would like
to refer you to the original file
sicherman.orig.c and he suggests that you
then compare it to sicherman.c for some good old
C-fashioned fun!
Later on Cody improved the fix so that it looks much more like the original entry.
1986/hague (README.md)
Cody added alt code that uses fgets() to avoid alarming and annoying warnings
about gets() being unsafe. The reason this is alt code, at least for now, is
that although it will print the results in both forms of invocation, after the
output in one invocation form it will segfault. This might be addressed later on
or it might be decided that it is worth it, with a caveat in the Makefile or at
least the README.md file, since it still prints out the correct output, though
that seems like it might not be so ideal unless it can be fixed (which might be
done). See the bugs.md file for details.
1986/holloway (README.md)
Cody fixed this to compile and work with clang (it already worked with gcc).
The problem was that clang is more strict about the type of second arg to
main(). However simply changing it to a char ** and updating the *s to **s
caused a segfault. By adding a new variable, char *t, initialising it to s
and then using t instead of s it compiles and runs successfully under clang
and gcc.
1986/marshall (README.md)
Cody got this to compile and work with clang and gcc. He noted that he tried to keep the ASCII art as close to the original as possible. The line lengths are the same but some spaces had to be changed to non-spaces.
This fix was very interesting and quite amusing, showing up problems with compilers. This is a brief summary but much more is explained in the README.md, giving which compilers had which problems in which systems: the optimiser being enabled in one compiler let it work but broke it in the other; and disabling it would let it work in the one that didn't work but suddenly the one that worked would be broken.
This problem was only after getting clang to compile, of course. It did not
compile it because it is more strict about the second and third args to main()
and the third arg was an int.
We encourage you to read the README.md file to see how odd this problem was and what Cody did to fix it!
1986/pawka (README.md)
Cody noticed and fixed a funny mistake in the Makefile where a
-Wno-strict-prototypes was in the wrong location, suggesting that there is a
-D needed to compile the entry.
1986/wall (README.md)
Cody fixed this so that it does not require -traditional-cpp. This took a fair
bit of tinkering as this entry is strange; fixing -traditional-cpp is, as
noted earlier, very complicated, but we encourage you to look at original
code to see how different C was in 1986.
Yusuke originally patched this to use strdup() on two strings and this let it
work with gcc but it still required -traditional-cpp. The alternate
code is the version patched by Yusuke should you wish to
try it with a compiler that has the -traditional-cpp. See the README.md file
for details.
If you'd like to see the difference between the version that requires
-traditional-cpp and the fixed version, try:
diff 1986/wall/wall.alt.c 1986/wall/wall.c
1987/heckbert (README.md)
Cody made this look more like the original entry by restoring the #define of
define. It's not used but it now looks closer to the original.
Also because index(3) is deprecated and in some systems requires the inclusion
of strings.h and because it's identical in use to strchr(3) (and we noted
that for System V we had to do this) Cody added to the Makefile
-Dindex=strchr.
1987/lievaart (README.md)
Cody made this ever so slightly like the original code by adding back the
#define D define even though it's unused. This was done for both versions as
well (the one with the board and the one without, the entry itself with the
limitations of the contest).
1987/wall (README.md)
Cody made this safer by using fgets() instead of gets(). This prevents an
annoying and potentially alarming warning at compiling, linking or runtime.
Though this could be partly remedied through redirecting stderr to /dev/null
this would not truly resolve the problem either and in order to avoid the
warning one would have to always redirect stderr to /dev/null.
Later Cody improved upon the gets()/fgets() change to make it more like the
original by redefining gets() to use fgets() (with the correct args) so that
the code can refer to gets() instead.
1987/westley (README.md)
Cody fixed this for modern systems. The problem was 'assignment to cast is illegal, lvalue casts are not supported'. For the original file see the
README.md file. Unfortunately this ruins some symmetry. To try and resolve this
as much as possible at first code was commented out but later on the commented
out code was removed and another part changed so that, although it has some code
no longer there, it has a closer match in symmetry and since the code was
commented out it's probably not a big deal to have it removed instead as it does
look more symmetrical now.
Cody also added to the Makefile -include stdio.h in the nowadays very
unlikely(?) but nevertheless suggested case that putchar() is not available.
1988/dale (README.md)
Cody fixed this twisted entry (as we called it :-) ) for modern compilers,
including making it no longer require -traditional-cpp. There were two
problems here to fix, which Cody did.
One, as noted above, was that the entry required -traditional-cpp
(which not all compilers support clang does not support)
It needed that option in modern systems because of two things it did:
#define a(x)get/***/x/***/id())
/* ... */
p Z=chroot("/");L(!a(u)execv((q(v="/ipu6ljov"),v),C);Z-=kill(l);
/* ... */
case_2:L(!--V){O/*/*/c*c+c);wait(A+c*c-c);L(!Z)f(A,"\n",c);return(A*getgid());};C++;
This macro, a, formed the functions (the names) getuid() and getgid(), but
this no longer works. The code still uses the macro a to form the names but
it's done differently, using the C token paste operator ##. It's done like
thus:
--- i/1988/dale/dale.c
+++ w/1988/dale/dale.c
@@ -9,18 +9,18 @@
#define L if
#define I goto
#define l 1
#define f write
#define J else
-#define a(x)get/***/x/***/id())
+#define a(x)get##x##id())
The second is that
for/*/(;;);/*/k()){O/*/*/c);
cannot form fork()) in modern C compilers. Since it was not done through a
macro it was simply changed to be 'fork()', rather than adding a new macro.
(What is quite fun is that at least some C pre-processors can form these constructs! Can you figure out why this is?)
The other problem that could not be resolved by the -traditional-cpp was that
modern compilers do not allow directives like:
#define _ define
#_ P char
#_ p int
#_ O close(
/* ... */
so Cody changed the lines to be in the form of:
#define P char
#define p int
#define O close(
/* ... */
However, to keep the entry as close to as possible in look, Cody kept the _
macro in place it's just no longer used.
See the README.md file for details on the original code, provided as an alt
version in case you have an older compiler or wish to try -traditional-cpp.
1988/isaak (README.md)
Cody fixed this to work for modern systems. The problem was that the important
function, a redefinition of exit(), was not being called in main(). The
original version is in 1988/isaak/isaak.alt.c. See the
README.md file for more details.
1988/phillipps (README.md)
Cody fixed this for modern systems. It did not compile with clang because it
requires the second and third args of main() to be char ** but even before
that with gcc it printed random characters.
After fixing it for clang by changing main() to call the new function pain()
(chosen because it's a pain that clang requires these args to be char ** :-) )
with the correct args it now works.
1988/reddy (README.md)
Cody made this use fgets() to prevent annoying warnings during compiling,
linking and runtime, the latter of which being the most annoying.
1988/spinellis (README.md)
Cody provided an alternate version so that this will work with compilers like clang. An alternate version had to be provided because not doing so would be tampering with the file too much. It would work but it would not show the same creativity. The original file exploits a fun mis-feature that works with gcc but not clang. This resulted in a change of rules which is another reason to not modify the original. See the README.md file for details on the alternate code.
Meanwhile Cody was twisted enough to point out (though to be fair he felt sick doing this) that with a slight modification this entry can be C++ instead. We don't thank him for this ghastly point! :-)
1988/westley (README.md)
The original version, provided as alternate code, was fixed by Misha Dynin, based on the judges' remarks, so that this would work with modern C compilers. We encourage you to try the alternate version to see what happens with current compilers! See the README.md files for details.
1989/fubar (README.md)
Cody got this to work with modern systems. The main() issues were an
#include had to be added along with fixing the path (due to . not being in
$PATH) to files referred to in the code.
1989/jar.2 (README.md)
Cody fixed this to work with modern compilers. Modern compilers do not allow code like:
#define D define
#define a include
#D foo bar
#a <stdio.h>
He notes that there is a way to get it (or something close to it) to work. Do you know how?
1989/ovdluhe (README.md)
Cody provided an alternate version based on the author's remarks. See the README.md for details.
1989/paul (README.md)
Cody fixed a segfault under macOS. The problem was that the int (from #define f) should be a long. This became apparent when he was using lldb and saw that
the type of a pointer was too long :-)
1989/robison (README.md)
Yusuke Endoh fixed this to compile under modern systems. To see the changes made, try:
git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..9d63c37f490da333fbb1ed7db9571902570d4bad 1989/robison/robison.c
(It adds the C token pasting operator ## instead of /**/.)
1989/tromp (README.md)
We used a patch from Yusuke to get this to compile under gcc.
Cody fixed this to work with clang by further changing the variable a to be
not the third argument to main() but instead be a variable declared in
main().
Cody also bug fixed it so that the high score file would work (it was not even
being created) and after this making sure the terminal stayed sane (the letter
'u' could not be typed and echo was disabled outright after the segfault fix /
high score file was reinstated). Although we appreciate the help here, he
cynically noted that he had to have an IOCCC
Tetris working (this of course was not
his only reason :-) )
1989/westley (README.md)
Cody got some of the versions (the original and ver0) to work with some
versions of clang. Unfortunately there are some defects in clang that break
this entry either in full or in part.
Cody provided the compile.sh script to generate the files and then try and compile them (which ones succeed depend on whether or not clang is the compiler). The script allows one to change the path of the compiler if they have another one. See the README.md for details.
As there are some important notes on this in the README.md file we have left the details in that file and further details are in the bugs.md file.
1990/baruch (README.md)
Cody added an alternate version which allows certain compilers to compile the code, based on the author's remarks.
1990/cmills (README.md)
Yusuke got this to work in modern systems (it previously resulted in a bus error).
To prevent alarming warnings at linking or runtime Cody made the entry use
fgets() rather than gets(). He notes that another option would have been to
redirect stderr to /dev/null but he did not think of that at the time.
Cody later improved upon the gets()/fgets() fix to make it more like the
original where the code can refer to gets() in the way it originally did. This
was done through a macro to redefine gets.
BTW: Cody asks the following question: if the compiler compiles, the linker links and the user executes does that make the compiler the jury, the linker the judge and user the executioner? :-)
1990/dds (README.md)
Yusuke and Cody in conjunction fixed this for modern systems (both fixed a different compiler error but more fixes were also made).
Yusuke added the comma operator for a binary expression with free(3) which is
is a compiler error because free() returns void. Cody then made it slightly more like the
original in this way by redefining free to have the comma operator itself.
Cody fixed another compiler error by removing the erroneous prototype to
fopen(). Cody also changed a file to be a proper FILE * and fixed a typo in
LANDER.BAS.
Cody also made this use fgets() instead of gets() to make it safer and to
prevent an annoying and potentially alarming warning at compiling and/or linking
and/or runtime, the latter of which is unfortunately interspersed with the
output of the program.
Later Cody improved the gets()/fgets() fix by redefining gets() to use
fgets(). Notice that the original entry used fgets() in one case as it has
to read from another file and in this place nothing was changed.
With these improvements the entry looks much more like the original!
1990/jaw (README.md)
Cody fixed the script to work properly in modern environments (to do with $PATH
not having . in it). He notes that with an invocation in the try section will
with macOS show what appears to be an error message but is actually okay. He
gives more information in the bugs.md file.
NOTE: as btoa is not common we used a ruby script from Yusuke.
1990/tbr (README.md)
Cody fixed this to work with modern compilers; exit(3) returns void but the
function was used in a binary expression so this wouldn't even compile. Cody
also changed the code to use fgets() instead of gets() so one would not get
a warning about the use of gets() at linking time or execution, the latter of
which was causing confusing output due to the warning being interspersed with
the program's interactive output.
Cody later improved his fix so that it looks more like the original. A problem
that usually occurs with gets() to fgets() is for 'backwards compatibility'
(so the man page once said) fgets() retains the newline and gets() does not.
In this program if one does not remove the newline it breaks the program. This
usually requires that one check that fgets() does not return NULL but with
some experimenting this proved to seem to not be a problem here so by adding a
couple macros that redefine exit() and gets() a whole binary expression
could be removed (thus removing an extra exit() call) and it now almost looks
like the same as the original.
Additionally, Cody fixed the shortened version provided by the author in the
same way as the original entry, first the compile fix and then later on making
it look more like the original by redefining exit and also redefining gets()
to be fgets() in the same way that the original entry is. This way the alt
version is equivalent in function, like the author intended, but more compact.
1990/theorem (README.md)
Cody fixed this to compile with modern systems.
He also fixed some bugs that impacted the usability of this program including some
segfaults under modern systems (and possibly in some cases earlier systems) with
this entry. Originally we noted that the 4 trailing args '0 0 0 0' were
required on systems that dump core when NULL is dereferenced but this problem
showed itself in modern systems even with the 4 '0 0 0 0'. He also fixed a
segfault if not enough args are specified and fixed the code so that the
generated fibonacci.c actually works; before it just printed 0 over and over
again (since it did not work anyway a segfault prevention was added here). He
also fixed some array addressing (some of which might not be strictly necessary
but as he was testing the fibonacci.c bug he ended up changing it anyway).
Finally he changed this program to use fgets() not gets() to make it safer
and to prevent a warning about gets() at linking or runtime. Since this
program is so incredible the extra fixes were deemed worth having and this is why
it was done.
Cody disabled a warning in the Makefile that proved to be a problem only with clang in linux but which was defaulting to an error. This way was the simplest way to deal with the problem in question due to the way the entry works.
Yusuke pointed out that atof nowadays needs #include <stdlib.h> which was
used in order to get this to work initially (prior to this output was there but
incomplete).
1990/stig (README.md)
Cody fixed the paths in the Makefile so that this would build in linux (it worked fine in macOS).
1990/westley (README.md)
Cody fixed this for modern systems. It had 1s in places for a short int which
was changed to just 1. Since it's instructional to see the differences he has
provided an alternate version, westley.alt.c which
is the original code.
1991/brnstnd (README.md)
Cody fixed this for modern systems. There were two invalid operands to binary
expression (char * and void and int and void) to resolve and
additionally a mis-feature of the C pre-processor which no longer works had to
be changed as well in order to get this to compile. In particular the macro C,
defined as C =G to make += and similar operators no longer works. The
invalid operands to binary expressions were resolved with the comma operator.
1991/dds (README.md)
Cody fixed a segfault that prevented this entry from working in any condition
and he also made an alternate version that works with
clang. The alternate code, described in the README.md file, is what is needed
for clang. Reading it might be instructive even if you have gcc.
1991/fine (README.md)
Cody made it look much more like the original entry even after the fix that
increased the count in characters from 80 to 106, getting it back down to just 85.
This was done by redefining main at the compiler line so that it looks like
the original where one didn't have to worry about the type of args of main() and
there were other fewer restrictions and also by removing a cast that was
not strictly necessary (this does create a new warning: ordered comparison between pointer and integer ('char **' and 'int') but it works just fine).
Cody also added the demo.sh script which feeds the program some fun input for fun but mostly different output.
1991/westley (README.md)
Cody fixed a segfault in this program which prevented it from working. The
problem was that the read-only char array char *z[] was being written to. The
fix was to change it to char z[][100] in two spots (see if you can determine
why two places, not one!). Why 100 when the longest string is < 100? Because a
shorter value caused strange output and it's easier to just choose a larger
value that works without having to find the correct value.
1992/adrian (README.md)
Cody changed the location that it used gets() to be fgets() instead to make
it safer and to prevent annoying warnings during compiling, linking or runtime
(interspersed with the program's output).
Later Cody improved the change to fgets() to make it slightly more like the
original. This still requires the additional stripping of the newline inside the
loop but now it uses what looks like before, just a call to gets().
One might think that simply changing the gets() to fgets() (with stdin) would
work but it did not because fgets() stores the newline and gets() does not.
The code was relying on not having this newline. With fgets() the code
if(A(Y)) puts(Y); ended up printing an extra line which made the generation of
some files (like adhead.c) fail to compile. Why? There was a blank line after
a \ at the end of the first line of a macro definition! Thus the code now
first trims off the last character of the buffer read to get the same correct
functionality but in a safe way and non obnoxious way.
But the improvement so that it uses gets() could not be changed to have the
macro do the removal of the extra line (as in with a comma operator or a &&)
as this caused compilation errors with another generated file (adwc.c). Thus
after the gets() call in the line that looks like:
while( gets(Y) ){ Y[strlen(Y)-1]='\0'; if(A(Y)) puts(Y); }
one must keep the Y[strlen(Y)-1]='\0'; part and keep it there.
This is a complex change due to the way the program and Makefile generate additional tools.
1992/gson (README.md)
Cody changed the buffer size in such a way that gets() 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() 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() 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() is called as m = gets(m)) but
trying to change it to use fgets() 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() was not used in a
loop).
1992/kivinen (README.md)
It was observed that on modern systems this goes much too quick. Yusuke created
a patch that calls usleep() but Cody thought the value was too slow so he made
it a macro in the Makefile Z, defaulting at 15000. You can reconfigure it
like:
make clobber Z=1000 all
This was not made an alternate version because it moves so fast that it's nigh impossible to use otherwise.
Yusuke also noted that there is a bug in the program where right after starting it moves towards the right but if you click the mouse it goes back.
1992/lush (README.md)
Yusuke supplied a patch which makes this work with gcc. Due to how it works (see Judges' remarks in the README.md file) this will not work with clang.
Cody also provided the runme.sh script to demonstrate it as using make was
problematic.
Cody made it use fgets() instead of gets() to prevent annoying warnings
getting in the way (in linux linking in a binary with gets() produces a
warning that might get in the way with this entry and in macOS at runtime it
prints a warning which often is interspersed with the output of the program
which can be confusing) and also added the runme.sh script to demonstrate it
(using make was problematic). Cody notes that unfortunately this does not work
with clang due to different compiler messages.
Cody later improved the fgets() change to look more like the original i.e. it
now uses a redefined gets(). This did require modifying the line number with
#line 1 under the macro gets().
Still this cannot work with clang due to different compiler messages. See bugs.md for details.
1992/nathan (README.md)
Cody added the original file back as it was deemed that the export restrictions should no longer be a cause of concern for this entry. Doing this did require a change to Cody's 2020/ferguson2 entry as it's referenced.
Cody cynically noted that if he goes quiet, for instance if he no longer participates in the IOCCC, that it must be our fault! :-)
1992/westley (README.md)
Cody fixed this to work for clang by changing the third and fourth arg of
main() to be char ** inside main(); clang requires args 2 - 4 to be char ** and some versions do not even allow a fourth arg.
He also added the alternate version that the author gave in the remarks that is specifically for the USA rather than the world.
NOTE: as noted in the README.md file and the bugs.md, this program and the alternate version will very likely crash or nuke the entire world or just the USA, respectively, without enough args (2). And not that we need the help or anything for this :-) but we do encourage you to test this :-) This should NOT be fixed.
1993/jonth (README.md)
Both Cody and Yusuke fixed this so that it will work with modern systems. Yusuke provided some fixes of the X code and Cody fixed the C pre-processor directives so that it would compile. It used to be that you could get away with code like:
G int i,j
K case
and expect G; to equate to int i, j; (though it's now a long) and K to mean
case but that's no longer the case so the offending lines had #define
prepended to them.
1993/leo (README.md)
Cody fixed this to work with modern compilers. This involved different header files for functions.
1993/lmfjyh (README.md)
Cody added an alternate version which does what the program did with gcc < 2.3.3. See the README.md file for details and for why this was made the alternate version, not the actual entry.
1993/plummer (README.md)
Cody added an alternate version which uses
usleep() so you can see what is happening with faster systems. See the
README.md files for details.
1993/rince (README.md)
Yusuke supplied a patch to get this to work in modern systems.
Cody provided an alternate version to simplify slowing the game down. This was based on our suggestion that it might be desired to slow down but done in a way that makes it easy to configure at compile time. See the README.md for details.
1993/schnitzi (README.md)
Cody made this use fgets() not gets() to make it safer and to prevent an
annoying warning with compiling and/or linking and/or runtime, the latter of
which is unfortunately interspersed with the output of the program itself.
Cody later improved the fix to use gets() via a macro so that it looks like
the original code.
1993/vanb (README.md)
Cody fixed this to work with clang. The problem was that the third arg to main()
was not a char **. Instead O5() (which was main()) is now its own function
which main() calls with the right parameters.
1994/ldb (README.md)
Cody fixed this so it would compile and work with modern compilers. The problem
was that srand() returns void but it was used in a || expression. Thus the
comma operator was needed.
Cody also fixed it for clang under linux which objected to incompatible pointer
type (because time(2) takes a time_t * which in some systems is a long *
but what was being passed to it is an int).
Cody also changed the entry to use fgets() instead of gets() to make it safe
for lines greater than 231 in length and to prevent a warning at linking or at
runtime, the latter of which can be interspersed with output of the program.
Note that this now prints a newline after the output but this seems like a
worthy compromise for preventing the interspersed output in macOS and at the
same time it's safer (fixing it to not have the extra newline is more
problematic than it's worth and in macOS another line of output would be shown
without the change anyway and the difference is that now it's just a blank line
rather than an annoying warning).
A subtlety about this fix: if a line is greater than 231 in length if the program chooses that line it might print the first 231 characters or it might print (up to) the next 231 characters and so on.
1994/shapiro (README.md)
Cody fixed a bug on systems where EOF != -1. The problem is that getc() and
the related functions do not return -1 on EOF or error but rather EOF.
However EOF is not required to be -1 but merely an int < 0 and this program
assumed that getc() will return -1 on EOF or error, not EOF. On systems
where EOF != -1 it could result in an infinite loop.
For an interesting problem that occurred here and what was done to solve it, check the bugs.md file.
1994/westley (README.md)
Cody converted the spoiler compiler options (provided by the author) to be compiler commands and added a script spoiler.sh to automate the spoiler commands to make it easier to see the game in action.
1995/cdua (README.md)
Cody fixed this so that it would work with macOS. Once it could compile it additionally segfaulted under macOS which he also fixed. Cody also provided the Alternate code for fun :-) ) (in particular to make it easier to see the program do what it does in systems that are too fast ... if there is such a thing anyway :-) ). See the README.md for details on this.
1995/garry (README.md)
Cody fixed this so that it will compile with modern compilers. The problem was a
missing int for the f variable. He felt it was even more important that it
works because the layout does indeed look to him like a rat is dropping core :-),
something that the judges suggested.
1995/makarios (README.md)
Cody fixed this so that it will compile with versions of clang that has a defect
which only allows main() to have 0, 2 or 3 args. This is done by a new
function (pain() as it's annoying that clang is this way :-) ) that main()
calls which has the four args.
1996/august (README.md)
Cody fixed a segfault in this program that prevented it from working right but
he notes it hangs in macOS. This is because some compilers compile it into an
infinite loop and this was documented by the judges. It works fine in linux if
using gcc but macOS, having only clang by default, (even the gcc binary
/usr/bin/gcc) will not work.
1996/dalbec (README.md)
Cody proposed a fix for this to compile with clang and Landon implemented it after some discussion. The reason Cody did not do it is because he thought it was the wrong output but as it happens the try section below was worded a bit confusingly. He looked at Yusuke's] analysis found here but he missed that Yusuke added a '...' after the result which made him think the fix was wrong. Cody also made the recommended change of the author to make it so that each number is printed on a line by itself rather than having a long string of numbers on the same line. This was not put in an alternate version but perhaps it should be.
1996/eldby (README.md)
Cody provided an alternate version which uses
usleep() in between writing the output to make it easier to see what is going
on with faster systems and importantly also for those who are sensitive to text
flashing by rapidly (it affects him too but he also thinks it moves too fast
nowadays anyway). We recommend that you try the alternate version first due to
these reasons.
1996/gandalf (README.md)
Cody fixed this to compile and work with modern systems. As he loved the references in the code that could not compile he just commented out as little as possible to get this to compile.
1996/jonth (README.md)
Cody fixed this to not segfault under macOS. The problem was that the function
pointer w, which points to XCreateWindow(), did not specify the parameters of
the function in the pointer assignment.
1996/westley (README.md)
Cody fixed a segfault in this entry as well as it displaying environmental
variables. Although the scripts showed correct output, it somewhat lessened the
usability because they segfaulted and showed (an) environmental variable,
interspersed with the output of the program. With the fix they no longer have
this problem. If argc < 5 (argv[4] is referenced) it will not do anything
and it will not segfault either - this was caused by the body of the for() loop
which is now empty (it doesn't appear to be needed at all at least modernly).
Note that you should check the westley.alt.c file
when reading the author's comments. To see how to use the original, see the
README.md file.
1998/chaos (README.md)
Cody added a call to endwin() to restore terminal sanity (echo etc.) when
exiting the program.
1998/fanf (README.md)
Cody fixed this for Linux. The problem was the intermediate steps to get to the final code that is compiled. The entry itself is what was essentially what used to be compiled. Now it works with both Linux and macOS (and BSD?).
1998/schnitzi (README.md)
Cody fixed invalid data types which prevented this entry from working, causing a segfault. This showed itself in two parts which required two fixes, one for linux and further changes for macOS. He also fixed a segfault (after printing garbage) when the arg specified evaluated to 0. It was decided that these segfault fixes should be made because the program is so beautiful.
1998/schweikh1 (README.md)
Cody fixed this for modern systems (it did not work at all) and added an
alternate version that works with macOS. Cody also made it ever so slightly more
portable by removing the hard-coding of gcc, instead hard-coding it cc. Doing
this not only lets it work with systems without gcc (though in macOS it does
exist but is actually clang) as cc always should.
Getting this entry to work was quite complicated but is also very interesting. To see how the macOS fixes works, see the README.md but do note that this includes spoilers for both versions! The fixes to get it to work at all are described next.
So what was wrong with the original?
The call to freopen() was incorrect with the second arg (the mode) being
5+__FILE__; it is now "r". (Observe that the mode to the fopen()
call is: 44+__FILE__. This might seem incorrect and indeed it can be changed
to "r" as well but this was not actually necessary so once this was noticed it
was changed back to the original.)
Another important change is that the files are only closed if the FILE *H is
!= NULL. Without this check, because it's almost certain that some files will
not exist, it would dereference a NULL pointer and very likely crash or halt and
catch fire :-), preventing the entry from working. Notice how H is a funny
macro defined as:
%:define H(x) <st%:%:x##.h>
and yet the FILE * can be called H! This might or might not make sense to
you but if it doesn't can you figure out why?
Another fix is that previously the program would return 1 if a file failed to
open but for the same reason as above, it being very likely some files will not
exist, the return was removed so that if the statement of the if is true the
while loop run, rather than having the loop by itself. It was done this way to
make it as close to the original as possible and to maintain the obfuscation as
close as possible as well.
Also crucial, and the final fixes to make it work, is that the arrays K and
L had to be increased in size. They were originally (somewhat bewildering at
first glance) defined as K[X(*)], L[X(<<)] but they were changed to
K[(X(*))*4], L[4*X(<<)] though it is no longer clear just how necessary this
might be.
As noted, a limitation of gcc existing was removed by Cody to make it so that
gcc is not required as cc should exist in every system with a C compiler and
as the author stated: as long as the options -E -dM of the compiler prints out
the macros in the form of gcc -dM i.e. the lines are in the form #define MACRO value it will work, assuming that compiler can run, of course.
As for the version for macOS, the even more complicated details are described in the Alternate code section of the README.md file as these changes pertain to the described version therein.
1998/schweikh2 (README.md)
Cody fixed the code to not trigger an internal compiler error in gcc:
:10:16: warning: type defaults to 'int' in declaration of 'zero' [-Wimplicit-int]
: In function 'main':
:12:1: warning: missing terminating " character
:12:19: internal compiler error: invalid built-in macro "__FILE__"
The string "01\015" had to be changed to ONE(O(1,1,2,6,0,6)). For an
interesting historical explanation and further details and fun, see the
historical remarks in the
README.md.
2000/anderson (README.md)
Cody changed this entry to use fgets() instead of gets() to make it safer
and to prevent annoying warnings from showing up at compiling, linking and/or
runtime, the latter interspersed with the output of the program.
Cody later improved the fix to use gets() by redefining gets() so that the
code looks like before.
2000/briddlebane (README.md)
Cody fixed this to compile in systems that require one to explicitly link in
libm.
2000/dlowe (README.md)
Cody fixed this to compile with more recent perl versions; the symbol that's now
PL_na was once na. He notes that this entry crashes under macOS but it works
under linux after this change.
2000/jarijyrki (README.md)
Cody made it easier to compile this in some cases by adding X11/ to the
includes of Xlib.h and keysym.h.
2000/natori (README.md)
Cody fixed this for modern compilers. Depending on the compiler it would either segfault when run or not compile at all (gcc and clang respectively).
Cody also provided alternate code that supports the southern hemisphere.
Later on Cody restored the #includes in the source code which had been changed
by us to make it a one-liner again but this was an error as it was not a
one-liner but rather a small program. At the same point Cody made the code
itself a one-line like the code is in the original entry. Now it looks much more
like the original entry but with the two fixes.
2000/thadgavin (README.md)
Cody fixed the code and added an appropriate make rule so that the SDL version works independent from the curses version (using the same code).
To see the craziness of the SDL fix (because of a terrible design choice of the
SDL1 developers) see the log for commit
dd0b26b5d6. Be prepared for a surprise!
Cody also added an alternate version to help see what is going on in more modern systems and in case you're sensitive to rapidly moving swirling. See the README.md for details on that. Note that this alternate version only will impact the curses and the SDL versions as Cody does not have a DOS system to test the other version in.
2001/anonymous (README.md)
Cody fixed both the supplementary program and the program itself (both of which segfaulted and once that was fixed only the binary was modified; it was not run but according to the author's remarks it should be executed). He managed to do this with linux but it will not work with any system that does not allow one to compile 32-bit binaries such as macOS. See bugs.md for why this is; this is not a bug, it's a feature inherent in what it does!
Below is what it took to fix.
#include <sys/mman.h>formmap()andmunmap().- have
main()call another function which is no longer a recursive function; this preventedmain()from entering an infinite recursive loop.
Without these it would crash and prevent modification of the 32-bit ELF (not elf :-) ) binary. But again see bugs.md here.
These also had to be done:
- when
open()ing the file the file descriptor had to be saved so it could be closed prior to executing the program. This is thefvariable which is of typel, a#defineforint *. munmap()also had to be called prior to executing the program. This involved a newoff_t Nso which was added in themmap()call which was then used in themunmap()call.
Without those changes the program was not executed after modification which it was supposed to do; instead it reported text file busy error.
Notice that the location of munmap() and close() followed by execv() does
matter!
To get this to compile with clang, main() had to change from:
main (char *ck, char **k)
to:
int main (int cka, char **k) { char *ck = (char *)cka; /* ... */ }
The following change was also made to be more portable, in case the constants
PROT_READ and/or PROT_WRITE are not standardised or some platform does not
follow it:
Change 3 in the call to mmap() to be PROT_READ|PROT_WRITE: just in case
PROT_READ|PROT_WRITE does not equal 3 (though it seems to be equal in both
macOS and linux).
NOTE: there might be educational value to see the progress of this fix; if you
wish to see, try the following commands from the 2001/anonymous directory:
git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..93aa8d79f208dcccc3c5a2370a727b5cf64e9c53 anonymous.c
git diff 93aa8d79f208dcccc3c5a2370a727b5cf64e9c53..c48629017117379a52b1a512ef8f2593ca9569c8 anonymous.c
git diff c48629017117379a52b1a512ef8f2593ca9569c8..efdee208a2bc650256637b9357ddfd0de82d2f41 anonymous.c
git diff efdee208a2bc650256637b9357ddfd0de82d2f41..e9a3f77ea3b209e63ac3f9c06bb84ad86e5ea706 anonymous.c
git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..2159caec4677e0f25ad704a74e04c8196fd6c343 anonymous.c
git diff 2159caec4677e0f25ad704a74e04c8196fd6c343..4bc03de321612869aebf855850c6500df95cb6ef anonymous.c
Finally to see from start to finish:
git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..4bc03de321612869aebf855850c6500df95cb6ef anonymous.c
Cody also added a program like anonymous.ten.c Ten Green Bottles but which sings Ten in the Bed.
As well he added the try.me.sh so that one can attempt to use the program as it was designed but if compiling as 32-bit fails it will at least run the supplementary program as a 64-bit program directly.
2001/bellard (README.md)
Cody fixed this to compile with clang but according to the author this will not work without i386 linux. It generates i386 32-bit code (not bytecode) but unfortunately it will not work without i386 linux. See bugs.md.
Cody fixed an earlier segfault so that it can at least now open the file should
you have an i386 linux machine (it can open it in other platforms too, of
course, but it won't work). This involved pointer updates and also changing an
int to a FILE *. Where possible he left the macros as the same but in the
case of main() this was not possible.
Yusuke added another change (see below) to make it even more portable across compilers besides what Cody did.
Cody entirely fixed the supplementary
bellard.otccex.c so it does not segfault and
works as well (it did not work at all). The main problem was that some ints were
being used as pointers. This includes, for example, an int used as a char *,
an int used as a function pointer and an int to access argv as well as there
being invalid access to argv. He updated the Makefile so that this program
will compile by default.
Also the Fibonacci sequence (fib()) will overflow at n > 48 so this is
checked prior to running the function just like the author did for the factorial
(overflowing at >12). Either way unfortunately this entry seems to not work in
64-bit linux or macOS. See below portability notes as well as another fix in
this entry by Yusuke.
Portability notes:
With a tip from Yusuke we rediscovered the author's web page for this program where it is stated that this will only work in i386 linux. The author also stated in the remarks in this document that they used gcc 2.95.2 but we don't know if that's relevant or not.
Yusuke offered a modification which is not needed with gcc but with some
versions of clang it is. With gcc we can get away with -rdynamic -fno-pie -Wl,-z,execstack which solves the problem of execution in memory but any
compiler that does not support this would not work. Thus we use the modification
by Yusuke.
2001/cheong (README.md)
Cody fixed this to work with clang by adding another function that is allowed to
have a third arg as an int, not a char **. He chose pain() because it's a four
letter word that would match the format and because it's pain that clang forces
this. :-) This fix makes a point of the author's notes on portability no longer
valid, btw.
2001/coupard (README.md)
Cody fixed this to compile with clang in linux. The problem was C99 does not support implicit int:
coupard.c:31:10: error: parameter 'h' was not declared, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
void e(n,h){
^
coupard.c:31:8: error: parameter 'n' was not declared, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
void e(n,h){
^
One fix would be to disable that warning. Another one might be to change the C standard. The one that was done, to make it more portable, was to just add 'int' to the function parameters.
Thanks go to Yusuke for providing a proper command line for macOS (to do with sound; see his /2013/endoh3/README.md entry where he also refers to sound devices in macOS).
2001/ctk (README.md)
The ANSI escape codes were no longer valid but Yusuke provided a patch to fix the ANSI escape codes. This works with macOS as well.
2001/dgbeards (README.md)
The author provided two changes: one to speed it up and one to make it not crash on losing. Cody provided an alternate version which does the former but he felt that the idea of crashing on losing (see the README.md for details on why that might be) too good to get rid of so he kept that in.
He also points out that there is a way to get the computer to automatically lose very quickly and he also points out that there is a flaw in the alternate version that the author did not note. Do you know what these are?
2001/herrmann1 (README.md)
Cody fixed this so that the when compiling the code the program is not executed itself by itself which just showed the usage string and exited. The script herrmann1.sh is used to compile the program but it's also how you invoke the program.
He also fixed the script herrmann1.sh for shellcheck. In particular there were quite a few:
SC2086 (info): Double quote to prevent globbing and word splitting.
SC2248 (style): Prefer double quoting even when variables don't contain special characters.
errors/warnings.
2001/herrmann2 (README.md)
Cody fixed this to work with both 64-bit and 32-bit compilers by changing most of
the ints (all but that in main) to longs. He also fixed it to compile with
clang by changing the args of main to be int and char ** respectively and
changing specific references to the argv arg, casting to long (was int but
the 64-bit fix requires long) which was its old type. The original file, used
for demonstration purposes, as well as if you want to see if your system works
with the original code, is the alternate version. See the README.md for details.
2001/kev (README.md)
Cody slowed down the ball just a tad as it went too fast for the speed at which the paddles move even when holding down the movement keys.
Cody also provided an alternate version which lets you use the arrow keys on
your keyboard instead of the more awkward ',' and '.'.
2001/westley (README.md)
Cody added the script westley.sh to automate a heap of commands that we, the IOCCC judges, suggested, as well as some additional ones that he thought would be fun. He also provided the sort and punch card versions, described in the README.md, based on the author's remarks.
2004/arachnid (README.md)
Cody added an alternate version which allows those like himself used to h,
j, k and l movement keys to not get lost. Non rogue players, vi users and
Dvorak typists are invited to get lost (or use the original version)! :-)
2004/burley (README.md)
Cody fixed this to compile with clang and also fixed it to work.
For clang the problem was that main() had one arg, a char * and this is not
allowed in any version of clang. In some versions it is allowed if the arg is an
int but never if it's anything else. To get it to work took numerous changes.
First the inclusion of setjmp.h was necessary. Without this longjmp()
implicitly returned int which was used for the purpose of binary expression but
this no longer worked.
But by including setjmp.h it naturally made the binary expressions invalid (as
it returns void which no longer is allowed in binary expressions) so the comma
operator with 0 (,0) had to be used (,1 was tried first but this did not
work right).
longjmp() was being called with one arg which was an element
of an int[4][1000] which had to be changed to a jmp_buf p[4] (this due to
the prototype being included).
main() also called itself but this was a problem so it now calls another
function poke() which calls itself instead (this is sometimes necessary
nowadays).
Finally the optimiser cannot be disabled so the compiler flags were changed for this.
2004/gavin (README.md)
Yusuke provided the kernel and fs.tar files which can be used if you cannot
normally use this entry. Instead of generating the files just use the files
provided, found under the img/ directory. Note that the
img/fs.tar extracts into fs/ so you will have to fix the tarball; this is
done this way to prevent extraction from the entry directory overwriting the
files and causing make clobber to wipe some of them out.
2004/jdalbec (README.md)
Cody fixed this to compile with gcc (it worked with clang). The problem was the cpp being unable to parse the generated code (see the README.md for details) and this ended up with a number of errors like:
jdalbec.c:64:5: error: stray '##' in program
64 | B N##B (I) ; \
| ^~
..
jdalbec.c:65:5: error: stray '##' in program
65 | V F##B (B) ; \
| ^~
jdalbec.c:65:5: error: expected ';' before 'B'
65 | V F##B (B) ; \
| ^ ~
| ;
and various other problems.
2004/kopczynski (README.md)
Cody reported that this entry cannot be optimised by the compiler if it's to work. He also added the file kopczynski-a to demonstrate what happens when art more like a letter is fed to the program.
2004/newbern (README.md)
Cody and Landon individually fixed this to work with clang. Cody then turned the
second arg to main, which clang requires to be a char **, to be not the same
name as a function defined earlier in the code and to use that variable which
main() used.
2004/vik2 (README.md)
Cody fixed this to compile in Linux. Although it compiled cleanly in macOS (and BSD?) the code failed to compile at all in Linux due to:
cc -E vik2_1.c > vik2_2.c
In file included from vik2.c:945,
from vik2.c:959,
from vik2.c:972,
from vik2.c:1025:
vik2.c:383:8: error: no macro name given in #ifdef directive
383 | O \
| ^
In file included from vik2.c:946:
vik2.c:383:8: error: no macro name given in #ifdef directive
383 | O \
| ^
In file included from vik2.c:947:
vik2.c:383:8: error: no macro name given in #ifdef directive
383 | O \
| ^
In file included from vik2.c:948:
vik2.c:383:8: error: no macro name given in #ifdef directive
383 | O \
| ^
...
In file included from vik2.c:182:
vik2.c:992:85: error: #include nested depth 201 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
992 | I
| ^
vik2.c:1497:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
vik2.c:1498:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
vik2.c:1499:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
vik2.c:1500:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
vik2.c:1501:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
vik2.c:1504:21: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
make: *** [Makefile:133: vik2] Error 1
Unfortunately the fix required heavy modification to the original file (see below) and also inclusion of what used to be generated by the Makefile and will, in Linux, give many warnings like:
cc -std=gnu99 -Wall -Wextra -pedantic -Wno-strict-prototypes -Wno-implicit-function-declaration -O3 -DFNAME='"vik2.c"' '-DSTOP=_5' vik2.c -o vik2
In file included from vik2.c:1002:
vik2_1.c: In function 'main':
vik2_1.c:1:3: warning: style of line directive is a GCC extension
1 | # 1 "vik2.c"
| ^
...
(which does not show up in macOS) but now it at least works for both Linux and macOS.
As for the fix itself it required changing the C pre-processor macros that
resulted in macros themselves like #ifdef, #else etc. to be #ifdef,
#else etc. and also the inclusion of the file vik2_1.c
which used to be generated by the Makefile via cc -E. As one can see that file
has references to macOS things but this is not harmful in Linux. It might be
that those lines can be removed but there is no harm and since there are a lot
of it this has not been done (vik2.c has 1009 lines and vik2_1.c has 1555
lines!).
2005/aidan (README.md)
Cody fixed the test script, described by the author in their remarks, to refer to the proper compiled program (it's hardcoded). This had never been done and it broke the script.
2005/anon (README.md)
The author stated that if stty does not work right on your system you can
compile it differently so that the program does not use stty. Cody set this
up so that one need not update the Makefile. There's a fun command
that Cody provided, to try, to see a feature that the author implemented. See
the README.md for details.
2005/giljade (README.md)
After Landon fixed the entry to compile with clang Cody noticed this does not work at all in modern systems (see below). He fixed this to work and then he later fixed the self-test feature.
The problem that was showing up is that with either optimising or if anything
but 32-bit (as in -m32) was used it would not work (at least in 64-bit
systems?). The optimising cannot be used still but it now works with both 32-bit
and 64-bit. The solution has to do with the size difference between int and
long so that the long*E is now int*E. This solves a specific problem for
linux (32-bit, 64-bit) and macOS (arm64).
To get the self-test feature to work it was required to remove from the code:
O-b-f-u -s-c-a-t-e;
as it caused a compilation error in some of the generated code but served no purpose, didn't affect the output of the puzzle and since the 'string' is already in the code there is no problem omitting it.
main() was also changed to be in the old format:
-(B[h]=N-B,N= N+6);}main(int Z,char**Y ){char*U=Z ;
+(B[h]=N-B,N= N+6);}main(Z,Y )char**Y;{char*U=Z ;
Finally because clang has -Werror by default the program was changed to use
make and then rm -f on the output of the compiler instead. This change might
also not have been necessary if using different flags to cc but this felt
cleaner, somehow.
2005/jetro (README.md)
Cody added explicit linking of libm (-lm) for systems like linux that seem to
not do it implicitly (like macOS does).
2005/mikeash (README.md)
Cody fixed this to work in linux. The problem was an unknown escape sequence,
\N, which caused a funny compiler error:
};n b[2048];int i
mikeash.c: In function 'R':
mikeash.c:7:1: error: '\N' not followed by '{'
7 | ;C!='\n';A()
| ^
mikeash.c:7:1: error: incomplete universal character name \Ne
The problem was that in the string above there was a \Newline but this is
invalid C. This was changed to be \nNewline and then, because the code is
supposed to output itself when fed itself, the reference to 'N' had to be
updated in both the string and the code to be 'n'.
The array size of c was updated by 1 out of caution just in case as the array
is used to store at least part of the string.
2005/mynx (README.md)
Cody fixed this so that the configure script (which is not
needed but part of the entry) would work with compilers that have by default
-Werror like clang in macOS.
Cody also added the alt code which does scan for https. Futile, maybe, based on how https is set up, in which case just enjoy it for what it was. But there might be some command line that will let it work that way.
2005/toledo (README.md)
Cody fixed this to compile with some versions of clang which have an additional
defect where main() can only have 0, 2 or 3 args (it was 4). It now calls
another function that takes 4 args and which is what used to be main().
The alternate versions were also fixed.
2006/birken (README.md)
Cody fixed a segfault in macOS with this entry. The problem was a missing +1
for strlen() with malloc(). This prevented it from working.
2006/borsanyi (README.md)
Cody fixed the Makefile under some systems where the lpthread was not
implicitly linked in.
2006/monge (README.md)
Cody pointed out that without SDL1 (not SDL2) this will not link because two
functions that are used were removed from SDL2. Since SDL1 is still available
and since changing the code to use SDL2 would be more complicated he decided to
change the Makefile to use sdl-config not sdl2-config. Nevertheless he
points out that the entry requires x86/x86_64 CPUs. Without it it might very
well segfault (for instance it segfaulted on his MacBook Pro with the M1 chip).
2006/night (README.md)
As Cody is a lost :-) vim user he took the author's remarks to add support
back for arrow keys in the alternate version.
2006/sloane (README.md)
Cody fixed this entry to work with clang which has a defect with the args to
main(): it requires specific types: int and char ** for the first and
latter args.
Curiously, although clang requires the types of args to be strictly correct it allows for only one arg which Cody made it as the second arg was not used and this allows for a closer match to the original format of the entry.
He also made sure that the Makefile links in libm as not all systems do this by default.
Since the author suggested that the lack of certain #includes might break the
program in some systems he added -include ... to the Makefile as well.
The alternate version, which allows one to see what is going on in modern systems, and which we recommend one use first, was provided by Cody.
2006/toledo2 (README.md)
Cody fixed a segfault in this program which was making it fail to work under
macOS - it did not seem to be a problem under linux, at least not fedora. The
problem was wrong variable types - implicit ints instead of FILE *s. It now
works with both macOS and linux.
2006/toledo3 (README.md)
Cody fixed a crash and a display problem in this entry so that it now works in
modern (64-bit) systems. The crash appears to only occur in macOS but the fix
lets it work in both linux and macOS. The problem was that it relied on 32-bits
so some ints were changed to longs. The display problem might or might not
have been a problem in linux with the old ints but this is no longer known.
2011/goren (README.md)
Cody fixed this for macOS. Before the fix it segfaulted. It worked fine under
linux. After fixing it it was noticed that the author stated it does not work
for 64-bit so it was then tested as a 32-bit binary (linux) and 64-bit binary
(linux, macOS) and both work. It was fixed by changing some ints to longs
and now it does work with 64-bit systems as well as 32-bit systems.
Cody added the following words of wisdom: 'this is not a pipe'.
2011/richards (README.md)
Cody fixed a minor problem that showed up in both linux and macOS. He notes however that as of this time this entry does not work properly with macOS at least with the silicon chip (Intel has not been tested) and it is quite possibly an inherent problem in macOS to do with executing code in in memory/JIT and in particular with the silicon chip. See bugs.md for more details and a document from Apple about how it might be fixed if anyone is brave enough to try.
2011/vik (README.md)
Cody, though he feels slightly sick :-), added a version for Windows based on the author's comments (along with looking up the function for the right header file). To build try the alt rule of the Makefile.
2012/blakely (README.md)
Cody added explicit linking of libm (-lm) as not all systems do this
implicitly (linux doesn't seem to but macOS does).
2012/endoh1 (README.md)
Cody added explicit linking of libm (-lm) as not all systems do this
implicitly (linux doesn't seem to but macOS does).
2012/kang (README.md)
Cody changed the code to accept the proper German for four 'vier' where before it was spelt with the sound of V (fier not vier). But was this a bug or a feature? He's on the fence here but he went ahead and did it anyway as it seems useful and not having it fixed somewhat lessens the usability, especially for those who know German and expect it to be 'vier' :-)
2012/vik (README.md)
Based on the author's description it should be able to get this entry to work for Windows. With his instructions Cody added the alternate version that does this for the few who might use Windows.
We're not sure whether we want to thank Cody or not for this :-) and he's not sure if he wants to be thanked either :-) but we appreciate it nonetheless.
2013/birken (README.md)
Along with the demo.sh that he added, Cody also added an
alternate version which allows one to control how fast the painting is done,
based on the author's recommendations, except that Cody made it configurable at
compile time just like he did with other entries (in all but one it was
alternate code) that use usleep(). The alternate version and the original
version were swapped in the To build, To run and Try sections, with what
is normally Alternate code being Original code.
2013/cable3 (README.md)
Cody fixed this to compile with modern systems. The problems were that
localtime() is used differently and time.h being included (with SDL2 in
macOS - but see below) there was a conflicting function type. This appeared to
be a problem with macOS and only when SDL2 was included (but which as noted next
it cannot be).
The other problem is that this entry uses SDL functions that were
removed from SDL2 so the Makefile has to use sdl-config and not sdl2-config.
This meant that at one point to be strictly technical, the removal of
localtime() wasn't necessary but this change was left in place anyway.
Later on in an updated macOS (problem discovered in macOS Sonoma) the entry
failed to compile again also due to localtime() so he removed the prototype
entirely to solve the problem.
Cody also slightly improved the runme script to not assume that the program has
been compiled by running make clobber all || exit 1 and he also made it pass
shellcheck (using [[ .. ]] over [ .. ]).
As well, based on the author's remarks, Cody added the alternate
code which should be compilable for Windows/MS Visual
Studio. This is done by in the compile line undefining KB (-UKB) and then in
the source code defining KB to what the author suggested,
(kb=H(8),kbhit())&&(r[1190]=getch(),H(7)). It need hardly be mentioned that
this will not link in Unix systems (including macOS).
Finally Cody provided the bios.asm that the author referred to, found at the GitHub repo for the entry.
2013/dlowe (README.md)
Cody added the source code that we suggested one should compile and run with
different compilers as fun.c. He modified the Makefile so
that running make all will compile it, saving you the effort.
He also provided the script sflen.sh, fixing it for
shellcheck, which is based on the author's remarks, giving a script that shows
the spark line of the file lengths (as in wc -c). These fixes were applied in
the author's remarks as well.
Since the author called the program sparkl Cody modified the Makefile so that
running make all will create a symlink to dlowe as sparkl. Running make clobber will delete both and running make clobber all will ensure that the
symlink is created. The sflen.sh script also explicitly makes sure to create
the symlink as it uses it, even though it runs make clobber all.
Cody also added the demo.sh script to more easily try the program.
2013/endoh2 (README.md)
Cody fixed the Makefile check rule so that it checks :-) that both
Ruby and ImageMagick are
installed before trying to run the ruby script. To be more technically correct:
it checks that the convert tool of ImageMagick is available (via type -P)
because convert is part of the ImageMagick suite.
This is useful because the Ruby script tries to run (via IO.popen()) the
convert tool but without ImageMagick being installed, if one is unaware of
where it comes from it will appear to be an error in the Ruby script (it might
also appear to be an issue with the script even if you know of convert: it was
another day that Cody remembered it and why it wasn't installed on his MacBook
Pro even though in the past it had been and is indeed now).
The rule will report the tools not installed and where to find them, if they are not installed, and after checking these requirements it will exit if either is not found.
The entry can still be enjoyed if you do not have these tools, however.
2013/endoh4 (README.md)
Cody added the run.sh script which temporarily turns off the cursor as suggested by the author, with the addition that if no file is specified it will feed the source code endoh4.c to the program rather than the file specified. It does not try and detect if the file exists or can be read as that will be handled by the shell/program.
2013/endoh4 (README.md)
Cody added the run.sh script which temporarily turns off the cursor as suggested by the author, with the addition that if no file is specified it will feed the source code endoh4.c to the program rather than the file specified. It does not try and detect if the file exists or can be read as that will be handled by the shell/program.
2013/hou (README.md)
Cody fixed the Makefile so that this would work properly. Before this the use of
the program just did what the judges' remarks said as far as how it might
violate rule 2: the program is really just a decompressor to generate the
real source of the program. So the source of the entry has to be compiled and
then run, and the output has to be compiled to be hou. This allows the real
program to be used. Thus the Makefile rule looks like:
${PROG}: ${PROG}.c
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
./${PROG} | ${CC} ${CFLAGS} -xc - -o $@ ${LDFLAGS}
which then compiles like:
cc -std=gnu11 -Wall -Wextra -pedantic -Wno-sign-compare -Wno-strict-prototypes -O3 hou.c -o hou -lm
./hou | cc -std=gnu11 -Wall -Wextra -pedantic -Wno-sign-compare -Wno-strict-prototypes -O3 -xc - -o hou -lm
The LDFLAGS were updated to have -lm as the author suggested it uses the
math.h library which not all systems link in by default (linux for instance
does not).
Further, after the file 2013/hou/doc/example.markdown was moved to
2013/hou/doc/example.md to match the rest of the repo
this broke make which Cody also fixed.
2013/misaka ([README.md)[2013/misaka/README.md))
As there are a lot of commands to try, Cody added the demo.sh script to do this, sleeping for approximately 1 second between commands.
2013/morgan1 (README.md)
Cody added explicit linking of libm (-lm) as not all systems do this
implicitly (linux doesn't seem to but macOS does).
2014/deak (README.md)
Cody fixed the code that the author provided which would be what the program would look like if, as the author put it:
The usage of recognizable elements from the C programming language in the application source code is intentionally kept to a bare minimum. If this phrase would not be true, the application would be the following:
It did not compile because a value was left off the return statement.
Cody added this as alternate code just for fun and so one can more easily see the difference to really appreciate the obfuscation.
2014/endoh1 (README.md)
Cody added the rake.sh script and make rake rule that
runs the script. This script will check that rake is installed and if it is
not it will report this and then check that gem is installed. It checks that
gem is installed in this case because gem is how you install rake. If
gem is not installed it tells you to get it along with how to install gem.
Then it tells you how to install rake. If rake fails to run then it tells
you to install a specific gem and then to try again. Finally if rake succeeds
it will verify that prog is executable and if it is it will run it.
Barely worth noting but done nonetheless, Cody renamed the read_me.md
file to spoilers.md to be clearer in its purpose as
it is a file with spoilers.
2014/maffiodo1 (README.md)
Cody fixed the build for this entry: it does not require SDL2 but SDL1 so there were linking errors.
2014/skeggs (README.md)
Cody fixed the Makefile to compile this entry in modern systems. The problem was
that the CDEFINE variable in the Makefile was missing 's: the #define CC
is an actual string that is, in the Makefile, is "${CC} -fPIC", which
translates to whatever the compiler is followed by a space followed by -fPIC
but without the 's it was incomplete and so would not compile. Cody didn't
have a chance to really look at the compiler error.
Yusuke suggested that one should use -ldl in the Makefile. This was not
originally done because it seemed to work but since it uses dlsym() it was
added later to make it more portable.
The program creates files in the working directory as part of how it works (see
the README.md file for details) so Cody made sure that make clobber (via make clean) removes those files and so that they are ignored by .gitignore.
2014/vik (README.md)
Cody added an alternate version that is based on the author's remarks that will theoretically work for Microsoft Windows compilers (if anything works in Windows :-) ). We have no way of testing this and if anything has changed since 2014 that would break it we do not know.
2015/endoh3 (README.md)
Cody fixed this to compile with linux which was having a problem with duplicate
symbols of main(). The fix is through the compiler option -fcommon which
will let it compile like it does with macOS.
Cody also made it easier to enjoy the theme of Back to the
Future using this entry by
simply typing make back_to or make mullender.
2015/hou (README.md)
Cody added explicit linking of libm (-lm) for systems that do not do this
(linux doesn't seem to but macOS does).
2015/yang (README.md)
Cody fixed an unfortunate typo in the Makefile that was preventing some of the files from compiling properly, trying instead to compile already compiled code.
He also added explicit linking of libm (-lm) for systems that do not do this
(linux seems to not but macOS does).
2018/bellard (README.md)
Cody added explicit linking of libm (-lm) for systems that do not do this
(linux doesn't seem to but macOS does).
2018/ferguson (README.md)
Cody, with irony well intended :-), fixed the test.sh script for portability, shellcheck, making it executable and other things, fixed dead links in the man page, updated the test-strings.txt file and other things as well.
Landon notes that Cody will probably never finish changes in his entries and that's probably true: let's just say that for the IOCCC I'm (Cody) a weasel! :-) (but isn't that kind of the point ? :-) )
2018/hou (README.md)
Cody added explicit linking of libm (-lm) for systems that do not do this
(linux doesn't seem to but macOS does).
2019/burton (README.md)
Cody fixed the Makefile which had a bad character, a '%' instead of a '$' which caused a rule to fail.
2019/ciura (README.md)
Cody fixed invalid bytes error in tr in the scripts. He notes that at least on
his systems (macOS and fedora linux) the alternative languages do not work.
Perhaps that is the wrong locale or it's unable to come up with perfect pangrams
but one will not get errors now (it did not work before the fixes either).
2019/diels-grabsch1 (README.md)
Cody made the author's statement that the entry compiles cleanly true by fixing
warning: a function declaration without a prototype is deprecated in all versions of C (in main()). Not strictly necessary but if he's making fixes he
might as well.
2019/diels-grabsch2 (README.md)
Cody made the author's statement that the entry compiles cleanly true by fixing
warning: a function declaration without a prototype is deprecated in all versions of C (in main()). Not strictly necessary but if he's making fixes he
might as well.
2019/dogon (README.md)
Cody added explicit linking of libm (-lm) for systems that do not do this
(linux does not seem to but macOS does).
He also fixed the Makefile so that it compiles with clang in linux.
2019/endoh (README.md)
As this is a backtrace quine having the optimiser enabled is not a good idea so
Cody disabled it. For this same reason he also added the -g flag to the
compilation as debugging symbols might just be useful for an entry that's
supposed to segfault :-)
2019/poikola ([README.md[(2019/poikola/README.md))
Cody added a missing rule to the Makefile.
2019/karns (README.md)
Cody reported that with -O level > 0 this program segfaults (sometimes?). He's
not sure why as it worked fine before on the same systems tested but -O0
appears to fix the problem in both macOS and linux. Perhaps this is the problem
that the author reported where it sometimes segfaults but Cody did not try
debugging it since it works with -O0.
He also added the script demo.sh to showcase the entry a bit more easily.
2020/ferguson2 (README.md)
Cody, with intentional irony here :-), fixed formatting, links and typos in various files.
He improved the termcaps.c test utility, bug fixed
play.sh, fixed other scripts and the Makefile, changed
some files to be markdown (and fixed problems that he caused in doing so :-) ),
fixed typos and formatting and he also fixed some issues that occurred when
files were renamed to .md from .markdown.
Most importantly he also added some corrections to the vital Double layered chocolate fudge cake recipe :-)
Yes the irony here is as rich as the chocolate cake: the question is do you know how rich it is? If not and you like chocolate I (that is Cody :-) ) highly recommend you give it a go! :-)
2020/ferguson2 (README.md)
Cody, with intentional irony here :-), fixed formatting, links and typos in various files.
He also fixed some issues that occurred when files were renamed to .md from
.markdown.
Most importantly he also added some corrections to the vital Double layered chocolate fudge cake recipe, enciphered though it is :-)
2020/kurdyukov2 (README.md)
Cody added -L/-I paths to the Makefile to let this compile more easily if
the user has installed the appropriate library with
MacPorts (with the default MacPorts prefix
/opt/local).
