From aa70cf88d09dbfadcfaba851e2ab84860d5cea96 Mon Sep 17 00:00:00 2001
From: Landon Curt Noll
./natori./try.shTry running this on different days, say a few days apart, and each -time run it several times in a row (or several times in a day).
+Try running this on different days, say a few days apart (even better +if the Moon phase changes), and each time run it several times in a row +(or several times in a day).
Also try modifying the code so that it will show another Moon phase based on input or else just by the code itself. Bonus points if you can -make it show all~
+make it show all. +NOTE: if it’s a Full Moon the script won’t look as nice.
The author noted that those in the southern hemisphere might want to
change acos(l/2) into acos(-l/2) which we have
@@ -156,8 +158,10 @@ differences?
./try.alt.shLike with try.sh, try using this multiple -times.
+Like with try.sh, try using this multiple times +in a row or throughout the day on different days (if different phases of +the Moon you’ll see more of a difference, of course).
+NOTE: if it’s a Full Moon the script won’t look as nice.
Here is a nice compact program that changes with the phase of the Moon. Can you figure out how it does it?
diff --git a/CODE_OF_CONDUCT.html b/CODE_OF_CONDUCT.html new file mode 100644 index 000000000..5378df855 --- /dev/null +++ b/CODE_OF_CONDUCT.html @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + +
+ We as members, contributors, and leaders pledge to make participation +in our community a harassment-free experience for everyone, regardless +of age, body size, visible or invisible disability, ethnicity, sex +characteristics, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation.
+We pledge to act and interact in ways that contribute to an open, +welcoming, diverse, inclusive, and healthy community.
+Examples of behavior that contributes to a positive environment for +our community include:
+Examples of unacceptable behavior include:
+Community leaders are responsible for clarifying and enforcing our +standards of acceptable behavior and will take appropriate and fair +corrective action in response to any behavior that they deem +inappropriate, threatening, offensive, or harmful.
+Community leaders have the right and responsibility to remove, edit, +or reject comments, commits, code, wiki edits, issues, and other +contributions that are not aligned to this Code of Conduct, and will +communicate reasons for moderation decisions when appropriate.
+This Code of Conduct applies within all community spaces, and also +applies when an individual is officially representing the community in +public spaces. Examples of representing our community include using an +official e-mail address, posting via an official social media account, +or acting as an appointed representative at an online or offline +event.
+Instances of abusive, harassing, or otherwise unacceptable behavior +may be reported to the community leaders responsible for enforcement at +https://www.ioccc.org/judges.html. All complaints will be reviewed and +investigated promptly and fairly.
+All community leaders are obligated to respect the privacy and +security of the reporter of any incident.
+Community leaders will follow these Community Impact Guidelines in +determining the consequences for any action they deem in violation of +this Code of Conduct:
+Community Impact: Use of inappropriate language or +other behavior deemed unprofessional or unwelcome in the community.
+Consequence: A private, written warning from +community leaders, providing clarity around the nature of the violation +and an explanation of why the behavior was inappropriate. A public +apology may be requested.
+Community Impact: A violation through a single +incident or series of actions.
+Consequence: A warning with consequences for +continued behavior. No interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, for a +specified period of time. This includes avoiding interactions in +community spaces as well as external channels like social media. +Violating these terms may lead to a temporary or permanent ban.
+Community Impact: A serious violation of community +standards, including sustained inappropriate behavior.
+Consequence: A temporary ban from any sort of +interaction or public communication with the community for a specified +period of time. No public or private interaction with the people +involved, including unsolicited interaction with those enforcing the +Code of Conduct, is allowed during this period. Violating these terms +may lead to a permanent ban.
+Community Impact: Demonstrating a pattern of +violation of community standards, including sustained inappropriate +behavior, harassment of an individual, or aggression toward or +disparagement of classes of individuals.
+Consequence: A permanent ban from any sort of public +interaction within the community.
+This Code of Conduct is adapted from the Contributor Covenant, +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+Community Impact Guidelines were inspired by Mozilla’s code of conduct +enforcement ladder.
+For answers to common questions about this code of conduct, see the +FAQ at https://www.contributor-covenant.org/faq. Translations are +available at https://www.contributor-covenant.org/translations.
+ + + + + + + +
+ Please visit www.ioccc.org for +the official IOCCC web site.
+Please do NOT bookmark or link to this experimental web +site.
+When this experiment is finished, this site will go away!
+This test web tree is part of the temp-test-ioccc +GitHub repo.
+This web site will be undergoing major changes, so expect many broken +links, typos and other problems. If you wish to recommend changes +(understanding that things may be rapidly changing out from under your +copy), then consider making pull requests against the temp-test-ioccc +GitHub repo.
+XXX - The text from the top down to the What follows is the +actual README.md file line will be removed when this web site +becomes official - XXX
+render obscure, unclear, or unintelligible: the spelling changes +will deform some familiar words and obfuscate their etymological +origins.
+late Middle English (as adjective): from late Latin +obfuscat- ‘darkened’, from the verb +obfuscare, based on Latin fuscus +‘dark’.
the action of making something obscure, unclear, or +unintelligible: when confronted with sharp questions they resort to +obfuscation | ministers put up mealy-mouthed denials and +obfuscations.
+late Middle English: from late Latin obfuscatio(n-), +from obfuscare ‘to darken or obscure’ (see +obfuscate).
The official IOCCC web site is https://www.ioccc.org.
+The original inspiration of the International Obfuscated C Code
+Contest came from the Bourne Shell source and the finger(1)
+command as distributed in 4.2BSD.
+If this is what could result from what some people claim is reasonable
+programming practice, then to what depths might quality sink if people
+really tried to write poor code?
I put that question to the USENET news groups net.lang.c and +net.unix-wizards in the form of a contest. I selected a form similar to +the contest (Bulwer-Lytton) +that asks people to create the worst opening line to a novel (that +contest in turn was inspired by disgust over a novel by Edward +Bulwer-Lytton that opened with the line “It was a dark and +stormy night.”). The rules were simple: write, in 512 bytes or +less, the worst complete C program.
+Thru the contest I have tried to instill two things in people. First +is a disgust for poor coding style. Second was the notion of just how +much utility is lost when a program is written in an unstructured +fashion. Contest winners help do this by what I call satirical +programming. To see why, observe one of the definitions of +satire:
+++Keen or energetic activity of the mind used for the purpose of +exposing and discrediting vice or folly.
+
The authors of the winning entries placed a great deal of thought +into their programs. These programs in turn exposed and discredited what +I considered to be the programmer’s equivalent of “vice or +folly”.
+There were two unexpected benefits that came from the contest +winners. First was an educational value to the programs. To understand +these C programs is to understand subtle points of the C programming +language. The second benefit is the entertainment value, which should +become evident as you read further!
+You are strongly urged to try to determine what each program will +produce by visual inspection. Often this is an impossible task, but the +difficulty that you encounter should give you more appreciation for the +entry.
+If you have the energy to type in the text, or if you have access to +a machine readable version of these programs, you should next consider +some preprocessing such as:
+sed -e '/^#.*include/d' prog.c | cc -EThis strips away comments and expands the program’s macros without
+having things such as includes and macros cluttering up the output. If
+the entry requires or suggests the use of compile line options (such as
+-Dindex=strchr) they should be added after the
+-E flag. See the entry README.md and/or Makefile. For the
+Makefiles look at the variable CDEFINE.
The next stage towards understanding is to use a C beautifier or C +indenting program on the source. Be warned that a number of these +entries are so twisted that such tools may abort or become very +confused, sometimes even preventing them from compiling. You may need to +help out by doing some initial formatting with an editor. You might also +try renaming variables and labels to give more meaningful names. Be +aware, however, that some entries will not work if you rename variables, +even if you manage to determine where exactly they are (to say nothing +of the fact that the name might be elsewhere in the code).
+Now try linting the program. You may be surprised at how little lint +complains about these programs. Pay careful attention to messages about +unused variables, wrong types, pointer conversions, etc. But be careful, +some lints produce incorrect error messages or even abort (or even +crash)! Your lint may detect syntax errors in the source. See the next +paragraph for suggestions on how to deal with this.
+When you get to the stage where you are ready to compile the program,
+examine the compilation comments above each entry. A simple
+#define (or -D at the compiler) or edit may be
+required due to differing semantics between operating systems. If you
+are able to successfully compile the program, experiment with it by
+giving it different arguments or input. You may also use the Makefile
+provided to compile the program. Look at the To build and
+Try sections at the top of the README.md for each entry as
+well. Keep in mind that C compilers often have bugs, or features which
+result the program failing to compile. You may have to do some syntax
+changing as we did to get old programs to compile on strict ANSI C
+compilers.
Last, read the judges’ remarks/spoilers on the program. Hints for
+foo.c are given in README.md. Often they will
+contain suggested arguments or recommended data to use. Authors also
+sometimes give spoilers.
If you do gain some understanding of how a program works, go back to +the source and reexamine it using some of the techniques outlined above. +See if you can convince yourself of why the program does what it +does.
+Each sub-directory contains all the entries for a single year. Often
+the file names match one of the last names of the author. Judges’ hints
+are given in files of the form README.md.
You may need to tweak the Makefile to get everything to compile +correctly. Read the README.md files for suggestions.
+The rules for a given year are given in the file named
+rules.txt. Each archive contains a copy of the rules for
+the upcoming contest.
The following URL is the official archive of the winning entries: https://www.ioccc.org/years.html.
+All contest results are in the public domain. We do ask that you +observe the following request:
+You may share these files with others, but please do not prevent them +of doing the same. If some of these files and/or contest entries are +published in printed form, or if you use them in a business or classroom +setting, please let us know. We ask that you drop a line to the judges’ +email box. See https://www.ioccc.org/contact.html for instructions on +how to send us a message.
+While the idea for the contests has remained the same through the +years, the contest rules and guidelines vary. What was novel one year +may be considered common the next. The categories for awards differ +because they are determined after the judges examine all of the +entries.
+The judges’ hints assume that the program resides in a file with the
+same username as the author or prog.c (depending on the
+year). Where there is more than one author, the first named author is
+used. If an author wins more than one entry per year there are
+different formats used but the first entry has 1 appended, the second
+has 2 etc. In some years it was .1 and .2
+instead.
Some C compilers are unable to compile some of these programs. The
+judges tried to select programs that were widely portable and
+compilable, but did not always succeed. As of 1990, an entry may use
+both K&R and ANSI C compilers. Makefiles for both types
+of C compilers are used. See the contest rules for details.
You are strongly encouraged to read the new contest rules before +sending any entries. The rules, and sometimes the contest email address +itself, change from time to time. A valid entry one year may be rejected +in a later year due to changes in the rules. See https://www.ioccc.org/index.html#enter for up to date +information on how to enter.
+Last, PLEASE don’t code in the style of these programs It is hoped +that you will gain an understanding that poor style destroys an +otherwise correct program. Real programmers don’t write obfuscated +programs, unless they are submitting a contest entry! :-)
+Happy pondering!
+The official IOCCC +entries GitHub repository are the official winners of the +International Obfuscated C Code Contest (IOCCC), the +Internet’s oldest ongoing contest.
+IMPORTANT NOTE: See contact.html for up to date contact details as +well as details on how to provide fixes to any of the entries. See also +the IOCCC FAQ for addition information on the +IOCCC.
+Copyright (C) 2020,2023,2024 Landon Curt Noll. All Rights Reserved. +This work is licensed under a Creative Commons +CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International license. +If you do use this work in some form, the IOCCC +judges would appreciate (but do not require) if you were to send us a note about your use.
+ + + + + + + +
-[ A B C -D E F -G H I -J K L -M N O -P Q R -S T U -V W X -Y Z] +Jump to authors starting with: [ A +B C D +E F G +H I J +K L M +N O P +Q R S +T U V +W X Y +Z]
[ +
Jump to authors starting with: [ A B C @@ -771,7 +771,6 @@ fi ]
+ There are a number of known problems with IOCCC entries: many of +which have to do with differences between today’s compiler environments +and those of today. In some cases the original code has a bug, some of +which were recently discovered and many of which were fixed. In some +cases attempt to port older code to more modern environments introduced +bugs.
+The following is a known list of BUGS and +(mis)FEATURES in IOCCC entries.
+Can you fix/improve entries not under the INABIAF (it’s not a bug +it’s a feature)? You are VERY WELCOME to try.
+NOTE: currently this file is mostly for us. We are not yet ready for +help except for dead links and missing files. We will remove this notice +when this changes. We will note this below for each status we’re not yet +ready for help with.
+As far as how to help: please submit your fixes in a GitHub pull +request (with ONE PULL REQUEST PER FIX, please)!
+We will be happy to credit anyone who submits successful GitHub pull +requests in the thanks +file. If you’re a previous winner we will add a link to your winning +entries in the file (if you’re not a previous winner we can add a link +to your GitHub page or personal website if you have one, should you +wish).
+If you do fix an entry please feel free to delete the entry from this +file! Otherwise if you wish to not worry about it we can do that to make +sure the format is consistent and clean.
+THANK YOU!
+If you’re the author of an entry that has been fixed and you find it +against your liking PLEASE let us know and we’ll be +happy to undo any fixes even if it takes away some instructional value +or even usability. _In this case we’re VERY SORRY_ +about it: it’s a fine line, we know, and we tried to use careful +judgement but invariably some might have been the wrong decision. Thank +you for understanding!
+I (Cody Boone +Ferguson) accept the blame in some cases; when working on getting +entries to compile sometimes I got carried away with it and there might +be that I fixed some things that should not have been fixed. I am +correcting these mistakes as I come across them but if I miss any please +let the judges or me know.
+Make ABSOLUTE CERTAIN that you test the entry
+BEFORE AND AFTER your changes! This
+includes output and the same input functionality! Sometimes it might
+seem to be fine but is actually not! We will note some where this is
+known to happen (if it’s not yet fixed). This has actually already
+happened to us. Sometimes it is okay: some entries are known to not work
+but they can still have improvements (rarer situation but it’s
+happened). Some might have slightly different output but which is not a
+problem for instance a newline after output in Cody Boone Ferguson’s
+changing it to 1994/ldb use
+fgets() from gets().
Make ABSOLUTE CERTAIN that you read the README.md +file BEFORE your changes as it’s important to see that the code +is doing what it is supposed to. In the case that it’s not obvious (some +README.md files do not even have commands to try or even explain how to +use it!) then you should either skip the entry OR ask someone who will +know e.g. us.
+Make ABSOLUTE CERTAIN that you read the next +section, the list of statuses and the related information, BEFORE you +submit a pull request!
+BE VERY AWARE that sometimes fixing an entry for one +platform will break it under another so if you have more than one +platform (e.g. macOS and linux) it would be wise to test it under all +that you have access to. Otherwise we can do that. Of course if the +entry does not work under any platform and you fix it for one that’s +more than fine (and it has been done numerous times).
+Again, THANK YOU!
+NOTE: when going through the entries you can skip to the next entry
+(some are detailed explanations) by searching for
+^## STATUS: in your editor (or searching for it - probably
+without the ^ in your browser). For a specific year try
+^# YYYY where YYYY is the year as a
+number.
Entries below have one or more of the following +STATUS values. Please see the text below for +more information. If an entry has more than one status it means that +either they all apply or they compliment each other. For instance 2004/gavin crashes but it also doesn’t +even compile with some platforms/architectures.
+Cody Boone Ferguson +has been working on resolving these issues and has fixed many but you’re +welcome to have a go at it too (though he’ll be very sad if he doesn’t +have a chance to at first fix it :-( so you might want to hold off for +now :-) .. or not :-) ). He hopes to have most of the remaining entries +resolved in the near future but nevertheless if you’re okay making +people very sad you may have a go at the entries :-) Yusuke Endoh has also fixed a +number of entries though at this point he does not know it. :-) Cody +will remove this part later on.
+In general warnings should NOT be addressed. The only time they +should be CONSIDERED is when the entry does not work. However note that +sometimes trying to fix the warnings will actually introduce bugs! Other +times ‘fixing’ them will break the entry (see below).
+Below in some entries we do list some warnings that definitely should +be ignored (including some introduced by fixes) but we do not list them +all: trying to keep track of them all would be impractical especially as +different compilers give different warnings.
+Another type of warning that would be hard to keep track of is
+different data sizes on different platforms. These tend to be required
+at the risk that sometimes the entry will not work for certain
+platforms, some of which might or might not be fixable; a good example
+where it was required to change and is okay is when Cody Boone Ferguson fixed
+the segfault in macOS of 1989/paul:
+changing the int * to a long * was required
+and it works just as well with linux.
But even if they are fixable (which will likely be hard to do) it’s +almost certain that such code would be just as non-portable (importable +? :-) ).
+In rare cases they are valid. For instance Cody noticed in linux the +following warning in 1985/applin with +gcc:
+applin.c:1:78: warning: incompatible implicit declaration of built-in function 'execlp' [-Wbuiltin-declaration-mismatch]
+ 1 | main(v,c)char**c;{for(v[c++]=strdup("Hello, world!\n");(!!c)[*c]&&(v--||--c&&execlp(*c,*c,c[!!c]+!!c,!c));**c=!c)write(!!*c,*c,!!**c);}
+ | ^~~~~~
+and this reminded him of his fix to 1984/anonymous. In the case of
+1984/anonymous it was a bit more involved but with
+1985/applin one need only add to the Makefile
+-include unistd.h. So there are some cases where fixing
+warnings can fix a problem but in general they should be ignored even if
+they’re annoying.
Hopefully with the example entries listed above you get the idea.
+If you’re fixing an entry please make as FEW CHANGES AS +POSSIBLE! This is to make it as close to the original but allowing +it to work. This might be less of a problem when providing alternate +versions but it might still be nice to have it as close as possible to +the original. See also below two points.
+For one-liners PLEASE KEEP THE FILE ONE LINE IF AT ALL
+POSSIBLE! If it needs an include you can update the Makefile
+CINCLUDE variable. For instance if it needs
+stdio.h you could do -include stdio.h. Please
+leave a space after the = in the Makefile. You may also
+have extra long lines if this seems useful to make it a one-liner even
+if it kind of makes it longer than what the judges consider a one-liner.
+Thank you!
If you make changes PLEASE TRY AND KEEP THE SOURCE CODE LAYOUT AS +CLOSE TO THE ORIGINAL AS POSSIBLE. This might not always be +possible and if you have an editor that does formatting it can cause +problems. Sometimes formatters can even break code! Cody Boone Ferguson has +experienced this many times with vim so he tends to disable all format +options when formatting code. In vim you should be able to do that +with:
+:set formatoptions=
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Entries with this status have one or more bugs that need to be fixed. +Are you able to fix it? We welcome your help!
+An important point to note is that there is a very fine line when +fixing bugs where it might sometimes border on tampering with the +program. And after all, these are not meant to be maintainable or even +good programming style! Use careful judgement when fixing bugs +please!
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Entries with this status might or might not have a bug possibly +depending on the system. In these entries it’s unknown if there is a bug +and sometimes it’s because we do not remember and sometimes we don’t +have the appropriate system or environment to test and fix any possible +problems.
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Although these entries appear to work for one or more +reasons we’re unsure if they are completely functional. Can you confirm +this? Please let us know so we can fix it!
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Entries with this status almost certainly have a bug or some other +problem. The issue or issues might depend on the system much like the +above STATUS: possible bug (possibly depending on system).
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Entries with this status do not work under some OSes and/or +architectures (and/or something else?). Please help us to fix it!
+NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Some entries do not work with some compilers. A good example is 1992/lush which uses error messages from the +compiler to generate its output.
+If you can provide code that works for multiple compilers without too +much tampering this is okay though it’s probably not possible with the +above mentioned entry; otherwise it would be better to provide alternate +code. In some cases it might be better to provide alternate code anyway. +Use a judgement call here as best you can manage.
+NOTE: it appears that most if not all of these have been fixed except +perhaps for 1989/westley but this +has probably been fixed as much as possible given the nature of how it +generates code: the entry itself compiles but two versions of code it +generates does not work with clang.
+However some still might have problems of some kind or another and
+some might not yet be located as an additional defect of clang was
+noticed where main() is not allowed four args or one
+arg.
This is what the status means, however.
+Entries with this status have a problem in that the args to main()
+are not of a specific type or there are too many due to this being
+allowed in earlier C. Some compilers like clang have a defect where they
+do not allow this and some versions have an additional defect where they
+only allow 0, 2 or 3 args, the latter of which affected
+1989/westley, so these entries do not work with clang.
Cody Boone Ferguson
+looked at the source code of clang and reported that there is no way to
+override the requirement of arg types so these entries will fail to
+compile with clang. That’s why in some entries he fixed he did it by
+adding a function called pain(). :-) He did not check for
+the number of args as that was discovered later but he suspects it’s the
+same issue.
NOTE for macOS users: please be aware that
+gcc under macOS is actually clang despite the
+fact it might appear to be gcc: no symlink and both gcc and clang exist
+but the gcc is clang which you’ll see if you run
+gcc --version.
A tip and some fix methods from Cody: in the older days args to
+main() not given a type were implicit ints but when they’re required to
+be char ** this can cause a problem. In some cases Cody was
+able to use a char * inside main() (see 1989/tromp/tromp.c and 1986/holloway/holloway.c for two examples
+though done slightly differently). In other cases he was able to
+dereference the pointers to be used like an int and other times a cast
+was necessary. He used other various techniques to get them to compile.
+In some cases this introduced a problem but typically if not always that
+problem exists with compilers that are less strict.
Because some versions of clang complain about the number of args of
+main() and in particular say (when it has four, for
+instance) that it’s only allowed to have 0, 2 or 3 args, numerous
+entries had a second arg added to main() (if they only had
+one). This is in case clang adds further restrictions which is not
+impossible especially as it already claims having only one arg is not
+allowed. At this time (04 Feb 2024) there is one entry known (it is
+possible that not all were checked) that has this problem but it’s not
+as simple as the others to fix without breaking it.
NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+While such entries can compile, the resulting executable sometimes or +always crashes.
+NOTE: this does NOT apply to entries under the INABIAF status (though +they’re not mutually exclusive in some cases).
+REMINDER: if you’re debugging a crash it will be very helpful to have
+-O0 -g or if you can -ggdb3 when compiling as
+that will help with debugging symbols.
NOTE: we’re still locating entries and working on fixes with this +status so we’re not yet ready for help. We will remove this when we +are.
+Entries with this status use gets() which is unsafe
+because it has no limit on the length of the string. Cody Boone Ferguson has
+fixed several of these and he’s working on others in between fixing
+other things.
There’s a very good reason for this even though it is bordering on +tampering entries: in modern systems one will get possibly alarming and +certainly annoying warnings during at least one of compiling, linking +and execution. In macOS it’s most annoying as it happens during +execution (also compilation) with the warning being interspersed with +the output of the program, often causing confusing output with the +entry. A good example that was fixed is 1990/tbr.
+Cody provided some important notes on this status with respect to +fixing / changing entries:
+In some cases changing the entry to use fgets() will
+break the entry and in some cases cause it to crash. Where this is known
+we will document it. Some of these Cody is also off and on working
+on.
You MUST check the output before and after to +make sure that it remains the same. Sometimes the output might not be +immediately obviously wrong but is. We will document known examples as +we come across them.
gets() does NOT STORE the '\n' but
+fgets() DOES! This is one of the reasons some of the
+entries break when changed to fgets(). Cody has fixed some
+of these but there are others he hasn’t had time to address or even
+discover yet.
Just because you don’t see the string gets in the
+code does not mean it’s not used. It is after all the International
+Obfuscated C Code Contest! :-) Sometimes it will be in the
+Makefile and other times it will be obfuscated in other ways. Compilers
+and linkers tend to warn about its use (and as noted in macOS it also
+happens at execution) and this is a good way to find entries that use it
+even if it’s not visible in the code.
NOTE: this status is NOT necessarily mutually +exclusive with the INABIAF (it’s not a bug it’s a feature) +status. The reason for this is due to warnings during compiling, linking +and/or runtime, sometimes causing confusing output (as noted above).
+Sometimes getline(3) will work but note that this
+function also stores the newline just like fgets(3).
In these entries one file or multiple files are missing from the +repo. In some cases these files can be found on the IOCCC website but in other cases they +are entirely absent. In this case you’ll probably have to contact the +author (unless you are the author! :-) ).
+In these entries one or more make rules noted by the author and/or +judges is/are missing. You might consider looking at the archive as a good place to find them.
+This is as they sound: a link is either missing or it’s no longer +valid. In many cases the Internet +Wayback Machine will be very useful but there happens to be numerous +links that this is not helpful. In other cases the URL has changed. Some +of these have been discovered by the Internet Wayback Machine with the +orange status.
+The archive website will tell you if the link was never captured.
+Entries with this status should NOT be touched (unless they have +another status that suggests that that issue can be changed): +they are system specific by design or are other things that are not +actually bugs or bugs even if they appear to be. Or they might be +documented bugs or things that simply are part of the entry. Nonetheless +they are noteworthy.
+NOTE: the definition of this status changed over time. At one point +it was when something was noted by the author, the judges, a consequence +of earlier requirements for winning entries or the purpose was to do +something that might appear to be buggy. An example of system specific +entries:
+1984/mullender (see below +and the FAQ for a version that works in modern +systems) is very system specific and was before system specific winning +entries were discouraged. This is an all time personal favourite of +Landon Curt Noll. Run the alternate code to understand why this might be +(along with how strange the source code is :-) ).
+An example where a crash is not a bug: 2019/endoh is supposed to crash. There are +others that are also supposed to crash or that are known to segfault but +are considered features.
+An important note is that if the README.md of the entry has a bug +status that says it can be fixed it can be. Otherwise it should not +be.
+Nonetheless we challenge you to fix these entries for +educational/instructional value and/or enjoyment but we kindly request +that you DO NOT submit a pull request unless it’s a bug +or (mis)feature we would like you to fix! If you can’t figure it out +you’re invited to look at the git diffs, where there are some (some were +fixed earlier on but rolled back as both Cody and Landon individually +felt that the fix was tampering with the entry).
+NOTE: in the case of gets() we’ve fixed some to avoid
+the warning of the compiler, linker or even during runtime, depending on
+the system. In some cases like 1990/tbr the
+fix actually prevents confusing output (though that was not the only fix
+made in that entry).
Of course if you’re the author you’re welcome to fix your own entry, +prefer your own fix or suggest that they’re fixed!
+The purpose of this program is to print out a string of rubbish. In +particular you should see something like:
+$ ./decot
+'",x); /*
+\without a newline after the \. This is not a bug.
Although there is an alt version and supplementary program added by +Cody that will work in modern systems, if you do not have a VAX-11 or PDP-11 to run the +original entry on it will not work. See the README.md for details on the +alternate versions.
+Cody added and fixed the gentab.c which is from the author’s
+(or one of them, Mullender) remarks found by Cody. Cody fixed this to
+compile and work (as best as he can determine: he has no VAX-11 or
+PDP-11 or emulator to test it) but running the code on the binary itself
+produces a short[] that can compile in modern systems
+though it’ll not work.
There are no known bugs and (Mis)features for entries in 1985.
+This entry is known to segfault after printing its output. It was +documented by the judges and shouldn’t be fixed.
+There are no known bugs and (Mis)features for entries in 1987.
+In linux it might happen that despite no error message or message +about doing so, the program drops a core file into the directory even +though the entry works and does not crash.
+If you use either fubar or ouroboros.c
+(it’s executable, see README.md for details) with a number < 0 or
+larger than, say 20, it’s very likely that the program will turn into an
+infinite loop trying to compile code with syntax errors.
If you want to try and fix this (mis)feature, you are welcome to +try.
+This program will very likely crash or break into tiny bits :-) if +you feed it numbers with non-binary digits.
+There are also other cases where this can happen for instance using
+unsupported operators like /. To see what operators are
+supported check the source code.
With version 2 it sometimes segfaults even with the same input where +other times it does not. We don’t believe this is because of the fix +that lets some versions be compiled with clang. An example invocation +is:
+./ver2 < westley.cIt should be noted that in additional to rot13 names there is code +that is the reverse of other code (also wrt names). See the source file +and the README.md (in the author’s remarks) for more details.
+Fixing the (Mis)feature is likely to be a very difficult challenge +especially without breaking something else which is far more likely (see +below in tips from Cody). You are welcome to try and fix it if you +can!
+The reason this is crashing is that the array irk is
+being accessed way out of bounds by the int gnat. For
+instance:
Program terminated with signal SIGSEGV, Segmentation fault.
+#0 0x0000000000401335 in main (ABBA@entry=<optimized out>, tang@entry=<optimized out>, gnat@entry=<optimized out>, Near@entry=<optimized out>)
+ at ver2.c:23
+23 &&gnat!({)Near,noon,/*krelc*/)<0&&(Near= - irk[-gnat--]-2)))&&main(ABBA,
+(gdb) p gnat
+$1 = -518733305
+The real trouble is that the code is generated and in a complex way +or rather ways.
+I will explain this a little bit (though it might be more than a bit +according to many :-) ) but that is all I can do for now. The program, +when used without any args, will print out what it reads. If one arg is +specified it will do a ROT13 of it. If two args are specified it will +print out the text backwards (WITHOUT ROT13!). If three args +are specified it will do both reversal AND +ROT13.
+So ver0 is the same as the main program;
+ver1 is the ROT13 of the code (but see below);
+ver2 will reverse the code and ver3 will both
+reverse and ROT13 the code. But it’s trickier than that as one might
+expect.
The comments are processed too. Furthermore it happens that the last +line becomes the first and the first line becomes the last! Now if you +look at the code you’ll see on the first line:
+/**//*/};)/**/pain(/*//**/tang ,gnat/**//*/,ABBA~,0-0(avnz;)0-0,tang,raeNIn ver0 it’ll be the same but the others are more
+interesting.
In ver1 you’ll see on the last line:
cnva((vag)NOON&2/*//*\\**/,gnat,tang ,NOON/**//*/(niam/**/);}/*//**/and on the first line:
+/**//*/};)/**/cnva(/*//**/gnat ,tang/**//*/,NOON~,0-0(niam;)0-0,gnat,enrAObserve that the ROT13 of pain is cnva and
+the ROT13 of main is znva. The ROT13 of
+NOON is ABBA. vag is ROT13 of
+int, gnat and tang are ROT13 of
+each other as well which is the reverse of the original (this is not
+because it goes backwards (it doesn’t in this version) but because they
+are ROT13 pairs!). main spelt backwards is
+niam and pain spelt backwards is
+niap. Furthermore see the Makefile for other defines that
+had to be specified and for ver2 and ver3 (that both work with gcc) one
+had to be undefined (search for CDEFINE and
+-U). These details will be important momentarily.
As far as NOON and ABBA being ROT13 pairs,
+notice how NOON is not in the original code but
+ABBA is; but in other versions it becomes NOON
+and they also have abba which the original code does
+not!
Now notice how the avnz in the first line got changed to
+niam, its ROT13 value. Notice also how some of these are in
+comments!
main() is in there somewhere and that had to be changed
+to call pain() (see the thanks file (see the
+1989/westley section for details on how as this was not as
+straight forward as it is for other entries) as well. Now if you notice
+on that line you have in a comment niam. If you were to
+change that to niap (pain backwards) that function would
+end up as pain() in generated code! That’s assuming that
+it’s just the reversal version, of course but ver1 is the ROT13
+version.
These facts are bad enough but then you throw in the reverse of it +without ROT13 and then another version that has the reversal +and ROT13 then you can see it’s nigh impossible to fix if not +impossible.
+The fix to get it to even compile with clang and then get the first
+two (counting the original, ver0) to work was the hardest
+fix I made due to how the comments in reverse and ROT13 of it all works
+together, especially allowing all versions to compile with gcc. The only
+reason that it doesn’t work completely with clang is the arg types of
+main() (see if you can figure out how the change of main()
+in westley.c is not carried over to versions 2 and 3!);
+originally none of them compiled with clang.
But it was possible to get the ROT13 code to compile with clang but +the other versions, reversed as well as ROT13 and reversed code, proved +much more problematic. I got it to compile (or maybe mostly compile) all +versions with clang but I then carried it over to gcc in another system +and it had syntax errors.
+That’s about all I can say for how it works as other things have to +be done too. Enjoy! :-)
+A point worth considering is that as the number passed into the +program gets bigger the number of lines of output gets substantially +larger and it takes much more time and resources to run as well. For +instance:
+$ for n in $(seq 1 18); do echo "$n"; echo "$n" | time "./baruch" | wc -l | sed -E -e 's/[[:space:]]//g'; done
+1
+3
+./baruch 0.00s user 0.00s system 5% cpu 0.115 total
+2
+1
+./baruch 0.00s user 0.00s system 64% cpu 0.004 total
+3
+1
+./baruch 0.00s user 0.00s system 60% cpu 0.003 total
+4
+11
+./baruch 0.00s user 0.00s system 64% cpu 0.003 total
+5
+61
+./baruch 0.00s user 0.00s system 66% cpu 0.003 total
+6
+29
+./baruch 0.00s user 0.00s system 61% cpu 0.003 total
+7
+321
+./baruch 0.00s user 0.00s system 69% cpu 0.002 total
+8
+829
+./baruch 0.00s user 0.00s system 76% cpu 0.003 total
+9
+3521
+./baruch 0.00s user 0.00s system 87% cpu 0.005 total
+10
+7965
+./baruch 0.01s user 0.00s system 95% cpu 0.014 total
+11
+32161
+./baruch 0.05s user 0.00s system 98% cpu 0.053 total
+12
+184601
+./baruch 0.29s user 0.00s system 99% cpu 0.294 total
+13
+1031969
+./baruch 1.78s user 0.00s system 99% cpu 1.794 total
+14
+5483941
+./baruch 11.26s user 0.02s system 99% cpu 11.311 total
+15
+36466945
+./baruch 79.20s user 0.15s system 99% cpu 1:19.72 total
+16
+251132705
+./baruch 592.89s user 0.77s system 99% cpu 9:55.34 total
+17
+1724671873
+./baruch 4535.71s user 5.25s system 99% cpu 1:15:49.76 total
+18
+12655721857
+./baruch 37496.97s user 58.50s system 99% cpu 10:27:48.29 totalCody
+Boone Ferguson fixed some issues in this program and Yusuke Endoh
+provided the btoa script but it appears there is a bug in
+this entry. The judges wrote that to test the entry one can do:
echo "Quartz glyph jocks vend, fix, BMW." | compress | ./btoa | ./jawwhich should apply the identity transformation to a minimal +holoalphabetic sentence.
+But doing this shows instead:
+echo "Quartz glyph jocks vend, fix, BMW." | compress | ./btoa | ./jaw
+a얖?)V...?????777??hC??h??-? )SSSSXXX????r?L=???*?-???ppp,,,?R
+?j
+111-)))? '..F@E
+ ???b111?
+..F..F.?n,,,,,L@E$Notice how there’s no newline at the end: that final $
+is the prompt.
If one does, however:
+echo "Quartz glyph jocks vend, fix, BMW." | compress | ./btoa | ./jaw | ./jawthey will get just
+oops
+which seems to be an error message (one of the fixes was to make it
+not use perror(3) - this fixed something else though it’s
+no longer known what).
The script shark.sh has some issues
+too in that due to path not having . (this and maybe some
+other things were fixed) and tar not wanting to accept
+reading from stdin (this in particular) even with the right
+options used, seemingly, it has to write to disk the tarball which seems
+to defeat the purpose. This would ideally be fixed.
The authors provided a list of features in the BUGS section in their remarks.
+Cody Boone Ferguson
+fixed many bugs that prevented this from working properly (including
+segfaults) but one thing to note is that if you pass two zeroes to
+theorem_bkp or fibonacci the program will
+enter an infinite loop, printing 0 over and over again; another
+condition where this occurred was fixed but this one should not be
+fixed. Thank you.
If the maze file cannot be opened, either because the path specified +does not exist or because the default (whatever the source file was at +compilation time) file does not exist in the directory, this program +will very likely crash.
+This is a feature, not a bug.
+There is a very simple way to always win. The program doesn’t catch +you and as someone called Cody’s late grandmother said to him: ‘it’s not +cheating unless you’re caught’. :-)
+Please don’t try and fix it as it’s not a bug and was actually +documented as a possibility. Can you find out how? There’s also a way to +make it so that even when you’re cheating it ends up winning! Can you +figure that out as well?
+The author stated that if the file cannot be opened then it will +print a system error but this is not the case unless it’s showing a +fault. However this was instead fixed by Cody as part of another problem +that was detected so that the program just exits 1 if the file cannot be +opened.
+Also, if some of the programs are not given an arg they will
+very likely crash or do something funny. For instance
+adsleep and adbasename. This is very simple to
+fix but the author explicitly noted that this will segfault and it is
+that that is the error message.
Another thing is that the code:
+printf((W,Y));appears to be wrong because W is a FILE *
+and Y is a char[] but if one changes it to use
+fprintf() on the file (which, incidentally, is opened in
+read only mode which is another reason) with the %s
+specifier it will make adhead not work: it’ll print nothing
+at all! So this code should not be changed either even if it appears to
+be wrong. Notice too a curious thing: if you did change it to fprintf,
+even if you have the right number of args, you’d have to remove the
+outer () pair.
Leo Broukhis, before he was an IOCCC judge, sent the IOCCC judges an +email:
+From: leo _at_ zycad -dot- com (Leo Broukhis)
+Date: Tue, 30 Jan 96 17:37:51 PST
+To: judges _at_ toad -dot- com
+Subject: IOCCC 1992 - a bug
+
+Dear Judges,
+
+albert.c (even in its fixed form) still has a bug. Although I don't
+remember the number that exposed the bug (afair, resulting in coredump)
+in albert.orig.c that has been fixed in albert.c,
+
+I've found a number exposing another bug: 10000000001 (that's 9 0's).
+Both albert and albert.orig loop without printing anything, although
+the first factor is 101 and is usually found in an instant.
+A quick debugging session from Cody suggests that the problem with +this value is that:
+if ( ppp->qq!=48 ) return;is never reached because the value is never 48 (it is in other cases +but not for the example input). It varies in value at this point. +Observe that the next lines of code are:
+while ( ppp->qq==48 )
+{
+ printf("%ld\n",qqq-45);
+ *pp = ppp;
+ ppp = ppp->p;
+}so it is expected that that value is 48, before printing the numbers,
+but if it’s not it should not proceed at all, not even to go past that
+loop. In other words that loop should always be entered for at least one
+iteration. The check for the != 48 is also required.
Perhaps more useful to know is that at this point in the code the +code:
+if ((((( !(aa=setjmp(ppp->ppp))||aa==aaaaaa )))))appears to be entered because of the return value of
+setjmp(), not the other condition.
The alt version does fix the problem but it is not obfuscated and not +like the entry itself. Can you fix the actual entry? You are welcome to +try and do so.
+Cody changed it so that the buffer size is ARG_MAX+1 to
+try and get past the 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 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).
When you start the program everything starts to move over to the +right side and then ends. Yusuke +Endoh pointed out that if you click the mouse it takes it back +towards the centre.
+If you want to try and fix this (mis)feature, you are welcome to +try.
+We used a patch from Yusuke
+Endoh to get this to work but it only works with gcc. Cody removed
+the warnings of gets() and provided a script to run the
+entry properly.
Unfortunately due to the way the entry works and the fact that other +compilers like clang have different warnings and errors this simply does +not work with them.
+Some tips from Cody:
+This entry relies on specific compiler warnings. With gcc it will +look something like:
+[...]
+lush.c: In function 'main':
+lush.c:40: warning: "f" redefined
+ 40 | main
+ |
+lush.c:1: note: this is the location of the previous definition
+ 1 | #define gets(_) fgets((_),999,stdin)
+ |
+lush.c:42: warning: "f" redefined
+ 42 | #define f 001:
+ |
+lush.c:40: note: this is the location of the previous definition
+ 40 | main
+ |
+lush.c:44: warning: "f" redefined
+ 44 | #define f 100:
+ |
+lush.c:42: note: this is the location of the previous definition
+ 42 | #define f 001:
+ |
+lush.c:45: warning: "f" redefined
+ 45 | _[i--
+ |
+lush.c:44: note: this is the location of the previous definition
+ 44 | #define f 100:
+ |
+lush.c:46: warning: "f" redefined
+ 46 | #define f 126:
+ |
+lush.c:45: note: this is the location of the previous definition
+ 45 | _[i--
+ |
+Now one can use sed to get the warning:
+line correct but there is more to it than that. For instance this is
+what it looks like with clang:
lush.c:40:9: warning: 'f' macro redefined [-Wmacro-redefined]
+#define f 001:
+ ^
+lush.c:1:9: note: previous definition is here
+#define f 000:
+ ^
+lush.c:42:9: warning: 'f' macro redefined [-Wmacro-redefined]
+#define f 100:
+ ^
+lush.c:40:9: note: previous definition is here
+#define f 001:
+ ^
+As you might see the part under the warning: line is
+different.
The entry is supposed to show warnings and then print:
+Hello World.
+Can you help us?
+When your own checkmate is imminent it prints "Har har"
+but does not exit so it can ‘rub your nose in defeat’, as the author
+puts it. You will have to exit it yourself through ctrl-c or killing it
+in some other fashion.
Cody improved the usability of this program by making it so that as +long as the terminal columns is >= 80 it will display properly, +rather than having to wrap at 80 columns. However due to the nature of +the program if the terminal is < 80 in column width it will not +display right. To see the number of columns in your terminal try:
+echo $COLUMNSThe author suggested that the alternate version, which Cody added +(but fixed for modern systems), should print
+main(l,a,n,d)...
+[A M E R I C A]...…going down the left edge if your terminal auto-wraps at 80 +characters.
+This however does not seem to work. It does not appear to be because +of the fix for modern systems as it doesn’t work for gcc either, even +before any changes. This might be a misunderstanding or it might be that +having 80 columns (resized) does not count (though the output before the +fix of the 80 column requirement showed was correct when at 80-columns +so it seems like this could be a bug if not a misunderstanding).
+The author stated that:
+The expression `(a*)*` compiles but loops forever.
+
+There is no check for trailing backslash (`\`) in the pattern.
+
+There is no check for unbalanced brackets. Omitting a closing bracket
+will generate a "Pattern too long" error, which is not the real error.
+The author wrote in the documentation file ant.txt that there is a version of the code
+that is not obfuscated. This file, agag.c does not exist in
+the archive. Do you have it? Please provide it!
In multiple platforms, both macOS and also linux (in particular a +RHEL 9.3 system), this entry just shows a blank screen.
+Can you fix it? We welcome your help.
+This entry relied on a bug in gcc that was fixed with gcc version +2.3.3. This cannot be fixed for modern systems as the bug is long +gone.
+An alternate version that will work for modern systems, however, does +exist. See the README.md file for details.
+Although the code checks if the file can be opened or not, badly +formatted files will cause problems. No other checks are performed +either.
+There is no end of game checking method so you will have to quit the +game through ctrl-c or such.
+If the file cannot be opened it will very likely segfault. This +should not be fixed except for an exercise to yourself, should you wish +to try.
+This program uses system(3) so if you provide invalid
+characters in the question you might cause an error. For instance don’t
+do this:
$ ./schnitzi schnitzi.info
+This program answers questions about paragraphs
+of text posed to it in English. It is written
+in C. Mark Schnitzius is the author of this
+program.
+
+The Loch Ness monster has been captured. Elvis
+is alive. Hostler was a woman. The NASA moon
+landings were clearly faked.
+
+
+? What is foo'?because doing so will result in something like:
+sh: -c: line 0: unexpected EOF while looking for matching `''
+sh: -c: line 1: syntax error: unexpected end of file
+with the program terminating. Other characters will also cause this +problem.
+Of course if you do something like:
+What is 'foo'?
+it will work fine.
+No spaces are allowed in the expression.
+The program does no error checking so erroneous expressions will +produce spurious results.
+The unary - is an operator so decimal -46
+should be entered as -d46 and not d-46.
When you initiate shooting via the s command you
+immediately lose an arrow before you choose where to shoot.
When you shoot it will move you to that room so if you end up +shooting into a pit room you will end up dying even though you didn’t +explicitly move there.
+Cody Boone Ferguson
+fixed this to compile with modern systems (see the thanks file for what had to change) but
+the entry also used gets() which in some systems would
+print out a warning along with the output of the program. Naturally it
+could also overflow long lines. Cody changed it to fgets()
+to prevent the display problem but this introduces another problem
+namely that newlines can be printed if the line length < 231.
This seems like a worthy compromise to not have messed up output and +although it would be ideal for it to never print a newline unless that’s +the line itself it might be tampering too much with the entry as it’s +not a real problem and as a one liner it’s already quite long.
+NOTE: the generated code of all versions, when fed its own source, +will differ even when it works. See the author’s remarks in the +README.md for details. Increasing the buffer size and having it, when +fed its own source code, generate code that will compile with the same +buffer size is difficult: it just uses the original size. Cody explains +this further down.
+Getting it to use fgets() is even harder as when fed its
+own code it will generate code that cannot even compile let alone use
+fgets(3).
In both cases, changing the buffer size and changing it to use
+fgets(3), will cause compilation errors without other
+adjustments.
See the below magic for details. Along with the author’s remarks in
+the README.md file it might prove possible to get it to use
+fgets(3). Cody, writing this on 02 November 2023, only just
+noticed the author’s remarks and will later on look at this if nobody
+takes up the challenge. More important work like getting to a place that
+the next contest can run must be done first.
Cody Boone Ferguson +explains the magic of how this entry works, which will be necessary if +this entry is to be fixed, below.
+You might wish to run the command:
+make diff_orig_progto see what had to change for the buffer size, when looking at the +below. Furthermore you will want to look at:
+diff schnitzi.alt.c schnitzi.alt2.cas the fgets() version can compile it just can’t
+generate compilable code (let alone using fgets()) when fed
+itself (to reiterate, just changing the call to fgets(3)
+does not mean it can compile and there’s a further problem in that
+fgets(3) retains the newline whereas gets(3)
+does not). Nevertheless looking at these commands will be of help to
+understand how it works.
For the alternate versions the other functionality is unaffected.
+The problem is getting the generated code to use fgets()
+(once it even compiles which was easy to do) and also have the updated
+buffer size be the same (which was easy to do too at least in the
+original version). The generated output, when changed to
+fgets() failed to compile and it also used
+gets(3) and these are the bugs here.
The buffer size, when using gets() is still the same but
+as noted above the original code has had a buffer size increase.
The real problem is with formatting the code. Take a look at the
+interesting comment as well as the int r=0,x,y=0 at the top
+of the file. If you look at each column go down that column you can see
+how it spells out the code! For instance the first column looks
+like:
i
+n
+c
+l
+u
+d
+e
+
+<
+s
+t
+d
+i
+o
+.
+h
+>
+If you join the lines you end up with:
+#include <stdio.h>If you look at column 25 which is the end of the word ‘mh111’ and you
+go down to the next row you’ll see a 0 and if you go one row down
+another 0. This is the buffer size, 100, for u! The column
+to the left is the same for the t variable.
Thus it seems that in order to get the generated output correct one +needs to provide the correct input in comments or possibly by +rearranging some of the code (this was actually required to make the +generated code compile at all when changing the buffer size, see +below).
+Getting this entry to use fgets() is easy but the
+problem is you’re supposed to be able to feed the source to the program
+and the output of that will be compilable. It however will create
+compiler errors. So it’s not just changing the code to get it to use
+fgets()! I (Cody) already did this before I noticed the other part which
+is why I rolled that part back. I did increase the buffer size but that
+only works on the original source.
To say just how sensitive this entry is: even a space, lack of space +or a character, wrong character, lack of character or character in the +wrong place can cause a compilation error! Make sure that the output +of:
+./schnitzi < schnitzi.ccan be compiled and the output of that new program when fed itself +can also be compiled!
+This program will likely crash if the source code file (by the name +of the file that’s compiled) cannot be opened in the directory it is run +from.
+Cody Boone Ferguson +noted that the README.md file refers to an alternative version of the +code that is not obfuscated but it is missing from the entry directory +and the archive. Do you have this file?
+We would be grateful if you could provide it to us. If you can +provide this file you might consider removing this entry from this file +as well but if not we’ll take care of it.
+-1 value check for
+getc():Cody Boone Ferguson
+fixed the code to not use -1 for the return value of
+getc(); this is important because EOF is
+NOT guaranteed to be -1 but rather any
+negative value. On systems where EOF != -1 the program
+would enter an infinite loop until the program crashed, by chance reads
+a -1 or was killed (it is for this same reason that one
+should not use EOF for the getopt() functions
+as they return -1 when all options are parsed (for details
+on the definition of EOF see
+7.21 Input/output<stdio.h> subsection 1 of the
+standard)).
An interesting problem occurred where changing the -1 to
+EOF caused both
+warning: illegal character encoding in string literal and
+error: source file is not valid UTF-8. But since
+EOF is simply an int < 0 and making the loop condition
+check that the return value is >= 0 does not cause a compilation
+error and it functions correctly it will address the systems where
+EOF != -1 just as if it checked for
+!= EOF.
Since it works there is no need to fix this except for a challenge to +yourself.
+The judges said the following in their remarks:
+The fractally minded may be able to detect that mode 0 does not calculate
+Mandelbrot/Julian sets correctly. Can you find the bug? Better still, can you
+fix it without breaking something else?
+You are welcome to try and fix it and open a pull request, providing +that it doesn’t break something else.
+This did not originally compile under macOS and after it did compile +under macOS, it crashed. Cody Boone Ferguson fixed +these problems.
+It should be noted however that there is a condition where the
+program will prompt you to press return again. This was thought to be a
+bug but looking at the code it can clearly be seen that if
+g - a is 0 then the message is supposed to be printed again
+and one is supposed to press a key as at that point it calls
+getchar() via the pointer m. So this is a
+feature not a bug.
The judges suggested that the following commands should result in +output:
+./leo 1 | cat - /dev/tty | gs -
+
+./leo 37 80 | cat - /dev/tty | gs -The first one can work if one does instead:
+echo "" | ./leo 1 > foo.ps
+gs foo.psbut it is supposed to work in the pipeline as is. The second one does +not appear to work at all even if one redirects to a file (like the +workaround for the first) as it appears to just block.
+It is not known if this is platform specific but this was observed in +macOS and it would be good if it was fixed.
+This program expects a POSITIVE number. If you specify a negative +number it will not show any output, stuck in a loop.
+The authors stated that they included a version that allows people +with just K&R compilers to use the program but this file is missing. +Can you provide it?
+We would appreciate anyone who has it or even just knows the name! +Thank you.
+The link was http://www.tc3.co.uk/~gandalf/G.HTML but this no longer +exists as it was instead requiring a login / password.
+Do you have an updated link? We welcome your help!
+The changing to using fgets(3) in this entry is a bit
+more complicated. It can almost be done except that some of the output
+of the try.sh is wrong, especially the
+last one.
This diff almost does it but not quite:
+diff --git i/1996/huffman/huffman.c w/1996/huffman/huffman.c
+index a5745bc7f4fa28b834c004f4cf19633e40ad9165..5e5e5334f33f9dbd95c70eddece3189d9bcff5e9 100644
+--- i/1996/huffman/huffman.c
++++ w/1996/huffman/huffman.c
+@@ -1,15 +1,16 @@
+ #define x char
+ #define z else
+ #define w gets
++#define gets(b) ((b)[0]='\0',(fgets((b), 100, stdin)))
+ #define r if
+ #define u int
+ #define s main
+ #define v putchar
+ #define y while
+ #define t " A?B?K?L?CIF?MSP?E?H?O?R?DJG?NTQ?????U?V?????X???????Z????W??Y??"
+- s ( ) { x* c , b[ 5 * 72 ]; u a, e , d [ 9
++ s ( ) { x* c , b[ 5 * 72 ]; u a, e , d [ 9
+ *9 *9 ] ; y (w ( b) ){ r ( 0 [ b] -7 *
+ 5 ) { c = b ; y ( (* c - 6
+ * 7 )* * c )c = c+ 1 ; r (( -0 ) [ c ] && w ( b +
+ 8 * 5* 3 ) && w (b +8 *5 * 6) )
+ { a = 0; y ( a [ b ]But since it does not for the time being it is advisable to just
+redirect stderr to /dev/null
+(2>/dev/null).
If X is not running this program will very likely crash or do +something funny. This should NOT be fixed.
+NOTE: the two boards will be on top of each other so you will have to +drag one off the other so that you can properly play.
+As well: the link which was http://www.uio.no/~jonth is no longer +valid and there’s no archive on the Internet Wayback Machine. Do you +know of a proper URL? We greatly appreciate your help here!
+There was no IOCCC in 1997.
+The domain http://pootpoot.com no longer exists as it once did. The +judges have given a script that can be used to make a similar page +(warning: not checked for security in modern days!). Do +you have a server with enough bandwidth and would like to set it up? +We’ll gladly thank you in the README.md file and link to the page as +well! You’ll have IOCCC fame for reviving a pootifier! :-)
+See above entry 1998/dlowe.
+A point worth considering is that as the number passed into the +program gets bigger the number of lines of output gets substantially +larger. For instance:
+$ ./schnitzi 9|wc -l
+ 771999The larger the number the bigger the file can become too, even
+becoming gigabytes in size. The range is checked for
+>0 && <27 as not having this can be a problem
+including a segfault.
If you use the generated program and do not give enough numbers in +input something funny will happen, very possibly with different results +per run. This is in the README.md file as something to try and +ponder.
+There was no IOCCC in 1999.
+This MIGHT be better described as doesn’t work with
+some versions of perl: the author states that in perl < 5.6.0 there
+is a bug with a core dump in what they said is in
+Perl_sv_upgrade. This does not exist in the code,
+seemingly, but it might be that this is impossible to fix without
+getting a perl upgrade. In any event the below details a problem.
+Another bug that happens in linux also is below.
In macOS this program crashes. A tip from Cody is that the code that +crashes is:
+perl_eval_sv
+(newSVpv("_:$_= <> ; defined or exit; @ARGV"
+"=split; __:$_= shift;defined or goto _; chomp "
+";(m*^\\x70oO" "\\x74$*i)?(pri" "nt \"$_ w\\x"
+"61s h\\145r\\x" "65!\\n\"):((m*" "^\\s\\*(-?\\d+"
+"(\\.\\d+)?)\\s" "\\*$*)?(push@SS ,$1):(&{chr(((o"
+"rd)%39)+3**4)x2 } )); goto __; sub ff { @SS= ("
+")} sub __{print \"stack empty\\" "n\"} sub ss{$#"
+"SS<0 and goto & __; print $SS[$" "#SS].\"\\n\"} "
+"sub SS{ $#SS<0 and goto &__ ; print pop @SS}"
+"sub _ { print \"divide by zer" "o\\n\"}sub ii{"
+"map{ print\"$_" "\\n\" } reverse @SS} sub AUTOLO"
+"AD { print\"un" "implemented\\n" "\"} sub gg{ $#"
+"SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ "
+"$#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS"
+"[$#SS-1]=$SS[$" "#SS]-$SS[$#SS-" "1]; $SS[$#SS]-"
+"=$SS[$#SS-1]} ",0),0 );and in particular it appears that it is the perl itself. In other +words if one changes it to be:
+perl_eval_sv(newSVpv("",0),0);it will not crash. But of course it won’t do anything either. So it’s
+more specifically that the call to newSVpv() crashes the
+code but INSIDE (key point!) the call to
+perl_eval_sv() that does it. Given what the author stated
+and that the version of perl is < than 5.6.0 that might be exactly
+what is going on.
The example command above should print:
+$ echo "13 14 15 16 17 + - * / p" | ./dlowe
+-0.0515873015873016and that’s what it shows in linux.
+Note that with different perl libraries in macOS (for instance from +Homebrew and MacPorts it will likely print +different warnings when compiling. It was observed that with Homebrew it +does not report any warnings but with MacPorts it results in a total of +92 warnings! Nonetheless neither works okay and both crash.
+The author gives an example command:
+echo "7 P 6 d P P 8 p" | ./dlowe | tr 876 tpowhich should print out poot but it doesn’t, not in linux
+and not in macOS.
In linux it doesn’t crash but it doesn’t print anything out +either.
+In macOS it crashes; it might appear to not crash in macOS but this
+is because of the pipeline. If you remove the | tr 876 tpo
+part of the command you will see that it does indeed crash!
The reason for this not working is really strange.
+$ echo "7 P 6 d P P 8 p" | ./dlowe
+7668
+$ echo "7 P 6 d P P 8 p" | ./dlowe | grep 7
+$Why? Is it writing to stdout? Let’s try some other things:
+$ echo 7668 | tr 876 tpo
+pootOkay so we know that it SHOULD work. But we also know something funny +is going on with stdout and the entry. Another experiment:
+$ echo "7 P 6 d P P 8 p" | ./dlowe 1>&2 | grep 7
+7668Okay so now it sees it, grep. But watch!
$ echo "7 P 6 d P P 8 p" | ./dlowe 2>foo 1>&1
+7668
+$ cat foo.. so at this hour it does appear to be writing to stdout but yet +somehow it doesn’t? But watch:
+$ echo "7 P 6 d P P 8 p" | ./dlowe 1>foo 1>&1
+$ cat foo
+$Well this explains why the tr does not transliterate it
+to poot but why is this happening? Why can’t it be
+redirected to another file even?
If it could be figured out why it’s not writing to stdout and yet at +the same time is writing to stdout one bug could be fixed. Maybe it’s +the perl messing with things but we don’t know.
+Other commands do work, however, and give the appropriate output, +such as:
+$ echo 1 2 + p | ./dlowe
+3so something is wrong with some commands/operators.
+Another feature that does work in linux is:
+$ echo poot | ./dlowe
+poot was here!Can you help fix these problems?
+Cody provided the C code that creates an unformatted perl script that
+will just print ‘unimplemented’ for operators but it seems to work in
+some other ways (see below for how to go further than unimplemented)
+which is the exact perl from the C program except that it has the
+#!/usr/bin/env perl and use warnings; as well.
+A note below might suggest that doing this creates incomplete perl.
+Anyway:
#include <stdio.h>
+int main(void)
+{
+ printf("#!/usr/bin/env perl\nuse warnings;_:$_= <> ; defined or exit; @ARGV"
+ "=split; __:$_= shift;defined or goto _; chomp "
+ ";(m*^\\x70oO" "\\x74$*i)?(pri" "nt \"$_ w\\x"
+ "61s h\\145r\\x" "65!\\n\"):((m*" "^\\s\\*(-?\\d+"
+ "(\\.\\d+)?)\\s" "\\*$*)?(push@SS ,$1):(&{chr(((o"
+ "rd)%%39)+3**4)x2 } )); goto __; sub ff { @SS= ("
+ ")} sub __{print \"stack empty\\" "n\"} sub ss{$#"
+ "SS<0 and goto & __; print $SS[$" "#SS].\"\\n\"} "
+ "sub SS{ $#SS<0 and goto &__ ; print pop @SS}"
+ "sub _ { print \"divide by zer" "o\\n\"}sub ii{"
+ "map{ print\"$_" "\\n\" } reverse @SS} sub AUTOLO"
+ "AD { print\"un" "implemented\\n" "\"} sub gg{ $#"
+ "SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ "
+ "$#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS"
+ "[$#SS-1]=$SS[$" "#SS]-$SS[$#SS-" "1]; $SS[$#SS]-"
+ "=$SS[$#SS-1]}");
+}Compiling this you can generate:
+#!/usr/bin/env perl
+use warnings;_:$_= <> ; defined or exit; @ARGV=split; __:$_= shift;defined or goto _; chomp ;(m*^\x70oO\x74$*i)?(print "$_ w\x61s h\145r\x65!\n"):((m*^\s\*(-?\d+(\.\d+)?)\s\*$*)?(push@SS ,$1):(&{chr(((ord)%39)+3**4)x2 } )); goto __; sub ff { @SS= ()} sub __{print "stack empty\n"} sub ss{$#SS<0 and goto & __; print $SS[$#SS]."\n"} sub SS{ $#SS<0 and goto &__ ; print pop @SS}sub _ { print "divide by zero\n"}sub ii{map{ print"$_\n" } reverse @SS} sub AUTOLOAD { print"unimplemented\n"} sub gg{ $#SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ $#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS[$#SS-1]=$SS[$#SS]-$SS[$#SS-1]; $SS[$#SS]-=$SS[$#SS-1]}Here is example input/output:
+p
+stack empty
+5 p
+5
+5 + 5 p
+unimplemented
+5
+P
+5
+p
+5
+So you can see that if one uses operators it just shows +‘unimplemented’ (observe how this does not happen in the C program in +linux!) but if one uses ‘p’ by itself it will print what’s on the stack +(for example).
+To not get ‘unimplemented’ you can remove from the perl:
+sub AUTOLOAD { print"unimplemented\n"}(Note that the author stated this was used for exception handling so +another possibility is that the C code doesn’t generate the correct perl +and indeed even spaces is known to break the perl in at least one way, +syntax errors, but maybe others too.)
+Here is an example run of several operations in the perl script after +removing that subroutine:
+$ echo 5 5 p | ./dlowe.pl
+5
+$ echo 5 5 + p | ./dlowe.pl
+5
+Undefined subroutine &main::UU called at ./pl.pl line 2, <> line 1.
+$ echo 5 5 * p | ./dlowe.pl
+5
+Undefined subroutine &main::ww called at ./pl.pl line 2, <> line 1.
+$ echo 5 5 - p | ./dlowe.pl
+5
+Undefined subroutine &main::WW called at ./pl.pl line 2, <> line 1.
+$ echo 5 5 / p | ./dlowe.pl
+5
+Undefined subroutine &main::YY called at ./pl.pl line 2, <> line 1.
+$ echo 5 P | ./dlowe.pl
+5$ echo p | ./dlowe.pl
+stack empty
+$ echo P | ./dlowe.pl
+stack emptyNote the undefined subroutine error: that happens with commands that
+are not even in the program. Again the author used AUTOLOAD
+for exception handling so it seems likely that there is something
+missing (which the below shows as well). For instance inputting
+D followed by XX:
Undefined subroutine &main::nn called at ./pl.pl line 2, <> line 6.
+Undefined subroutine &main::[[ called at ./pl.pl line 2, <> line 1.
+That means then that in linux despite the subroutines seemingly not +existing it works in the code, at least in some cases.
+As far as the unimplemented error goes: the author stated that it +means there is invalid input. But as can be seen by the input I (Cody) +gave the input is not actually incorrect. It is also curious to note +that it ends up printing what’s on the stack at that point:
+$ echo 5 5 + p | ./dlowe.pl
+unimplemented
+5which might (?) suggest that the + operator is
+unimplemented. Unfortunately it has been many years since I have used
+perl and I was never a guru either.
This program does not do what you might think it does! Running it +like:
+./primenum 13will seemingly wait for input exactly because it is waiting for +input. See the README.md file or look at the source.
+Although the name of the program suggests it prints prime numbers +this is not the case. This is by design. See the author’s comments for +more details or better yet look at the code and if necessary try it out. +Please do not try and fix this.
+A crash in the program is known as well. This is also a feature. +Please do not try to fix the crashing of this code except to challenge +yourself (if you think that it’ll be worth your two second fix :-) ). If +you do fix it please do not make a pull request.
+If DISPLAY is not set the program will very likely
+crash, do something strange (or if you’re very unlucky your computer
+might halt
+and catch fire! :-) ).
Cody Boone Ferguson +fixed this so that it doesn’t segfault and then also fixed the +functionality of it (but see below).
+Cody also fixed the anonymous.ten.c program (it
+also segfaulted) but notes that it MUST be compiled as
+a 32-bit ELF binary so it will NOT work in macOS (for
+example); if you cannot use -m32 or even if you can but it
+cannot compile as an ELF binary (not elf binary :-) ) (but see below)
+then the anonymous program itself will very likely crash if
+you run it on the compiled anonymous.ten.c but if nothing
+else it will not modify the target executable (this part of the fix at
+least should be correct).
The file 2001/anonymous/anonymous.ten.32 is a
+pre-compiled 2001/anonymous.ten.c as
+a 32-bit ELF binary in case you can run ELF binaries but cannot compile
+32-bit binaries.
Other BSD Unices were not tested.
+Note also that if you don’t specify a file or you specify a +non-32-bit ELF file this program will very likely crash or do something +strange like slaughter the elves of Imladris :-(
+The two statuses might seem contradictory but that is a complicated +question. The author stated that it only works with i386 linux so on the +one hand the fact it doesn’t work in modern systems is considered a +feature and not a bug. But on the other hand it would be nice if there +was an alternate version which worked for modern systems. This does seem +quite unlikely but some fixes, described next, were made.
+Cody Boone Ferguson +fixed an initial segfault (trying to open the file) and he also fixed +the supplementary program +bellard.otccex.c but this still crashes in systems not i386 linux +which is what the author stated.
+On the other hand if you do have a fix for 64-bit systems you’re +welcome to provide it as an alternate version. If by chance you have a +fix so that it works for both 32-bit and 64-bit systems that is also +okay.
+The author said that they compiled it with gcc +version 2.95.2. We don’t know if a certain gcc version is necessary +but it might be helpful to download and compile that version to test it +- or it might not.
+I (Cody) have no i386 system to test this but perhaps this is why I
+can’t get it to work. Yusuke was able to get this to work with
+-m32 but only in an emulator.
On the author’s web page for this +program it is explicitly stated that it requires i386 linux.
+There I found what should be a more portable version which is
+included as otccelf.c (after adding
+some #includes and the modification by Yusuke noted in the
+thanks file) but it appears this
+also requires i386 linux; indeed looking at the code it hard
+codes paths that are i386 specific to linux.
Another point of interest is that the author provided de-obfuscated +versions which might be of value to look at. I might do that as well but +this entry is very likely never going to work for 64-bit linux so that’s +not that likely since there are other things that are more +important.
+If you have a fix for 64-bit systems this is welcome as an alternate +version, as stated above. You might like to look at the otccelf version +but note that it (at least in 64-bit linux and macOS) has compilation +errors.
+This is a good question. The reason is we believe it better to fix +some obvious problems: there were some bugs that would very possibly +prevent it from working even if it was in i386 linux though Yusuke +seemed to get it to work in an emulator so perhaps not. Still it’s +better to have the type of the file pointer correct and so that the file +can at least be opened in modern systems even if the compiler won’t work +there.
+Also the supplementary program, which did not work at all, was fixed +(by Cody) and it can be run by itself for fun in modern systems, which +was not possible before the fixes there.
+This program deliberately crashes if it loses (which is what it aims +to do).
+The author referred to the file herrmann1.turing but it
+does not exist not even in the archive. Do you have a copy? Please
+provide it!
There is also a bug in part. During compilation you’re supposed to +see some animation but this does not seem to work with modern gcc +versions. It appears that version 2.95 works but maybe others do as +well. Do you have a fix? We would appreciate your help!
+If you want to try and fix this (mis)feature, you are welcome to +try.
+Sometimes when one player presses q it will result in
+broken pipe on the other end.
The author also noted that some versions of curses have
+problems with getch() having a delay.
The program is very likely to segfault if the specified port can’t be +bound or connected to.
+If the terminal is too wide (the author suggests over 500 characters) +the program can segfault.
+It’s also possible to crash the program if a player scores over a +billion points.
+Although it is independent of endianness both systems need the same +character set. In other words both have to be ASCII or EBCDIC - not one +of each.
+The author stated that there is a cat man page for this program in +case one wanted to install it as a tool but this is missing.
+The glob pattern must match the whole string. See the author’s +comments for details and a workaround.
+There’s also no way to escape meta characters.
+This function uses gets(3) but it would be ideal if it
+used fgets(3). This one is rather complicated and will be
+looked at later (some progress was made by Cody but it is less important
+than other work) but you are welcome to try and fix this if you
+wish.
This program only has one arg to main(). However
+changing it to have 2 is not as simple as it might seem. Doing this
+breaks things. If memory serves changing it to two will, for instance,
+break the punch card code output. It might be that that is for
+fgets(3), however, but the point remains: in order to test
+any fixes you must determine if the extra files generated (some from
+sort(1)) - see the README.md file - generate correct output
+as well as that the main entry does too. You might try running the
+try.sh script and redirect it to a file first so that you
+can compare the output. Make sure to recreate the extra files as
+described by the author if you do fix this. This might be looked at
+later if nobody else takes up the challenge.
The author referred to a file card.gif but this file is
+missing. Do you have it? Please provide it!
There seem to be a couple bugs at least in this entry. The first one
+is that when it does reach a certain point it crashes. This is in the
+function J() (or one it calls?). But sometimes it seems to
+not get that far, just showing lines moving back and forth. This is also
+in J(). It is not confirmed but it might be that the lines
+are drawn by XDrawString(), the last part in
+J().
J() has a for loop identified by
+for and also a couple while loops, identified
+by R.
Since the game never ends properly the score is not printed +either.
+It appears that the crash happens in more than one place. For +instance it has happened at
+XCheckMaskEvent(d, 4,&e)but it’s also happened at
+else XDrawPoint(d ,w,g,(l.s+=l.a)>>9, h=(l.c+=l.b)>>9)In both cases the pointer d was corrupted:
(lldb) p d
+(Display *) 0x0000000000000001
+It is believed that it also happened at
+XDrawString(d,w,g,W/3,H/2,m,B);in J() and for the same reason.
The loop seems to be stuck in the call to usleep(3)
+like:
usleep(p*200);which happens to be in a while() loop.
There is a way to get the code to crash. If you don’t do anything +until everything is destroyed (where you’d lose the game if it ended) +and then you start to shoot your missiles repeatedly it will eventually +crash. It appears not to be the case (though this was not tried as many +times) if you start shooting when the missiles come down. The fact you +can shoot after it starts that sleeping in a loop does suggest that it’s +not stuck only showing those lines and sleeping.
+There was no IOCCC in 2002.
+There was no IOCCC in 2003.
+Segmentation fault will occur in some systems. For instance on macOS +with the arm64 chip:
+./gavin > kernelWhen trying to link gavin.o to produce sh,
+the linker generates:
Undefined symbols for architecture arm64:
+ "start", referenced from:
+ -u command line option
+ (maybe you meant: __start)
+ld: symbol(s) not found for architecture arm64
+We believe that this simply won’t work with non x86 specific systems +but perhaps you have a fix? We welcome your help!
+Although not related some recent changes were made to 2004/gavin to +let it compile under clang. The following patch was applied:
+diff --git a/2004/gavin/gavin.c b/2004/gavin/gavin.c
+index c967b7e..2082b49 100644
+--- a/2004/gavin/gavin.c
++++ b/2004/gavin/gavin.c
+@@ -1,8 +1,9 @@
++int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); }
+ #define G(n) int n(int t, int q, int d)
+ #define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023))
+ #define U(m) *((signed char *)(m))
+ #define F if(!--q){
+-#define I(s) (int)main-(int)s
++#define I(s) (int)cain-(int)s
+ #define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k
+
+ G (B)
+@@ -52,7 +53,7 @@ else
+
+ G (_);
+ G (o);
+-G (main)
++G (cain)
+ {
+ Z, k = K;
+ if (!t)The original Makefile from 2004 had the following to say about this +entry:
+# Special flags for the gavin entry
+#
+# FYI: Older versions of GCC have a bug in -O2 optimization, hence -O1
+#
+GAVIN_OPT= -O1
+GAVIN_FLAGS=\
+ '-DY(m)=*((int*)(m))'\
+ '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)'\
+ '-DM=for(D=0;D<786432;D++)'\
+ '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D'\
+ '-DV=0x90200'\
+ '-DK=0'\
+ '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){'\
+ '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}'
+
+# ...
+
+# Best of Show
+#
+gavin: gavin.c
+ ${CC} ${GAVIN_OPT} -o gavin ${GAVIN_FLAGS} gavin.c
+ ${RM} -f kernel
+ ./gavin > kernel
+ ${CC} ${GAVIN_OPT} -c ${GAVIN_FLAGS} -DB=_start '-Dputchar(a)=' gavin.c
+ ${RM} -f sh
+ ${LD} -s -o sh gavin.o
+ ${RM} -f vi
+ ${CP} sh vi
+ ${RM} -f fs.tar
+ ${TAR} -cvf fs.tar sh vi gavin.c README.md prim
+
+gavin_clean:
+ ${RM} -f sh vi kernel gavin.o
+
+gavin_clobber: gavin_clean
+ ${RM} -f gavin fs.tar
+
+gavin_files: boot.b lilo.conf prim gavin_install.txt
+The current (Makefile was modified +to try and fit into the current IOCCC build environment.
+See known features in +the README.md for things that are not bugs but documented +(mis)features.
+The author stated that:
+Arguments matching `/[^2]22$/` cause the program to segfault
+after rapidly exhausting the available stack space. I could
+probably fix this by adding some special cases to the code,
+but [Blaine the Mono] it's quite a bit more exciting this way,
+don't you think?[/Blaine] Since the trailing `22` will be
+its own atom anyway, you can just insert a space in front of
+it if you run into this feature (e.g. `1 22` instead of `122`).
+
+Arguments matching `/(?:.){10,}/` will produce visually incorrect
+results (e.g., generation 1 starting from 1111111111 will
+print as `: 1`), but there's nothing interesting about these
+arguments that can't be modeled using shorter runs of the same
+symbol.
+
+Arguments matching `/(?:.){257,}/` may produce mathematically
+incorrect results (e.g., generation 1 starting from a string
+of 257 `1`s will be calculated as `11`); the remark from the
+previous paragraph applies here also.
+The generated code will very likely segfault or do something not +intended if not given the right args. See the README.md file for the +correct syntax.
+This program sometimes will create unsolvable puzzles :-) just to +hook you. As a protection against this - and to prevent you from +spending too much time on such puzzles (or too big puzzles if you insist +on doing this) - it deliberately destroys its runtime stack. See the README.md for more details on this.
+If you specify more than three args the program might also crash or
+do something strange. This might also happen if you specify excessively
+large board dimensions. Try 100 100 100 for instance and
+see what happens!
This entry will very likely segfault or do something strange if the +source code does not exist.
+This entry requires that sed and make are
+in the path.
The author states:
+The only built-in functions are defvar,
+format, substitute, char-upcase,
++, -, *, and
+/.
Only one variable is available. This variable is called
+q, although any symbol name starting with the letter
+q will be mapped to this variable.
Only the first letter of a function name is significant. For
+example, format, f, farm, and
+various other words starting with f will all map to the
+format function.
The defvar function completely ignores its first
+parameter. It will always store the result of evaluating its second
+parameter in q. Unlike in Common Lisp,
+multiple invocations of defvar on the same variable will
+overwrite old values.
Character constants are limited to #\Newline and
+single-character constants such as #\x.
The char-upcase function will give strange results
+if passed something other than a lowercase character.
The format function takes exactly three parameters.
+The first parameter is ignored; output always goes to
+stdout. The second parameter must have exactly one
+~s format specifier in it, and no other format specifiers
+are permitted.
The arithmetic functions take exactly two parameters.
All tokens must be separated from a following ) by
+whitespace.
A lot of other things. Notably, the language which this program +interprets is nowhere near Turing-complete.
Basically, the [LISP][] interpreter is good for some basic math +operations, and for running itself.
+Cody Boone Ferguson +notes that, though probably obvious, this entry will not work with +https. He added an alt version that scans for https in case someone +wants to set up a pipeline or other workaround (perhaps with stunnel) or +even add additional code to it to make it work with https but the +problem otherwise is a secure connection has to first be set up in order +to give http commands. This is not a bug but it’s worth pointing out as +it won’t work on as many websites as it used to including the IOCCC website itself.
+The author stated the below points of interest.
+The machine emulated is an older 40 column one so 80 column programs +will not show up correctly.
+There is no emulation of PET graphics +characters.
+The parameter controls the speed of the 60Hz “jiffy clock”, and not +the processor speed. This means many games may run too fast to be usable +- it really depends on the speed of your machine.
+Although the PET emulator can do
+LOAD and SAVE, it cannot VERIFY
+or OPEN and CLOSE files.
The PET +hardware emulation +is not at all complete - features such as the hardware timers are +completely missing. Some programs will not run correctly.
+The 6502 +emulation does not +include the seldom used decimal mode, or any of the “undocumented” +instructions.
+This entry uses gets(3) which is unsafe and provides
+annoying warnings, most obnoxious in macOS as it shows it at runtime
+(redirecting stderr to /dev/null will silence
+it). The following diff will almost work but it crashes with at least
+computer.tofu input file:
12a13
+#define gets(c) fgets((c),PI,stdin)&&(((c)[strlen((c))-1]='\0'),c!=NULL)The string specified must be <= 42 characters and may only consist
+of the characters in the regex a-z_A-Z0-9@.-. Breaking
+these constraints will end up with possibly corrupt GIF files.
This program requires x86 (with an x87 FPU) or x86_64 machine and it +requires the SDL1 library.
+This program also requires being able to read, write and execute +memory. With the Apple silicon chips this is not allowed. Fixing this +might be quite challenging but you are welcome to try and fix it.
+If you do fix this it might be good to fix the alternate code as well +or else provide it as an additional alt version. Fixing this is very +likely to be very challenging and in some systems it will not be +possible to fix but you are welcome to try and fix it if you wish +to!
+Incorrect formulas will ungracefully crash the program.
+The author stated:
+If you pick a number higher than 19186, the program will return a
+solution but it will be a rotation of one of the first 19186. This is
+because the cross shaped piece fits 48 ways in the 4x4 cube, but only
+2 of those ways are unique - you can rotate one of those to make any
+of the other 46. The algorithm used always places the cross piece
+first, so the first two placings of that piece result in the 19186
+unique solutions.
+
+If you pick a number higher than 460464 (24x19186) the program will
+return without outputting a solution. If you can wait that long.
+Cody Boone Ferguson
+fixed this program to not crash in macOS (it appeared to work fine in
+fedora linux on an x86_64 architecture but he does not know
+if it crashed in macOS Ventura due to the fact it is an
+arm64 CPU - the Apple silicon chip). This fix, BTW, is a
+mix of a fix by Yusuke Endoh
+and Cody’s. Nevertheless there are two features that are not bugs. Later
+the author made some slight changes to make it not crash in x86_64
+macOS.
By design this program is supposed to crash on termination. This +actually no longer seems to happen but we don’t need this to be added +even if it might be called a bug :-)
+You must type in caps (except in strings) and this program is indeed +case-sensitive.
+There was no IOCCC in 2007.
+There was no IOCCC in 2008.
+There was no IOCCC in 2009.
+There was no IOCCC in 2010.
+For a great amount of data points the program will crash, depending +on your available stack space.
+Giving too few (distinct) points can also cause a crash or division +by zero.
+The program expects plain numbers separated by whitespace.
+This program assumes ASCII.
+If you give the program any arg it might flood the screen.
+It requires both syscalls fork(2) and
+wait(2).
Giving any arg to the program is likely to flood your screen.
+Rounding errors might cause an omission in the highest bin. There +might be empty bins at the edges.
+The author’s website, http://www.pootpoot.net, no longer exists as it +once did, instead being something else entirely. The Internet Wayback +Machine, although it archived it, did not load scripts. Do you know if +the domain was moved? Do you have an archive or mirror? Please provide +us it! Thank you.
+The author states the following:
+Bad input (e.g. nonexistent files, non-numeric number of +iterations, etc.) tends to result in empty output.
Given exactly one corpus, the program will crash or produce +garbage.
Leaks memory and file descriptors while processing +files.
Will crash and die horribly if it runs out of memory.
If you want to try and fix this (mis)feature, you are welcome to +try.
+The author stated that there are a number of features and +limitations. As the list is rather long see other features and +limitations +and remarks instead.
+This does not appear to work with macOS, resulting in a segfault (and +sometimes a bus error).
+We’re not sure if this is to do with the Apple silicon chip or not +but it seems like it might (see Apple resources below) be but +it could also be a wider problem with macOS. It appears that Apple does +not allow certain combinations of memory protections with the arm64 +processor.
+Cody Boone Ferguson +tried some of the workarounds but at this time he could not get it to +work. He offers some earlier debugging sessions below as well as a +resource from the author as well as some resources on Apple’s website +should anyone wish to take a crack at it. He might address it later but +a starting point might be in richards.alt.c.
+At first glance it appeared to be that it might be the function
+pointers or the fact it is trying to execute code in memory (as noted
+above). The function pointers were changed a bit but this has not helped
+solve the problem with macOS. A few things that were noticed depending
+on asan sanitisers specified. With address in
+linux:
richards.c:101:9: runtime error: null pointer passed as argument 2, which is declared to never be null
+but it actually works. This code is:
+ } else
+ p++;
+ W(c)} /* LINE 101 */
+ }Okay but what about argument 2? Well W is defined
+as:
#define W(c) e=memmove(e,x[(u)c], y[(u)c])+y[(u)c];so it would appear that
+x[(u)c](at least in my tired head?) is NULL. But why does it work then?
+NOTE: u is int.
Under macOS (with the arm64 chip) we get:
+UndefinedBehaviorSanitizer:DEADLYSIGNAL
+==10834==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0xffffffffffffffff (pc 0x00019f446748 bp 0x00016f353100 sp 0x00016f352b90 T139066)
+==10834==The signal is caused by a WRITE memory access.
+ #0 0x19f446748 in _platform_memmove+0xa8 (libsystem_platform.dylib:arm64e+0x3748) (BuildId: 756cd10d62a032839e57cbaa810c95ac32000000200000000100000000030d00)
+ #1 0x100c33c2c in main richards.c:202
+ #2 0x19f0bff24 (<unknown module>)
+
+==10834==Register values:
+ x[0] = 0xffffffffffffffff x[1] = 0x0000000100ab18c1 x[2] = 0x00000000000000cf x[3] = 0x0000000000000000
+ x[4] = 0x0000000100ab18a1 x[5] = 0x0000000000000001 x[6] = 0x000000000000000a x[7] = 0x0000000000000000
+ x[8] = 0x00000001015972b8 x[9] = 0xffffffffffffffff x[10] = 0x0000000000000001 x[11] = 0x00000000000001f0
+x[12] = 0x0000000000000001 x[13] = 0x00000000000003e0 x[14] = 0x0000000000000001 x[15] = 0x0000000000000084
+x[16] = 0x000000019f4466a0 x[17] = 0x00000001ff3ad908 x[18] = 0x0000000000000000 x[19] = 0x0000000100c32a80
+x[20] = 0x00000001017e0000 x[21] = 0x00000001017e1910 x[22] = 0x000000016f353530 x[23] = 0x000000019f13a366
+x[24] = 0x000000016f3534b0 x[25] = 0x0000000000000001 x[26] = 0x0000000000000000 x[27] = 0x0000000000000000
+x[28] = 0x0000000000000000 fp = 0x000000016f353100 lr = 0x0000000100aaf880 sp = 0x000000016f352b90
+UndefinedBehaviorSanitizer can not provide additional info.
+SUMMARY: UndefinedBehaviorSanitizer: SEGV (libsystem_platform.dylib:arm64e+0x3748) (BuildId: 756cd10d62a032839e57cbaa810c95ac32000000200000000100000000030d00) in _platform_memmove+0xa8
+==10834==ABORTING
+and naturally it does not work.
+Adding the proper PROT_WRITE constant to the
+mmap() call does not seem to help. Of course with the
+address this is not surprising so why is a different address allocated
+in macOS? Or is it?
Now with address sanitiser both linux and macOS crash
+at:
=================================================================
+==10983==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00016f8d5e78 at pc 0x0001005dd910 bp 0x00016f8d5cd0 sp 0x00016f8d5cc8
+READ of size 8 at 0x00016f8d5e78 thread T0
+ #0 0x1005dd90c in rd richards.c:132
+ #1 0x1005ddf8c in re richards.c:149
+ #2 0x1005110a0 in t richards.c:108
+ #3 0x1005df72c in main richards.c:189
+ #4 0x19f0bff24 (<unknown module>)
+
+Address 0x00016f8d5e78 is located in stack of thread T0 at offset 56 in frame
+ #0 0x1005dd678 in rd richards.c:129
+
+ This frame has 2 object(s):
+ [32, 36) 'v.addr'
+ [48, 56) 'a' (line 130) <== Memory access at offset 56 overflows this variable
+HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
+ (longjmp and C++ exceptions *are* supported)
+SUMMARY: AddressSanitizer: stack-buffer-overflow richards.c:132 in rd
+Shadow bytes around the buggy address:
+ 0x00702df3ab70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3ab80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3ab90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3aba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3abb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+=>0x00702df3abc0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 00[f3]
+ 0x00702df3abd0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3abe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3abf0: 00 00 00 00 f1 f1 f1 f1 00 f3 f3 f3 00 00 00 00
+ 0x00702df3ac00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0x00702df3ac10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Shadow byte legend (one shadow byte represents 8 application bytes):
+ Addressable: 00
+ Partially addressable: 01 02 03 04 05 06 07
+ Heap left redzone: fa
+ Freed heap region: fd
+ Stack left redzone: f1
+ Stack mid redzone: f2
+ Stack right redzone: f3
+ Stack after return: f5
+ Stack use after scope: f8
+ Global redzone: f9
+ Global init order: f6
+ Poisoned by user: f7
+ Container overflow: fc
+ Array cookie: ac
+ Intra object redzone: bb
+ ASan internal: fe
+ Left alloca redzone: ca
+ Right alloca redzone: cb
+==10983==ABORTING
+/bin/bash: line 1: 10983 Abort trap: 6 ./richards
+which corresponds to the code:
+o rd(u v)
+{
+ o *a = 0, **b = &a, **c = b + 32;
+ x[v] = w;
+ for (; b < c && (*b < (o *)w || *b > (o *) T || *b == &v); b++); /* LINE 132 */but this seems to not necessarily be relevant since without it it +works in linux.
+A warning of interest when compiling is:
+
+richards.c:169:15: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'o ()' (aka 'void ()') [-Wincompatible-pointer-types]
+f *lib1[] = { T, T, T, T, T } ;
+
+...
+
+richards.c:170:15: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'o ()' (aka 'void ()') [-Wincompatible-pointer-types]
+f *lib2[] = { T, ld, lp, lx, l1 } ;
+ ^
+richards.c:170:18: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'void (volatile dt)' (aka 'void (struct (unnamed at richards.c:36:3) *volatile)') [-Wincompatible-pointer-types]
+f *lib2[] = { T, ld, lp, lx, l1 } ;
+ ^~
+richards.c:170:22: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'void (volatile dt)' (aka 'void (struct (unnamed at richards.c:36:3) *volatile)') [-Wincompatible-pointer-types]
+f *lib2[] = { T, ld, lp, lx, l1 } ;
+ ^~
+richards.c:170:26: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'void (volatile dt)' (aka 'void (struct (unnamed at richards.c:36:3) *volatile)') [-Wincompatible-pointer-types]
+f *lib2[] = { T, ld, lp, lx, l1 } ;
+ ^~
+richards.c:170:30: warning: incompatible pointer types initializing 'f *' (aka 'void (**)(volatile void *)') with an expression of type 'void (volatile dt)' (aka 'void (struct (unnamed at richards.c:36:3) *volatile)') [-Wincompatible-pointer-types]
+f *lib2[] = { T, ld, lp, lx, l1 } ;
+ ^~
+This can be fixed easily enough however but it doesn’t appear to +matter in this case.
+It might be helpful to use the try.alt.sh script to test that it +does not crash and functions properly.
+The author has more about the entry at https://github.com/GregorR/ioccc2011.
+Porting +Just-In-Time Compilers to Apple Silicon
+Allow +Execution of JIT-compiled Code Entitlement
+Looking at https://github.com/apple/darwin-xnu/blob/5394bb038891708cd4ba748da79b90a33b19f82e/bsd/kern/kern_mman.c
+Cody noticed a curious thing in the mprotect() function:
+#if CONFIG_DYNAMIC_CODE_SIGNING and the protection variable
+has the VM_PROT_TRUSTED set it might allow overriding the
+problem but this is unconfirmed and it’s not known when
+CONFIG_DYNAMIC_CODE_SIGNING would be defined.
Do you have a fix? We welcome it!
+The author stated that the program will crash if no argument is +passed to the program though we note that your computer might also halt +and catch fire :-)
+The author stated:
+If there is a division by zero, square-root of a negative number, or similar
+operation, then the results are undefined.
+The author stated:
+The memory locations of `argv` are used for various purposes. Therefore, the
+program name (default `deckmyn`) must be *at least 4 characters long*, including
+possibly the path. This, along with the ending `'\0'`, gives a minimum 5 bytes of
+useful memory space. Otherwise, the program may attempt to write outside the
+string.
+
+The code is quite sensitive. Errors in the input can lead to strange results.
+The code does not read beyond the end of the music input, but that is about the
+only error checking available. Any input that is not according to the rules in
+the deckmyn.md, may cause errors.
+
+The program has no special hardware limitations or requirements, other than 8bit
+`char` (`signed` or `unsigned`) and two's complement negatives.
+
+The limitations of using `char` as counters for e.g. the number of music staves
+are minor. 127 staves to a page is rather a lot.
+
+The file layout must be exactly the same as deckmyn.c though, only the locations
+of space (`" "`) may differ.
+
+Every element in the music is given by a string of *exactly* 3 characters. Any
+violation of this will result in the rest of the music being interpreted in some
+randomly wrong way. Notice that in a file, the newline is also a character!
+Therefore, when preparing music in a file, care should be taken that the last
+musical element of a line is only 2 characters!
+The manual referred to is here.
+The author stated:
+splash.d, dead.d and
+sprites.d).The author stated:
+If the input doesn't start with a valid program, that is,
+if the interpreter reaches end-of-file during program parsing,
+it will crash in some way. E.g. the following might dump core:
+
+ echo -n "U" | ./tromp
+
+Furthermore, the interpreter requires the initial encoded lambda term to be closed,
+that is, variable n can only appear within at least 'n' enclosing lambdas.
+For instance, here the term '\ 5' is not closed, causing the interpreter to crash when
+looking into a null-pointer environment:
+
+ echo ">Hello, world" | ./tromp
+
+will likely dump core.
+
+The author stated that the program will crash if no argument is +passed to the program or if invalid arguments (e.g. file does not exist) +or images of mismatching sizes or unsupported pixel formats though we +note that your computer might also halt +and catch fire :-)
+The author stated:
+This program will possibly crash or draw something strange with 0 +args. Then again it might not. :-) This is easy to fix but would add +bytes and since the author noted it is a feature and not a bug. You of +course can try and fix it yourself but please do NOT open a pull request +for this: just do it as an exercise to see if you understand the +code.
+You can try and answer the questions, too: when will it crash? When +will it draw something funny (or will it? :-) ) and when will it just do +nothing?
+The author also stated:
+From the author:
+–
+This program supports only “Combinator-calculus style notation” of +Lazy K. “Unlambda style” and “Iota and Jot” style are not supported.
+Also, it requires a space between identifiers. In short, use
+(S K) instead of (SK), “`sk”,
+**i*i*i*ii*i*i*ii, or 11111100011100.
Huge memory may be required to compile the program (about 300 MB on +my machine).
+In addition, there are some limitations (and workarounds) mentioned +in Spoiler section.
+–
+From the author:
+–
+You can NOT write a note length immediately followed by a
+note E, such as C2E2.
Can you figure out why?
+A workaround is inserting a whitespace: C2 E2.
–
+Invalid input files will very likely crash the program.
+This program will not terminate on its own; you must kill
+hou (but not Qiming Hou :-) ) yourself. This should not be
+fixed.
The author reminds us that if you kill the program you will have to +wait a short bit of time before you can start it again if you want it to +be able to bind to the socket (which obviously you do). The source is +out the scope of this document but the author does mention the well +known (at least to those of us who have experience with socket +programming :-) ) fix. However as the author pointed it out as a known +limitation it is not a bug but a feature.
+The author noted that in macOS the colours might be wrong. They gave +a solution. However Cody didn’t see any problem with it and he beat the +series many times. Of course the game here is small and he’s practically +blind and it’s been a while since he last played so it might be wrong. +Nevertheless the author does give a way to reconfigure the colours.
+The author noted that the character cannot go through walls and the +impression is that this is how it was believed but Cody ironically +pointed out that there are known glitches where in some places you +actually could go through walls. This might even have applied to the +arcade version, Mario Bros, though that can no longer be confirmed by +Cody. The point here is that in this game you cannot go through walls +but it’s not a bug.
+On the other hand, the author also stated:
+–
+When the Super character becomes bigger
+(ZOOM flag), the character can collide with blocks and get
+stuck inside them. This is a KNOWN BUG. When your player become bigger,
+stay away from blocks!
–
+but since it’s documented it’s considered a feature, not a bug to +fix.
+This program will very likely crash if no arg is given.
+Cody Boone Ferguson
+discovered a bug to do with translating sound to text that shows itself
+in some cases (it works in others) when working on his winning 2020 Enigma machine (‘Most enigmatic’)
+entry. See his README.md for
+details (search for vik in the file). This one might be
+more of a limitation but this is not known.
He provides a tip in testing the problem: it might help to use his +Enigma machine to find problems as it will allow you to verify what is +correct and what is not. Again see his README.md for details. However it +is also possible to not rely on the entry as the below shows. One should +be able to do:
+echo 'No. I want chocolate!' | ./prog > chocolate.raw
+
+./prog e < chocolate.rawand get:
+No. I want some chocolate!
+but instead we get:
+IT FHOCOLITE!
+which is very wrong. If however one does:
+echo IOCCC | ./prog > ioccc.raw
+
+./prog e < ioccc.raw
+they will properly get:
+IOCCC
+The author stated:
+–
+Hard requirements:
+The platform must implement the double type as
+IEEE754-compliant 64-bit floating point numbers. The 80-bit intermediate
+format used by x87 is considered as an violation of this. The code
+should print an error message on such platforms.
The program must start with the CPU / FPU in round-to-nearest +mode.
Soft requirements:
+The compiler must respect volatile. The code is
+formatted to warn about that, though.
The printed result is only correct on little-endian machines. The +program takes care to warn about this issue after printing an incorrect +big-endian result. Error messages become garbled, though.
–
+The program doesn’t look at the header of files so if it’s passed +something hat is not compressed data it’s likely to crash.
+The program depends on little endian systems.
+The program assumes that EOF is -1. This
+can be fixed but at this time it is uncertain if it should be.
The author also stated:
+–
+While the program works best when bytes/characters are octets and the
+number of bits in a type is sizeof(typ) << 3, it will
+work correctly on 24-bit or 36-bit systems with 9 bits/byte, or systems
+where sizeof(typ) is 1 even for int and so on.
+On such systems, it will only use 8 * sizeof(typ) bits per
+place. It does not work when CHAR_BIT <= 7.
–
+There was no IOCCC in 2016.
+There was no IOCCC in 2017.
+The author wrote:
+int is less than
+32 bits.-d or -h is
+fully possible if it is not the first file provided, even though I am
+not sure why you would want to do that.When you run it on a JSON file you will see something like:
+$ ./prog < ioccc.json > ioccc.html
+Assertion failed: (rulez), function C, file prog.c, line 124.
+Abort trap: 6(from say running
+./try.sh) but this is expected and the fileioccc.html` will
+be generated properly.
Some JSON files might cause the program to continue to run and
+seemingly infinitely increase the size of the output file. This can
+happen if you try fixing the syntax error in the generated
+ioccc.json file.
After exiting the program (with ctrl-e) if you try running it again +you will likely see:
+>bootT5pw
+ ]h_ 8D3[]
+where [] is the cursor. When this happens if you hit
+enter (this is necessary or else it’ll happen again) and then exit again
+(ctrl-e) and run prog again it’ll be okay.
The author stated that if you make a typo it can happen that the boot +loader can crash and halt. If this is the case type ctrl-e to quit the +emulator and try again.
+The author also stated that it is possible to corrupt the virtual
+disk. If you do this you should type make clobber all and
+try again.
Cody caused a funny problem where it showed ERROR after
+each command. The solution was to hit ctrl-e and start again. He does
+not know if this is what was referred to by the author but there was
+likely no typo involved.
Cody notes that if you are using the saved mode you must type
+sync prior to exiting the program or else the next time you
+run it the file will not exist (or in the case of compiled code it won’t
+be executable).
The author wrote the following:
+Despite appearances, it does not handle numbers in hex, or
+provide a curses(3)-based interface.
The expected input format is zero or more lines of +space-separated integers. If other characters appear in the input, it +will either reject the input entirely and exit with a non-zero status, +or skip number(s) adjacent to the non-digit characters, depending on +where the characters appear. Tabs and multiple consecutive spaces are +handled correctly, however.
Individual lines of input longer than 0x3543 - 1
+bytes will be split and processed as if they were multiple lines of
+input, which can produce incorrect results. This magic number’s
+significance is described earlier.
The algorithm expects its input to represent a fully connected +graph. While the output is otherwise topologically sorted, if there are +nodes completely unconnected to the rest of the graph (with or without +self-cycles), they will be output as soon as they are processed – this +means that, when there are disconnected nodes, reordering the input +lines can produce different output. Addressing this by adding another +pass is would put the program over the size limit.
While the node IDs don’t need to be consecutive or start at 0, +the implementation doesn’t have special handling for sparse graphs. If +you give it a graph with nodes numbered 0 and 2147483647, it will +attempt to allocate sufficient memory (potentially around 32 GB) for the +entire range of graph nodes, even if those are the only ones. If memory +allocation returns NULL, it will gracefully exit, otherwise it will +succeed, eventually, perhaps after a great deal of swapping.
Node IDs >= 2147483648 will cause the program to print an +error message and exit with a non-zero status. This shrinks the code +that detects overflowing the array size by a bit.
A very large group of nodes in a cycle can cause a stack +overflow. This typically takes over 100,000 nodes, and depends on the +order the nodes are visited. Addressing this would put the program over +the size limit.
The implementation depends on the characters '0',
+'1', … '9' having the values 48
+through 57, rather than using isdigit(3). As
+noted above, this program has nothing to do with a hand.
Certain input can crash this program. The file crash.unl is an example file.
+The author pointed out that some implementations of
+wc(1) show different values but his implementation matches
+that of macOS and FreeBSD.
Cody Boone Ferguson +fixed the scripts so that they can work but it might end up that the +scripts don’t show any output anyway as they use the full alphabet. To +test that it works one can have a script like:
+LC_ALL=C aäbcdefghijklmnoöpqrsßtuüvwxyz | LC_ALL=C grep .. | LC_ALL=de_DE.UTF-8 ./prog aäbcdefghijklmnoöpqrsßtuüvwxyzIf you run this you should see:
+aäbcdefghijklmnoöpqrsßtuüvwxyz
+which shows it works. However as the de.sh script refers to all +letters it can’t find a perfect pangram. BTW, as far as the question of +whether the umlaut letters or the Eszett are considered letters in the +German alphabet, Cody noted in the de.sh/de.alt.sh scripts:
+# Are the umlauts ä, ö, ü and Eszett (ß) letters in the German alphabet? There
+# is more than one opinion on the subject but a lot of words do have an umlaut
+# (or Umlaut in German). In some (probably all) systems this script outputs
+# nothing probably because it's very hard to form a perfect pangram in German,
+# if it's not impossible. Nevertheless, we do include the other characters
+# whether or not they are in your view considered part of the alphabet for the
+# reason that so many words have them.
+The author does not it uses gets() and one will get
+warnings but it would be ideal if this was not the case.
There are two things to be aware of with this entry.
+If the file being used (to draw) is deleted it might lock any session +still in use. These will have to be killed from another shell session or +by closing the terminal tab. This will also happen if the file cannot be +opened in the beginning.
+This program will also very likely leave sockets lying about in the +current working directory. For instance Cody Boone Ferguson showed +us this:
+$ ls -al |grep '^s'
+srwxr-xr-x 1 cody staff 0 Apr 6 08:19 .BDHFHALG=
+srwxr-xr-x 1 cody staff 0 Apr 6 08:15 .CGGHAMGC=
+srwxr-xr-x 1 cody staff 0 Apr 6 08:16 .CMDGAELH=
+srwxr-xr-x 1 cody staff 0 Apr 3 08:47 .CMLBCCDA=
+[...]This is NOT a bug and you’ll have to (at least at this time?) delete +the files manually. You shouldn’t have to worry about these being added +to git: it seems to ignore sockets (it did at least in macOS).
+He provides the following tips on this situation. A simpler way to +find sockets in the directory:
+file .*|grep socket|cut -f1 -d:To delete them you can do:
+find . -exec file '{}' \;|grep socket|cut -f 1 -d: | xargs rm -fthough one might want to check that the program is not currently +running. :-)
+As a backtrace quine this entry is SUPPOSED to +segfault so this should not be touched either.
+The author stated the following:
+The author wrote that there are a number of differences from what one +might expect. Rather than duplicate the information we refer you to the +author’s remarks in the sections Syntax and Caveats.
+The author wrote that if you decide to change networks or use a +different input file you should delete all the checkpoint files because +the format depends on both the network and the input – using the wrong +checkpoint is likely to cause a crash.
+The author also wrote:
+IMPORTANT NOTE: Since OMLET uses the system stack
+for network storage, larger networks may cause OMLET to crash (typically
+with a message like Segmentation fault) unless the system
+stack size is first increased. The exact command for doing so depends on
+your shell and your system’s hard limits. On
+sh/ksh/bash shells, you can view
+the hard limit with ulimit -Hs and set it with
+ulimit -s 65532 (replacing 65532 with the
+actual hard limit). On csh/tcsh shells, you
+can view the hard limit with limit -h stacksize and set it
+with limit stacksize 65532 (replacing 65532
+with the actual hard limit).
This program will not validate input so it might fail or get stuck if +invoked erroneously.
+Also, the maximum file size is 1GB.
+The author noted that if the program runs out of memory it is likely +to crash.
+The author also stated that ‘if input contains CR-LF end of line
+sequences, those CRs are silently dropped. In fact, most
+control codes are silently ignored except line feeds (preserved) and
+tabs (expanded to 8 spaces).’
This entry is known to crash if no arg is specified. Although easy to +fix it is documented and should not be fixed (of course you may fix it +to see if you can but it shouldn’t be made into a pull request).
+It will also show funny output with more than one arg. This should +not be fixed either. But can you figure out why this happens?
+The author stated that bad things happen if the entered move is
+outside of the range [1..9]. We observed a crash but we also observed a
+tie and other things besides (say with the input -1,
+-, -10 and others).
If a player makes a move over their opponent’s place they will +automatically lose.
+If a player tries to play a move they already played they will +forfeit their move.
+If you have audible bells enabled the program will beep at every +turn.
+There are some things that might appear to be bugs but are actually +features or things that are misinterpreted as bugs. See the bugs.md and troubleshooting.md files +for details.
+The author noted that the program only supports WAV files that have +exactly 16 bits per sample, but it allows any sample rate and any number +of audio channels.
+The author listed the following limitations:
+The program does not support MIDI files over 4 MB (specifically,
+it will not take input files larger than 2^22 - 1 bytes).
+This is unlikely to be a big limitation in practice, since even lengthy
+MIDIs are rarely over a couple hundred KB.
Not all MIDIs set (or correctly set) their timing +information, which will lead to the tempo of the drum beat not matching +the track. This will be especially true for “live performance” .mid +files.
There may be some types of MIDI messages that the program is +unable to correctly parse, but I have rarely seen this in practice. The +largest cause of program failures, in my experience, has been Limitation +2.
See also the Program error +codes written by the author which lists some other conditions which +should be considered features, not bugs.
+There was no IOCCC in 2021.
+There was no IOCCC in 2022.
+There was no IOCCC in 2023.
+We hope to run the IOCCCMOCK this year, 2024, and hopefully the next +IOCCC, but for now we wish everyone a happy new year!
+We hope this document was of use to you in determining which entries +are known to have a problem, what entries are known to have features +that are not bugs and so on. We also thank you for going through this +document and, if you propose any fixes] via a GitHub pull +request or otherwise, we thank you as well for the help! We will +happily add you to the thanks file as +well.
+ + + + + + + +
-
If you want to contact the IOCCC please send email to: +
+ q.YYYY@ioccc.org+ + -
IMPORTANT: The YYYY in the above Email address MUST be changed to the current 4 digit year!+
-You must include the following two words (separated by a space) in the subject of your email, otherwise the email will be rejected: + + -
IOCCC YYYY+
IMPORTANT: The YYYY in your subject line MUST be changed to the current 4 digit year!+ + -
| © Copyright 1984-2023,
-Landon Curt Noll and Leonid A. Broukhis. - All rights reserved. -This work is licensed under the -Creative -Commons CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International License. -If you do use this work in some form, the -IOCCC judges would appreciate (but does not require) -if you were to send us a note about your use. |
-
If you are trying to:
+Instead of sending us Email, Please consider using +the GitHub pull +request process against the master branch of the ioccc-src/winner +repo.
+If you are trying to:
+Instead first look at the IOCCC issues to +see if the problem has already been reported. If it has been reported, +feel free to add a comment to the issue. If you do not find an it has +been reported, then fee free to open a new IOCCC issue.
+See the above FAQ entries for more details.
+Did you look at the above section?
+If you must contact the IOCCC judges by email, then please send email +to: q.YYYY@ioccc.org
+IMPORTANT: The YYYY in the above Email +address MUST be changed to the current 4 digit +year!
+You MUST include the following two words (separated +by a space) in the subject of your email, otherwise the email will be +rejected:
+IOCCC YYYY
+IMPORTANT: The YYYY in the above Email +address MUST be changed to the current 4 digit +year!
+ + + + + + + +
+ gets(3) changed to use fgets(3)?To submit your code to the IOCCC, you MUST follow +these steps:
+Verify that the IOCCC is open for submissions
+Check the status.json URL and check the IOCCC news to see of the IOCCC is open.
+You may only register for the IOCCC and you may only submit your +entries to the IOCCC when the IOCCC is OPEN.
Read the latest IOCCC rules and review the IOCCC guidelines
+Please pay close attention to the official +IOCCC rules.
+You are also highly encouraged to review the official IOCCC guidelines as they contain +important suggestions, useful hints, and IOCCC humor. :-)
Register for the IOCCC
+XXX - instructions TBD - XXX
+Once you have been registered, you will receive an email message for +how to prepare your entries for submission, and how to upload the +compressed tarballs to our submission portal.
Obtain the latest mkiocccentry toolkit
+If you do not have an mkiocccentry tool directory:
+cd some_directory git clone git@github.com:ioccc-src/mkiocccentry.git +cd mkiocccentry
+If you already have an mkiocccentry tool directory:
+cd mkiocccentry git fetch git rebase
Make the mkiocccentry toolkit
+make clobber all
Run the mkiocccentry tool to form your entry tarball
+ ./mkiocccentry work_dir prog.c Makefile remarks.md [file ...]
+where:
+work_dir directory where the entry directory and tarball are formed +prog.c path to the C source for your entry
+Makefile Makefile to build (make all) and cleanup (make clean & +make clobber)
+remarks.md Remarks about your entry in markdown format NOTE: See the +markdown syntax +guide.
+[file …] extra data files to include with your entry
+NOTE: It is NOT necessary to install the tools to use them +as you can run the tools from the top of the mkiocccentry repo +directory just fine.
+If mkiocccentry tool indicates that there is a problem
+with your entry, especially if it identifies a rule 2 related problem, you are
+strongly encouraged to revise and correct your entry
+and then re-run the mkiocccentry tool.
If you choose to risk violating rules, be sure an explain your reason +for doing so in your remarks.md file.
Upload your entry to the IOCCC submit server
+XXX - instructions TBD - XXX
There are types of entries that show up over and over again. The +IOCCC judges, and we suspect the public that enjoy viewing the results +of the IOCCC, like variety.
+While it is possible to win a new IOCCC with one of these +over-submitted types of entries, level of the +competition from previous IOCCC entries make it more challenging to be +successful.
+It is also important to note that the guidelines say:
+++We tend to dislike programs that: are similar to previous +winners
+
As you can see, just a list of primes (let alone small primes) +does not cut it anymore.
+1994/smr - _do not claim your +program is the smallest one without seeing this!
2000/dhyang - unless +you beat this one, your chances are slim
…it’s so 20th century…
+HINT: It is not fatal to send in those types of entries, it is just +MUCH HARDER to win. Such an entry would have to do something really +unique AND interesting to even make it into the +final judging rounds. Entries that reuse these ‘worn out’ themes +frequently lose to other entries that do something different.
+HINT: If you really MUST send in an entry based on an ‘overused +theme’, be sure that it is obfuscated in several new and novel ways. Be +sure to clearly explain near the beginning of your remarks why +you are submitting a entry based on an ‘overused theme’ and why the +judges should not simply toss it out as being boring.
+We recommend starting with the sample
+Makefile as found in the mkiocccentry GitHub
+repo, (renamed as Makefile of course) as a starting
+point for your entry’s Makefile.
The Makefile is a file used by the make(1)
+command that contains rules and UNIX shell-style commands.
The first and default rule should be the “all” rule and should build +your entry’s executable file.
+If your entry depends on a particular source file name during
+compilation or execution, your Makefile should copy
+prog.c into the desired filename. For example:
If you are not familiar Makefiles, you might consider
+the following tutorials:
For the make(1) connoisseur: As of 2023, IOCCC
+judges use GNU make
+compatible make(1) command that is compatible with GNU
+Make version 3.81.
While your entry’s source filename, as submitted, must be
+prog.c, your entry’s Makefile may copy
+prog.c to a different filename as part of the
+compiling/building process. For example:
all: desired_name
+
+desired_name: desired_name.c
+ cc desired_name.c -o $@
+
+desired_name.c: prog.c
+ rm -f $@
+ cp -f prog.c $@
+
+clobber:
+ rm -f desired_name.c desired_name
+We recommend that the make clobber rule remove files
+that your entry creates as part of the compiling/building process.
You may also copy the compiled prog into a different
+file as part of compiling process. For example:
different_name: prog
+ rm -f $@
+ cp -f prog $@
+Your entry must compile with GCC and run under at least one flavor of +UNIX (e.g. Linux or Solaris). To improve chances to win, it should work +under both BSD and SysV style UNIX (think stty cbreak), +and should not depend on “Endianness”. If it can compile and run on +Windows and/or Mac (see 2000/thadgavin for one example, +amongst others), even better. Being able to compile with other compilers +like clang is also a good thing.
+One day (1984 March 23 to be exact), Larry Bassel and I (Landon Curt +Noll) were working for National Semiconductor’s Genix porting group, we +were both in our offices trying to fix some very broken code.
+Larry had been trying to fix a bug in the classic Bourne shell (C
+code #defined to death to sort of look like Algol) and I
+had been working on the finger program from early BSD (a bug ridden
+finger implementation to be sure).
We happened to both wander (at the same time) out to the hallway in +Building 7C to clear our heads.
+We began to compare notes: ‘You won’t believe the code I am +trying to fix’.
+And: ’Well you cannot imagine the brain damage level of the code +I’m trying to fix’.
+As well as: ’It’s more than bad code, the author really had to +try to make it this bad!
+After a few minutes we wandered back into my office where I posted a +flame +to net.lang.c inviting people to try and out obfuscate the UN*X +source code we had just been working on.
+BTW: I (Landon Curt Noll) had to post this typo +correction. Thus began the tradition of putting typos in the contest +rules and guidelines … to make them more obfuscated of course! :-)
+BTW: This posting was made back in the days when AT&T was the +evil giant. Now, Microsoft makes AT&T look mild and kind in +comparison. :-( (IMHO) ).
+BTW: See the story about the ‘Bill +Gates’ award. :-)
+OK, back to the story.
+We (Larry and I) received a number of entries by email. When we began +to receive messages from outside of the US, Larry and I decided to +include International in the name.
+The 1st +IOCCC entries were posted on 17 April 1984.
+There were 4 winners in 1984:
+ +BTW: The (dis)honorable mention wished to remain anonymous. While +many have asked who it was, we have continued to follow the author’s +wish to remain anonymous.
+A few years ago, we asked the author if they still wanted to remain +anonymous. They said: ‘Yes, I want to keep my anonymity. But you can +tell them that I am well known for my connection to the C +language’. It was not until 2001 that another anonymous entry received an +award.
+BTW: The 1984 winner remains +one of my (Landon Curt Noll) all time favorites.
+The name used in the posting of the 1st +IOCCC winner posting was International +Obfuscated C Code +Contest or IOCCC for short.
+The posting said ‘1st annual’, so in 1985 we held the 2nd IOCCC contest and the tradition +continues as the longest running contest on the Internet.
+P.S. Part of the inspiration for making the IOCCC a contest goes to +the Bulwer-Lytton fiction +contest.
+P^2.S. See the overall README for more +details.
+Some years, such as 1997, 1999, 2002-2003, 2007-2010, 2016-2017, +2021-2023, no IOCCC was held.
+While we try to hold the IOCCC every year, sometime the other demands +on the IOCCC judges so not permit us to hold a new IOCCC.
+The pause during the 2021-2023 period was due to the IOCCC judges +developing tools to make is much more likely for the IOCCC to be held in +a yearly basis later on.
+The long history of the official +IOCCC web site can be viewed at the Internet Wayback Machine Wayback +Machine.
+One can view several thousand snapshots showing how the IOCCC +web site has evolved going back as far as 1998 +Dec 12 www.ioccc.org.
+On 2020 Dec 31, the IOCCC source tree was moved to the IOCCC +winner repo on GitHub. From this +point on, the official IOCCC web +site became a GitHub Pages +web site.
+Furthermore, a bzip2 compressed tarball containing the released IOCCC +winner source code may be found under the archive/historic directory. The file archive-all.tar.bz2 +contains all years and the individual years are in the form +archive/historic/archive-YYYY.tar.bz2.
+These files were obtained from the Internet Wayback Machine from the snapshot +of the website on 2020 Dec 28. See archive/historic/README.md for +details about these bzip2 compressed tarballs.
+XXX: Change the references to +temp-test-ioccc to winners when these fixes are +merged.
+On 2022 Dec 29, the IOCCC winner repo, from +which the official +IOCCC web site of 2022 Dec 29 was generated, was forked into a +temporary repo where it underwent several thousand changes and important +improvements such as:
+On 20yy mm dd, the temporary repo was merged back into the IOCCC winner repo +resulting in substantial improvements to the official IOCCC web site.
+XXX: Fill in the date when the pull request happens +including the size of the pull request and/or number of changes that +went into the pull request. We call this the great fork +merge.
+The IOCCC size rule has changed over the years.
+In later years, Rule 2 was split into two parts. These two parts of +Rule 2 are:
+NOTE: The size rule was actually rule 1.
+NOTE: The size rule was actually rule 1.
+NOTE: The size rule was actually rule 1.
+By tradition, we do not say.
+While you may put in as much or as little as you wish into your
+entry’s remarks.md file, we do have few important
+suggestions:
We recommend that you explain how to use your entry. Explain the +command line (if any command line options and arguments are used) and +any input or actions if applicable.
+We highly recommend that you explain why you think your entry is well +obfuscated.
+For those entries that win the IOCCC, we often use much of text from
+the remarks.md file in the Author’s remarks
+section of the README.md file. For this reason, a well
+written remarks.md file is considered a plus.
While not required, consider adding bit of humor to your
+remarks.md as most people who are not humor impaired, as
+well as the IOCCC judges appreciate the opportunity for a fun read as
+well as a chuckle or two.
explaining what your entry does
how to entice it to do what it is supposed to do
what obfuscations are used
what are the limitations of your entry in respect of portability +and/or input data
how it works (if you are really condescending)
admitting that your entry is not very obfuscated (you see, the +contest is called the IOCCC, not the +INVOCCC :-) ); but even if you do not admit it, not +very obfuscated entries have a minuscule chance to win (although 2000/tomx is a notable +counterexample).
mentioning your name or any identifying information in the remark +section (or in the C code for that matter) - we like to be unbiased +during the judging rounds; we look at the author name only if an entry +wins. See the guidelines if this is not clear!
leaving the remark section empty.
Because the publication on the IOCCC site +IS the award! Anyone is free to put their +IOCCC hopefuls, lookalikes and/or non-winners on their web page for +everyone to see.
+It takes a fair amount of time to setup, run, answer email, process +entries, review entries, trim down the set entries to a set of winners, +doing the write-up of the winners, announcing the winners, reviewing +final edits of the winning entry set, posting the winners, being flamed +:-), tell folks who send in late entries to wait until the next contest, +etc… It takes a few weekends and a number nights of study and work … +which is hard given that we are busy with many other activities as +well.
+Note that we do not contact the author if an entry does not compile +or does not work as advertised, we might attempt to fix obvious +compilation problems or incompatibilities, but no more than that - so be +sure that your entry does work on at least a couple different platforms, +at least one of them being UNIX or POSIX-conforming.
+Are you trying to trick us? :-)
+By tradition, we do not say how many judging rounds we have in a +given IOCCC.
+We often report when the IOCCC judges start the 1st round, and when +usually report when the IOCCC judges start near final judging rounds, +and sometimes we also report when we enter what we believe is the final +judging round, so you may guess that we have at least 3 rounds. :-) The +actual number of rounds is certainly more than 3.
+In some years, the IOCCC judges discover a truly amazing IOCCC winner +that stands out among all of the other IOCCC entries received that year. +For such an IOCCC winner, the IOCCC judges award a “Grand Prize” or +“Best of Show award.
+In 1984-1987, the grand prize winners are:
+ +Starting from 1988, the entry we liked the most in that year is +called “Best of Show”. Here are the “Best of Show” entries:
+In 1993, 1994 and 1995 the judges were unable to select a clear +overall winner. So to give a nod to the entry that had the highest +approval ranking from the judges, they used the following awards:
+1993/rince - Most Well +Rounded
1994/shapiro - Most Well +Rounded
1995/leo - Best Use of +Obfuscation
These could be considered the ‘best entry’ for those years with 1 or +more other entries that came in close behind.
+Once the IOCCC +closes, the judges will select the winning entries announce +them on the @IOCCC mastodon feed, +notify the winners via email using their previously registered email +address, and upload the winning code to the winner repo which in turn +will cause them to be displayed on the IOCCC winning entries +page.
+In general the best way to compile everything in an entry directory +is to run:
+make clobber allIf you wish to compile every entry for every year you should go to
+the top level directory and run the same command as above,
+make clobber all.
The all rule will build everything necessary except for
+the alternate versions. Every Makefile has an alt rule but
+it will only do something if an alternate version exists. To build all
+the entries along with any alternate code you can do from the top level
+directory:
make clobber everything
+If you wish to only build alternate code you can do:
+make clobber altIf you wish to not remove the entry binaries and only compile the +additional alt versions:
+make altThe following Makefile rules should be in all Makefiles:
+clobber that only removes
+object files. make clobber depends on clean so
+running make clobber will invoke
+make clean.make all alt.Are there any other rules? You tell us!
+NOTE about the above rules: the Makefile default assumes
+cc which might be a gcc-based compiler, or a clang-based
+compiler, or some other compiler. Only by forcing CC=clang
+or CC=gcc will one invoke a specific compiler to, say,
+enable or disable additional warnings or flags. Even so different
+versions or compilers might do different things, have different defects
+or other issues.
Some winners, particularly winners from long ago, no longer compile +on more modern systems because the C language has evolved (i.e. the +modern C compilers are much more strict in what they accept as a valid +program), or the entry depended on operation system and library features +that where common back then but are different/missing today.
+Please see the other FAQs in this section as they might offer helpful +hints, especially in cases were something else needs to be +installed.
+Please see the bugs.md file for details about +known problems with IOCCC entries. In some cases you may be dealing with +a problematic entry. In a few fun cases, the IOCCC does not compile by +design!
+If you have a fix that makes a minimal impact to the entry, then +please consider submitting that change in the form of a pull request. +Please see FAQ 5.2 “How may I submit a fix to an +IOCCC winner” for details.
+In some cases alternative code has been added that does compile on
+some or most systems. Check the write up for the entry for “alt” code
+and possible ways to compile and run that code. In some cases we
+replaced the original code (but not the .orig.c file!) with
+code that works for modern systems but one can view the original code in
+the .orig.c files (sometimes the original code is also in
+the directory as a winner.alt.c or
+prog.alt.c).
Unfortunately some older entries are non-portable and require 32-bit +support or 32-bit binaries. A problem system here is macOS Catalina +(10.15) as as of that version macOS no longer supports 32-bit binaries. +If the entry acts on a certain type of binary, say ELF, then that will +also be a problem depending on the entry. For example 2001/anonymous requires 32-bit ELF +binaries.
+There are numerous example entries that require 32-bit binaries. We +have tried to note these in both the respective Makefiles and README.md +files but it is possible that some were missed. These entries are very +likely in the bugs.md file and we welcome any +help in making an alternate version for 64-bit systems. Many were fixed +to work with modern systems but some are supposed to only work with +32-bit systems so any updated version of these entries should be an +alternate version.
+Other entries like 2001/herrmann2 now work +with 32-bit AND 64-bit systems.
+Please see the bugs.md file for the +problematic entry in question to see if the problem is known, and if a +fix is wanted, consider trying to port the code to a 64-bit system and +submitting a pull request with that change. Pull requests that fix such +code while trying to minimize the impact of any changes and preserving +the spirit of the original code are very welcome! Please see FAQ 5.2 +“How may I submit a fix to an IOCCC winner” +for details.
+If the entry requires gcc and you did not explicitly install gcc in
+macOS you will not be able to run or use these entries. This is because
+macOS gcc is actually clang, even /usr/bin/gcc.
That being said many (if not most) of these entries have been fixed +and some others will be looked at, when found.
+In some cases the bugs.md file may note a +known macOS problem with an entry. Should you manage to port the entry, +and assuming your changes also attempt to preserve the original intent +of the IOCCC entry, we would encourage you to submit a pull request with +your ported code. Please see FAQ 5.2 “How may I +submit a fix to an IOCCC winner” for details.
+Although we have fixed numerous entries to work with clang (sometimes +in an alt version but usually in the program itself) there are some that +simply cannot be fixed or if they are fixable they have not yet been +fixed (we are working on this but other things have to be done too and +all on free time).
+This is because clang has some defects where the args of main() are +required to be a specific type and some versions of clang allow only 1, +2 or 3 args, not 4, to main(). In the case of types of args many were +changed to the right type and then what was main() became another +function of the original main() type.
+At the same time some entries are not designed to work with clang. +There might be alternate code added at some point but as above this +depends on free time and other things that have to be done plus +remembering to do it.
+See if the problem is mentioned in bugs.md. If
+you have a change that fixes the problem (even if it just a change to
+the Makefile) that doesn’t negatively impact the entry too
+much, consider submitting that change in the form of a pull request.
+Please see FAQ 5.2 “How may I submit a fix to an
+IOCCC winner” for details.
This was a C beautifier for Unix, both AT&T and Berkeley, but it
+seems to no longer be available, code wise, except for Plan 9, but Plan
+9 was never used for judging the IOCCC. A Unix man page for
+cb still
+exists.
The simplest way to do this is to type reset. If echo
+was disabled you can get usually away with stty echo.
+Sometimes you can also get away with stty sane.
+reset does the most but note that it will clear the screen
+(obviously clear will too but it won’t reset the
+terminal).
You must have the X11 related include files and X11 libraries in +order to compile the IOCCC winner. In order to do this you will need to +install Xorg and related packages including development related +packages. If you have macOS see further down for different instructions. +Otherwise: in particular you must:
+By X11 terminal application we suggest one of:
+ +See below for various system related hints that may be of help.
+The Red Hat RHEL9.0 release notes state that X.org +Server is now deprecated.
+According to this Linux +for Devices tutorial on XOrg as of 2023 Mar 25:
+++Recently, RHEL developers categorized Xorg +was put in the ‘deprecated’ software, as its development has mostly +halted. Subsequent updates will completely replace it with Wayland, a +more modern windowing system.. Although Wayland is not fully developed +yet, many applications do not support it properly yet and screen sharing +might not work sometime, but it is the future. Fedora, also developed by +RHEL, has switched to a Wayland session as it’s default windowing system +(And it works flawlessly on my Laptop).
+
See the Wayland web +site for more details.
+IMPORTANT NOTE: We do NOT know if +IOCCC entries will run under Wayland. Some IOCCC +entries that use X11 might be OK while other IOCCC winners that use X11 +in an unusual way might fail under Wayland.
+See the Wayland +FAQ for more information.
+If your system uses Wayland and not X11, you might +give the IOCCC entries that use X11 a try. They might work but again we +do not know.
+IMPORTANT NOTE: The IOCCC +judges do not support IOCCC entries. So if +an IOCCC winner that uses X11 fails under Wayland, and +you wish to provide a fix to the IOCCC winner so that it will run under +Wayland, then consider submitting a fix so that it will run under +Wayland.
+Basically: if you discover an entry does not work in Wayland you are +welcome to provide alternate code that works for +Wayland. We will happily credit you in the thanks-for-help.md file.
+First, see the above note on installing and +starting Xorg.
+Install Xorg and related packages:
+sudo dnf install --skip-broken --best --exclude xorgxrdp --exclude xorgxrdp-glamor '*xorg*' 'libx*' 'libX*' 'fontconfig*'See also:
+ +IMPORTANT NOTE: The X.org +server has been deprecated. See the above note for details.
+First, see the above note on installing and +starting Xorg. However, for macOS, instead of installing the Xorg +server, you need to install and launch the most recent XQuartz application and +then run the IOCCC winner from the Xterm window shell.
+As an example we will use 1993/jonth which works with macOS +14.2.1 (macOS Sonoma).
+First of all you will need to install the most recent XQuartz, preferably on an
+Apple supported version of
+macOS, preferably the most recent version. After it is installed,
+open the “XQuartz” application (usually located in
+/Applications/Utilities/XQuartz.app) by typing at the
+command line:
open /Applications/Utilities/XQuartz.appWith the “XQuartz” application open you will get an X Window System Manager launched with +an Xterm window shell +started:
+
At this point you need to cd to the winning directory and compile it. +For example:
+
And then run the program as directed by the README.md
+file. For example with 1993/jonth:

