This is a HUGE commit:
417 files changed, 874 insertions(+), 874 deletions(-)
As the IOCCC website now is https enabled I have updated the
'http://www.ioccc' to 'https://www.ioccc'.
There was also a typo in Makefiles where it said 'for VERY WELCOME' when
it should be 'are VERY WELCOME'.
Finally slashdot.org is also https enabled so references to
'http://slashdot' were changed to 'https://slashdot'.
This was done by my sgit tool (see https://github.com/xexyl/sgit)
like:
sgit -e 's,http://www.ioccc,https://www.ioccc,g' -e 's/for VERY WELCOME/are VERY WELCOME/g' -e .
but because I didn't have a list of files that should be modified I had
to be careful which files to commit as I had files that were changed but
not ready to be committed. Since I did it in steps, finding typos as I
went along, I actually ran sgit three times but to simplify the above
(and to show that it's possible to do more than one sed command) I made
it all as one. Since I did not have a list of files ahead of time I had
to determine what files to commit, first going through them like:
for j in $(for i in $(git status|grep modified|cut -d: -f2); do \
git grep 'https://www.ioccc' "$i"; done|cut -d: -f1|sort|uniq); \
do git diff "$j"; done|less -r
(I had to pipe through less because of a strange problem with the git
diff which appears to be because of a terminal problem maybe due to the
command above but it was all I could come up with in a very tired head.)
The above and
git status | grep modified:
showed that some C files had been modified which obviously should not be
done so I had to do:
git co '*c'
to undo those changes.
Finally to commit the correct files I did:
for i in $(git status|grep modified|cut -d: -f2); do \
git grep -E 'https://www.ioccc|https://slashdot|are VERY WELCOME' "$i"; \
done |cut -d: -f1|sort|uniq|xargs git commit -v
or so (with any formatting issues or typos here due to typos in the log
due to the terminal (in)sanity issue described).
Fixed supplementary program to add a newline after printing the first
line: else the output of both lines were merged and hard to read.
Updated Makefile to always compile the supplementary program.
Modified thanks-for-fixes.md wrt this entry including fixing the link to
the supplementary program (it did not specify the directory: it just had
the file name itself).
This is to make it more standard which further allows one to run make on
some other source code, say because they want to try and fix an entry
but forget to update the Makefile. Or if they're the author they can not
worry about it in some cases. But since LDFLAGS is the standard way it
seems better to have the LIBS variable in the Makefile be LDFLAGS.
Maybe there is a reason to not have this and I'm happy to close this in
that case but it does seem better this way so I'm doing this commit.
As besides the entries that are not supposed to compile/cannot compile
due to architectural limitations all the entries can compile in macOS
(though some do not work - yet(? I have plans to work on more later)) it
was not necessary to not silence the warnings after all as the entries
that don't work will be easy to identify ('they don't work' :-) ) so I
can just do make CSILENCE= all in the directory of those entries which
solves the problem I had originally thought of.
Some of the Makefiles have retained other changes I had to make
yesterday to get the entries to work with clang in linux but most of
them were either not changed or were made better with the rollback of
the commit that originally silenced warnings.
Now work on silencing warnings for linux can be done.
Due to the fact we now have .orig.c files and thus the possibility of
winner.orig or prog.orig being built I have updated all the .gitignore
files so that these files ignored. This was done with the following
shell commands, for reference:
for i in $(find 19* 200* 201[0123] -mindepth 2 -maxdepth 2 -name .gitignore) ; do echo $(dirname "$i"|sed -e 's,[0-9]\{4\}/,,g').orig >> "$i"; done
for i in $(find 201[4-9] 2020 -mindepth 2 -maxdepth 2 -name .gitignore) ; do echo prog.orig >> "$i"; done
and the two commands is because it was only in 2014 that the winning
entries were renamed to prog so prog.orig is the correct glob.
C99 does not support implicit int. There are three ways I can think of
that would solve this problem but I chose to add the 'int' to the
parameters to prevent any problems in the future.
Used the following script to check for warnings
not silenced via ${CSILENCE}:
```sh
find ???? -mindepth 1 -maxdepth 1 -type d | while read dir; do
(cd "$dir"; echo =-=-= "$dir" =-=-= ; csilence -v 1 clobber all ; echo ; csilence -v 1 clobber alt)
done 2>&1 | less
```
The script herrmann1.sh invoked the program itself which is not needed
and would in fact invoke it during compilation as the script is what
compiles the program. The program is to be invoked via the script
itself but the script also compiles the program as well.
Fixed the script for shellcheck.
Note that there still is a problem in that with older gcc versions it's
supposed to animate on compilation but this no longer works. See the
bugs.md for details.
At least one entry was missing (1984/anonymous).
Some entries were removed. One such entry was not ever broken but
instead when I had renamed a file (to markdown) I forgot to update the
DATA variable in the Makefile which then broke compilation. This was
seen in the log and mistakenly believed that there was something wrong
with the entry when there wasn't. Other entries removed were not fixes
but notes.
Various README.md files have been updated for this sometimes just
formatting merely because I opened the file because for instance there
is an alternate version (many by me) that is referred to. I'd not be
surprised if more README.md files have to be updated for this much
better system but these will be found in time when I do another pass
(and some years I have not checked at all yet).
The fix thank you's have been moved from `README.md` to
`thanks-for-fixes.md`.
**WARNING**: Some mistakes may have been made in doing this.
We presume later changes by others will correct any issues.
The `CONTRIBUTING.md` was renamed `how-to-enter.md`.
A 3rd line of links was added to top level html such as
`contact.html`, `index.html`, `judges.html`, `winners.html`,
and `years.html`.
Improved blank line use in a number (but not all) `README.md` files.
The is a file excluded from this commit that has had the change because
there are other changes but the file is incomplete. That file will be
committed when the fixes are complete which will happen at a later date.
Since arrow keys can be more natural than other keys like the program's
',' and '.' for movement I added a version which lets you use arrow keys
instead. One player could use the ',' and the other '.' or both can play
with the same, whichever they pick.
I also slowed down the speed of the ball as it moved very fast
considering the slow speed the paddle moves. The README.md shows how to
reset it or change the value via make.
Updated .gitignore.
Added herrmann2.alt.c. This is for a new try command to show a feature
of the entry. It can generate the original code so the try command does
this, redirecting stdout to a file (herrmann2.orig.c) and then does a
diff on the two files, to show how they're the same.
The make alt rule was fixed so it doesn't compile with herrmann2.c but
rather herrmann2.alt.c though I'm not even sure why that was defined at
all except to say that it must have been something I forgot to change
after fixing it properly.
Updated .gitignore to add herrmann2.orig.c.
Further format fixes in README.md.
This sings a different counting song, Ten in the Bed. It uses another C
feature (a char *[]) that the Ten Green Bottles does not use. This is
for fun as well as to show another program (with a different C feature)
that the program works on, again assuming -m32 is allowed.
Instead of using numbers it uses strings (as expected with a char *[])
in the singing.
This was for fun (and to see if the program would work on arrays) after
I remembered the song in a comment on GitHub - about the Ten Green
Bottles song.
Running make alt will compile the anonymous.ten.c without specifying
-m32: whether it'll end up being 64-bit or not would depend on the
system but it'll be saved as anonymous.ten.64 anyway.
The try.me.sh script will run this program directly, skipping the entry
itself, if the anonymous.ten.c cannot be compiled as a 32-bit binary.
Updated .gitignore.
Added a couple git diff commands to try and moved the INABIAF and the
warning from the author to below the judges' comments as already most
people probably will want to skip past long before to the next section.
Perhaps the fix should be moved to under the judges' comments as well
but I don't know.
There is one exception that I'm aware of and that is the U macro (U is
referenced only in strings) and this is because it segfaulted and it was
a minor change so didn't seem worth investigating further, at least for
now (if not for ever).
This feels like a new pull request is appropriate here so although it's
technically the same idea of the previous pull request this is what
should be the final revision (again unless I figure out why U
segfaulted).
Although the 'p' macro was used in other places too now it's used in one
place that had been changed to the translation. More will follow in
coming commits soon or if not hopefully later on in the day.
It now uses the G macro that was unused in the fix. I plan to look at
the other macros that were changed to be unused as well. The hope is I
can make it look much more like it originally looked but still let it
work. Last I remember unfortunately it's not simply a matter of changing
that function that uses the macros but it might be worth trying that
again.
Also in this commit I changed the literal "anonymous.c" to be __FILE__
like it was before.
In other words try and make it so that the munmap(),close(),execv() is
like how it was before (comma operator in succession) though of course
the munmap() and close() were not there until yesterday's fix as text
file busy error (ETXTBSY) was not a problem in the past with this entry.
These were part of debugging the reason execv() did not run the target
program but I forgot to remove them once I found out it was a text file
busy error.
Also added to README.md another git diff to try as it might be
instructive.
I can now report happily that the program works as it was thought to -
both modify the binary and run it. A problem was that it used to call
main() infinitely (seemingly) call main() recursively but this was
causing a problem. It had to be (as I did some while back) moved to a
new function which is not recursive. My guess is that in the past it was
okay due to exit() but I don't know if this is true or not. So what
could be done?
We have to make sure we have BOTH the file descriptor AND the mmap()d
memory close()d and munmap()d as otherwise we would get a text file busy
error. Then we simply call execv() again. I didn't change it so that the
earlier call to execv() is no longer called because I didn't want to
break anything even though at that point M is actually empty.
The astute programmer would observe that the execv() call is slightly
different: don't use M as the path but rather k[1]. Why? Because
initially M is empty but after the function is called it ends up being
something like '.anonymous.ten134517173' but this file never exists. If
you observe even no file is created (or so it seems) as only cpp is
used, not cc (I'm not actually clear what the purpose of that is). The
mmap() call is important of course as is the open() call as one of the
parameters of mmap().
Is this a workaround? Perhaps in a way but it's the only way it'll work
that I can think of as munmap() and close() must be called lest we get a
text file busy error and only then can we call execv().
Removed cpp.c and cpp make rule.
Add back cpp.c which is a C pre-processed version of anonymous.c. Added
comments and tried to format it some. Perhaps I should use a formatted /
de-obfuscator from some years ago in the IOCCC (by Dave Burton) but I
didn't think of that until much later on: I'll consider it another time.
The Makefile builds cpp by default. Works as well as anonymous.c: will
modify 32-bit ELF binaries in the right systems (it won't touch them in
macOS - I pre-compiled anonymous.ten.c as 32-bit ELF in linux and added
it to the repo as anonymous.ten.32 mostly for those who might be able to
run 32-bit ELF binaries but have no way to compile them though maybe no
system has that but it also allows for partly 'testing' the program in
macOS).
Change main target to compile to anonymous and not anonymous_tmp. This
is because otherwise running make would repeatedly try and build it. I
did try changing the target but that didn't want to work possibly due to
the cp updating the timestamp though that's a quick thought in the head
of someone who's been awake too long at the hour.
Instead anonymous.sh is the script to run to 'emulate' the running of
the target program (again assuming that's correct which does seem likely
but is still unconfirmed).
The anonymous.sh script now checks for compiling anonymous.ten.c but
uses anonymous.ten.32 as a backup if it exists.
Update bugs.md and README.md.
Anything else I'm afraid I've forgotten.
For some reason the check that exists has opposite meanings in macOS and
linux so instead of checking the status of make I check if the file
exists after a make clobber all.
Using a script running ./anonymous will run the program after modifying
it. This is a temporary workaround and it's not certain when this will
be changed back or fixed if it even can be. I am aware of some things
that might make it work IF it actually IS supposed to run the program
that it's run on (an additional reading of README.md suggests this might
indeed be the case). In any event the entry DOES modify 32-bit binaries
(bit twiddling) and then running the script (made a copy of
anonymous.sh where anonymous.c is compiled to anonymous_tmp) it will run
the program after doing this, assuming that the program to modify
actually exists.
It should be noted that because things have changed so much it is hard
to know if the modifications to 32-bit ELF binaries are correct but if
nothing else the binary will not crash on 32-bit ELF binaries and it
will modify it but still let it run (though from the author's comments
this might not be possible; this cannot yet be confirmed). Leo it
appears wrote the judges' comments so I will try and get more
information from him later on.
As it's uncertain (both to Landon and me) whether it's supposed to
execute programs it is run on or only modify it which it does (if 32-bit
ELF - which is the only kind it's supposed to act on) with my fix (see
README.md for commit ids) I have added a new bug status:
STATUS: might not be completely functional - can you confirm?
and added this new status to this entry. When or if we figure out the
functional status we will remove (if completely functional or we figure
out what's wrong and fix it which of course is the ideal case) or change
(if it is not completely functional) the status. If anyone knows the
functionality status *please* let us know!
I also updated the try.me.sh script to be quiet on make clobber so that
if -m32 does not work nothing but the error message will be shown and if
it does work only the commands and output of the commands will be shown.
In other words make commands are not shown.
Fix typo fix and format fix in 2001/anonymous/README.md.
Improve try.me.sh: test compile as 32-bit anonymous.ten.c and exit if it
cannot be done as it will otherwise not truly work right.
I also observed that this _might_ not be fixed completely. The binary
_is_ modified and _does_ run after execution, will crash on 64-bit
binaries (and it's not supposed to work on 64-bit binaries and probably
anything other than 32-bit ELF binaries) but the author comments are not
entirely clear to me. It might be that the program is supposed to be
run. At the same time though the compilation is unclear to me too: the
entry itself need not be compiled and the binary isn't compiled either
(is it supposed to be?) so why is it there? The program is at least
partially fixed in that it used to crash no matter what and it does in
any case modify the binary which was supposed to be done (and this is
why I'm still unsure about why it does anything with compilation).
Perhaps it's time to bring back the C pre-processed code but I will find
more out in the coming days I hope and if necessary I will add this
entry back to bugs.md and then look at fixing it after some higher
priority things are finished. The higher priority thing in particular
has to do with issue #4 but I have a number of already modified files
that I would like to get committed before I continue on that to make my
repo a clean state. I might or might not do that before but it might be
that there are numerous commits prior to the CSV file being worked on
again.
This was done quite easily with a bit of thought. I generated a script
that could be modified in vim if necessary (as it turned out to be
though some of it could have been generated too but I did not think of
everything at once and it is a hack).
This is how I generated it:
echo '#!/bin/bash' > bin/check_awards.sh ; ( while read -r g ; do echo grep "$g"; done < <(sed -e 's,_,/,g' -e 's/"/\\"/g' tmp/year-auth-prize.csv | awk -F, '{print grep "\x22" $2 "\x22" " " $1 "/" "README.md"}' ); ) >> bin/check_awards.sh
Then I I modified the file (again this was a hack to make it easier and
quicker and better for being tired too) in vim to make the grep use -Hc
so I could pipe it to 'grep :0'. This found the files without the right
award. So the final command was:
sh bin/check_awards.sh |grep :0
though I did have to edit some files several times.
For reference the script has been added to the repo too but with +x
permissions.
This change also required updating the CSV file in tmp/.
By chance I looked at this entry again and it immediately popped into my
head how to get it to work. Except for the one in main() the ints need
to be longs. This will now compile and work as expected both with
64-bit and 32-bit compilation.
Disabled make alt and updated .gitignore.
At the request of Landon all Makefiles have had trailing spaces removed.
The request also included README.md files but this is more complicated
as some lines have to end in spaces in order to force line breaks. For
Makefiles it's fine though. Tested the Makefiles by doing 'make clobber
all everything' from the root directory and all appears to be fine. This
testing is important because depending on how this process (removal of
trailing spaces) was done it could break the Makefiles; for instance
trying something like:
sgit -e 's/\s.*$//g' '*Makefile'
would rather break the Makefiles. This makes sense to anyone who knows
my script (and obviously sed :-) ) as long as they're not also tired but
I AM tired and so it was the first thing I tried (without thinking of
course ... though I had first thought of the correct way :-) ).
But what happens to the universes (yes I at least want to believe in the
multiverse theory and I hope it's true :-) ) when trailing spaces are
removed? :-)
As it turns out the only Makefiles touched were:
modified: 1987/wall/Makefile
modified: 1992/adrian/Makefile
modified: 1994/ldb/Makefile
modified: 2000/anderson/Makefile
modified: 2001/anonymous/Makefile
modified: 2001/bellard/Makefile
modified: 2004/kopczynski/Makefile
modified: 2015/howe/spoiler/Makefile
modified: 2019/karns/Makefile
and most of them were my fault.
Whereas fact() (factorial) is an overflow if n > 12 the Fibonacci is an
overflow if n > 48. In this case it reports an empty string - when it
finally finishes. For instance if you use n = 99 it takes a long time to
finish. Since n == 49 prints an empty value we check for overflow just
like the author did for factorial.
Add compilation of bellard.otccex.c to Makefile; this can be compiled as
64-bit so we no longer specify -m32 in ARCH but instead we do that
explicitly for bellard.c. This way users can at least enjoy the
supplementary program even if not by the bellard.c directly compiling
and executing it.
In order to know what had to change exactly I tested this out (though
it's possible I forgot to initially document changes and so I did not
test everything) and I have documented it in the README.md. The required
changes:
- remove infinite recursion from main(): move the body of main() to
another function.
- add #include <sys/mman.h> for mmap().
Without either this did not work. I also changed (in case of
non-standardised constants) '3' in the call to mmap() to be
PROT_READ|PROT_WRITE but this appears to not be strictly required.
I added the script try.me.sh which has more commands than the previous
try section to show how it works and what changes etc.
Updated .gitignore as the above script creates some.
Make make all attempt to compile anonymous.ten.c: it's an important part
of the program though it can work on other 32-bit ELF binaries.
Update bugs.md explaining why this won't work with macOS.
By instinct I suspected that the reason it did not work fully (some
invocations do work) is that it's being compiled as 64-bit. This proved
to be the case: 32-bit works in full. Thus make alt now compiles it as
64-bit and the default compiles it as 32-bit.
To prevent making the Makefile more complicated for the default (not the
alt) target we add -m32 and the alt does not do anything special.
Updated bugs.md as the bug status and other information about it has
obviously changed. Same with README.md.
Updated .gitignore.