Note that you can compile the code in your regular terminal prior to +opening XQuartz, should you wish to. You can even run it from that +terminal and it should open XQuartz.
+IMPORTANT NOTE: The X.org +server has been deprecated. See the above note for details.
+First, see the above note on installing and +starting Xorg.
+According to the Debian Xorg +wiki, installing X11 requires:
+sudo apt install xorgIMPORTANT NOTE: The X.org +server has been deprecated. See the above note for details.
+First, see the above note on installing and +starting Xorg.
+For general documentation on installing X11, this ServerGUI for +Ubuntu, and in particular, these may be helpful:
+ +See also:
+ +For systems that have the dnf(1) command:
sudo dnf install --skip-broken --best --exclude xorgxrdp --exclude xorgxrdp-glamor '*xorg*' 'libx*' 'libX*' 'fontconfig*'For systems that have the yum(1) command:
sudo yum install --skip-broken --best --exclude xorgxrdp --exclude xorgxrdp-glamor '*xorg*' 'libx*' 'libX*' 'fontconfig*'IMPORTANT NOTE: The X.org +server has been deprecated. See the above note for details.
+First, see the above note on installing and +starting Xorg.
+See the X.org foundation web +site.
+IMPORTANT NOTE: The X.org +server has been deprecated. See the above note for details.
+This depends on your operating system but below are instructions for +Linux and macOS with alternative methods for macOS and different package +managers with Linux.
+Execute the following as root or via sudo:
+dnf install SDL2 SDL2-devel sdl12-compat sdl12-compat-develOlder RHEL distributions might have to use “yum” instead of “dnf” in +the above command.
+In the past it was said that one might need to run make
+like:
make ... SDL2_INCLUDE_ROOT=/usror set the following environment variable:
+export SDL2_INCLUDE_ROOT=/usrbut this might not be necessary in more modern days especially as we
+use sdl-config and sdl2-config which should
+find the proper paths.
If you’re using macOS there are at least three ways to obtain it. You +can use Homebrew or MacPorts. If you do not wish to use either of those +package managers, you can always try to install via the package website. +For macOS we do recommend using Homebrew or MacPorts instead of using +the package website.
+If you have not already done so, install Homebrew.
+Then to install SDL and SDL2, execute the following command:
+brew install sdl2 sdl12-compat
+eval "$(/opt/homebrew/bin/brew shellenv)"If you haven’t already, install MacPorts. Then run:
+sudo port install libsdl libsdl2Execute the following as root or via sudo:
+apt install libsdl1.2debian libsdl1.2-dev libsdl2-devand then try make all again.
In the past it was said that one might need to run make
+like:
make ... SDL2_INCLUDE_ROOT=/usror set the following environment variable:
+export SDL2_INCLUDE_ROOT=/usrbut this might not be necessary in more modern days especially as we
+use sdl-config and sdl2-config which should
+find the proper paths.
Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the SDL website and follow +their instructions for downloading, installing and using SDL.
+We recommend trying a method suitable for your environment first, if +possible.
+In the case that some entries do not work even with SDL1/SDL2 +installed it might be that you need additional SDL libraries. See the +entry’s README.md for details. If something is not noted you’re welcome +to report it as an issue or fix it and make a new pull request.
+This depends on your operating system but below are instructions for +Linux and macOS with alternative methods for macOS and different package +managers with Linux.
+Execute the following as root or via sudo:
+dnf install ncurses ncurses-develWith macOS it should already be installed. If it is not you might +have to do:
+xcode-select --installand agree to the terms and conditions and proceed with the +install.
+Not applicable, see above.
+Not applicable, see above.
+Execute the following as root or via sudo:
+apt install libncurses6and then try make all again.
Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the ncurses +website and follow their instructions for downloading, installing +and using ncurses.
+We recommend trying a method suitable for your environment first, if +possible.
+This might depend on the entry but most likely the Swiss Army Knife +of sound processing programs, SoX, will work. How to install +depends on your OS.
+As root or via sudo:
+dnf install -y sox sox-develFor macOS there are two well known options.
+If you have not already done so, install Homebrew.
+Then to install SoX, execute the following command:
+brew install sox
+eval "$(/opt/homebrew/bin/brew shellenv)"If you haven’t already, install MacPorts. Then run:
+sudo port install soxUsually the README.md file will explain how to use it under Debian so +we do not include this here, at least for now.
+Not applicable, see above.
+Usually the README.md file will explain how to use it under Linux so +we do not include this here, at least for now.
+While we know that use of -Weverything is generally not
+recommended by clang C compiler developers, we do use the
+-Weverything option in a certain case in IOCCC winner
+Makefiles.
The use of -Weverything is limited to when one forces
+CC=clang or more generally if the string ‘clang’ is in
+$(CC). If $(CC) contains ‘gcc’ the ‘gcc’
+specific options are run instead.
Users with clang compilers are not required to set
+CC=clang or equivalent but when they do,
+-Weverything is enabled with all of its challenges,
+pedantic warnings, and sometimes warnings about things that do not
+matter, some of which are frankly frivolous and often downright
+dubious.
To enable this feature:
+make clobber all CC=clangor:
+make clobber all 'CWARN+= -Weverything'though it should be noted that if one tries -Weverything
+with compilers that are not clang they might see
+something like:
echo 'int main(void) {}' > foo.c ; cc -Weverything foo.c -o foo
+cc: error: unrecognized command-line option '-Weverything'which means that it can’t even be compiled. Thus the proper way to do
+it is the first way, make clobber all CC=clang.
IOCCC authors who have access to clang might wish to try
+their hand at compiling with -Weverything while using a
+minimum of -Wno-foo statements. Sometimes there is a
+technical or pedantic issue that -Weverything warns about
+that would merit a change to your C code; often, however, it is not even
+possible to fix let alone is it worth it. Of course if you’re running
+out of bytes due to rule 2[ab] one might not have much choice. This is
+something that obfuscation authors simply sometimes have to deal
+with!
If you try to minimize the number of -Wno-foo options
+needed with -Weverything, please mention this in your
+remarks about the entry, as the judges note you attempt to honor it (see
+also below). In some cases your obfuscated code will issue warnings with
+-Weverything no matter what: the
+-Wno-poison-system-directories is a common example of this
+but there are others as well, sometimes depending on the version of
+clang.
If you do try for a compile with clang -Weverything,
+keep on mind that while your compile environment might be
+warning free, a different clang version or a different build environment
+might still have warnings. For instance the warning set is different in
+macOS (which by default is clang: even when run as
+gcc!) than Linux (due to versions and possibly other
+things)!
Given that your entry MUST work as documented, you
+may be safer to say that your entry keeps the number of warnings and
+-Wno-foo options while compiling with
+clang -Weverything at a minimum. You might want to say the
+version number and platform too as an extra safety net. Because if you
+claim zero warnings, and we find a warning situation, this may diminish
+the value of your entry as it is not as documented. Thus it might be
+wise to point this out and if you can test it in multiple platforms (or
+versions of clang, see below note) this would be
+advisable.
NOTE: different versions of clang have other differences
+as well. For instance a defect of clang that required
+numerous entries to be fixed for clang is that it requires that
+main()’s arguments to be of a specific type. However some
+versions of clang are more strict in the number of args
+allowed. These reasons are part of why numerous entries had to be
+modified so that main() calls another function instead of
+doing it all in main() (another reason was that some
+entries that recursively called main() caused a crash or
+otherwise broke the entry in modern systems). Some entries do not work
+in clang (or at least do not work completely) due to these
+defects, for instance 1989/westley; Cody Boone
+Ferguson was able to get much of it to work and looking at that
+entry might be of value to your submissions, at least if you can figure
+the code out :-). To see the differences, try from
+1989/westley:
make diff_orig_progIf you have colordiff try:
make DIFF=colordiff diff_orig_progAlternatively you can try:
+git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..eb9e69fde657acc8c85a618a8a99af4c2f93b21d westley.cAs you can see, using clang has some additional problems
+to work out but if you can get your entry to work well in
+clang it might very well be considered better than other
+entries.
For some entries one needs to send interrupt or EOF or some other
+signal/other special characters. There are typical defaults like (where
+^ = ctrl):
^D for EOF (eof)^C for interrupt (intr)^U for kill (kill)and various others. But if you don’t know this you can find out
+through the stty(1) command with the -a
+option. For instance with macOS you might see:
$ stty -a
+speed 9600 baud; rows 40; columns 155;
+intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; [..snip..]If you know the name you can use grep to find the
+correct line and if your implementation of grep(1) has the
+-o option you can filter it. For instance to find what the
+intr is set to:
$ stty -a |grep -o 'intr = ^[[:alpha:]]'
+intr = ^C… assuming of course that it’s a ctrl combination :-) If for some
+strange reason it’s not you might have to do something else including
+just piping it to just grep intr or whatever.
What may have worked years ago may not work well or work at all +today. Please note that the IOCCC judges do NOT support +IOCCC entries. Nevertheless, there may be a number of reasons why an +IOCCC winner may fail to compile or run well or fail to run on your +system.
+In some cases the American National Standards Institute’s ANSI C +committee has damaged the C standard to the point where perfectly valid +C programs no longer compile with modern compilers. As such some old +IOCCC entries cannot no longer be compiled with modern compilers.
+In some cases programs that may have worked on an old computer system +longer work on modern computers. Some IOCCC entries do not work well, or +no longer work on modern computers or modern operating systems. Some +IOCCC entries fail to compile under clang, or gcc. Some IOCCC entries +require operating system services that may not be present on your +system.
+In some cases the IOCCC winner simply has bugs or (Mis)features.
+If you are having problems compiling or running an IOCCC winner, we +recommend that you look in bugs.md to see if +there is a known bugs or (Mis)feature. In some cases what you may think +is a bug is actually an feature that was intentionally written by the +authors. In some cases the problem is well known and we are looking for +someone to attempt to fix it.
+In some cases there is an alternate version of the IOCCC winner that +you may wish to try.
+It also possible that you may have discovered a bug in an IOCCC +winner. If so, you are invited to try an fix the IOCCC winner and submit +that fix by way of a GitHub pull +request. Please see FAQ 5.2 for how to submit +a fix to an IOCCC winner.
+If your OS package manager does not have the package
+tcpserver you can download, making sure you’re in a
+temporary directory, and compile the source like:
wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
+tar ucspi-tcp-0.88.tar.gz
+cd ucspi-tcp-0.88
+makeThen as root or via sudo(1) enter:
make setup checkThat will install it to /usr/local/bin. Now you should
+be able to use the entry in question.
This depends on your operating system for which we describe a couple +below.
+Execute the following as root or via sudo:
+dnf install netpbm-progs netpbmOlder RHEL distributions might have to use “yum” instead of “dnf” in +the above command.
+If you’re using macOS there are at least three ways to obtain it. You +can use Homebrew or MacPorts. If you do not wish to use either of those +package managers, you can always try to install via the package website. +For macOS we do recommend using Homebrew or MacPorts instead of using +the package website.
+If you have not already done so, install Homebrew.
+Then to install netpbm, execute the following command:
+brew install netpbmIf you haven’t already, install MacPorts. Then run:
+sudo port install libnetpbm netpbmExecute the following as root or via sudo:
+apt install netpbmand then try make all again.
Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the netpbm website +and follow their instructions for downloading, installing and using +netpbm.
+We recommend trying a method suitable for your environment first, if +possible.
+This depends on your operating system for which we describe a couple +below.
+Execute the following as root or via sudo:
+dnf install libjpeg-turbo-utils libjpeg-turbo-devel libjpeg-turboOlder RHEL distributions might have to use “yum” instead of “dnf” in +the above command.
+If you’re using macOS there are at least three ways to obtain it. You +can use Homebrew or MacPorts. If you do not wish to use either of those +package managers, you can always try to install via the package website. +For macOS we do recommend using Homebrew or MacPorts instead of using +the package website.
+If you have not already done so, install Homebrew.
+Then to install libjpeg-turbo, execute the following command:
+brew install libjpeg-turboIf you haven’t already, install MacPorts. Then run:
+sudo port install libjpeg-turbo libjpeg-turbo-develExecute the following as root or via sudo:
+apt install libturbojpeg0 libturbojpeg0-devand then try make all again.
Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the libjpeg-turbo +website and follow their instructions for downloading, installing +and using libjpeg-turbo.
+We recommend trying a method suitable for your environment first, if +possible.
+This depends on your operating system for which we describe a couple +below.
+Execute the following as root or via sudo:
+dnf install ImageMagickOlder RHEL distributions might have to use “yum” instead of “dnf” in +the above command.
+If you’re using macOS there are at least three ways to obtain it. You +can use Homebrew or MacPorts. If you do not wish to use either of those +package managers, you can always try to install via the package website. +For macOS we do recommend using Homebrew or MacPorts instead of using +the package website.
+If you have not already done so, install Homebrew.
+Then to install ImageMagick, execute the following command:
+brew install ImageMagickIf you haven’t already, install MacPorts. Then run:
+sudo port install ImageMagickExecute the following as root or via sudo:
+apt install imagemagickand then try make all again.
Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the ImageMagick website +and follow their instructions for downloading, installing and using +ImageMagick.
+We recommend trying a method suitable for your environment first, if +possible.
+This depends on your operating system for which we describe a couple +below.
+In general OpenGL needs X11 to be installed and the X Window Server +to be running. See FAQ 3.7: How do I run an IOCCC +winner that requires X11? for general information about X11.
+Once X11 is install and the X Window Server is running, one needs to +compile and link with the two libraries, GL and +GLU:
+cc ... -lGL -lGLU -L _location-where-X11-libs-are-installed_ -lX11
+``
+
+NOTE: The OpenGL development effort is being manageed by [vulkan.org](https://vulkan.org).
+We suggest you check out their resource for further information on OpenGL.
+
+
+#### Red Hat based Linux
+
+Execute the following as root or via sudo:
+
+```sh
+sudo dnf install glew-devel SDL2-devel SDL2_image-devel glm-devel freetype-develSee OpenGL +Programming/Installation/Linux for details.
+Older RHEL distributions might have to use “yum” instead of “dnf” in +the above command.
+In the past, macOS has come with OpenGL pre-installed. However as of +macOS 10.14, OpenGL +has been deprecated on macOS (in favor of Metal).
+As long as Apple continues to ship OpenGL pre-installed and it works, +you should be able to go. However in Apple drops support for OpenGL +later on, you might look to install OpenGL via Homebrew or MacPorts.
+Execute the following as root or via sudo:
+sudo apt-get install libglew-dev libsdl2-dev libsdl2-image-dev libglm-dev libfreetype6-devand then try make all again.
See OpenGL +Programming/Installation/Linux for details.
+Use your package manager to install the appropriate packages. Try the +search feature of the package manager to determine which packages you +need to install. Note that you might have to install both the library +and the developmental packages: one for compiling and one for linking / +running.
+Go to the Vulkan website and follow +their instructions for downloading, installing and using OpenGL.
+We recommend trying a method suitable for your environment first, if +possible.
+It is very likely in this case that the code was fixed to work for
+modern systems as part of the reworking of the website. If you have this
+problem in some entries you should look at the original code as in
+winner.orig.c or prog.orig.c.
+winner is the directory name. For instance, one of Landon’s
+favourite entries of all time is 1984/mullender and the winner there
+would be mullender. Sometimes the original is in an alt
+version like winner.alt.c or prog.alt.c. In
+fact it is advisable to look at the original code when reading the
+author’s (and sometimes authors’) remarks.
It is very likely in this case that the code was fixed to work for
+modern systems as part of the reworking of the website. If you have this
+problem in some entries you should look at the original code as in
+winner.orig.c or prog.orig.c.
+winner is the directory name. For instance, one of Landon’s
+favourite entries of all time is 1984/mullender and the winner there
+would be mullender. Sometimes the original is in an alt
+version like winner.alt.c or prog.alt.c. In
+fact it is advisable to look at the original code when reading the
+author’s (and sometimes authors’) remarks.
gets(3)
+changed to use fgets(3)?Some may wonder: “Doesn’t this tamper with the entry too much?”
+A fine line indeed has to be drawn here but it was decided that it is +worth it because of alarming warnings that can be displayed, in some +systems at runtime interspersed with the output of the program.
+For instance in macOS the entry 1990/tbr would output the warning in such +a way that caused confusing output for the entry, looking like:
+$ ./tbr
+$ warning: this program uses gets(), which is unsafe.
+# nothing here, what to do?In some cases changing the code to use fgets() is not so
+easy to fix and in one case at least there is an alternate version that
+has the fix instead due to a problem it creates (correct output but
+segfaults after the output in one of the forms of input).
In some cases it is not possible to fix or at least it is highly
+unlikely and so those have mainly not been touched except one that has
+had the buffer size increased (which could be done for others that are
+not possible to change to fgets() though this has not been
+done).
Some entries can be made to look almost identical to the original
+entry. For instance the fix to 1988/reddy required only a single
+#define be added.
In the future we, the judges, would prefer that entries use
+fgets() to prevent these problems.
An annoying fact is that for ‘“compatibility” reasons’
+fgets() retains the newline and gets() does
+not. As the Unix version 7 man page used to say:
BUGS
+
+The fgets(3) function retains the newline while gets(3) does not, all in the
+name of backward compatibility.
+We’re not sure how this is compatibility but either way it can cause +a problem and it is this that has complicated most of the fixes though +again some can look almost identical.
+We have set up make rules to easily do see what was changed in the
+IOCCC winner source. Using the Makefile in the winner
+directory, use one of the following make(1) rules:
The following make rules exist to make a difference:
make diff_orig_prog:
+entry.orig.c to
+entry.c).make make diff_alt_orig:
+entry.alt.c to entry.orig.c). If no
+alt code exists nothing will be shown.make diff_alt_prog:
+entry.alt.c to entry.c).make diff_orig_alt:
+entry.orig.c to entry.alt.c).make diff_prog_alt:
+entry.c to entry.alt.c).make diff_prog_orig:
+entry.c to entry.orig.c).For instance one of Landon’s all time favourite entries is 1984/mullender so the file names
+would be: mullender.orig.c, mullender.alt.c
+and mullender.c. For later years, it would be instead
+prog.orig.c, prog.alt.c and
+prog.c.
Note that you might see something like:
+make: [Makefile:170: diff_orig_prog] Error 1 (ignored)
+at the end of the output but this is completely normal if there are +differences.
+If the alt code is the same as the original, say with 1984/anonymous, then naturally +there is no point in running the rule and the same applies for all the +other rules but this system allows for easily seeing the diffs.
+As some examples we’ll first look at one that has really long lines
+which will make it harder to see what is different, 2001/anonymous. What you would do
+is cd 2001/anonymous and then do:
make diff_orig_progand then be really confused! :-)
+But for an entry like 1991/dds, you
+can see the differences much more easily. 1991/dds is a
+good example where it’s very simple to see what is different as it’s
+just a couple lines.
You might be quite surprised how little some entries had to be +changed and at the same time how much other entries had to be changed, +often with quite complex differences! In some cases if the line is +rather long, like the above mentioned one, it will be harder to see what +changed but in other cases like 1984/decot or 1986/wall it’s a lot easier.
+Well, at least it’s easier see the differences on a line-by-line +basis but maybe not what actually changed, especially since it’s easier +to know what was fixed when you have compiler errors :-) (though there +are, as noted, some examples where it’s quite easy to see the +differences).
+1991/dds is also a good example to
+see the alt difference very easily. To do that cd 1991/dds
+and then do:
make diff_alt_progand you’ll see a single line changed and very simply.
+colordiff installed it’s a lot easier to see
+the differencesTo use these rules but provide a different diff, for
+instance colordiff, just do:
make DIFF=colordiff diff_orig_prog # for orig to prog diff
+make DIFF=colordiff diff_alt_prog # for alt to prog diffObviously if you want to view the alt code or the orig code you can +just open the files as described above.
+If the entry has been fixed for modern systems and this fix required +modification to the code then invariably there will be entries where the +remarks of the author or authors are inconsistent with the original +code, the size of the code might be against rule 2 and other kinds of +inconsistencies might also be there.
+This is why we recommend that when you read the remarks, sometimes
+the judges’ remarks and always the author’s or authors’ remarks, you
+look at the original code. When the entry source code is called
+prog.c the original code is in prog.orig.c;
+otherwise it is winner.orig.c. For instance one of Landon’s
+all time favourite entries is 1984/mullender and the original
+code is in mullender.orig.c. In some
+cases, such as 1984/mullender, the original code is the
+same as the code as no changes were made (there is an alt version for
+systems that are not VAX-11/PDP-11, however).
See also FAQ 4.2: What was changed in an IOCCC +winner source code?
+Due to the fact that the original code has sometimes had to change +these files are the original winning entry or as close to as possible to +the original that we can find.
+The known bugs file, order by IOCCC years, +contains a list of known bugs & (mis)features. If you are looking +for an IOCCC winner to try and fix, this file is a good place to +start.
+See FAQ 5.2 for information on how to submit a +fix to an IOCCC winner. Before you consider trying to fix an IOCCC +winner, please check the known bugs file for the +IOCCC winner in question. Note that in several cases what you may have +discovered, while a (mis)feature is not considered a bug and should +not be fixed. In cases where the bug is known, the +entry’s known bugs file section may offer you +important fixing clues.
+We do not ‘maintain’ the contest winners as such. The code is made +available on an ‘AS IS’ basis. If you have a FIX for an entry, we +suggest that you submit your fixes in a GitHub pull +request as we welcome pull requests that have a minimal impact on +the entry while improving the portability, functionality, and/or +addressing known problems.
+If you do submit a pull request, we ask that each pull request +address just one IOCCC winner at a time.
+Note that just because you have a fix does not mean it’ll be +accepted. This might be because the author objects or it doesn’t fit in +some way or another. Of course if the entry does not work we’ll +certainly be more inclined to accept the fix. If it is accepted we’ll be +happy to credit you in the thanks +file. If you’re a previous winner we will happily link to your entries; +if you’re not we can link to your website if you wish.
+See FAQ 5.2 for information on how to submit a +fix to an IOCCC entry.
+If you see a problem with an IOCCC entry, first check the known bugs file. In some cases what you might think +of as a bug is instead a known feature. In some cases the bug is known, +but no fix has ever been submitted. In other cases you may have found a +new problem.
+If you do have a fix, and the known bugs file +does not recommend against fixing it, then please +consider opening a GitHub pull request +against the master branch of the ioccc-src/winner +repo.
+BTW: A problem is not limited to the code itself. +Fixing typos in files such as “README.md” files, fixing issues +in a “Makefile”, or otherwise correcting an IOCCC winner is +VERY MUCH WELCOME! Please use the same GitHub pull request +process against the master branch of the ioccc-src/winner +repo.
+NOTE: some of the issues in the bugs.md file +includes just missing files and we welcome these too!
+Please also help us fix typos and / or otherwise improve the +write-up of how IOCCC winning entries are presented!
+In any event we will happily add you to the thanks file for your help!
+And of course, an IOCCC winner may update their own entries (metadata +as well as source code and any extra files) by opening a GitHub pull request +against the master branch of the ioccc-src/winner +repo.
+Note that we’re much more inclined to accept an author’s fixes but +the judges have the final say in the matter.
+If you discover a problem with the IOCCC web site that is related to +a particular IOCCC winner, please see FAQ 5.1 for +information about reporting a bug in an IOCCC winner, and see FAQ 5.2 for information on how to submit a fix to an +IOCCC winner.
+If you discover a problem with the IOCCC web site (such as a broken +link, which may or may not be specific to a particular IOCCC winner) +that is not related to a particular IOCCC winner, the +best way you can help is to submit a fix to the IOCCC web site. See FAQ 5.4 for information on submitting fixes to the +IOCCC web site.
+If you do not have a IOCCC web site fix, and just wish to report a +general IOCCC web site problem, we ask that you first look at the IOCCC issues to +see if the problem has already been reported. If it has been reported, +feel free to add a comment to the issue. If you do not find an it has +been reported, then fee free to open a new IOCCC issue.
+For IOCCC web site problems that relate to a particular IOCCC winner, +please see FAQ 5.2 for information on how submit a +fix to an IOCCC winner.
+You may open a GitHub pull request +against the master branch of the ioccc-src/winner repo to +submit a fix.
+Most HTML files on the IOCCC web +site are built from markdown files. +If you see lines containing:
+!!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!!
+!!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!!
+!!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!!
+This means that the file is generated by a tool from the build-ioccc repo +using files found in the ioccc-src/winner +repo.
+XXX - the text below for this FAQ entry needs to be updated - XXX XXX +- the text needs to be synced with what tools be written will do - +XXX
+You will find a HTML comment of the form indicating which tool was +used to generate the contents:
+file: __some_file_path__ created by: __something__ version: __something__
+Along with HTML comments of the form indicating which files were used +by the tool to generate the HTML file;
+content source: __some_file_path__
+content source: __another_file_path__
+...
+Those content source: comment lines will give you a +clue to the content that is used by the tool to generate the DO +NOT MODIFY THIS FILE HTML file.
+When in doubt, consider opening up an IOCCC issue. See +FAQ 5.3 for information on opening up an IOCCC +issue.
+Authors of IOCCC winning entries are kept in JSON files of the +form:
+author/author_handle.json
+where author_handle is an author handle. See FAQ 6.5 for more information about an author +handles.
+The contents of these JSON files contain the best known information +about authors of IOCCC entries. See FAQ 6.6 for +information about the contents of these JSON file and how they are +used.
+You may update IOCCC author information in a
+author_handle.json file by opening a GitHub pull request
+against the master branch of the ioccc-src/winner
+repo.
We would appreciate if you try to fix the broken (the link goes +nowhere) or wrong (the link goes to something that clearly is not the +original intent) web link. If wish to fix such links, you may open a +GitHub pull request as described in FAQ 5.4. In +the case of dead links or invalid links it doesn’t matter if it’s a +specific winner or not; the procedure is the same: open a pull request +to fix the problem.
+As far as how to find the updated link you can try using the Internet Wayback Machine and see if +you can find the last non 4xx non 3xx page. Note, however, that just +because it redirects, does not mean it’s not valuable. Other times you +might find it with a web search.
+Some links were changed to more recent URLs by doing this exact same +thing. Some links, while they were a valid web page, no longer reach the +intended web page (for example when the domain is sold and the new +domain owner’s content no longer provides the content that was +originally intended .. and while the content of the web page may be +humorous to some, the original content may have literally gone “up in +smoke”).
+In cases where the original content is lost, try searching for it on +the Internet Wayback Machine. When +searching look back for dates that are around the year of given IOCCC +contest. If you do find the original content in Internet archive +history, please consider submitting a change to replace the link +accordingly.
+If there is no alternative that you can find you might want to remove
+the link instead by replacing the link with just phrase of text. For
+example, if the text in some README.md file was:
See the [author's description of the program](https://example.com) for more information.
+Assuming that the author’s description cannot be found in the Internet Wayback Machine archive, +then replace that text with:
+See the **author's description of the program** (sorry the content is no longer available) for more information.
+If you just wish to report the bad link issue, see FAQ 5.3.
+As entries have been fixed it is entirely possible that some of the +entries no longer fit within the year’s size restrictions. Invariably +the length of columns and/or number of rows have also changed.
+The winner.orig.c file contains the original source code
+that was subjected to rule 2 of the given IOCCC. You may also wish to
+see the /archive directory where you can find all
+the original winning entries as compressed tar files for a given
+year.
In some cases the entry may have abused rule 2 and declared an “abuse +of the rules” (although now blatant abuse of the rules to get around +rule 2 size limits is discouraged).
+Yes! Please see bugs.md for a list of known +bugs and/or issues of a variety of kinds.
+Note that just because an entry is not in the bugs file does not mean +there is not an issue and note that some issues are simply missing +files, dead URL(s) or something like that.
+We are not accepting mirror requests at this time, sorry. However you +are free to fork the IOCCC +winner repo. We do ask that your fork keep up to date with the +latest changes when possible.
+While IOCCC judges look favorably on most requests to use IOCCC +material, we request that you ask the IOCCC +judges first.
+Please send your request using the instructions on the contacting the IOCCC Judges page.
+As a precedent for first person plural, we +may sight Two-, +Three-, and Four-Atom Exchange Effects in bcc in 3He and the +co-authorship of F. D. C. +Willard as well as the APS +New Open Access Initiative.
+The number of IOCCC +judges has always been “> 1” such that IOCCC judges often prefer +to themselves in the plural, sometimes in the common plural, +sometimes in the first +person plural, there may be some who reject such a practice. +Therefore please consider that when you believe that just one of the IOCCC judges is in action, +you may consider that F. D. C. +Willard has been consulted, agreed, and has authorized the statement +thus allowing the in the +common plural to be used without offense.
+And while some might claim that F. D. C. +Willard died in 1982, we suggest that the Schrödinger’s +cat superposition may still be in effect and the 1982 report +of death was an exaggeration.
+p.s. Here is an image of F. D. C. Willard:
+ +An author_handle is string that refers to a given author
+and is unique to the IOCCC. Each author has exactly one
+author_handle.
For each author_handle, there will be a JSON file of the
+form:
author/author_handle.json
+See FAQ 6.6 for information about the contents +of these JSON file and how they are used.
+Because the author_handle is used to form a JSON
+filename, the string must be POSIX safe string. Furthermore, the
+author_handle must be an ASCII string that matches this
+regexp:
^[0-9A-Za-z][0-9A-Za-z_]*$
+Default author_handle’s do not have multiple consecutive
+_ (underscore) characters. Nevertheless, multiple
+consecutive _ (underscore) characters are allowed. Contest
+submitters who wish to override their default author_handle
+may do so.
The author_handle is derived from the name of the
+author. While there is a algorithm that maps the name of the author
+(which can contain any UTF-8 characters) into a default
+author_handle string, those who submit an entry to the
+IOCCC are free to choose a different author_handle string
+if they so desire.
An author who has won a previous IOCCC is encouraged to
+reuse their author_handle so that new winning entries can
+be associated with the same author.
For an anonymous author, their handle is one of these
+forms:
Anonymous_year
+or:
+Anonymous_year.digits
+The latter form is in case there are more than one anonymous author +in a given year.
+NOTE: even if the directory name is not anonymous the
+above rules apply as in in the case of 2005/anon.
Anonymous author_handle’s match this regexp:
Anonymous_[0-9][0-9][0-9][0-9][.0-9]*$
+See FAQ 5.5 for information about how to update +and/or correct IOCCC author information.
+TL:DR: The contents of these JSON files contain the +best known information about authors of IOCCC entries and is used to +help form HTML files as well to contact an author.
+The content of these JSON files are used by tools from the build-ioccc repo to
+help build HTML content for the official
+IOCCC web site. For example, the index.html file for
+each IOCCC winner contains selected information about the authors. Tools
+from the build-ioccc
+repo use the content of these JSON files to generate the
+index.html files for each IOCCC winning entry.
Moreover, should the IOCCC judges need to +contact an authors of a IOCCC winner, they will consult the contents of +the author’s JSON file for ways to contact them.
+Each author of an IOCCC winning entry has their own
+author_handle.json file of the form:
author/author_handle.json
+where author_handle is an author handle. See FAQ 6.5 for more information about an author +handles.
+The syntax of a author_handle.json follows the
+So-called JSON spec. See json_README.md
+for information on the So-called JSON spec.
A good way to understand the JSON file contents of a
+author_handle.json file is to look at an example, the
+author_handle.json file for Yusuke Endoh:
author/Yusuke_Endoh.json
+As of Thu Nov 30 23:51:12 UTC 2023, the contents was as +follows:
+{
+ "no_comment" : "mandatory comment: because comments were removed from the original JSON spec",
+ "author_JSON_format_version" : "1.0 2023-06-10",
+ "author_handle" : "Yusuke_Endoh",
+ "full_name" : "Yusuke Endoh",
+ "sort_word" : "endoh",
+ "location_code" : "JP",
+ "location_name" : "Japan",
+ "email" : "mame@ruby-lang.org",
+ "url" : "https://mametter.hatenablog.com",
+ "alt_url" : null,
+ "deprecated_twitter_handle" : null,
+ "mastodon" : "@mame@ruby.social",
+ "mastodon_url" : "https://ruby.social/@mame",
+ "github" : "@mame",
+ "affiliation" : null,
+ "winning_entry_set" : [
+ { "entry_id" : "2012_endoh1" },
+ { "entry_id" : "2012_endoh2" },
+ { "entry_id" : "2013_endoh1" },
+ { "entry_id" : "2013_endoh2" },
+ { "entry_id" : "2013_endoh3" },
+ { "entry_id" : "2013_endoh4" },
+ { "entry_id" : "2014_endoh1" },
+ { "entry_id" : "2014_endoh2" },
+ { "entry_id" : "2015_endoh1" },
+ { "entry_id" : "2015_endoh2" },
+ { "entry_id" : "2015_endoh3" },
+ { "entry_id" : "2015_endoh4" },
+ { "entry_id" : "2018_endoh1" },
+ { "entry_id" : "2018_endoh2" },
+ { "entry_id" : "2019_endoh" },
+ { "entry_id" : "2020_endoh1" },
+ { "entry_id" : "2020_endoh2" },
+ { "entry_id" : "2020_endoh3" }
+ ]
+}We now will walk thru the above JSON document looking at various JSON +members:
+ "no_comment" : "mandatory comment: because comments were removed from the original JSON spec",Because the authors of the so-called JSON spec removed the ability to +use comments in JSON (for reason(s) that seem to be less than credible), +the IOCCC mandates this JSON member be present in all IOCCC +related JSON files.
+There MUST be one and only one
+no_comment JSON member and the JSON value
+MUST be the exact JSON string as shown
+above.
"author_JSON_format_version" : "1.0 2023-06-10",This JSON member holds the format version of the
+author_handle.json JSON file.
There MUST be one and only one
+author_JSON_format_version JSON member and the
+JSON value MUST be a JSON string.
This is NOT the version of the contents! When
+updating an author_handle.json JSON file, DO NOT
+MODIFY author_JSON_format_version! As of Thu Nov 30
+23:51:12 UTC 2023, the JSON value MUST be
+“1.0 2023-06-10”.
The author_JSON_format_version would only changed when the +overall format of the these files is modified: and then only those who +maintain the official IOCCC web site +would be the one to do this in conjunction with changes to the build-ioccc +repo.
+ "author_handle" : "Yusuke_Endoh",This JSON member holds the author handle of the author.
+There MUST be one and only one
+author_handle JSON member and the JSON
+value MUST be a JSON string that is also
+a value author handle.
See FAQ 6.5 for more information about an +author handles.
+Normally the author_handle JSON value should
+NOT be changed unless there is a strong reason
+to do so. If the JSON value changes, then all of the
+.entry.json files for all of this authors winning IOCCC
+entries should also be changed. The author_handle JSON
+value must match the basename (without the leading path and without
+the trailing .json) of the author_handle.json
+file. So a change of author_handle JSON value would
+also require the author_handle.json file to also be
+renamed.
"full_name" : "Yusuke Endoh",This JSON member holds the full name of the author.
+There MUST be one and only one
+full_name JSON member and the JSON value
+MUST be a JSON string.
The full name of an author may use non-ASCII characters so long as +the full name is properly encoded as a JSON string.
+ "sort_word" : "endoh",This JSON member holds the string that will be used to sort +the author.
+There MUST be one and only one
+sort_word JSON member and the JSON value
+MUST be a JSON string. Moreover the string
+MUST be a lower case ASCII alphanumeric string that
+starts with a lower case ASCII letter.
The JSON value is used, for example, to place a reference to
+the author in the /authors.html file.
Normally the sort_word JSON member JSON
+value is the last name of the author, translated into lower case
+ASCII alphanumeric string that starts with a lower case ASCII letter. If
+the author wishes to be found in the /authors.html file
+under a different string, such as if they wish to be listed under their
+first name or their username, then they may change this accordingly.
"location_code" : "JP",This JSON member holds the string that is the ISO +3166-1 alpha-2 code of the author’s location or country.
+There MUST be one and only one
+location_code JSON member and the JSON
+value MUST be a JSON string. Moreover the
+string MUST be 2 character UPPER case ASCII alphabetic
+string that is NOT an Unassigned ISO
+3166-1 alpha-2 code value (not a 2 character symbol with a gray
+background on that Wikipedia table)
The soup/location tool from the mkiocccentry repo,
+when run without arguments, will print the ISO 3166-1 alpha-2 codes that
+permitted, along with the location name.
We use the term “location” (and not “country”) because some of the +ISO 3166-1 alpha-2 codes belong to locations that are not technically a +country, such as “Antarctica” or a User-assigned code.
+If the author wishes to not specify a location, they should select +XX.
+ "location_name" : "Japan",This JSON member holds the string that is the canonical
+location name as reported by the soup/location tool from
+the mkiocccentry
+repo, when given the location code as
+specified above.
There MUST be one and only one
+location_code JSON member and the JSON
+value MUST be a JSON string. Moreover the
+string MUST be what the soup/location tool
+prints when given the location_code as an argument.
We use the term “location” (and not “country”) because some of the +ISO 3166-1 alpha-2 codes belong to locations that are not technically a +country, such as “Antarctica” or a User-assigned code.
+Often a given location may have a long official name, and multiple +common names. For names associated with the location DE +might be:
+Germany
+Federal Republic of Germany
+Bundesrepublik Deutschland
+Deutschland
+...
+The “location_name” printed by the soup/location tool is
+often a short, common string that is sometimes called the formal
+location name for the given ISO 3166 code. Thus in the above example for
+DE, the location name of Germany is used.
If the author wishes to not specify a location, they should select +Anonymous location.
+ "email" : "mame@ruby-lang.org",This JSON member holds the email address of the author, or +is the value null.
+There MUST be one and only one email
+JSON member and the JSON value MUST
+be a JSON string or it MUST be a JSON
+null.
If the author wishes to not specify an email address, or if the email +address is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "email" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "url" : "https://mametter.hatenablog.com",This JSON member holds the URL of the author’s home +page.
+There MUST be one and only one url
+JSON member and the JSON value MUST
+be a JSON string or it MUST be a JSON
+null.
If the author wishes to not specify an email address, or if the URL +is unknown, they should use the JSON null as the JSON +value of this JSON member. For example:
+ "url" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "alt_url" : null,This JSON member holds an alternate or 2nd URL a home page +for the author.
+There MUST be one and only one url
+JSON member and the JSON value MUST
+be a JSON string or it MUST be a JSON
+null.
In some cases the author may wish to record a special URL for their +IOCCC entry, or a 2nd URL such as a work or school or personal home +page. For example, Cody as of Thu Nov 30 23:51:12 UTC 2023 +used:
+ "alt_url" : "https://ioccc.xexyl.net",If the author wishes to not specify an email address, or if the +alternate URL is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "url" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+This JSON member used to hold the twitter handle of the +author.
+There MUST be one and only one
+deprecated_twitter_handle JSON member and the
+JSON value MUST be a JSON string or
+it MUST be a JSON null.
The IOCCC no longer is associated with twitter (or whatever someone
+chooses to call it), and so the deprecated_twitter_handle
+is no longer used. A JSON value that is not a
+JSON null is kept for only historic reasons. For example,
+Anthony C. Howe once used:
"deprecated_twitter_handle" : "@SirWumpus",If the author wishes to not specify an twitter handle, or if the +twitter handle is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "deprecated_twitter_handle" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "mastodon" : "@mame@ruby.social",This JSON member holds the Mastodon +social network handle of the author.
+There MUST be one and only one mastodon
+JSON member and the JSON value MUST
+be a JSON string or it MUST be a JSON
+null. The JSON string just be a valid Mastodon handle. In
+particular is must start with an at sign (@_), followed by the Mastodon username, followed
+by a 2nd sign (@_), followed by the Mastodon server instance used
+by the author.
For more information in Mastodon, see the Mastodon help guide. See the “Mastodon +Address” section of that page in particular.
+The IOCCC Mastodon handle is:
+@ioccc@fosstodon.orgThe IOCCC uses the Mastodon social network for announcements such as +the opening and closing of a new IOCCC, changes to the IOCCC web site, +updates during the judging process, and when new IOCCC entries are +selected. We recommend you follow us on Mastodon.
+If the author wishes to not specify an Mastodon handle, or if the +Mastodon handle is unknown, they should use the JSON null as +the JSON value of this JSON member. For example:
+ "mastodon" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "mastodon_url" : "https://ruby.social/@mame",This JSON member holds the URL of the author’s Mastodon +page.
+There MUST be one and only one
+mastodon_url JSON member and the JSON
+value MUST be a JSON string or it
+MUST be a JSON null. The JSON string
+just be a valid URL. If the mastodon handle is a JSON
+null, them the mastodon_url MUST be a
+JSON null. If the mastodon handle is a JSON
+string, then the mastodon_url MUST be
+a JSON string.
The mastodon_url is just a translation of the above
+mentioned mastodon handle. For example, if the
+Mastodon handle is:
@user@server.domain
+Then the mastodon_url would be:
https://server.domain/@user
+If the author wishes to not specify an Mastodon URL, or if the +Mastodon URL is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "mastodon_url" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "github" : "@mame",This JSON member holds the GitHub handle of the author.
+There MUST be one and only one github
+JSON member and the JSON value MUST
+be a JSON string or it MUST be a JSON
+null. The github JSON string
+MUST start with an at sign (_@_) and MUST be a valid GitHub
+username.
The IOCCC uses GitHub to hold the official winner repo of the +IOCCC, and hosts official IOCCC web +site on GitHub pages.
+The IOCCC GitHub handle is:
+@ioccc-src
+If the author wishes to not specify an GitHub handle, or if the +GitHub handle is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "github" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "affiliation" : null,This JSON member holds the affiliation of the author.
+There MUST be one and only one
+affiliation JSON member and the JSON
+value MUST be a JSON string or it
+MUST be a JSON null.
An affiliation might be the name of a school, university, company, or +organization. It is recommended that the affiliation JSON +string be the formal affiliation name. For example, the affiliation +for the IOCCC would be:
+The International Obfuscared C Code Contest
+If the author wishes to not specify an affiliation, or if the +affiliation is unknown, they should use the JSON null as the +JSON value of this JSON member. For example:
+ "affiliation" : null,NOTE: The JSON null is NOT enclosed in +quotes!
+ "winning_entry_set" : [
+ { "entry_id" : "2012_endoh1" },
+ { "entry_id" : "2012_endoh2" },
+ { "entry_id" : "2013_endoh1" },
+...
+ { "entry_id" : "2020_endoh1" },
+ { "entry_id" : "2020_endoh2" },
+ { "entry_id" : "2020_endoh3" }
+ ]The winning_entry_set JSON member holds
+JSON array containing one or more entry_id _JSON
+member_s.
There MUST be one and only one
+winning_entry_set and the JSON value
+MUST be a non-empty JSON array. Each value in
+that JSON array MUST must contain a JSON
+member whose JSON name MUST be
+“entry_id” and those JSON value is a valid winner
+ID.
Due to the nature of the So-called JSON spec, the last value
+of the winning_entry_set JSON array cannot end in
+a comma (,).
See FAQ 6.7 for information about winner +ids.
+See FAQ 5.5 for information about how to update +and/or correct IOCCC author information.
+A entry_id is a string that identifies a winning entry
+of the IOCCC.
A entry_id is a 4-digit year, followed by an underscore,
+followed by a directory name.
For example, the entry_id associated with Cody Boone
+Ferguson’s 2nd winning IOCCC entry of 2020 is found under the following
+directory:
2020/ferguson2
+The entry_id for that winning entry is:
2020_ferguson2
+The .top file resides at the top directory. This +file contains the complete list of IOCCC years.
+Under each IOCCC year. one will find a .year file. These
+files contain directory paths from the top directory, of the IOCCC
+winner directories for a given year. For example, see the 1984/.year file.
Under each IOCCC winner directory, you will find a .path
+file. These files contain the directory path from the top directory. For
+example see 1984/anonymous/.path.
The .top, .year and .path files are generated from the top level +Makefile, by:
+make genpath
+ 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 entries. We are pleased to note the many contributions, +made since 2021 Jan 01, on a winner by winner +basis.
+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()).
Later Cody corrected the mistake where the
+"hello, world!" string was on one line rather than two
+lines which the author told us (Landon) that they liked. Thus now it is
+like the original where the first line ends with "hell\ and
+the second line starts with o, world!\n".
By request, the original code is provided as anonymous.alt.c so that one +can look at it and the famous tattoo which we also include here:
+
+
+…which was done in 2005 by Thomas +Scovell.
+Cody fixed this to not require
+-traditional-cpp which some compilers like clang do not
+support. Fixing -traditional-cpp is, as noted later on,
+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 most are not used; they are left in just to
+make it look more like the original entry. Nevertheless those 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 also bringing back
+double (x1, y1) b; and even this funny code that could be
+kept in:
#define char k['a']
+char x {sizeof(
+ double(%s,%D)(*)())This does mean that there cannot be a second arg to
+main() as clang requires that to be a char **
+and the char redefined would not allow this. Some versions
+of clang say that main() must have either 0, 2 or 3 args
+but these versions do not object to 1 arg. However as the
+char macro seems more obscure and it is possible that a new
+version of clang will be even more strict the int i
+parameter in main() was moved to be inside
+main(), set to non-zero (setting i to 0 will
+not work). This way main() has zero args.
Observe how on line 29 there is a call to main() which
+does pass in a parameter. It has never been observed to be an error to
+pass in too many parameters to a function (main() or
+otherwise - it warns with other functions but does not appear to with
+main()) but only that main() itself has a
+certain number of args (in some versions) and that the first arg is an
+int and the others are char **s. This is why
+the arg was removed and the call to main() was not updated
+beyond what had to be done to fix it for compilers that do not support
+-traditional-cpp.
If the ANSI C committee or a new version of clang messes this up +(both of which seems possible) it is easy to fix but it is hoped that +this won’t happen.
+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:
+cd 1984/decot ; make diff_orig_progCody also fixed this to not crash when no arg is specified. Note that +if the arg is not a positive number it will not do anything useful or +anything at all. This was fixed on 30 October 2023 after the bug status +was changed from INABIAF (it’s not a bug it’s a feature) to bug.
+Cody provided an alternate version, an +improved version of the judges, so that everyone can enjoy it with +systems that are not VAX/PDP. It moves at approximately the same speed +as the original did. We also refer you to the FAQ +as there are some winning entries that also let one enjoy it (which +through trial and error was how the right speed was discovered) - with +more to them of course! The difference between the original is that it +will start over after it times out but that might not happen with the +original (might need you to press a key though this is not known for +sure).
+Cody also added the gentab.c
+file, fixed to compile (and work, though see bugs.md) 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.
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.
Cody, out of abundance of caution, added a second
+arg to main() because some versions of clang object to the
+number of args of main(), saying that it must be 0, 2 or 3.
+The version this has been observed in does not actually object to 1 arg
+but it is entirely possible that this changes so a second arg (that’s
+not needed and is unused) has been added just in case.
Cody also 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.
+Cody also added the try.sh script
+(which calls primes.sh whether primes(6) is
+installed or not but it only does it once with the default value).
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.
+Cody also provided the try.alt.sh script.
+Cody added the alt code which allows one to +resize the maze and he also added the try.alt.sh script that randomly +selects sizes (five times) and compiles and runs it. After the five runs +it prompts you to enter a number, in an infinite loop, exiting if any +non-digits are in input (this includes negative numbers which in the +code actually sets it back to 39, the default).
+Cody fixed this very twisted entry to
+not require -traditional-cpp. Fixing
+-traditional-cpp is, as noted later on, 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 (alternatively, see below explanation)!
Later on Cody improved the fix so that it looks much more like the original entry. He did this +several more times and it’s as close to the original as one can get +without causing compiler errors.
+To get this to all work the following changes were made. If you +really want to understand this Cody provides the following. First run +the following command from the directory:
+make diff_orig_progand then read the following (you might also wish to look at the code +in an editor with syntax highlighting):
+Because of the macros C and V in the
+original code, the args to main() were actually not what
+they appear: the only arg that existed in main() was
+Manual. Thus it now looks like:
main(
+/* C program. (If you don't
+ * understand it look it
+ * up.) (In the C*/ Manual)
+{The macros C and V were changed to
+lower case. This is because it felt like the C=" ..’ part
+in subr() would be better to be upper case as it talks
+about the language. Also in the second alternate version (the first
+being the original code) which is in case a new version of clang ever
+objects to only one arg in main() (which is not out of the
+realm of possibility), main() can have C as
+argc to main() so it would read like it once
+did: C manual albeit with a , separating the
+two. The second alternate
+version is compiled in case the first does not. Originally the macros
+were kept the same and the C in subr() was
+c. It feels better (in some ways) to make it so that the
+C for the language is upper case though, and since it
+actually translated to /**/ it can just be c,
+not C. The V was changed to v to
+be the same case as c.
The code:
+C="Lint says "argument Manual isn't used." What's that
+mean?"; while (write((read(C_C('"'-'/*"'/*"*/))?__:__-_+
+'\b'b'\b'|((_-52)%('\b'b'\b'+C_C_('\t'b'\n'))+1),1),&_,1));had to be changed to:
+C="Lint says \"argument Manual isn't used.\" What's that\
+mean?"; while (write((read(('"'-'/*"'))?__:__-_+
+'\b'b'\b'|((_-52)%('\b'b'\b'+C_C_('\t'b'\n'))+1),1),&_,1));because of the missing " at the end of the line and
+because _|_ is not a function call.
The \" had to be done to keep the "s there
+though the string could be broken up into multiple " pairs
+instead; that seemed less authentic, however. Notice how the last line
+of code in that function is the same as before and actually that there
+aren’t that many changes in the function at all!
Notice also that the parameter C remained the same due
+to the macro C rename to c.
The chars _ and __ in
+main() were copied to file scope so that
+subr() could actually compile but this does not affect the
+ones in main(). Why is this? You tell us!
The code in main() is where there are significant
+changes, changing from:
while (read(0,&__,1) & write((_=(_=C_C_(__),C)),
+_C_,1)) _=C-V+subr(&V);to:
+while (read(0,&__,1) & write((_=(_=C_C_(__),
+V))?__:__-_+'\b'b'\b'|((_-52)%('\b'b'\b'+~
+' '&'\t'b'\n')+1),1),&_,1))_=c-v+subr(&v));Note how numerous of the macros (though two changed in case) can
+still be used but some cannot be. Can you figure out why? Why too is it
+that the subr() function is called but it appears that some
+of the code in that function is also in main() in the
+while condition? What happens if you remove it from
+main()? What happens if you remove it from
+subr() or don’t even bother calling
+subr()?
Additional code was added in case the fix cannot be compiled by some
+compilers should they object to main() having only one arg.
+This version will automatically be compiled if the entry fails to
+compile for some reason but one can compile it manually as
+make alt in which case it’ll be compiled as
+sicherman.alt (if it’s done because sicherman.c fails to compile it
+will be built as sicherman as part of the
+sicherman rule).
Cody also added the try.sh and +try.alt.sh scripts.
+Cody made the C file executable so one does not
+have to do sh ./applin.c or ./applin; they can
+do either ./applin.c or ./applin.
Cody made this use fgets().
Cody also added the try.sh script
+which also feeds to the program the added input.txt
+file.
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.
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 two different compilers. This is a brief summary but much more is +explained in the compilers.md +file, 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 wouldn’t work. And by ‘not working’ it +did not work in more than one way and for different platforms it had +other problems as well.
+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 compilers.md file to see how odd +this problem was and what Cody did to fix it, if nothing else but for +entertainment!
+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.
Cody restored the original entry which was a +single line. The code being longer (in 1986 a one liner could be longer) +was split to three lines to avoid problems with news and mail but as it +was the ‘Best one liner’ it is now one line.
+Cody also added the stein.sh +script which runs the two commands that we suggest in order to get it to +show clean output.
+Cody fixed this so that it does not require
+-traditional-cpp. This took a fair bit of tinkering as this
+entry very twisted; 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, as well as below.
Yusuke originally patched this to use
+strdup() on two strings and this let it work with gcc but
+it still required -traditional-cpp.
If you’d like to see the difference between the version that requires
+-traditional-cpp and the fixed version, try:
cd 1986/wall ; make diff_orig_progSome of the changes required:
+Instead of using the c_, defined as
+c_(cc)c cc=, like:
c_(+)o
+
+ /* ... */
+
+ :c_(+)' '-1;
+ }}c_(&)'z'+5;
+use:
+ :c +=o[c&__LINE__-007];
+
+ /* ... */
+
+ :c+=' '-1;
+ }}c&='z'+5;
+Observe however that this macro is still used in the code like:
+ main(;c_(=(*cc);*cc++)c,for);Instead of code like:
+ main(0xb+(c>>5),C_(s))
+ _'\v'
+ :__ _'\f':
+ main(c,C_(s));
+use instead:
+ main(;c_(=(*cc);*cc++)c,for);
+ #define _O(s)s
+ switch(0xb+(c>>5)){
+ _'\v'
+ :__ _'\f':
+ switch(c){;The macro:
+ #define C_(sand)_O(sand)witch
+could not be used like:
+ C_(s));_
+to create:
+ switch);_
+and neither could the macro:
+ #define O_(O)_O(O)stem(ccc(
+be used like:
+ :O_(sy)";kkt -oa, dijszdijs QQ"))_C
+to create:
+ :system(ccc(";kkt -oa, dijszdijs QQ"));returnAnd of course as noted two strings had to be
+strdup()d.
There might have been other changes as well.
+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.
Cody also added the try.sh script +which shows how the program works but also how the folded code can +recreate 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.
Cody added the try.sh script and the C file goto.c and the text file goto.txt for demonstration purposes. +Notice that the program is case sensitive which running the program on +the text file demonstrates.
+Cody added back the documented checks for invalid
+input which no longer worked and instead resulted in either accepting
+the level, whether or not it was a number or out of range (see below on
+range). For the move it entered an infinite loop, prompting the player
+with "You:" but not letting the player input anything so
+that the screen was flooded and the game could not be played.
For both the level and move it did a scanf() with a
+%d specifier but this resulted in, if invalid input, either
+proceeding (for the level), presumably incorrectly done as it might not
+even be a number (see below) or printing "You:" in an
+infinite loop, expecting input again but not letting the player input
+anything, both as noted above.
The fix is that now the specifier is a %2s for a
+char A[100] (yes 100 is overkill; there’s no good reason
+for it here: it was just arbitrarily selected).
For the level if atoi(A)>10||<0 (see next part) or
+!isdigit(*A) it goes back and prompts again. The level is
+checked for >=0||<=10, perhaps incorrectly or perhaps
+not, because in the code that variable is checked for
+<10 and if that is the case it is incremented by 2. I do
+not know the rules of the game and neither do I know what the author had
+in mind so I chosen 10 as the maximum.
As for the move the do..while loop works properly now
+that it does it in two steps (scanf("%2s", A); m=atoi(A);)
+so there’s no need to check the value explicitly, again. Thus it will
+prompt until valid input is entered, but only showing
+"You:" once per prompting.
In the case of the level prior to prompting for the level it does a
+*A='\0'; and in the case of the move it does it after the
+m=atoi(A);. This is done this way because the check for the
+value of the level (atoi(A)) is done in the
+if() that also checks for a digit (though it does
+(u=atoi(A))>10||u<0 first, thus checking the level,
+and || !isdigit(*A)). Of course since - is not
+a digit the <0 is superfluous but it’s done anyway. If
+that if is 1 then it immediately goes back to the prompting
+of the level.
But for the move it can happen after due to the fact the condition of
+the do..while loop will take care of things.
Cody also 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 size constraints of the contest).
Cody made this use fgets(3).
Cody also added the try.sh script.
+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.
Cody fixed this twisted entry (as we called it
+:-) ) for modern compilers, including making it no longer require
+-traditional-cpp. Fixing -traditional-cpp is,
+as noted later on, very complicated, but we encourage you to compare the
+fix from the original entry. There was another problem to resolve as
+well, however.
First of all, as noted above, 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.
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.
Cody also provided the try.sh +script.
+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.
Cody added the alt code which is code that we +suggested at the time of publication, in the remarks, to help understand +the entry, and for fun.
+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 garbage and then crashed.
After fixing it for clang by changing the very main()
+(in fact it called itself up to 12 times!) to call the new function
+pain() (chosen because it’s a pain that clang requires
+these args to be char ** :-), which is just as recursive,
+with the correct args it now works with both gcc and clang.
Later Cody improved the fix to make it look a bit more like the
+original, using K&R style functions, and trying to match the format
+as best as possible of what main() used to look like but
+without the full body that cannot exist as it once did. The format of
+pain() is exactly like how main() was as it’s
+the same code. Additionally, main() returns
+!pain(...) like main() used to do to itself
+and pain() does now.
Cody made this use fgets(3).
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 entry too +much. It would work but it would not show the same creativity and +cleverness.
+The original entry 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! :-)
+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.
+Cody added the try.sh script to show the magic of the +entry as seeing the code with the result at once is far more +beautiful.
+Cody also changed the ints to be float as
+that’s what they are printed as: not strictly necessary but nonetheless
+more correct, even if not warned against.
Cody got this to work with modern systems. The
+main issues were that an #include had to be added along
+with fixing the path (due to . not being in
+$PATH) to files referred to in the code. The path problem
+was also fixed in fubar.sh.
A strange problem occurred where if one made modifications to the C +file it might end up failing to work even after changing it back. This +was resolved by:
+--- i/1989/fubar/fubar.sh
++++ w/1989/fubar/fubar.sh
+@@ -7,13 +7,12 @@ if [[ $# -ne 1 ]]; then
+ exit 1
+ fi
+
+ # run/compile it
+ rm -f ouroboros.c x1 x
+-ex - <<EOF
+-r fubar.c
++ex fubar.c <<EOF
+ 8,9j
+ w ouroboros.c
+ EOF
+ chmod +x ouroboros.cCody also ‘modernised’ the script to use bash and fixed
+for ShellCheck. The if [ .. ] was changed in the C code as
+well as the script.
Cody also added the try.sh +script.
+To prevent annoying output to /dev/tty we changed the
+code to simulate the output via strings(1) but Cody removed the ill-famed
+useless use of cat to shut ShellCheck up. Why is
+it ill-famed? Because there is no such thing as a useless cat, that’s
+why! For instance, the fact they even exist is proof that the Earth is
+NOT flat: because if it was they would have pushed
+everything off it by now! :-) They’re also a great joy to all
+ailurophiles and yes they most certainly do have a personality and they
+can be very sociable.
Whilst he was at it, Cody made it so that one need not run the alt +script or alt code directly, to match that of the main entry. As we +simulate the functionality anyway, and since one may still run the code +or the script (for the original entry and the alt code) anyway, it works +out well.
+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?
+Cody also provided the try.sh script
+and the supplementary files try.txt,
+fib.lisp and chocolate_cake.lisp. The
+try.txt comes from the author and the fib.lisp
+comes from Yusuke. Cody wrote the script and
+offered us some chocolate cake :-) See README.md for details on how to
+use the script.
Cody fixed an infinite loop where the program
+would print the same thing over and over again, flooding the screen. The
+problem is that there was a for loop that by necessity had
+to not have an increment stage but the pointer only got updated in the
+if path (in the loop itself).
Cody also provided the try.sh +script which runs the program four times on three files to show the +different output. It doesn’t run the program on each file four times in +a row but rather does it on each file and starts over, doing it four +times, to help with hopefully allowing different output.
+Cody also provided an alternate +version based on the author’s remarks and the try.alt.sh script that uses the alt +code, allowing one to configure the alt build. See the README.md for +details. The fix described above was fixed in this version too, after it +was discovered and fixed.
+Cody fixed a segfault under macOS that prevented
+it from working. 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 :-)
Cody also provided the alternate +version which has the trace function that the author included but +commented out. See the README.md for details.
+Yusuke Endoh fixed this to compile under modern +systems. To see the changes made, try:
+cd 1989/robison ; make diff_orig_prog(It adds the C token pasting operator ## instead of
+/**/.)
Cody also added the try.sh +script.
+Cody and Yusuke fixed this +entry: Yusuke fixed this to compile with gcc and Cody fixed it for clang +and made some other fixes as well.
+To get it to work with clang the variable a had to not
+be the third argument to main() but instead be a variable
+in main().
Cody also fixed a segfault and made it so the that the high score
+file would work (it was not even being created but it was supposed to
+be). This was happening due to a file pointer being declared as a
+long and more significantly is the command in
+popen(3) was not correct.
Another problem Cody fixed was that the terminal was left in an
+insane state where you could not type ‘u’ and echo was
+completely disabled.
Cody later on fixed the alt version, provided by the author, so that
+it would compile with clang, not abort (with an alarm), would have the
+tetriminos fall, it would write to the high score file (the command to
+popen(3) was incorrect here too but as can be seen it
+differs from the submitted version), could use stty
+properly (and thus turn on echo again - it did not work because it was
+in the popen(3) call rather than using
+system(3)), a couple compiler errors and various other
+things, so that now the alt version, which is better, can be used.
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 :-) )
+Cody fixed this for clang, except that two
+versions generated by the program cannot be compiled by clang due to
+inherent defects in the compiler and how the entry works. This is an
+incredibly hard one to fix for clang whilst still being
+compilable with gcc (and gcc can compile every generated version with
+the fix) and even if one fixes it to compile with clang it does not mean
+that any other version will compile! It is, however, possible to get
+clang to work with two versions generated, ver0 and
+ver1, though ver0 is actually just the main
+entry (but still generated by the program itself).
Unfortunately due to the way this entry works if it is even possible +to get all versions to compile with clang it will take heavy +modifications to get all versions to compile with clang. Cody almost got +it and knows how it functions but even getting it just about there +caused compilation errors in gcc so it might just not be possible.
+The way it was fixed might be hard to see and describe but this is an
+attempt. Because main()’s args were all ints,
+main() had to call a new function which is allowed to have
+args as int (instead of main()’s args being
+int and the rest being char **) but this is not as straight
+forward as it is for other entries (if you look at the code you might
+see what is meant; the function called is pain()).
The args of main() had to be set to the right type but
+only three args, not four, even though the original
+program has four args. This is because not all versions of clang support
+four args and that is one of the issues with version 2 and 3 as it
+generates main() to have four args and the wrong type, all
+ints.
In the call to the new function, pain(), from
+main(), one of the char **s is used twice,
+once as argc with bitwise AND with 2, naturally first being
+cast to an int ((int)ABBA&2), and once as
+a char **, the fourth arg to pain() (yes even
+though pain() takes all ints).
The argc,, meanwhile, tang, is used once and the second
+arg, char **gnat is used once (observe how
+tang is gnat spelt backwards as this is one of
+the things that makes this a masterpiece and very hard if not impossible
+to fix completely). Fortunately it is not actually necessary to use all
+four args (of main()) in the call which might or might not
+be surprising, especially as it uses one of the args, a
+char **, instead of an int (through casts),
+twice rather than just passing in for the fourth arg (the fourth arg
+passed in is the third arg to main()).
This program heavily uses recursion and depending on the number of +args it will print out output normally, ROT13 it, show it backwards or +both. Along with the ROT13 and reversed output of the code, it is the +comments that create the names and the rest of the +code!: sometimes it is the word backwards, other times it is +the ROT13 of it and other times it is both, both for comments and +otherwise. Trying to change comments can be very difficult though it was +done when clang could almost compile every version if not actually +compile all versions. Unfortunately when this was done it caused other +systems to have additional compilation errors so it seems highly +unlikely that version 2 and 3 can work for clang (versions 0 and 1 +can).
+Despite the risks of changing names this was done and indeed by +necessity. Comments might have been changed but it is no longer known if +that happened only in the working on version 2 and 3 or if in the fix +for clang as well as version 0 and 1.
+To make use of this several scripts were added by Cody.
+The compile.sh script that +removes the generated code, rebuilds the program and regenerates the +other code and then compiles it will work for compilers like gcc and one +can then use the try.sh script to see +example input and output.
+The compile.sh script allows one to specify the compiler
+with the CC environmental variable; see the README.md for
+details.
Cody also added an alternate
+version which allows Turbo-C and MSC to compile this code, based on
+the authors’ remarks, except that Cody did not change the
+" #Q" string as that showed worse looking output instead of
+improved output though he has no way to test the compilers in question
+(i.e. it was only tested in the original entry). YMMV.
Although this is appreciated we agree with him that no
+one very few users here will need it! :-)
Cody also made the code look more like the original, removing the
+int from the variables, adding instead
+-Wno-implicit-int. The newline added by the judges was
+retained.
Yusuke got this to work in modern systems (it +previously resulted in a bus error).
+Cody made this use fgets(3).
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 char * used
+for file I/O to be a proper FILE * and fixed a typo in LANDER.BAS.
Cody also made this use fgets(3).
Cody fixed this for modern systems. There were +two problems to be resolved.
+One can no longer do:
+#define d define
+
+#d b12(x) 12 x
+
+/* etc. */so the use of #d is now instead #define
+(the macro was originally deleted but later Cody added it back to make
+it more like the original).
The second problem was suggested by the judges at the time of +judging, to do with if the C preprocessor botches single quotes in cpp +expansion.
+Cody also added the try.sh script.
+Cody fixed the script to work properly in modern
+environments including writing to and extracting from
+stdout and relying on the exit code in the commands to
+allow for && ....
He also changed the perror(3) call to
+fprintf(3) because in macOS when errno is 0 it shows what
+looks like an error.
He added the try.sh to run the +commands that we suggested at the time.
+NOTE: as btoa is not common we used a ruby script from
+Yusuke but with a minor fix applied by Cody that
+made the program just show oops twice from invalid input
+but which now works.
Cody added the alt
+code which was suggested by the judges in the case that your
+compiler cannot compile X=g()... but it actually does
+something else and is recommended by the author as well.
Yusuke suggested -ansi to get the
+entry to compile due to trigraphs and Cody suggested
+-trigraphs. Both work but we used Yusuke’s idea.
Cody added the try.sh script to +show exactly what the entry does.
+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(3) 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.
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.
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).
BTW: why can’t the fix:
+if (a[1]==NULL||a[2]==NULL||a[3]==NULL||a[4]==NULL||a[5]==NULL) return 1;be changed to just test the value of A when
+a is argv and A is argc?
Cody also changed the code to use fgets(3).
Since this program is so incredible the extra fixes were deemed worth +having and this is why it was done.
+Cody later 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.
+Cody also added the try.sh script +which shows the original program and some of the programs it +generates.
+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).
Cody fixed the paths in the Makefile so that this +would build in Linux (it worked fine in macOS).
+He also changed the Makefile to use bash not
+zsh as not all systems have zsh and the
+Makefile actually sets SHELL to bash.
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.
He also changed the argc to be an int, not
+a char, even though it might often be the same (for the
+purpose of clang?).
He also fixed the code to not enter an infinite loop if arg is a +number not > 0 and to not crash if no arg is specified.
+Cody also added the try.sh +script.
+The alt code did NOT have arg checks added as it is actually a copy +of the original code.
+Cody added alt +code that will be a bit easier to use for those familiar with vim in +the following ways:
+0 to go to first column.$ to go to last column.w to go forwards one word.b to go backwards one word.q to exit.The other keys were left unchanged.
+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.
Later on, Cody added back the macro #define D define to
+make it look ever so slightly more like the original, even though it’s
+unused.
Cody also added the try.sh script +and try.txt which the script +uses.
+Cody fixed this so that the coordinates being
+specified would not crash the program. This happened because the
+function that calls atoi(3) took an arg without any type
+specified and as an implicit int it was not a
+char * which crashed the program in modern systems.
Cody also made the file name in the code (which is the default maze
+file) not hard-coded but instead be __FILE__.
Finally Cody added the alternate version
+which will possibly feel more at home with those familiar with vi(m) (it
+certainly does feel more at home with him): k for forward,
+h for left and l for right. This version also
+has a more useful way to exit, just entering q followed by
+enter, rather than completing or killing the program.
As some systems like macOS can be particular about not declaring
+functions Cody added to the Makefile some
+-include options. These appear to not be strictly necessary
+but it was done due to other syscalls being a problem not being declared
+first.
Cody fixed a segfault that prevented this entry
+from working in any condition and he also made it work for clang. He
+also added checks for NULL FILE *s. Furthermore he changed
+it so that the C from the BASIC uses fgets(), not
+gets(). For the magic of clang and fgets() see
+below.
Clang (at least in some systems?) defaults to having
+-Werror and the code that the entry generates had some
+warnings that were causing compilation to fail if cc is
+clang as it just ran cc a.c. It ran it by what was once
+system(q-6); but if cc is clang like in macOS
+this is not enough.
(Cody said he stupidly did the below manually until he thought to
+write a simple program to do the conversions which he used for
+gets() to fgets() and for making the generated
+code return a value from main() rather than just
+return;).
The following had to be added to the string s (which to
+fix the segfault was changed from char*s to
+char s[]):
!.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo
+and then the call to system() had to be changed to:
system(q-69);An important point is that the placement of this string in the
+s array does matter. This is because of the code:
*o=fopen(q-3,"w");which means the file name that translates to a.c has to
+be at the end of the string. Thus the end of the string actually looks
+like:
!.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!b/d
+But then there is the matter of getting the C to use
+fgets(3). As can be seen above it’s not as simple as
+changing gets(3) to fgets(3). This was more
+magic characters that had to be updated and some added. The C code:
atoi(gets(b))is in the string:
+bupj)hfut)c**
+which was changed to be (in C):
+atoi(fgets(b,99,stdin))which in the program is:
+bupj)ghfut)c-::-tuejo**
+That’s fine and well but since the code does not include
+stdio.h there obviously would be a compilation error. Thus
+the compiler line had to updated to have -include stdio.h
+which in this rotated string is:
.jodmvef!tuejp/i
+which had to be added after:
+efdmbsbujpo!
+which is the end of the warning disabled for clang as described +above.
+But now the system(q-69); had to be changed to
+system(q-86);.
Then, later on, Cody discovered that in some systems, clang triggers
+even more warnings so this had to be corrected too so the string was
+updated again and the system(q-86) had to be changed to
+system(q-104).
But then to prevent the need for disabling a warning and to be more
+correct code, the generated code was changed to return 1;
+rather than just return;. Thus in full the string
+became:
char s[]="Qjou!s\\311^-g\\311^-n\\311^-c\\::^-q-ma%mO1JBHm%BQ-aP1J[O1HB%[Q<n\
+bjo)*|gps)<<*txjudi)m*|aQdbtf!::::;sfuvso!2<aQefgbvmu;aQ<m,,a%CQ<csfbla%bQ<a\
+N2!Q\ndbtf!aP2Q;m>aP2Q<a%!D12J!JGJHJOJQJFJSJJJMHS%HD12D12N3!N4\nJUJT%UQm>aP4\
+HC%TQs\\q,,^>m,2<m>aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQU\
+aP1HR%PN4\nQ<g\\(aP3Q(^>aP2Q,2<n\\(aP3Q(^>aP4Hb%OD12D12N2!N3\nJVP3Q,,<jg)aP3\
+Q=>n\\(aP3Q(^*m>g\\(aP3Q(^<fmtf!m,,aHC%QN1!N1\nJ#Qqsjoug)#&e]o#-aP1Q*aHb%#Qq\
+vut)aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)ghfut)c-::-tuejo**aHb%JD12JON1!Qjg)a%\
+LN1UP1D12JIQUaP1HL%IQ*m>aN2!N2\nP2Q<fmtf!m,,aHC%MN1!N2>P2Q>aN2\nP2Hbdd!.Xop.\
+fssps!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!.Xop.jnqmjdju.jou!.jodmvef!tuejp/i!\
+b/d";and it now is system(q-87);.
It is hoped that this is the last time the string has to be updated +to work with all versions of clang but if not the above is how it +works.
+With these changes in place it will compile and work with both gcc
+and clang and the C code generated will use fgets(3), not
+gets(3), therefore removing the annoying warnings. Note
+that the array passed to fgets(3) is an int but that was
+the same for gets() and is not necessary to update to a
+char[].
The key to the string is that it rotates the character by
++1. This was not immediately clear until reading the
+author’s remarks so there was an alt version that was something of a
+kludge, running make a instead but that was removed.
Cody also fixed a typo in LANDER.BAS and made it so that if a file +could not be opened for reading or a file could not be opened for +writing it would not crash. The definition of whether that should be a +bug to fix or a feature to not fix was pondered and changed numerous +times and ultimately that problem with this entry was fixed. It has not +been done in all.
+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 (and later back down to 80, see +below).
+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).
That was fine as well but Cody decided to drop it back
+down to its original 80 which also resolved the warning described above.
+This was by more clever use of the Makefile which now has a
+-DB=(int)b so that B can be used in place
+where (int)b used to be necessary.
Cody also added the try.sh script +which feeds the program some fun input for fun but mostly different +output. He added a great string from Brian Westley and Cody also added +several of his own (can you figure out exactly which ones? :-) )
+Cody fixed it so that the messages that show if
+you won or lost will be seen after the end of the game. The reason it
+did not work before is curses was ended at the end of the program which
+clears the screen. To make it look most like the original entry Cody
+left the message before ending curses in and printed another message of
+the same kind after endwin() was called with the exception
+that he added a newline at the end of the screen to be more user
+friendly.
Cody also added two +alt versions, one to remove the maximum number of moves you may make +and another to let you configure the maximum number of moves, even if +that is making it harder to win. Naturally the above fix was applied to +these versions too.
+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.
Cody also fixed the ttt.sh script that prevented the
+game from working and he also improved it so that warnings/errors/about
+to compile messages are not shown unless the -e option is
+used. This is because the errors being shown kind of ruins the
+experience. Finally he made it pass ShellCheck.
Cody also added the alt version which is based on the author’s +remarks, a version that supposedly (:-) ) always wins.
+Cody also fixed the make clobber rule where a file was left lying +about when it should have been removed.
+Cody fixed the code so that it will try opening
+the file the code was compiled from (__FILE__), not
+adgrep.c, as the latter does not exist: adgrep
+is simply a link to adrian as adgrep is what
+the program was submitted as but the winner is
+adrian.c.
Not fixing the above problem would have also caused the program to
+crash if no arg was specified as the file doesn’t exist. In making the
+above fix, at first the change to check for a NULL file was
+added. Then it was noticed that the problem is that
+adgrep.c was an incorrect reference that never existed and
+it was never fixed in any of the files, not the code or the
+documentation, and thus was entirely incorrect code. A fun fact is that
+one can do:
W= fopen(wc>= 2 ? V[1] : __FILE__,"rt");if(!W)exit(1);but one CANNOT do:
+W= fopen(wc>= 2 ? V[1] : __FILE__,"rt");if(!W)exit(1);
+if (W==NULL)exit(1);because adwc.c will be empty! The difference is it is on
+a newline, the check. This is an example of how a simple change in code
+can break it and this is also true of another change as further
+below.
Cody also restored a slightly more obscure line of code that had been +changed:
+- putc("}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"[i]+i-9,stderr);
++ putc(i["}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"]+i-9,stderr);though it’s questionable how much more (if at all) obscure that is +:-)
+Cody also changed the location that it used gets() to be
+fgets(3). This was complicated because of how the other
+source files are generated (as above); simply changing the code could
+cause invalid output in the program which made other files fail to
+compile (for this example specifically, see below).
One might think that simply changing the gets(3) to
+fgets(3) (with stdin) would work but it did
+not because fgets(3) stores the newline and
+gets(3) does not. That is well known but this code was
+relying on not having this newline in a different way (see also
+above).
With fgets(3) 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 and
+non obnoxious way.
In this case the macro for 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, as might be expected
+from the above, caused compilation errors with another generated file
+(adwc.c)! Thus after the gets(3) 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.
These fixes are complex changes due to the way the program and +Makefile generate the additional tools.
+Cody finally added the try.sh +script that shows the entry and some of the tools this entry generates. +Unlike other scripts, it does not clear the screen after compilation so +that one can see how the other files are generated.
+Cody fixed this to compile with modern systems.
+Note that in 1996 a bug fix was applied to the code, provided as the alt
+code as that version is not obfuscated. Thus Cody’s fix applies to the
+original entry. The problems were that malloc.h is not the
+correct header file now (at least in some systems?) and a non-void
+(implicit int) function returning without a value. That
+function was changed to return void.
Cody also added the try.sh and try.alt.sh scripts that correspond to +the entry and the alt code.
+Cody fixed the Makefile so that the program will
+actually work with it (or at least the rule to clobber files and link
+am to ant). The issue was that the variables
+in the Makefile could not be evaluated in the same way as it’s not as
+feature-rich as other implementations of make(1). Thus the
+use of ${RM} and ${CP} were in the respective
+rules changed to rm and cp, for two examples.
+A new rule had to be added as well. The variable situation might be
+because they are obtained from the root variable Makefile
+var.mk via include which the program might not
+support (this has not been tested, however) and also because it appears
+that the syntax for this program is to use $() rather than
+${}.
Cody also fixed another problem, unrelated, in the Makefile with the
+.PHONY rule where a line was not ended with a
+\ but should have been.
The author stated that in some systems like DOS with Turbo C, it
+might be necessary to include time.h so Cody did this as
+well as this exists in other systems too.
Cody also added the try.sh script.
+Cody added a check for the right number of args, +exiting 1 if not enough (2) used. This was not originally done but at a +time it was changed to be considered a bug so it was fixed at that point +as it only took a few seconds and had to be verified that it was +consistent with the bugs.md file.
+He also added the try.sh script +to try out some commands that we suggested and some additional ones that +he provide for some fun.
+Cody fixed the alt code to compile. The problem
+was it assumed that exit(3) returns a value, not
+void. This was fixed with a ,0.
Cody also added the try.sh and +try.alt.sh scripts that +correspond to the entry and its alt code.
+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 added the try.sh +script.
+Cody also added the mkdict.sh +script that the author included in their remarks. See the README.md for +its purpose. It was NOT fixed for ShellCheck 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 for more details
+if you’re interested in trying to understand it (or fix?).
Cody provided the try.sh script.
+The original code, imc.orig.c,
+assumed that exit(3) returned a value but this will cause
+problems where exit(3) returns void. The source code was
+modified to avoid this problem but like Cody did with other fixes he
+made this more like the original by redefining exit to use
+the comma operator so that it could be used in binary expressions.
It was observed that on modern systems this goes much too quick. Yusuke created a patch that calls
+usleep(3) but Cody thought the value
+was too slow so he made it a macro in the Makefile Z (which
+can be redefined with make SLEEP=...), defaulting at 15000.
+This was made an alt version
+and it is recommended one use the alt version first. See the README.md
+file to see how to reconfigure it.
Cody also made the fixed version (the code relied on
+exit(3) returning to use in binary expressions) (and alt
+code from it) more like the original by renaming the ext
+macro to be exit which uses the comma operator. He made it
+so the line lengths match the original code, at least as best as
+possible (if not perfectly), including start and end columns, often (if
+not all) with the same start and end character.
Cody made main() have two args, not one, as some
+versions of clang have a defect with the number of args to
+main() though when it comes to 1 arg it is only in an error
+message if say 4 args are used. This is out of an abundance of caution
+as it’s quite possible that clang or the ANSI C committee end up further
+changing this.
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.
+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 lush.sh script to demonstrate it as using +make was problematic.
+Cody made it use fgets() instead of
+gets().
NOTE: this entry cannot work with clang due to different compiler +messages (it will compile fine but it won’t work). See bugs.md for details.
+Cody made this more portable by changing the
+void main() to be int main().
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! :-)
+Cody also added the try.sh script +that runs a few commands that we suggested as well as one he +provided.
+Cody fixed an infinite loop if one were to input
+numbers < 0 or > 077. The problem was
+that it tried to use scanf(3) with the format specifier
+"%o %o" in a loop, reading again if scanf(3)
+did not return 2 (that was not a problem in that scanf(2)
+will not return until the number of specifiers have been processed or
+some error occurs) or a function it called returned non-zero.
Instead the fix involves the scanf(3) specifiers being
+"%4s %4s" on two new char arrays (always cleared in the
+beginning of the loop) and then using strtol(3) with a base
+of 8 (as it’s octal), checking for
+< 0 || > 077 on both numbers (using
+"%o %o" does not solve the problem).
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. This had
+to be fixed for clang as well to make the args of main() be
+the correct type and by moving the body of main() to another function,
+pain(), which does the work since not all versions of clang
+support four args to main().
Cody also removed the restriction that one has to have a terminal
+that wraps at 80 columns so that as long as the terminal’s columns (try
+echo $COLUMNS) is >= 80 it should work. As most people
+have wider terminals than back in 1992 this should help make it much
+easier to use. Note that if the number of columns is < 80 it will not
+work right. The way this was done is that every 80 iterations in the
+final loop it prints another newline. This fix has another bonus in that
+resizing the terminal after running it should not mess up the display
+either, unless of course it becomes too small.
Cody added the scripts whereami.sh and whereami.alt.sh which +correspond to the entry and the alt code but first check that the number +of columns is at least 80 and if not it is an error.
+Cody added the try.sh script that
+shows the different cities that the author recommended one try as well
+as the one recommended by the judges (approximate judging location),
+labelling each city and printing a newline before the next city. The
+try.sh script uses the whereami.sh and
+whereami.alt.sh scripts, as long as they’re executable (if
+they’re not it first tries to make it executable and if it fails to do
+so it just uses westley or westley.alt. The
+scripts can be deceived by COLUMNS=80 ./try.sh (or
+COLUMNS=80 ./whereami.sh etc.) but this is a feature, not a
+bug.
Cody also added an arg check because the program and the alternate version might have +crashed or nuked 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 encourage you to try the original without +two args :-)
+Cody added the try.sh script and a data file, ants.txt, full of ants for the script.
+Yusuke suggested that with modern systems this
+goes too fast so he added a call to usleep(3) in a patch he
+made. Cody made it configurable at compilation by
+using a macro. This is in the alt version which is the recommended one
+to try first.
Cody fixed the dgibson.sh script to work which
+assumed that . is in the path.
Cody also added the try.sh script +which runs the above mentioned script on all the data files.
+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 caseand 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.
Cody fixed this to work with modern compilers. +This involved different header files for functions.
+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. This alternate version will compile automatically (as
+lmfjyh itself) in the very likely case (if you don’t have
+gcc < 2.3.3) that the entry fails to compile.
Cody also made the Makefile delete the very unsafe filename that is +compiled (or would be compiled if gcc < 2.3.3) whether or not +compilation succeeds (which is highly unlikely).
+Cody added check for two args.
+Cody also added an alternate
+version which uses usleep(3) so you can see what is
+happening with faster systems. This version also checks for two args and
+it is the one we recommend one try first. See the README.md files for
+details.
Cody also added the try.sh and try.alt.sh scripts that correspond +to the original entry and the alt version, both allowing one to change +the args (and in the case of the alt one allowing one to change the +amount to sleep).
+Yusuke supplied a patch to get this to work in
+modern systems. This fix also applies the compatibility issue of
+select(2) described in the README.md file.
Cody added a call to endwin() to
+help with terminal sanity after the program ends.
Cody provided two alternate versions to simplify slowing the game +down and, for the second one, to make movement keys (of the default +game) more familiar to vi users. The slowing down was based on our +suggestion that it might be desired to slow down but Cody did it in such +a way that makes it easy to configure at compile time. See the README.md +for details.
+Cody made this use fgets(3) not
+gets(3).
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() via
+-DO5=main) is now its own function which main() calls with
+the right parameters.
Later Cody fixed it again to look much more like the original where
+only a single line is added, that of main(), which calls
+O5(). This was done through -include stdio.h
+at the compiler (in the Makefile) and by removing the O3
+variable (an int) at the top of the file, instead making it a
+char ** in main() (O5() had three
+args) but then passing in 0 to O5() for the
+third arg (as it was 0 at file scope already this is perfectly fine and
+it means there’s no need to cast it to an int in the function call
+though that would also work).
Cody also added the alt code, provided by the author, which is:
+... a version of the program before it got formatted into the VIII,
+augmented with comments showing where each state begins. N1 and N2 are
+notes.
+but fixed to work with clang as well.
+NOTE: the N1 and N2 are provided as notes
+in the README.md file describing this code. Other code is also described
+there.
Cody also added the try.sh +script.
+Cody fixed an infinite loop that could happen
+when you shoot an arrow and end up having no arrows, thus making one
+force quit the game. The problem was in a condition in the outer loop it
+would repeatedly get input (if getchar() returned
+'\n'), only if one has more than one arrow, returning after
+that. But if there were 0 arrows left it did not return and so the loop
+started over, doing nothing. This fix also seems to have fixed a problem
+where if you shoot your last arrow it would not move you to the room you
+shoot into (whereas if you had more arrows it would).
Cody added an alt version that allows one to cheat by specifying how +many arrows to start with (this was for fun but it turned out a good way +to debug the above infinite loop too which hanged the program).
+As in some places it would properly say that you have ‘1 arrow’ or +else, if you have any other number of arrows (including 0), it would say +‘arrows’, Cody fixed a place where it always said ‘arrows’. A minor fix +and not that important.
+Cody also fixed the problem where one could only get the arrows back +from the robber if the robber stole as many arrows as you ever found +rather than that minus how many you have shot. In other words if you had +three arrows and shot one and found no more you could never get the +arrows back from the robber because you could never lose all three since +you spent one. This bug manifested itself in another way too: once you +got the arrows back the counter was not reset so you could only get the +arrows back once even if the robber stole more. Now the counters are +reset. The way this bug was fixed is that there is now a counter for how +many you have found and how many you shot in addition to the two that +already existed, how many you had and how many were stolen.
+Cody fixed this to check that four args were
+specified. With the use of the C pre-processor macro and inclusion of
+stdlib.h in the Makefile the layout of the source is
+exactly the same column width and no additional lines were added. This
+was done during one of the times where this was changed to bug to fix
+status, for better or worse.
Cody also fixed the Makefile which was causing alt code to be +compiled when it shouldn’t be.
+Cody also added the scripts try.sh +and try.alt.sh.
+Finally he added the article (written by the entry’s author) cited in
+the remarks: the full USENIX
+Association Newsletter ;login: September / October 1992 Vol. 17,
+No. 5 and the pages cited as a shorter PDF file, login_sept92-pp28-31.pdf.
+The full newsletter was found on the Internet Wayback Machine and the
+article was extracted as a PDF in the macOS Preview.app
+(File -> Print feature).
Cody also added inclusion of unistd.h for
+getpid(2). While strictly speaking this was not necessary
+(in multiple systems) it can sometimes be a problem and as it was
+noticed it was changed (the only case this was done except in the
+entries that actually did not work because of missing or incorrect
+prototypes).
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(3) instead of
+gets(3). This one has a minor annoyance in that it 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 and allows for parsing file with longer lines.
+Fixing it it to not have the extra newline is more problematic than it’s
+worth, in macOS another line of output would be shown without the change
+anyway - unless 2>/dev/null - 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.
Cody also added the try.sh script.
+Cody added two alt versions, one which uses
+fgets() but when fed its own source code cannot
+generate code that compile and another one with a bigger buffer size
+which, when fed its own source code, will generate compilable code but
+not with the same buffer size but rather the original buffer size. Cody
+explains this in the at 1994/schnitzi
+in bugs.md.
The purpose for these versions it both demonstrate how the magic
+works behind it and to help others, should they wish, get the code to
+work with fgets(3), with or without an increase in buffer
+size. Note that without this feeding longer files, say the README.md
+file, will crash the program. See 1994/schnitzi in bugs.md where Cody
+also explains the magic for more details. Later on, if nobody takes up
+the task, Cody might resume it, but for now there is more important work
+to do so that the next contest can run.
Cody also added the try.sh and try.alt.sh scripts.
+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.
+Cody added the try scripts, four total, colour +and black and white pairs for the original entry and the alt code. These +scripts are try.color.sh, try.bw.sh, try.alt.color.sh and try.alt.bw.sh, respectively. The +scripts go through each mode allowed with two sizes, 128 and 256, +allowing one to quit or skip each (given that there are a lot of +invocations this seemed like a good idea).
+Cody also made this use fgets(3) instead of
+gets(3). In this case the newline had to be terminated but
+it was a pretty straightforward fix. gets() was defined to
+use fgets() and the inclusion of stdio.h had
+to be added but to make it more like the original entry this was done in
+the Makefile. The alt code was also changed to use
+fgets(3).
Cody changed the Makefile to make this program +more user friendly and easier to use with other tools as well by making +the program output not a space after each number but rather a +newline.
+Cody also added the scripts try.sh and primes.sh. The
+primes.sh script is used by try.sh and if both
+primes(1) and rev(1) are installed it will
+reverse the lines of the weisberg, feeding it to
+primes(1), showing those that are primes. It only does the
+reversed output because the program actually prints primes.
Cody converted the spoiler compiler options +(provided by the author) to be compiler commands and added a script try.sh to automate the spoiler commands +to make it easier to see the game in action from start to finish.
+Cody also added the alternate version that will look fine on +terminals not set to 80 columns and the try.alt.sh script to automate the +play along the lines of the try.sh +script.
+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.
+Out of an abundance of caution with clang, Cody also added a second
+arg to main() as some versions of clang whine about the
+number of args on top of the type of args. In particular some versions
+supposedly only allow 0, 2 or 3 args. It actually appears to allow 1 but
+if you specify 4 it says 0, 2 or 3 and it is an error but it’s entirely
+possible that they will eventually make the defect function as the error
+message claims.
Cody added the try.sh script that uses the text file +he provided which is input we suggested one try with the entry.
+Cody fixed the alt code 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.
Cody also renamed garry.test.sh to try.sh and improved it to to make sure the
+program is compiled before trying to use it as well as adding a few
+enhancements. For the alt version he also added the try.alt.sh script to use the alt
+version, though the alt version is not as important as alt code in other
+entries. In order to get the paging to work right for the
+garry.data file leading blank lines had to be added.
At our change in how to deal with spoilers, Cody also uudecoded the +spoiler provided by the author, putting it in spoiler1.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.
Cody added the authors’ spoiler as a C file as in +2023 we have decided that in most cases all the code should be available +for the wider audience, without having to extract it. The exception is +when the files are created by the entry or the entry decrypts the text +or something like that.
+Cody also added the try.sh +script.
+Cody fixed a segfault in this program that +prevented it from working right and also fixed an infinite loop in the +try commands.
+The problem with the infinite loop is that the file
+august.oc had to have lines starting with #
+removed and it was not being done. After this is done with say
+sed(1) (like sed -i'' '/^#/d' august.oc which
+has been added to both the remarks and the try.sh script
+noted below) the code can proceed. This problem existed in macOS.
Cody also added the try.sh script +that runs all the commands that were given by the judges in the try +section, with the fix above applied.
+Cody proposed a fix for this to compile with +clang and Landon implemented it after some discussion (though Cody +changed the function name). 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.
+Cody also added the try.sh +script.
+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.
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.
+Cody also added the rather useful try.sh script to really demonstrate the +different ways of running the program ends up showing either different +output or the same output that we briefly pointed out.
+BTW: it is perilous to try the patience of Gandalf. Go +ahead, try it! :-)
+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.
NOTE: if there is no X server running this program will still +crash.
+The author stated that -I/usr/include is needed by gcc
+in Solaris because errno.h has two identical extern
+declarations of errno. That leads to an error due to the
+redefinition of main but the -I option makes
+sure the working /usr/include/rrno.h is found first, which
+shouldn’t cause any problems on other systems (the other file is
+gcc-lib/sparc-sun-solaris2.5/2.7.2/include/errno.h). Thus
+Cody also added this to the Makefile despite the fact that very few
+probably use Solaris nowadays.
Cody added the try.sh script with a few commands to +try along with a shorter version of something the author suggested one +try (it is suggested that one try the longer version too but it will run +in an infinite loop so having it in a script is less desired).
+Cody updated the Makefile so that if it fails to
+compile it will try he method suggested for SunOS rather than having to
+update the Makefile manually or running a more complicated command: now
+one can just run make.
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.
Cody also added the two scripts, try.sh and try.alt.sh to automate showing the +different clocks, both with the fixed version and the original (alt) +version.
+Also, to fix any potential problem with displaying in GitHub the
+scripts provided by the author, Cody added ‘.sh’ to the
+clock[1-3].sh scripts.
Cody improved the Makefile to allow for easier +redefining the control keys and time step that the author set up.
+Cody also set up the Makefile to have an alt build (using the same +code) for those who do not have a page up or page down key and added the +keysym.h header file as a reference +for other keys one can use if they wish to modify the controls. One can +certainly do this even if they do have page up and page down but this +gives a default for those who don’t have them like with Macs. The alt +build hard codes the page up and page down alternatives because not +doing so would overly complicate both builds and since you can configure +them all in both builds it shouldn’t matter.
+Cody, out of an abundance of caution, added a
+second arg to main() as some versions of clang whine about
+the number of args on top of what type they are In particular some
+versions claim that they only allow 0, 2 or 3 args. It appears that they
+do allow 1 but for instance 4 is not allowed. However as it’s quite
+possible they will ‘fix’ this defect it would be better to have this not
+be a problem at such a time.
Cody also added the bas1.sh script +to simplify running the program.
+Cody added the try.sh script which runs some default +actions as well as allowing one to pass in different file names or +strings.
+Cody added a call to endwin() to
+restore terminal sanity (echo etc.) when exiting the program (in both
+versions).
Cody also added the try.sh script +that runs the program on all the data files, giving instructions on how +to rotate and zoom in and out, prior to each run.
+Cody changed a int * used for
+fopen(3) to be a FILE * to be more correct and
+prevent any possible problems in some systems (which has happened).
Cody also made the fixed version to look more like the original
+version by using the old style of main() args so that it
+reads i,love_unix more naturally, and by changing the
+typedef int lint to be typedef int _int. See
+the code for why this has to be done this way.
Cody also added the try.sh script which
+runs the program in a loop until one hits q (or
+Q) or sends intr/ctrl-c. He also proposed there’s a way to
+cheat very easily. Can you figure out how?
Cody made the program more portable by changing
+the void return type of main() to be int (in
+both versions).
Cody added the scripts try.sh, try.alt.sh, pootify.sh and pootify.cgi.sh for a fun example +use of the program, a local pootifier of web pages and a CGI pootifier. +See historical +remarks for more details on the pootify scripts.
+Cody added alt code which has vi(m)
+movement (in addition to the other keys except for dropping it’s not
+d but j or space) keys as well as allowing one
+to quit the game.
Cody fixed this to compile. The problem was the +intermediate steps to get to the final code that is compiled. The code +is now what it essentially becomes when processed completely. The +intermediate steps can now be performed to see how it expands but it can +still compile and be used.
+Cody also added a second arg to main() out of an
+abundance of caution as some versions of clang whine about the number of
+args to main(). These versions claim that only 0, 2 or 3
+are allowed but it does allow 1 anyway. It is quite possible though that
+this will change so it is fixed in case this happens. As it is mostly
+just through the C pre-processor Cody added a new macro to make the code
+look like the original with just an extra arg.
In some versions of clang -Wno-int-conversion had to be
+added to the CSILENCE variable of the Makefile.
Cody also added the try.sh script to +show the output of some of the expressions that we selected.
+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 by us, the judges, that these +segfault fixes should be made because the program is so beautiful.
+Later on Cody improved the fixes by checking that the arg is a number
+>0 && <27 as that was noted by the author as
+a requirement and again since it’s such a beautiful program it is worth
+it, especially as the larger the number the larger the resulting program
+becomes. It can be gigabytes in length if it doesn’t crash. At this
+point since the author stated it has no while,
+do...while, for, if/else,
+switch, ?: Cody removed the if statement by
+doing:
((V[1]&&((atoi(V[1])>0&&atoi(V[1])<27))||(exit(1),1)));Cody also added the try.sh script +to help users try the commands that we recommended as well as some added +by him.
+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 macos.md file 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(3) was incorrect with the second arg
+(the mode) being 5+__FILE__; it is now "r".
+(Observe that the mode to the fopen(3) call is:
+43+__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.
Cody also added the perl script that the author provided that they +used to compute the character count in the code according to the contest +rules of 1998 in the file charcount.pl.
+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.
Cody also added an int after register in
+main() in case clang decides to have a problem with that in
+the future which is not entirely out of the question.
Cody also added the try.sh +script.
+Cody added the alternate code which +allows one to reconfigure the size constant in the rare case that the +author wrote about occurs.
+Cody made main() have two args out of an abundance of
+caution as some versions of clang say that main() can only
+have 0, 2 or 3 args. These versions accept 1 arg but it is entirely
+possible that they fix this so this should prevent it from breaking if
+that happens.
Cody added the try.sh script to +make it easier to try the commands that we suggested. One command was +not added, that of the to use command.
+Cody also made the Makefile rule all symlink the entry
+to samefile as that is the name of the program.
The author stated that:
+In the remote event that the input has more than `8192` files with
+the same size (on systems where `sizeof (char *) == 4`, or `4096` when
+`sizeof (char *) == 8`), increase the manifest constant 32767 on line
+31.
+so Cody changed the constant to a macro in the Makefile called
+SZ so one can more easily do this (though it indeed seems
+highly unlikely). See the README.md for more details.
There actually is a web page for the tool and this was added to the +author information for the entry. It has not been added to any JSON +file.
+Cody fixed the assumption that EOF
+is -1 (the author noted that it assumes it is
+-1 and it’s indeed a valid concern as the standard only
+guarantees that it’s a value < 0) and that
+1 is a valid code to return failure (it seems unlikely that
+it wouldn’t be but since the author suggested it it was changed to
+EXIT_FAILURE). To make it so the lines end at the same
+columns as the original the EXIT_FAILURE change was done by
+redefining exit(3) to be
+exit(a) return EXIT_FAILURE and 1 was passed
+to it (return was used because the original program had
+return 1).
Cody also added the try.sh script +to try out a few commands that we recommended.
+Cody changed this entry to use
+fgets(3) instead of gets(3). This involved
+changing the K arg to gets(3) to
+&K in fgets(3).
Cody also added the try.sh +script.
+Cody added the try.sh script with some improvements to +the commands we recommended like not assuming the number of columns one +has in their terminal.
+Cody fixed this to compile in systems that
+require one to explicitly link in libm.
Cody also added the try.sh +script for those who are feeling a bit too confident, cocky or even +happy :-)
+Cody made this more portable by changing the
+void main to int main.
He also added the try.sh +script.
+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.
Cody also added the try.sh +script.
+Cody made it easier to compile this in some cases
+by adding X11/ to the includes of Xlib.h and
+keysym.h.
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.
+Cody also provided the try.sh and
+try.alt.sh scripts that show the
+Moon phase in artistic ways. It is recommended one try both a number of
+times in a row on different days (that is run ./try.sh
+several times in a row a few days apart, until you see all the Moon
+phases, and run ./try.alt.sh a few times in a row a few
+days apart, until you see all the Moon phases).
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.
Finally Cody fixed the Makefile that had the -Wno-foo
+options in the CDEFINE variable which although works it is
+incongruent with the other Makefiles and is more confusing (even if not
+confusing).
Cody made this more portable by changing the
+void main to int main.
Cody also added the try.sh +script.
+Cody fixed an infinite loop that occurred if +invalid input was entered, flooding the screen with:
+Black position and direction: illegal
+This was fixed by having the scanf(3) read in a string
+and then use atoi(3) on it to assign to the
+ints, much like with 1987/lievaart. The
+strings are char[5] and the % specifier is
+%4s which is enough for the game.
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).
+Cody also added alt code to allow one to slow down the code. This +code also, at least for the curses mode, allows one to quit at any time +by pressing ‘q’. See below for more details.
+Due to a terrible design choice of the SDL1 developers something had +to be changed. As was noted in the log:
+The SDL version did not work for a number of reasons. First of all the
+code requires that SDL is defined. Second the path[sic] wrong header file was
+included. Third the SDL1 developers thought it would be a great idea
+(but obviously it's a terrible idea) to redefine main() (!!) so that any
+program that uses SDL1 has to have the same args as their definition.
+This program had 'main()' so the error message was:
+
+ thadgavin.c:60:1: error: conflicting types for 'SDL_main'
+ main()
+ ^
+ /opt/local/include/SDL/SDL_main.h:34:14: note: expanded from macro 'main'
+ #define main SDL_main
+ ^
+ /opt/local/include/SDL/SDL_main.h:35:12: note: previous declaration is here
+ extern int SDL_main(int argc, char *argv[]);
+ ^
+ 1 warning and 1 error generated.
+ make: *** [thadgavin_sdl] Error 1
+
+Thus main() was changed to 'int main(int argc, char **argv)'.
+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.
+Cody added the alt code based on the +author’s remarks with a fix for modern systems and he also added the two +scripts, try.sh and try.alt.sh for the main code and the +alt code respectively.
+And although the scripts do chmod +x on the source code
+(see the README.md for details) the source code is now executable by
+default.
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 +ELF binaries. See bugs.md +for why this is; this is not a bug, it’s a +feature inherent in what it does!
+The following had to be done to fix this:
+#include <sys/mman.h> for mmap() and
+munmap().main() call another function which is no longer a
+recursive function; this prevented main() 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:
+open()ing the file the file descriptor had to be
+saved so it could be closed prior to executing the program. This is the
+f variable which an int.munmap() also had to be called prior to executing the
+program. This involved a new off_t N which was added in the
+mmap() call which was then used in the
+munmap() 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:
+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.cFinally to see from start to finish:
+git diff d2a42f42e8f477f29e9d5ed09ce2bb349eaf7397..4bc03de321612869aebf855850c6500df95cb6ef anonymous.cor to not use git:
make diff_orig_progCody also added a program like anonymous.ten.c Ten Green +Bottles but which sings Ten in the Bed +instead.
+As well he added the try.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.
+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.
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.
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.
Cody also added the try.sh +script.
+He also fixed it to check the number of args.
+Cody added a value to return in
+main() to make it more portable.
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){
+ ^and for some reason it was being reported as an error. This was not
+really worth a thanks per se but it was originally done by adding
+int. The better solution is to disable the warning which is
+what was done later on to make it more like the original.
Yusuke provided a proper command line for those
+without /dev/audio or /dev/sound/dsp (which is
+most everyone nowadays, it seems, and especially those with macOS) (to
+do with sound; see his /2013/endoh3/README.md entry where he
+also refers to sound devices in macOS).
Cody added the try.sh.
+The ANSI escape codes were no longer valid but Yusuke provided a patch to fix the ANSI escape codes. +This works with both Linux and macOS.
+Cody fixed this so that it should always restore
+terminal sanity (echo enabled etc.) after exiting even if you don’t
+press ‘q’, if you crash or if you kill the program prematurely. This was
+done by adding an explicit call to e() at the end of
+main().
Cody also added the alt +code that adds vi(m) movement keys.
+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. Do you know what it is?
+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.
+Cody provided the file plus1.turing based on the +author’s remarks.
+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.
+Cody also added the try.sh +script.
+Cody fixed this to work with both 64-bit and
+32-bit compilers by changing most of the ints (all but that
+in main(int ...)) 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.
Cody also added the try.sh +script which might be more useful than any other place as the command to +try is quite long with C code.
+For some reason the original code was missing (presumingly because it
+had been added to .gitignore by accident) but Cody restored
+it from the archive.
Cody improved the Makefile to allow one to more
+easily set up the port, speed and socket(2) call that the
+author had set up.
Cody also slowed down the ball just a tad (it was already a
+-D macro that was used in the code) as it went too fast for
+the speed at which the paddles move even when holding down the movement
+keys (but see below).
Cody also provided an alternate
+version which lets you use the arrow keys on your keyboard instead
+of the more awkward ‘,’ and ‘.’.
He updated both versions to have #ifndef..#endif pairs
+for the macros so one can more easily configure different settings
+without having to specify all of them (though this change became
+unnecessary with an improvement on how it was done). The speed,
+SPEED, will be set to 50 if it’s not defined at the
+compiler line as 50 is what it used to be set to. This way it’s more to
+the original but without having to sacrifice playability by running
+make.
Cody also fixed it to not crash if not enough args, exiting 1 +instead. This was done at a time where it was said to be a bug that +should be fixed, for better or worse.
+Cody fixed this to not crash if not enough args +as this was not documented by the author. The other problems are +documented so were not fixed. See README.md for details.
+Cody also added the try.sh +script.
+Cody added the script try.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.
+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)! :-)
Cody also renamed the arachnid.info file to arachnid.txt as it’s not really
+an informative file but a maze file. The extension .maz was
+not chosen to help with (some?) browsers knowing what to do with it.
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(3) 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 is not
+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(3) 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 enabled so the compiler flags were +changed for this.
+Cody added three different alternate versions:
+stdout).Cody provided the alt code for those who
+want to use QEMU. The most important part of this is the macro
+K has to be defined as 1, not
+0.
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.
Cody fixed a bunch of links in the index.html
+provided with the entry (web server) that no longer exist or have
+changed in some other way (https instead of
+http for instance). In most cases a new link or change to
+https was all that was necessary but at least one or two URLs required
+the Internet Wayback Machine.
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.
+Cody also added alt
+code which allows one to control how many numbers after the
+: to print before printing a newline, so that one can see
+the output a bit better (though for lines that have a lot of numbers
+this will be harder to see).
Finally Cody added try.sh and try.alt.sh to demonstrate both +versions.
+Cody reported that this entry cannot be optimised +by the compiler as otherwise it will not work.
+Cody, out of an abundance of caution for clang, added a second arg to
+main() as some versions complain about the number of args
+and although they accept 1 it is entirely possible it will eventually be
+that they don’t.
Cody also added the try.sh
+script and various data files: kopczynski-a
+to demonstrate what happens when art more like a letter is fed to the
+program and the kopczynski*-rev files which are the data
+files reversed with rev(1). One had to be modified
+additionally to get it to work, that being
+kopczynski-10-rev.
Cody and Landon individually fixed this to work +with clang.
+Cody also added the try.sh script
+(with a hidden feature that the author referred to and was documented by
+Yusuke though Cody chose the word
+IOCCC instead of AAA).
Cody made this use fgets(3).
He also changed the time factor in the data files as the animations +went too fast in modern systems, especially the scrolling text of schnitzi.inp1.
+Cody also added the try.sh +script.
+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 1Unfortunately the fix required heavy modification to the original +file (see below) and also inclusion of what used to be generated by the +Makefile 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 actually includes itself,
+once directly and now by __FILE__) which used to be
+generated by the Makefile via cc -E.
Cody also made it so that the FNAME is (for the entry
+file itself and vik2_1.c: it shouldn’t be done for vik2.possible.cat.death.c!)
+__FILE__ just to make it a bit easier to compile.
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 so the script did not even work +(at least modernly?).
+He also added the alt +code based on the author’s remarks which is a different approach +than the one used and which (according to the author) ‘is slower +(particularly in worst-case or nearly so scenarios), inelegant, and not +a good starting place for sudoku generation.’
+Cody added the try.sh and try.alt.sh scripts that correspond to +the entry and alt code respectively.
+Cody added the make test and make test-n0
+rules for easier use of the test suite.
Cody fixed a problem where in some systems (like
+macOS) the stty sane would not work and end up causing a
+bus error. Instead of stty sane it uses
+stty echo which is what it was trying to accomplish.
The author noted that one can define NO_STTY to not use
+stty(1) at all (either to prevent having to hit enter or to
+turn echo off/on) which is explained in the README.md.
Cody added the alt +code with vi(m) like movements.
+Cody added the input.txt data file based on +suggested input from the author, adapting it to a command to try +out.
+Cody also added the try.sh +script.
+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.
+The most complicated fix was for, as might be expected,
+clang: it (at least some systems?) has -Werror
+by default so the program was changed to use make and then
+rm -f on the output of the compiled binary instead. This
+change might also not have been necessary if using different flags to
+cc but this is less portable and caused other problems.
+This was a complicated fix as it’s in the comments but in a funny way;
+the final result to get the test feature to work is:
;; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s/|sed*/
+/*-e/'s,intZ,int/ Z,g'>c.c;make/c;/ rm/-f/c*/
+;;changed from:
+;; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s>*/
+/*c.c;cc/c.c /-c*/;;or as a diff:
+-(t(m),(0));; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s>*/
+-/*c.c;cc/c.c /-c*/;;char*A=0,*_,*R,*Q, D[9999],*r,l
+-[9999],T=42, M,V=32;long*E,k[9999],B[1 <<+21],*N=B+
++(t(m),(0));; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s/|sed*/
++/*-e/'s,intZ,int/ Z,g'>c.c;make/c;/ rm/-f/c*/
++;;char*A=0,*_,*R,*Q, D[9999],*r,l[9999],T=42, M,V=32;int *E,k[9999],B[1 <<+21],*N=B+Cody also added the try.sh script +which also lets one see the beauty of the entry without having to use +vi(m), should they be afraid of getting stuck in it (and for ease of +use). :-)
+Finally, to improve upon the test-suite provided by the program, Cody
+added the make test rule which only shows lines matching
+'^Line' but writing to a temporary file the compilation
+including the ‘Line’ lines. After that is done it uses
+grep -c on the file to show that there are indeed as many
+versions the program generates as the author states, 180. If it does not
+find 180 it is an error; otherwise it is success. It uses test.sh.
Cody added explicit linking of libm
+(-lm) for systems like Linux that seem to not do it
+implicitly (like macOS does).
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 \NeThe 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.
It might be worth noting that the author stated that the reason for
+the \N is due to LISP having different escape sequences.
+The code was modified so that feeding the program itself will print
+itself, showing no difference, which is what is supposed to happen. It
+is not known, however, if having to change the \N to
+\n ended up breaking any LISP. The other examples given by
+the author also show correct output though.
Cody also added the try.sh +script.
+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 or perhaps someone wants to add the necessary code.
+Cody added the (untested) alternate code which
+should work for Windows as it sets binary mode on stdout.
+It is untested as Cody has no Windows system to test it on.
Cody also added the try.sh +script.
+Cody added the saved (with the SAVE
+command) BASIC program PET which was:
10 PRINT "2005'S IOCCC BEST EMULATOR"
+20 PRINT "BY STEPHEN SYKES!"
+followed by the commands:
+SAVE "PET"
+
+READY.
+NEW
+
+READY.
+LOAD "PET"
+
+READY.
+RUN
+2005'S IOCCC BEST EMULATOR
+BY STEPHEN SYKES!
+to both save and test run it.
+Cody added the try.sh script which +runs in a loop with a menu of things one might wish to try, asking if +they wish to continue when done.
+Cody added the script test.sh and
+the make rule test to run the test suite. The program will
+enter an infinite loop after it runs so you have to hit ctrl-c to end it
+which the script tells you.
The scripts note every time that one will have to send ctrl-c or +whatever their interrupt is set to in order to exit the program.
+Cody added try.sh. It only has one command as he +doesn’t want to knacker his brain any more than it might or might not +already be :-) and he doesn’t want to damage anyone else’s brain either. +:-)
+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.
+Cody fixed this in the case that the program is
+compiled or linked/copies to another file name: the code constructed the
+source code file name in a clever and more obscure way by copying to the
+buffer *argv and then using strcat(3) to
+concatenate to it .c. But this assumes that the executable
+is the same name as the source file which isn’t always be true. The
+author even stated: ‘as long as the source is in the same directory as
+the executable it should be able to find it’ but the source code file
+name is not always the same as the executable with the appropriate
+extension so this might be called a bug fix as well though if one runs
+it from another directory, specifying the directory, it’ll not catch
+it.
Cody fixed a segfault in macOS with this entry.
+The problem was a missing +1 for strlen() with malloc().
+This prevented it from working.
Cody also added the try.sh +script.
+Cody fixed the Makefile to work in systems where
+the lpthread is not implicitly linked in.
Cody also added the try.sh +script.
+Cody fixed this so that it will not crash without +an arg after it was suggested this should be fixed.
+Cody also added the try.sh +script.
+Cody added the alternate code that lets +one resize the image and redefine the number of iterations.
+Cody also added the try.sh and try.alt.sh scripts.
+Cody also fixed the Makefile to use sdl-config (which is
+what the author stated too though that was noticed later), not
+sdl2-config as two functions that are used were removed
+from SDL2, thus making it not link.
+Since SDL2 is still available and since changing the code to use SDL2 is
+much more complicated and also makes the entry less like the original it
+was simply made to link in SDL1.
Nevertheless this entry does require x86/x86_64 CPUS. This is a +documented feature but one which we will accept fixes to. See 2006/monge in bugs.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.
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.
Cody also provided the alternate +version, which allows one to see what is going on in modern systems, +and which we recommend one use first.
+Curiously, although clang requires the types of args to be strictly
+correct, some versions do allow only one arg. This was done at first
+because it’s not used but Cody discovered that later versions of clang
+have an additional defect where it does not allow only one arg so the
+second arg to main() was added back.
This was an unfortunate problem for the alt code as he has been using
+Z for alt code usleep() (for sleep) but in this case
+unfortunately the original entry used Z in
+main() (though unused) so to make it more like the original
+Cody renamed the macro Z for usleep() to
+S instead which can stand for sleep and also it is kind of
+like a backwards Z. That way Z could be in
+main().
Cody 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 also
+added -include ... to the Makefile as well.
Cody also fixed it so that if the file cannot be opened it exits +rather than trying to read from the file. This was done at a time when +it was considered to be a bug to fix.
+Cody provided the alt code based on the +author’s remarks.
+Cody also added the try.sh +script.
+Cody also provided the bedlam-cubes.pdf file, obtained +from the Internet Wayback Machine, as the file was no longer available. +The video was also no longer available but Cody found an alternative and +added it to the repo as well.
+Cody, out of an abundance of caution for
+clang’s defects, made main() have to args
+instead of 1 as some versions report that main() must have
+0, 2 or 3 args, even though at least one of those versions allows 1 arg
+only.
Cody also added the try.sh script +for easier use of the entry to show the clock update in real time.
+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.
Cody also added the (untested) alt code that is based on the author’s
+remarks to port this to systems that have the non-standard
+kbhit() and getch() (not the one from curses)
+which is typically (always?) in conio.h.
The author, Oscar Toledo G.,
+later went back over the program and modified the
+fread(3)/fwrite(3) section to use the variable
+FILE *e (that Cody changed) instead of int y,
+making it to work on x86_64 (perhaps Cody’s fix was for arm64 only?).
+Also, he added a note to clarify from where appears the
+IMPORT.COM and HALT.COM files.
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.
Cody also added the code that should work for Windows, toledo3.alt.c, based on the +author’s remarks. We’re not able to test this.
+Cody, out of an abundance of caution, added a
+second arg to main() as some versions of clang complain
+about not only the type of each arg to main() but the
+number of args as well.
Cody also added the try.sh +script.
+Cody added the video file boing-ball.mp4 which is the demo the author +referred to.
+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 also added the try.sh +script.
+Cody added the following words of wisdom:
+'"this" is not a pipe but "!" is'.
Cody added the try.sh script and the .nono
+files conway-game-of-life.nono,
+multi-solutions.nono, no-solution.nono, plus.nono and smiley.nono. The latter two
+.nono files were taken from https://web.archive.org/web/20130218055139/http://codegolf.com/paint-by-numbers
+and the others were from the authors’ remarks.
Cody fixed the program to not crash if no arg was +specified as this was not a documented feature.
+Cody also added the try.sh +script.
+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 2011/richards in +bugs.md for more details and a document from Apple about how it +might be fixed if anyone is brave enough to try. If they do they might +want to look also at richards.alt.c, for whatever it +might or might not be worth, as it is a possible starting point that +Cody added.
+Cody also added the try.sh and
+the try.alt.sh scripts. The
+try.alt.sh script will be helpful to test any fixes for
+Apple silicon chips (see 2011/richards
+in bugs.md for more details).
Cody added two alternate versions: one
+that lets one reconfigure the controls and also the size of the game and
+another version that should work in Windows, based on the author’s
+remarks and support file, layer.c.
The Makefile was also modified by Cody to make it simpler to redefine +the controls, width and height.
+Cody also added an alternate version for +Windows based on the author’s comments (along with looking up the +function for the right header files). To build try the alt rule of the +Makefile.
+Cody also added alt
+code that should work on Windows, based on the author’s remarks that
+if the system distinguishes binary and text then stdout
+needs to be set to binary mode.
Cody also added the PDF file sphere-tracing.pdf in case +the link eventually dies.
+Cody added explicit linking of libm
+(-lm) as not all systems do this implicitly (Linux doesn’t
+seem to but macOS does).
Cody also added the try.sh +script.
+Cody added explicit linking of libm
+(-lm) as not all systems do this implicitly (Linux doesn’t
+seem to but macOS does).
Cody also added two alt versions that let
+one control how fast the fluid moves (how long to sleep in between
+writes) and also the gravity factor, the pressure factor and the
+viscosity factor as well as an alarm that lets one run it in a loop
+without having to hit ctrl-c/intr in between (the alarm can be disabled,
+however). The Makefile allows one to easily do this with variable names
+rather than redefining CDEFINE.
The two different alt versions is because there are two versions: the +original and the colour version added by the author, Yusuke, at the request of the judges.
+Cody also added the try.alt.sh
+script that compiles the alt code in two ways, one with setting the
+gravity factor to I and another with the default, and which
+is run on the source file and each of the text files supplied by the
+author. This code has an alarm set at 10 seconds so that one need not
+hit ctrl-c/intr in between .. say to make it more fluid :-)
Cody also added the try.alt.bw.sh which is the same as
+the try.alt.sh except it does not use the coloured
+version.
Finally Cody added the try.sh and +try.bw.sh which correspond to the +coloured version endoh1_color.c and the original +submitted version without colour, endoh1.c.
+The endoh1.alt2.c was +provided by the author, Yusuke, at the time of the +contest as a de-obfuscated version.
+Cody added the try.sh script that runs everything, +filtered through less.
+Cody also fixed a typo in the ruby script find-font-table.rb.
+Cody also changed argv to be not
+const char ** but char **, mostly out of an
+abundance of caution in case clang, which already imposes restrictions
+on the types of args to main() including to do with
+char **, decides to further restrict them.
Cody also restored the original code from the archive.
+And although the URL works for now (via redirect), Cody changed the
+website linked to in the recipe file to the domain that the old one
+currently redirects to, in case the other domain ends up expiring or
+stops redirecting to the more recent domain. For historical purposes the
+old link was http://recipes.stevex.net/ but it redirects to
+https://www.mealsteps.com which the recipe file now links
+to.
Cody added the try.sh script and the helper Makefile
+rules hint.pdf, hint, hello.pdf
+and hello to simplify the procedure for both
+hint.pdf and hello.pdf as well as compiling
+them as C.
Cody added the try.sh script and restored the original hint markdown file as the changes made when
+converting to a GitHub README.md made the generated html not look
+correct; it did not have a title, a stylesheet etc. due to the fact that
+there is no # header (which specified title and stylesheet)
+and other formatting changes.
Cody added alt code that fixes a problem where in +German ‘v’ sounds like ‘f’ which the program has as ‘f’: with the +original version it would translate ‘fier’ to ‘4’ when the word is +‘vier’. But see below.
+Originally this was updated in the original code but it was noticed +that this caused other German (and maybe other languages?) +words to be incorrect so it was set as an alt version since the code was +already there. It might also be considered a feature and not a bug so an +alt version is the better way to go about it. Using both, however, +allows one to experience different capabilities and also enjoy or +appreciate the entry even more, given how simple the difference is.
+Cody also added six scripts: en.sh, de.sh, en.alt.sh and de.alt.sh which count from 0 through 13 in +English and German using the original entry and the alt version +respectively.
+In the German scripts it uses the umlaut and also does it without the
+umlaut (add an ‘e’). Notice how the program picks up on this! All
+scripts can use either version but the .alt.sh versions
+default to the alt version whereas the other defaults to
+the submitted entry. See the README.md for details.
The fifth and sixth scripts, try.sh +and try.alt.sh, run a sequence of +commands to show different languages and numbers with the submitted and +alternate version respectively. Notice how a single letter changes so +much!
+Cody added the alternate versions
+which will, if no arg is specified, read in the program itself, rather
+than /dev/urandom. This is mostly useful for those without
+a /dev/urandom device file (the default for the entry). The
+second alternate version is like the first except that it also sets
+binary mode on stdin and stdout which should
+theoretically make it work in Windows.
Cody also added the try.sh and try.alt.sh scripts.
+Based on the author’s description it should be able to get this entry +to work for Windows. With his instructions Cody also added the alternate +version that does this for the few who might use Windows.
+Cody test.sh
+script and the make test rule that uses the script along
+with a number of files that will correctly be flagged as incorrect
+(including a text file and a java file, with a joke, to show that it’s
+not that it parses C but rather just matching pairs though that’s
+probably obvious) and some correctly nested files were also added
+including 1984/anonymous (as the
+author explicitly mentioned it) and a java file as well with another
+joke.
A minor point is that the author noted that one should look at the +program source with tab space of 4 characters so Cody added the command +to do this in vim for those who use it, in the judges’ remarks, to make +it easier for those who do not know how, and to make it more obvious to +try it.
+Cody changed the return 0; at the
+end of the program to be return system("reset"); (via
+redefining exit(3) so that the column ending would be the
+same) so that as long as it runs to completion the terminal will be sane
+and the cursor will be visible. Using atexit(3) will not
+work if the program is killed, signals are ugly and these would be
+messing with the entry too much so these were not done.
Cody also added the alt version that lets one control how fast the +painting is done, based on the author’s recommendations, except that +Cody made it configurable at compile time. The Makefile was modified in +such a way as to make it very easy to redefine it at compile time.
+Cody also added the try.sh script +for the entry and the try.alt.sh +script for the alt code.
+Cody added the try.sh script which also has an joke +Easter egg in it based on the judges’ remarks.
+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 (renamed to
+cable3.sh for consistency with
+other entries that have wrapper scripts) 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).
Clang required a -Wno- option as well.
Finally Cody provided the bios.asm that the author referred to,
+found at the GitHub repo
+for the entry, and the ‘ready-made 40MB hard disk image containing a
+whole bunch of software’ in hd.img that the author linked
+to at https://bitly.com/1bU8URK.
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 slflen.sh which is based on the
+author’s remarks, fixing it for shellcheck and improving upon it (show
+what files will be processed). This script shows the sparkline of the
+file lengths (as in wc -c). The fixes (but not the
+improvements) were added to the author’s remarks.
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 slflen.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 try.sh script to +more easily try the program.
+He also added the diff.sh script +which is based on some commands to try that he suggested to see how +different lengths look.
+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.
+Cody also (out of an abundance of caution for clang(1)
+which is strict with arg type and count to main()) added a
+second (unused) arg to main().
Cody added the endoh4.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. One may pass more +than one file to the script.
+Cody also made it easier to redefine the size at compilation time
+(see the author’s remarks for more details on what this means). The
+endoh4.sh script allows one to redefine it as well.
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 -lmThe 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.
Cody also added the try.sh script.
+Cody fixed this so that the server would not
+refuse the connection after the first call to close(2). The
+problem was that because the backlog to listen(2) was 1
+once the connection closed the server was essentially ‘dead’. The
+backlog was changed to 10 and this solves the problem. It is not known
+if this was specific to macOS but it was not specific to a browser as
+Safari and Firefox both had the problem.
Cody added explicit linking of libm
+(-lm) as not all systems do this implicitly (Linux doesn’t
+seem to but macOS does).
Cody also added the try.sh +script.
+Cody provided the alternate code that
+lets one redefine the port to bind to in case there is a firewall issue
+or there is some other reason to not have the default port. Remember
+that ports < 1024 are privileged. It also lets you redefine the
+timing constant STARDATE (see the author’s remarks for more
+details on this macro). The Makefile was made to use variables so it’s
+easier to redefine the port and timing constant.
Cody added alt code that lets one +(via the Makefile) reconfigure the coordinates but instead of being a +modified version of the entry it is the version 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.
+
.. was not true.
+This alt version did not originally compile because a value was left
+off the return statement (this might have been fixed in the
+README.md file too) so that was fixed and it also has
+#include <stdio.h> for putchar(3). The
+#ifndef..#define..#endif was not part of the original alt
+code, of course.
Cody also added the try.alt.sh +script.
+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.
Cody also added the try.sh +script.
+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 (and too close to README.md?).
Cody fixed the build for this entry: it does not +require SDL2 but SDL1 so there were +linking errors.
+Cody also added the mario.sh +and giana.sh scripts which play, +respectively, Super Mario +Bros and one of The Great +Giana Sisters, but which let one configure the width and height of +the game.
+He also added the alternate code +provided by the author.
+Cody fixed the code so that the game can play
+automatically like it once did. The problem is that it expects a certain
+file name which was sinon.c. The code now refers to
+prog.c.
Cody also fixed the scripts glock.sh and hecate.sh which did not work after
+running either once as they compile run.c and then do
+./run | tee run.c which overwrites it with output that is
+not code.
Cody also added the try.sh script +that will first (if perl is installed) run the demo mode and then after +that it will run the above noted scripts in a loop until the user says +they do not want to try again (or they kill it). This is done this way +in case it jams (see README.md for details).
+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,
+"${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.
Cody added the try.sh script. Cody notes that there is a +bug that will show itself as one of the features does not work right. +The translation of the raw audio to text is buggy in some cases.
+Cody also 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.
+Cody added the try.sh script which is based on the +command to try in the ‘try’ section but improved so one can more easily +specify what ident tool they want to use and also change which sed to +use, should they want to. It also checks that both of these two tools +exist and are executable and it pipes it through less as it’s longer +than a page worth of output.
+Cody fixed the code so one can make use of the
+echo feature, where the first character of the filename starts with
+e. The only way it would work before that is if one did
+something like:
ln -sf prog eprog
+PATH=$PATH:. ; eprog '...'since otherwise the first character would not be e but
+rather a dot (./eprog). This was done by adding to the
+Makefile -include libgen.h and adding to
+main() after the variable declaration (V*A;)
+the code:
*K=basename(*K);This was done for both the prog.c
+and prog.alt.c. The Makefile was
+also updated to build eprog and eprog.alt to
+make use of the feature more easily. Each is a new target (first in
+TARGET and second in ALT_TARGET) which have a
+prerequisite of ${PROG} and ${PROG}.alt
+respectively both of which also copy the prog
+(prog or eprog) to the respective
+eprog (eprog or eprog.alt). With
+these changes now one can easily use the echo feature the author
+implemented.
Cody also added the try.sh script. +This involved adding a text file, try.this.txt.
+Cody also added calc.1 in place of
+calc.man to have proper formatting (in the style of
+man(1)). The calc.man was removed so as to not
+have to maintain two copies of the same text.
Cody updated the Makefile to copy the prog to
+calc and prog.alt to calc.alt.
+ecalc and ecalc.alt also work. This is because
+the program is called calc and is in documentation
+including the man page. Thus one only need add a ./ to the
+commands in the man page/README.md.
Cody improved the Makefile so that one can easily
+change the dimensions at compilation time via make(1).
Cody also added alt code that is based on the author’s remarks,
+suggesting that one change the value of q to a different
+number, in order to see a bug that they avoided.
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 added the try.sh script
+which makes use of the make rule he added (to enjoy the theme of the
+entry, Back
+to the Future using this entry by simply typing
+make back_to or make mullender) and then runs
+the famous 1984/mullender.c.
Cody added explicit linking of libm
+(-lm) for systems that do not do this (Linux doesn’t seem
+to but macOS does).
Cody also added the try.sh script and
+the large file large which the try.sh script
+uses.
Cody also added the RFC 1321 text file, rfc1321.txt to the directory, to make +it so one need not download it, and which the README.md file now links +to.
+Cody added the try.sh script, downloaded the War and Peace
+text file, fixed the avgtime.sh
+script (it resulted in standard input errors in piping to
+bc(1)) and added the cc.1 man
+page as not all systems have it (in fact it’s gcc(1) from
+Rocky Linux).
Cody added the try.sh script which changes the +parameters to what we had in the judges’ remarks to make it easier (he +only died when he tried to mark a reminder complete on the other side of +the screen at the same time and he almost survived that, scoring at that +point over 90 - but this also involves good eye-hand coordination and +playing games like this in the past).
+Cody fixed the build so that EOF
+will be -1 as the program assumes this. It was decided by
+Cody to do -UEOF -DEOF=-1 so as to not have to modify the
+code any with C preprocessor directives (the preferred way) or changing
+EOF to -1.
Cody also added the try.sh +script.
+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).
He also added the try.sh script.
+Cody added the try.sh and try.alt.sh scripts.
+Cody also, out of abundance of caution, added a second arg to
+main() because some versions of clang object to the number
+of args of main(), saying that it must be 0, 2 or 3. The
+version this has been observed in does not actually object to 1 arg but
+it is entirely possible that this changes so a second arg (that’s not
+needed and is unused) has been added just in case.
Cody also added explicit linking of libm (-lm) for
+systems that do not do this (Linux doesn’t seem to but macOS does).
Cody also added alt
+code that should work for Windows, based on the author’s remarks.
+The same thing with the number of args to main() that was
+done in the original entry was done with this version as well.
Cody fixed the scripthd script
+(referred to prog not ./prog) and renamed it
+to scripthd.sh to help browsers
+and GitHub as far as downloading/displaying goes.
Cody also added the try.sh script
+which also uses scripthd.sh to show how it differs from
+prog itself.
Cody fixed the make test rule: it
+tried to run tac(1) (in systems that have that command)
+rather than the entry itself which is called tac and the
+runtest script (which he renamed to runtest.sh
+for download/browser display purposes) was not executable.
Cody also renamed manpage to manpage.sh for
+download/browser purposes and he did the same with tokenfix
+to tokenfix.sh as well as spotcheck to
+spotcheck.sh, spotdiff to
+spotdiff.sh, freqcount to
+freqcount.sh and mkkeywords to
+mkkeywords.sh.
Cody also made the man page properly formatted for
+man(1) and renamed it the file tac.1.
Cody also renamed discrepancies to
+discrepancies.md and made it markdown format.
Cody added the tokcount.sh +script which was included in the remarks of the author but not an +included file.
+Finally Cody added the try.sh +script.
+Cody added the try.sh and try.alt.sh scripts and the PDF file, +lexicon.pdf, that was a dead link, +restored from the Internet Wayback Machine.
+Cody added the try.sh script which shows the input files +one at a time and after each one is shown, it feeds it to the program, +redirecting the output to the respective GIF file. It then will inform +the user they should open it in a GIF viewer that can show animation in +animated GIF files. It offers an example command for macOS like the +judges did in their remarks. The input files offered includes the prog.c +as the author, Yusuke, suggested that it too has a +secret.
+Cody fixed the run.sh script (had commands that didn’t
+exist and also didn’t work even after that was addressed) and added the
+try.sh, python.sh and python3.sh scripts. The
+try.sh script runs all three of the other scripts but each
+allows one to send an interrupt in the loops and still continue to the
+next script (if one does it when not in a loop it will exit the script).
+The make python and make python3 rules in the
+Makefile now run the respective scripts.
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 +(like adding the try.sh and try.alt.sh scripts).
+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 ? :-) )
+Cody added explicit linking of libm
+(-lm) for systems that do not do this (Linux doesn’t seem
+to but macOS does).
Cody also added the try.sh script.
+Cody, based on the author’s remarks, made it
+possible to save state between runs of the program so that one can
+resume where they left off. It should be noted that there is a bug in
+the entry (irrespective of save state option) where running
+./prog twice in a row involves having to hit (the second
+run) enter and then exit and then start the program again. Also if you
+do add a file you should run sync prior to exiting or else
+the file might not exist or it might be corrupt. See 2018/mills in bugs.md for more details on
+the bug.
Cody added the missing docs rule to
+the Makefile that forms a PDF file. The rule requires the tool
+pdflatex.
Cody also added the try.sh +script.
+Dave Burton, during the
+preview period, noticed a problem where the macOS
+Terminal.app does not work properly for this program. We
+added some additional notes on what might happen (it varies depending on
+configuration).
Cody added the try.sh script. This script will ask if the
+user wants to see some of the spoilers and only show them if they type
+y or Y.
Cody added the try.sh script and the Unlambda file crash.unl which is in the judges’ +remarks as to what can crash it - but it’s not a bug, it’s a +feature.
+Cody fixed the Makefile which had a bad +character, a ‘%’ instead of a ‘$’ which caused a rule to fail.
+Cody also added the try.sh script
+which shows a side-by-side comparison on several files of the entry and
+wc(1) as well as running make test.
Cody also fixed the script check.sh (renamed from
+check) in case x is specified and is not
+executable and also made it satisfy ShellCheck. He also made ShellCheck
+not be a cow and/or (to use Bart Simpson’s advice :-) ) ‘not have a cow’
+about certain things (including one thing it was wrong about) in cow.sh (which was renamed from
+cow) mootoo.
Cody also renamed the file on.one.liners to on.one.liners.txt to help with
+browsers/GitHub.
Cody fixed an invalid bytes error in
+tr in the scripts. This does not mean that they will
+produce any output, though, as they provide expect all letters and that
+makes it harder to form perfect pangrams. On the subject of German
+umlauts and Eszett (ß) see the entry in
+bugs.md.
Cody also fixed the Makefile so that the alt code would be built when
+running make alt.
Cody converted the PS file linked to by the author to a PDF (fasc5c.pdf) and added it to the +website.
+Cody also added the try.sh and try.alt.sh scripts.
+Finally he added the scripts for the different languages that use the +alt version but with the caveat that only English appears to work. See +the entry in bugs.md for more +details.
+Cody also added the file Shakespeare.txt from 2019/mills (after running
+make) so that one can not worry about having the entire
+winner tree (or at least the 2019 tree each winner in a subdirectory).
+This is more important as there is discussion of having tarballs for
+each individual entry as a convenience.
Cody added the try.sh script. This script will
+try and show the difference (i.e. the same output) between the program
+and the result of sha512sum or shasum -a 512
+if either of those tools can be found but otherwise it’ll just run the
+program itself, showing its own sha512sum value.
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.
+He also added the try.sh script.
+He also made it possible to easily redefine the memory macro
+Z at compilation time by modifying the Makefile.
He fixed a link in the spoiler source code. As a spoiler it felt more +important that this was done (some typos were fixed as well but only +some - the purpose was to only correct spelling and only some, not to +change wording or anything else).
+Cody made the make fullscreen more
+portable by not relying on stty(1) and sed(1)
+but rather it just uses tput(1). He also made it so that if
+tput(1) is not found it tells the user an easier way to
+compile the full screen size rather than having to modify the Makefile.
+This done with a script, fullscreen.sh, to simplify the
+Makefile and provide an easy way to tell the user how to compile it,
+assuming that the environmental variables LINES and
+COLUMNS are set. But even if they’re not set it explains
+how to easily compile the program to a specific size. Note that
+LINES and COLUMNS is not available to scripts
+so it can’t make use of them that way.
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
+:-)
Cody also added the simple ascii.c
+that (while it has an arg) prints out the character of the ASCII value
+(uses isascii(3) first). This combined with the try.sh script that he added allows one to
+easily reconstruct the source code through GDB by the fact it’s a
+backtrace quine.
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 try.sh to +showcase the entry a bit more easily.
+Cody also added the example-1.txt and example-2.txt text files from 2018/vokes so that the entry does not +rely on any other entry existing.
+Cody added the missing docs rule to
+the Makefile that forms a PDF file. The rule requires the tool pdflatex.
Cody also added the alternate code.
+Cody also added the try.sh and try.alt.sh scripts.
+Cody also disabled the optimiser because the author stated that for
+clang the levels [0123s] work okay but with GCC (6) they only said level
+0 works, suggesting that with some versions of GCC it might not be
+correct with levels != 0 and since 0 works with clang that’s okay.
+Similarly, the same for C standards tested: gnu17 was not
+tested but gnu11 was so the standard was set to
+gnu11.
Cody added the try.sh script which also involved slightly
+updating the sample_input.txt
+file (removed trailing newlines as it resulted in diff
+showing differences when it shouldn’t) and adding the ioccc.txt file.
Cody fixed the script check_be.sh: it assumed that
+prog_be was in PATH which is unlikely so it
+was changed to ./prog_be.
Cody also improved the make test rule (which uses
+check_be.sh and the Little Endian counterpart) so that it
+shows that the files are identical rather than showing nothing at
+all.
Cody also added the try.sh +script.
+Cody added the try.sh script which although at first +glance might not appear to have a point, it actually does, namely +showing how you can automate play and then reminding you to actually +play for real, with a friend, whether that’s real or imagined.
+Cody copied the files from the spoiler.zip file +(from his copy during the preview period) that was password protected +with a password that was no longer known.
+He also added the try.sh +script.
+Cody fixed the script run_clock.sh which gave a funny +error when running it:
+$ ./run_clock.sh
+-bash: ./run_clock.sh: cannot execute: required file not foundIf run from within vim a different error message occurred:
+/bin/bash: ./run_clock.sh: /usr/bin/end: bad interpreter: No such file or directory
+though this was only noticed later on after it was fixed.
+What was wrong? A typo in the shebang which had
+/usr/bin/end instead of /usr/bin/env. Anyone
+who knows Cody would know that he’d zoom in on that quite quick.
Also if clock did not exist and one tried to run the
+script it would make an invalid clock.c which meant it
+could not compile so it now runs make clock first.
Cody also reported (during the preview period of 2020) for some
+systems (at some point?) like macOS the use of make clock
+would not work due possibly to a timing issue so Yusuke changed it to compile the clock.c file directly (this might have
+been fixed in the Makefile later on but it doesn’t hurt to keep it in
+and this way it isn’t a problem in any system). How Cody remembers this
+minor detail more than three years ago is something that many people
+might wonder but he also once told us that if someone moves something of
+his even a millimetre from where it was he knows it so he might be
+called unusual (and he argues, with pride, eccentric :-) ) :-)
Cody also added the run_clock.alt.sh script which +is analogous to the run_clock.sh +but for the alt code provided by the author, Yusuke.
+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! :-) You’re welcome to ask +me questions if you wish and I encourage you to do so as the cake is +quite picky!
+Cody, with intentional irony here :-), fixed +formatting, links and typos in various files.
+He also added the try.sh +script.
+He also added the alt code and the try.alt.sh script.
+The try scripts involved the addition of a text file, key.txt which has the key of the file +the judges added in try.this.txt which itself was +based on something the author (Cody :-) ) submitted in the first +place.
+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 :-)
+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! :-) You’re welcome to ask +me questions if you wish and I encourage you to do so as the cake is +quite picky!
+Cody added the try.sh script. This script does the
+conversion of pi.wav (showing the digits) and also converts
+the number for jenny.wav and a number Cody ‘came up with’:
+one that resembles IOCCC 28: 10666-28. The
+6 is the closest to C in his head even though
+it’s not perfect.
If play(1) from SoX is not installed the script checks
+for aplay(1). If neither are installed it warns the user
+about this, linking to the FAQ about it, and tells them they will have
+to play the WAV files manually. Otherwise it’ll use the program to play
+the WAV files (and in one case stdout).
Cody also 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).
Cody also fixed the script makegif.sh in a variety of ways:
+shellcheck(1), make sure the program is compiled first (allowing one to
+specify which compiler to use with
+CC=foo ./makegif.sh ...), checking that
+convert(1) is found and that it worked properly (linking to
+the proper FAQ entry if not installed or it fails).
He also added a link that has much more details about this phenomenon +to the README.md. Naturally he’s one of the ones who can read text even +if it’s even more jumbled but we know of others too.
+Cody also added from 2019/mills +the text file Shakespeare.txt as we are +considering to have each entry have a tarball with the entry by +itself.
+Also, to explain the confusing to most people award, Cody gave a
+quick translation of lámatyávë, which comes from History of
+Middle-earth [HoMe], volume X, Morgoth’s Ring, which he also has (and
+which is part of the 12 volume set by the late Christopher Tolkien, son
+and literary executor and heir to J.R.R. Tolkien).
Cody added the MIDI files cvikl.mid and entertainer.mid from the URLs +we suggested so that one need not download them and to make sure they +can always be obtained even if the domain or link goes dead.
+Cody also added the try.sh +script.
+Cody added alternate code that will +feel more at home for vi users. One might still end up cursing (see the +README.md file) but probably a lot less :-)
+Cody also added a make rule (make cppp) for the author’s
+provided C++ code that can preprocess the generated output to make them
+more acceptable to typical compilers. See the README.md for more
+details.
Cody fixed the top level Makefile
+all rule which had a stray fi; without an
+if so the rule failed entirely.
Cody also made a variety of other changes in all the Makefiles, +sometimes to get an entry to work, all noted above, but he also +improved them all in at least one or two ways. Some of +the changes made are below.
+Cody 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 for instance
+having to disable the optimiser or enabling (in one case)
+-g.
Also, rather than check $(CC) for exact matches of
+gcc or clang it now is that if
+$(CC) contains gcc or contains
+clang then the specific actions related to the specific
+compiler will be done (priority is gcc then clang). This is useful
+because it’s not guaranteed that the compiler names for gcc
+or clang will be exactly that; in macOS for instance it can
+happen that they are in fact different names especially if one installs
+them from something like MacPorts
+or possibly Homebrew.
There were some other fixes as well including mass typo fixes in the +Makefiles (though that usually does not mean it is worth a thank you +note it might be worth noting in this case). Other times it was enabling +or disabling the optimiser to fix an entry, sometimes causing other +problems that also had to be fixed, a good example being 1986/marshall (see the compilers.md for the amusing +details and all that had to be done to fix it).
+There was a ‘problem’ where ${MAKE} was
+$(MAKE): this doesn’t break anything but it is inconsistent
+with the rest of the ${foo} tools even if by tradition it
+is $(MAKE).
Cody also added missing variables like BASH and
+PDFLATEX to the var.mk file and
+removed another that was deemed problematic or undesired. Other variable
+names had typos in them.
A comment was missing for the diff_alt_orig rule in all
+the Makefiles and this, along with many other fixes and changes to the
+Makefiles were made by Cody’s sgit tool but many other
+changes he did manually.
Cody, being the IOCCC’s resident corrections +officer :-) (and a fine one at that, we think :-) ), made many, many +typ0 (… :-) ) fixes throughout the README.md files, scripts, other data +files, Makefiles (see above) etc.
+He also updated the formatting of the README.md files (after renaming +the old files to README.md) to proper markdown.
+Where possible he made the presentation of the entries much more +consistent across the entries of all the years as well as other files. +This is not possible for everything (the remarks of authors, for +instance, cannot be and should not be made consistent but adding +markdown where necessary in the remarks is).
+A lot of these fixes were done with his sgit tool as well but many were +done manually too.
+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.
+A good number of the past winners of the IOCCC +tested, identified and helped correct and/or improve the write-ups of +fellow IOCCC entries 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 entries.
+We call out the extensive contributions of Cody Boone
+Ferguson who is responsible for most of the improvements and fixes
+including many EXTREMELY HARD bug fixes like 1988/phillipps, 1992/vern, 2001/anonymous, 2004/burley and 2005/giljade, making entries
+like 1985/sicherman and
+1986/wall not need
+-traditional-cpp (all EXTREMELY HARD),
+fixing entries to work with clang (some EXTREMELY HARD
+like 1991/dds) or as much as
+possible (1989/westley, a
+true masterpiece that is INCREDIBLY HARD, MUCH MORE SO
+than any other fix!), porting entries to macOS (some
+EXTREMELY HARD like 1998/schweikh1, fixing
+code like 2001/herrmann2 to work in
+both 32-bit/64-bit which can be EXTREMELY
+HARD, providing alternate code where useful/necessary,
+improving ALL Makefiles, writing scripts to
+greatly simplify running many of the entries and writing sgit to easily run
+sed on files in the repo to help build the website.
Cody Boone Ferguson also used one of his own tools to detect many +dead links. While the tool was not perfect it went a long way to uncover +a good number of bad, broken or otherwise invalid links. It was a very +laborious task to copy and paste problematic links into the Internet Wayback Machine in an effort +to try and find otherwise lost content. A good number of links that now +refer to something in the Internet +Wayback Machine replace bad, broken, or otherwise invalid links are +thanks to Cody’s efforts! Another tool he wrote detected inconsistent +award titles in the README files and CSV file (that he generated from +the SQL file).
+THANK YOU VERY MUCH for your extensive efforts in +helping improve the IOCCC presentation of past IOCCC entries and fixing +almost all past entries for modern systems!
+Yusuke +Endoh supplied a number of important bug fixes to a number of past +IOCCC entries. Some of those fixes were EXTREMELY TECHNICALLY +CHALLENGING such as 1989/robison, 1990/cmills, 1992/lush and 2001/ctk. THANK YOU VERY +MUCH for your help!
+If you submitted a fix to an entry for which you are not the author, +and your fix is accepted (in part or as a whole), we would be happy to +add you to this honor roll list.
+If you believe we incorporated one of your fixes to an IOCCC winner +(that you are not the author of) for which we neglected to mention in +this file, please contact the IOCCC so that +we may correct the record.
+ + + + + + + +