diff --git a/Makefile b/Makefile index a5f85d922..4d036e8ae 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ README2INDEX= bin/readme2index.sh QUICK_README2INDEX= bin/quick-readme2index.sh TAR_ENTRY= bin/tar-entry.sh TAR_YEAR= bin/tar-year.sh +TAR_ALL= bin/tar-all.sh ############# @@ -237,7 +238,7 @@ indent.c: # They might not even work (right now). :-) .PHONY: help genpath genfilelist verify_entry_files gen_authors gen_location gen_years \ - entry_index quick_entry_index form_entry_tarball form_year_tarball \ + entry_index quick_entry_index form_entry_tarball form_year_tarball form_all_tarball \ gen_year_index quick_www www # Suggest rules in this section @@ -258,6 +259,7 @@ help: @echo make quick_entry_index @echo make form_entry_tarball @echo make form_year_tarball + @echo make form_all_tarball @echo make quick_www @echo make www @@ -384,6 +386,17 @@ form_year_tarball: ${ALL_YEARS} ${TAR_YEAR} ${ALL_YEARS} -v 3 ${TAR_YEAR} -v 1 -W @echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-=' +# form compressed tarball for all of the IOCCC +# +# XXX - We also use -W because some entry files don't yet exist - XXX +# XXX - Remove -W when make verify_entry_files runs without err - XXX +# XXX - We do not yet form year level and the top level tarball - XXX +# +form_all_tarball: ${TAR_ALL} + @echo '=-=-=-=-= IOCCC begin make $@ =-=-=-=-=' + ${TAR_ALL} -v 1 -W + @echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-=' + # do work to build HTML content for the web site # # This rule uses quick_entry_index, not slow_entry_index, so @@ -405,6 +418,7 @@ quick_www: ${MAKE} quick_entry_index ${MAKE} form_entry_tarball ${MAKE} form_year_tarball + ${MAKE} form_all_tarball @echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-=' # do everything needed to build HTML content for the web site @@ -424,6 +438,7 @@ www: ${MAKE} entry_index ${MAKE} form_entry_tarball ${MAKE} form_year_tarball + ${MAKE} form_all_tarball @echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-=' diff --git a/README.md b/README.md index d9aa376d8..bcc75fb37 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,182 @@ 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 + ## What follows is the actual README.md file - Remove from top down to this line - XXX -# About the IOCCC winner GitHub repository + + +# The International Obfuscated C Code Contest + +# **Obfuscate** | *verb* [with object] + +- render obscure, unclear, or unintelligible: the spelling changes will deform +some familiar words and obfuscate their etymological origins. + + - bewilder (someone): it is more likely to obfuscate people than enlighten them. +obfuscatory | adjective + + From late Middle English (as adjective): from late Latin obfuscat- 'darkened', from the verb obfuscare, based on Latin fuscus 'dark'. + +## **Obfuscation** | *noun* + +- 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. + + From late Middle English: from late Latin obfuscatio(n-), from obfuscare 'to darken or obscure' (see obfuscate). + +The official IOCCC web site is . + +## How it was started: + +The original inspiration of the International Obfuscated C Code Contest came +from the Bourne Shell source and the finger 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](https://www.bulwer-lytton.com)) that asks people to create the +worst opening line to a novel (that contest in turn was inspired by disgust over +[a novel](https://en.wikipedia.org/wiki/Paul_Clifford) by [Edward +Bulwer-Lytton](https://en.wikipedia.org/wiki/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! + + +## Suggestions on how to understand the winning entries: + +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: + +```sh +sed -e '/^#.*include/d' prog.c | cc -E +``` + +This 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. 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. + +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! 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 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. + +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. + + +## Regarding the source archive: + +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: +. + + +Regarding the distribution of sources: + +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 for instructions on +how to send us a message: + +## Some final things to remember: + +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 most recent one is +the first entry has 1 appended, the second has 2 etc. + +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 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! + + +## About the IOCCC winner GitHub repository The [official IOCCC entries GitHub repository](https://github.com/ioccc-src/winner) are the official winners of the **International Obfuscated C Code Contest (IOCCC)**, the @@ -31,7 +205,7 @@ See also [the IOCCC FAQ](/faq.html) for addition information on the IOCCC. # Copyright and License -Copyright (C) 2020,2023, Landon Curt Noll. All Rights Reserved. +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](https://creativecommons.org/licenses/by-sa/4.0/) license. If you do use this work in some form, the [IOCCC judges](/judges.html) would appreciate diff --git a/all/.gitignore b/all/.gitignore deleted file mode 100644 index d332be6d3..000000000 --- a/all/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -1*/ -2*/ -3*/ diff --git a/all/README.md b/all/README.md deleted file mode 100644 index d55fb83e6..000000000 --- a/all/README.md +++ /dev/null @@ -1,182 +0,0 @@ -# The International Obfuscated C Code Contest - -*Last updated: Tue Apr 4 04:43:07 PDT 2023* - -### **Obfuscate** | *verb* [with object] - -- render obscure, unclear, or unintelligible: the spelling changes will deform -some familiar words and obfuscate their etymological origins. - - - bewilder (someone): it is more likely to obfuscate people than enlighten them. -obfuscatory | adjective - - From late Middle English (as adjective): from late Latin obfuscat- 'darkened', from the verb obfuscare, based on Latin fuscus 'dark'. - -### **Obfuscation** | *noun* - -- 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. - - From late Middle English: from late Latin obfuscatio(n-), from obfuscare 'to darken or obscure' (see obfuscate). - -The official IOCCC web site is . - -## How it was started: - -The original inspiration of the International Obfuscated C Code Contest came -from the Bourne Shell source and the finger 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](https://www.bulwer-lytton.com)) that asks people to create the -worst opening line to a novel (that contest in turn was inspired by disgust over -[a novel](https://en.wikipedia.org/wiki/Paul_Clifford) by [Edward -Bulwer-Lytton](https://en.wikipedia.org/wiki/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! - - -## Suggestions on how to understand the winning entries: - -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: - -```sh -sed -e '/^#.*include/d' prog.c | cc -E -``` - -This 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. 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. - -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! 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 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. - -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. - - -## Regarding the source archive: - -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: -. - - -Regarding the distribution of sources: - -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 for instructions on -how to send us a message: - -## Some final things to remember: - -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 most recent one is -the first entry has 1 appended, the second has 2 etc. - -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 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! - -## Copyright - -Copyright(c) Landon Curt Noll, Simon Cooper, Peter Seebach -and Leonid A. Broukhis, 1984-2023. -All Rights Reserved. Permission for personal, educational or non-profit -use is granted provided this this copyright and notice are included in its -entirety and remains unaltered. All other uses must receive prior permission -from the contest judges. - - diff --git a/all/summary.txt b/all/summary.txt deleted file mode 100644 index 23062667e..000000000 --- a/all/summary.txt +++ /dev/null @@ -1,374 +0,0 @@ -# yr entry Spoiler summary -# - -1984 anonymous prints hello world, where read is write -1984 decot prints garbage, weird cpp defines (keywords for others) -1984 laman prints spiralling numbers, laid out in columns -1984 mullender hardcoded vax and pdp-11 code to move :-) across the screen - -1985 applin one-liner to print hello world, with execlp -1985 august cpp obfuscated, compressed, main-recursive primes in binary -1985 lycklama heavily cpped with o_oo identifiers, scrolls text right -1985 shapiro two defines, one 7-liner, results in a maze -1985 sicherman rot13 with strange #defs that create comment headers etc. - -1986 applin hello world works under cc, /bin/sh, and f77 -1986 august struct-heavy e-computation, memory allocation with sbrk -1986 bright hex dump, cpp compressed, uses lost of << for constants -1986 hague morse code filter written with 'DIT DAH _DIT DIT_DAH' -1986 holloway prints hello world! via a recursive main -1986 marshall train engine-shaped program prints "choo choo" -1986 pawka prints 'obfuscated?' big, uses xyyyx idents... -1986 stein prints HHMMSS in UTC time -1986 wall dvorak keyboard emulator - -1987 biggar program: "P;" defined on command line -1987 heckbert obfuscated fold program -1987 hines counts goto's, all ids anagrams of 'goto', all flow w goto -1987 korn one-liner that prints a message on a Unix system -1987 lievaart very good othello player -1987 wall roman numeral -> decimal and vice versa conversion -1987 westley individually palindromic lines prints a palindrome - -1988 applin massive #define stuff, includes itself; prints table of primes -1988 dale prints command line, using lots of system calls -1988 isaak table driven table of the elements; cpp, self-inclusion -1988 litmaath sorts each arg using only argc, argv, and 'while();' -1988 phillipps 'first day of christmas', tables, heavily main() calling -1988 reddy prints name of 'char *(*(foo[16])();', compressed -1988 robison print e in any base, uses only --, >=, and while() -1988 spinellis #include "/dev/tty" -1988 westley prints '3.141', circle made of '_-_-_-_' in layout - -1989 fubar self-reconstructing, recompiling factorial program -1989 jar.1 char*_="Hello world.\n"; -1989 jar.2 lisp interpreter, compressed -1989 ovdluhe monkey-typer following template, 'APE' identifiers -1989 paul print Fibonacci base 2 by simulating Turing machine -1989 robison apl-expression interpreter (binary), written in C-- -1989 roemer prints e, script-pi shaped layout, _31415 identifiers -1989 tromp squished tetris -1989 vanb one-liner prints all subsets of arguments -1989 westley reversible, rot13able program that reverses and/or rot13s. - -1990 baruch short prog to solve N-queens problem -1990 cmills squished blackjack game -1990 dds basic interpreter, heavily compressed -1990 dg rot13 done with strange cpp macros -1990 jaw compress & atob standins -1990 pjr the quick brown fox... cppd, structs of functions -1990 scjones trigraph-abusing self-reproducing program -1990 stig nested-comment tester (all on command line) -1990 tbr simple compressed shell, silly layout -1990 theorem numerically solves the equation y'=f(x,y) -1990 westley poetic exchange between lovers, prints "luvs me, luvs not" - -1991 brnstnd sorta stack language -1991 buzzard walk thru a maze from a first person point of view -1991 cdupont prints a message without vowels -1991 davidguy plays life on a root window, doesn't need Xlib or include files -1991 dds basic compiler, heavily compressed -1991 fine rot13s lines of input -1991 ant compressed vi-like editor -1991 rince game with sprites, boulders, dimonds, and keys -1991 westley plays tic-tac-toe, compile output for next move, prints board - -1992 adrian grep-like utility using a state machine transition language -1992 albert factors multi-precision numbers with factors < MAX_LONG -1992 buzzard.1 print factorial, gcd or prime test using a Babbage-like engine -1992 buzzard.2 forth-like stack machine -1992 gson anagram generator -1992 ant make utility -1992 imc Mandelbrot/Julia drawer -1992 kivinen X11 space invaders, dropout and knockout games -1992 lush prints "Hello, World" using error messages -1992 marangon game to balance a grid of digits to all 5's -1992 nathan obfuscation by (trivial) encryption (source not exported) -1992 vern plays chess -1992 westley print ASCII world map and mark a location by lat/long - -1993 dgibson plays the game of like using cpp -1993 ejb tower of Hanoi and patience pizzle -1993 ant egrep utility with Posix-like documentation -1993 jonth game of Tetris -1993 leo game of mastermind (cows & bulls) -1993 lmfjyh source is the filename, prints value of __FILE__ -1993 cmills X11 program that shatters and bounces windows -1993 plummer prints numbers up to a given value -1993 rince game state machine language, comes with a number of games -1993 schnitzi answers questions about English text in a file -1993 vanb calculator that prints in octal - -1994 dodsond1 plays a game of othello -1994 dodsond2 Hunt the Wumpus (gziped source) -1994 horton Plot cubic equations on a tty -1994 imc print a random n by n magic square -1994 ldb print a random line from stdin -1994 schnitzi flips stdin along a diagonal (source mirrored along diagonal) -1994 shapiro print time of day on an tty -1994 smr world's smallest self reproducing program -1994 tvr interactive fractals for the X Window System -1994 weisberg prints prime numbers -1994 westley Adventure/Dungeon like game played via the C pre-processor - -1995 cdua Generate a maze on the scren and then solve it -1995 dodsond1 Text to "Pig Latin" translator -1995 dodsond2 Interactive 3D Maze -1995 esde Searches for words in a file which have the same Soundex code -1995 garry Environment-expansion and binary output via escaped env vars -1995 heathbar 16 bit addition the easy/hard way -1995 leo Output interesting patterns and cycles in PostScript -1995 makarios Emits the base 8 representation of prime palindromic in base 8 -1995 savastio Infinite-precision factorial calculator -1995 schnitzi Find divisors: where a core dump is a feature, not a bug -1995 spinellis Abusing the rules -1995 vanschnitz Towers of Hanoi via the C pre-processor - -1996 august Subset of C compiler and byte code interpreter -1996 dalbec Generator of strong probable-primes to a given base -1996 eldby Flying 3D spheres in an ASCII display -1996 gandalf Displays the ASCII and 8 bit character tables -1996 huffman Braille to ASCII and vice versa -1996 jonth X based dual player tic-tac-toe game -1996 rcm Gunzip equivalent -1996 schweikh1 Calculates Easter dates from 1582 to 2199 AD -1996 schweikh2 Search for a limited class of expressions that equal a constant -1996 schweikh3 Determins the memory allocation honesty of the OS -1996 westley Shows the time on clock with a configurable face and style - -# There was no IOCCC in 1997. - -1998 banks A flight simulator! -1998 bas1 Outputs a gziped 3D beam maze in Postscript -1998 bas2 determines the size of stdin under IOCCC sizing rules -1998 chaos Rotates and zooms an object using ASCII graphics -1998 df A word guessing game -1998 dlowe Pootifies stdin (useful to view Microsoft html files) -1998 dloweneil A very addictive ASCII poot game -1998 dorssel ASCII / Morse code translator -1998 fanf Translates Lambda expressions into combinator expressions -1998 schnitzi Prints a C program that sorts arguments using strange functions -1998 schweikh1 Tests to see if your compiler and headers are standard -1998 schweikh2 Prints random 0's and 1's; causes some gcc's as passes to choke -1998 schweikh3 Finds duplicate files that waste disk space -1998 tomtorfs CRC generator - -# There was no IOCCC in 1999. - -2000 anderson ASCII to semaphore code convertor -2000 bellard Prints M6972593 (2^6972593-1) by Modular Fast Fourier Transform -2000 bmeyer An image compressor -2000 briddlebane Verbally abuses the user -2000 dhyang Saitou Hajime image that prints a prog that prints a prog ... -2000 dlowe A dc-style calculator that uses embedded Perl -2000 jarijyrki An X-based spreadsheet program with graphing features! -2000 natori Phase of the moon -2000 primenum Source with English words that looks like a prime tester -2000 rince Plots the positions of the four Galilean moons of Jupiter -2000 robison Highly Compressed Program for Playing Hygienic Checkers -2000 schneiderwent Prints the aproximate time in words -2000 thadgavin Prints a dazzeling moving image under multiple interfaces -2000 tomx C source, shell program and Makefile - -2001 anonymous optimizing dynamic binary translator, x86 progs on any host -2001 bellard A C subset programming system for x86 -2001 cheong Computes arbitrary-precision square root -2001 coupard Outputs current time as a sound file -2001 ctk A driver game -2001 dgbeards Plays suicide chess -2001 herrmann1 A Turing machine using preprocessor -2001 herrmann2 A SIRDS/3D generator, the source is SIRDS/3D itself -2001 jason An Adventure-like game -2001 kev A Pong game across network -2001 ollinger Prints primes with a sieve graph -2001 rosten Makes X mouse pointer have inertia or anti-inertia -2001 schweikh Shell glob matcher -2001 westley Sorts/scrambles, outputs as text/punch-cards -2001 williams Plays X-based missile command - -# There was no IOCCC in 2002. - -# There was no IOCCC in 2003. - -2004 anonymous Rendering of a stroked font -2004 arachnid Curses maze displayer/navigator with only line-of-sight visibility -2004 burley A Poker game -2004 gavare A ray tracer -2004 gavin Mini-OS -2004 hibachi A CGI capable HTTP server -2004 hoyle Curses based polynomial graphing with auto-scale -2004 jdalbec Conway's look'n'say sequence split into elements -2004 kopczynski OCR of 8, 9, 10 and 11 -2004 newbern Renders arbitary bitmapped fonts -2004 omoikane A CRC inserter -2004 schnitzi Editor animation -2004 sds Space/tab/linefeed steganography -2004 vik1 X Windows car racing game -2004 vik2 Calculates prime numbers using only CPP - -2005 aidan Sudoku solver -2005 anon Multi-dimensional sliding tile puzzle generator -2005 boutines Voronoi diagram generator -2005 chia Java parody -2005 giljade 2D sliding tile puzzle solver -2005 jetro Audio synthesizer -2005 klausler Anagram generator -2005 mikeash Self-printing Common Lisp interpreter -2005 mynx Web browser -2005 persano Generates animated knots -2005 sykes Commodore PET emulator -2005 timwi A BF lanaguage interpreter -2005 toledo Play chess -2005 vik Wolfenstein style graphics engine -2005 vince Rotating GL Cube demo - -2006 birken Circuit Simulator -2006 borsanyi Email address to gif image -2006 grothe Plays audio using a monitor -2006 hamre A calculator for rational numbers -2006 meyer A two player sudoku like game -2006 monge Graphical fractal generator -2006 night A maze game -2006 sloane Animated donut -2006 stewart IFS fractal generator -2006 sykes1 Bedlam cube solver -2006 sykes2 A clock in one line -2006 toledo1 Solve the knight chess problem -2006 toledo2 An 8080 emulator -2006 toledo3 An X11 chess game - -# There was no IOCCC in 2007. - -# There was no IOCCC in 2008. - -# There was no IOCCC in 2009. - -# There was no IOCCC in 2010. - -2011 akari Downsampler with 3 embeded programs -2011 blakely Life/reverse life -2011 borsanyi Bar graph plotter -2011 dlowe Neural network classifier -2011 eastman Bouncing Ball in ANSI Graphics -2011 fredriksson Aproximate grep -2011 goren Magritte tribute -2011 hamaji Paint by number puzzle -2011 hou Scientific calculator -2011 konno QWERTY keyboard position identifer -2011 richards JIT dc -2011 toledo Dual player tank shooter game -2011 vik Tracker player -2011 zucker Text raytracing - -2012 blakely Animated GIFs of surfaces -2012 deckmyn Music notation printer -2012 dlowe Conway's game of death -2012 endoh1 ASCII fluid dynamics -2012 endoh2 Pi/e quine -2012 grothe Shamir secret sharing -2012 hamano PDF with little dancing men -2012 hou Syntax highlighter -2012 kang Decodes spelled out numbers -2012 konno Linear cellular automaton 1-liner -2012 omoikane Encodes text as a C program -2012 tromp Lambda interpreter -2012 vik Steganography -2012 zeitak Brace matcher - -2013 birken use Tetris to paint a picture -2013 cable1 1-liner party of a US President -2013 cable2 OCR in quick brown fox ASCII art -2013 cable3 IBM PC emulator -2013 dlowe ASCII spark line graph -2013 endoh1 SKI Combinator Calculus tool -2013 endoh2 JPEG quine that expands and inverts -2013 endoh3 play music with ABC notation -2013 endoh4 ASCII solid rotation -2013 hou ray tracer -2013 mills HTTP server ray tracing a timestamp -2013 misaka horizontal or vertical file concat -2013 morgan1 X11 based Solar system simulator -2013 morgan2 X11 & ASCII domino matching game -2013 robison multi-precision arithmetic - -2014 birken Klingon web server -2014 deak CPP and C99 abuse -2014 endoh1 QR encoder -2014 endoh2 ASCII to DNA transcoder -2014 maffiodo1 homage to a popular game -2014 maffiodo2 ASCII art 1-line converter -2014 morgan make clone -2014 sinon optimizer-controlled shooter game -2014 skeggs dynamic library abusing game -2014 vik Morse audio transcoder -2014 wiedijk Y combinator - -2015 burton hex/decimal calculator -2015 dogon X11 Minecraft demo -2015 duble handwriting with Braille -2015 endoh1 reaction-diffusion system HTTP server -2015 endoh2 hidden text quine -2015 endoh3 1984/mullender emulator -2015 endoh4 visual factorization -2015 hou MD5 without integers -2015 howe diff tool -2015 mills1 flappy bird -2015 mills2 uncompress -2015 muth preprocessor Turing engine -2015 schweikhardt Collatz bignum computation -2015 yang text encoder with sea star pattern, varies with C flavor - -# There was no IOCCC in 2016. - -# There was no IOCCC in 2017. - -2018 algmyr Converts text to sound using font as spectrogram -2018 anderson Visualizer of typographic rivers -2018 bellard Image compression demo -2018 burton1 Hex dumper -2018 burton2 Tokenize and count -2018 ciura Strunk & White checker -2018 endoh1 Animated GIF from text -2018 endoh2 Monty-Pythonesque animated quine -2018 ferguson Dawkins' weasel simulator -2018 giles SDL falling sand -2018 hou Converter of JSON to SVG pie chart -2018 mills PDP-7/11 simulator -2018 poikola Ursa Major ASCII animation -2018 vokes Computing strongly connected graph components -2018 yang Text rotator and shifter - -2019 adamovsky Unlambda interpreter -2019 burton Word count -2019 ciura Pangram generator -2019 diels-grabsch1 Tiny compress -2019 diels-grabsch2 Self hashing -2019 dogon X11 Golly game of Life -2019 duble Collaborative graphics editor -2019 endoh Backtrace quine -2019 giles WAV reverberator -2019 karns Breadth-first search on text -2019 lynn Haskell compiler -2019 mills Machine Learning on text -2019 poikola SHA, Prime, Fibonacci -2019 yang Text scrambler - -2020 burton Byte to binary, no loops, 1-liner -2020 carlini printf machine -2020 endoh1 Minesweeper solver -2020 endoh2 Star Wars crawler -2020 endoh3 ASCII clock -2020 ferguson1 Snake game -2020 ferguson2 Enigma machine -2020 giles DTMF encoder/decoder -2020 kurdyukov1 MD5 checksum -2020 kurdyukov2 Image segmenter -2020 kurdyukov3 Letter permuter -2020 kurdyukov4 Markov chain text generator -2020 otterness MIDI improver -2020 tsoj Asteroids -2020 yang PIN-protected program generator - -# There was no IOCCC in 2021. - -# There was no IOCCC in 2022. diff --git a/bin/README.md b/bin/README.md index c1dc1e483..0f97f6fdc 100644 --- a/bin/README.md +++ b/bin/README.md @@ -260,6 +260,17 @@ bin/all-run.sh -v 3 bin/tar-entry.sh -v 1 -W ``` +## [tar-all.sh](tar-all.sh) + +Form the compressed tarball for all IOCCC years and all IOCCC entries. + +Usage: + +```sh +bin/tar-all.sh -v 1 +``` + + ## [tar-year.sh](tar-year.sh) Form a compress tarball for an IOCCC year. diff --git a/bin/gen-years.sh b/bin/gen-years.sh index 8c5d413f6..d26dd3562 100755 --- a/bin/gen-years.sh +++ b/bin/gen-years.sh @@ -543,7 +543,7 @@ fi ## All IOCCC years -**Download IOCCC** [all entry source](all/ioccc.all.tar.bz2) +**Download IOCCC** [all entry source](ioccc.tar.bz2) ### Jump to: EOF diff --git a/bin/tar-all.sh b/bin/tar-all.sh new file mode 100755 index 000000000..3aa49745a --- /dev/null +++ b/bin/tar-all.sh @@ -0,0 +1,830 @@ +#!/usr/bin/env bash +# +# tar-all.sh - tar files for all IOCCC years +# +# Copyright (c) 2024 by Landon Curt Noll. All Rights Reserved. +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby granted, +# provided that the above copyright, this permission notice and text +# this comment, and the disclaimer below appear in all of the following: +# +# supporting documentation +# source copies +# source works derived from this source +# binaries derived from this source or from derived source +# +# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\ +# +# Share and enjoy! :-) + +# firewall - must be bash with a version 4.2 or later +# +# We must declare arrays with -ag or -Ag, and we need loops to "export" modified variables. +# +if [[ -z ${BASH_VERSINFO[0]} || ${BASH_VERSINFO[0]} -lt 4 || ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 2 ]]; then + echo "$0: ERROR: bash version must be >= 4.2: $BASH_VERSION" 1>&2 + exit 4 +fi + +# setup bash file matching +# +# Requires bash with a version 4.2 or later +# +shopt -s nullglob # enable expanded to nothing rather than remaining unexpanded +shopt -u failglob # disable error message if no matches are found +shopt -u dotglob # disable matching files starting with . +shopt -s globskipdots # enable never matching . or .. +shopt -u nocaseglob # disable strict case matching +shopt -u extglob # enable extended globbing patterns +shopt -s globstar # enable ** to match all files and zero or more directories and subdirectories + +# set variables referenced in the usage message +# +export VERSION="1.0 2024-02-17" +NAME=$(basename "$0") +export NAME +export V_FLAG=0 +GIT_TOOL=$(type -P git) +export GIT_TOOL +if [[ -z "$GIT_TOOL" ]]; then + echo "$0: FATAL: git tool is not installed or not in \$PATH" 1>&2 + exit 210 +fi +"$GIT_TOOL" rev-parse --is-inside-work-tree >/dev/null 2>&1 +status="$?" +if [[ $status -eq 0 ]]; then + TOPDIR=$("$GIT_TOOL" rev-parse --show-toplevel) +fi +export TOPDIR +export REPO_URL="https://github.com/ioccc-src/temp-test-ioccc" +export CAP_W_FLAG_FOUND= +GTAR_TOOL=$(type -P gtar) +export GTAR_TOOL +if [[ -z "$GIT_TOOL" ]]; then + echo "$0: FATAL: gtar (gnu tar) tool is not installed or not in \$PATH" 1>&2 + exit 9 +fi + +# set usage message +# +export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir] [-D docroot/] [-n] [-N] + [-p tool] [-u repo_url] [-w site_url] [-W] + + -h print help message and exit + -v level set verbosity level (def level: 0) + -V print version string and exit + + -d topdir set topdir (def: $TOPDIR) + -D docroot/ This option is ignored + + -n go thru the actions, but do not update any files (def: do the action) + -N do not process file, just parse arguments and ignore the file (def: process the file) + + -p tool This option is ignored + + -u repo_url This option is ignored + -w site_url This option is ignored + + -W Warn if a file in the manifest is missing: (def: error if a file is missing) + +Exit codes: + 0 all OK + 1 a file listed in .entry.json or .filelist is missing and -W was not used, or no files were found + 2 -h and help string printed or -V and version string printed + 3 command line error + 4 bash version is < 4.2 + 5 YYYY/dir is not a entry directory, or YYYY is not an IOCCC year + 6 bin/filelist.entry.json.awk is not a non-empty readable file + 7 error in trying to determine files used by the year + 8 missing critical top level file or missing .filelist file + 9 gnu tar is missing or execution failed + >= 10 < 210 ((not used)) + >= 210 internal tool error + +$NAME version: $VERSION" + +# setup +# +export NOOP= +export DO_NOT_PROCESS= +export EXIT_CODE="0" + +# parse command line +# +while getopts :hv:Vd:D:nNp:u:U:w:W flag; do + case "$flag" in + h) echo "$USAGE" 1>&2 + exit 2 + ;; + v) V_FLAG="$OPTARG" + ;; + V) echo "$VERSION" + exit 2 + ;; + d) TOPDIR="$OPTARG" + ;; + D) ;; + n) NOOP="-n" + ;; + N) DO_NOT_PROCESS="-N" + ;; + p) ;; + u) ;; + U) ;; + w) ;; + W) CAP_W_FLAG_FOUND="true" + ;; + \?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2 + echo 1>&2 + print_usage 1>&2 + exit 3 + ;; + :) echo "$0: ERROR: option -$OPTARG requires an argument" 1>&2 + echo 1>&2 + echo "$USAGE" 1>&2 + exit 3 + ;; + *) echo "$0: ERROR: unexpected value from getopts: $flag" 1>&2 + echo 1>&2 + echo "$USAGE" 1>&2 + exit 3 + ;; + esac +done + +# parse the command line arguments +# +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: debug level: $V_FLAG" 1>&2 +fi +# +shift $(( OPTIND - 1 )); +# +if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: file argument count: $#" 1>&2 +fi +if [[ $# -ne 0 ]]; then + echo "$0: ERROR: expected 0 args, found: $#" 1>&2 + exit 3 +fi +# + +# verify that we have a topdir directory +# +REPO_NAME=$(basename "$REPO_URL") +export REPO_NAME +if [[ -z $TOPDIR ]]; then + echo "$0: ERROR: cannot find top of git repo directory" 1>&2 + echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2 + exit 220 +fi +if [[ ! -e $TOPDIR ]]; then + echo "$0: ERROR: TOPDIR does not exist: $TOPDIR" 1>&2 + echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2 + exit 221 +fi +if [[ ! -d $TOPDIR ]]; then + echo "$0: ERROR: TOPDIR is not a directory: $TOPDIR" 1>&2 + echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2 + exit 222 +fi + +# verify that we have an bin subdirectory +# +export BIN_PATH="$TOPDIR/bin" +if [[ ! -d $BIN_PATH ]]; then + echo "$0: ERROR: bin is not a directory under topdir: $BIN_PATH" 1>&2 + exit 223 +fi +export BIN_DIR="bin" + +# cd to topdir +# +if [[ ! -e $TOPDIR ]]; then + echo "$0: ERROR: cannot cd to non-existent path: $TOPDIR" 1>&2 + exit 224 +fi +if [[ ! -d $TOPDIR ]]; then + echo "$0: ERROR: cannot cd to a non-directory: $TOPDIR" 1>&2 + exit 225 +fi +export CD_FAILED +if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: about to: cd $TOPDIR" 1>&2 +fi +cd "$TOPDIR" || CD_FAILED="true" +if [[ -n $CD_FAILED ]]; then + echo "$0: ERROR: cd $TOPDIR failed" 1>&2 + exit 226 +fi +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2 +fi + +# determine the name of our tarball +# +export TARBALL="ioccc.tar.bz2" + +# verify we have our awk tool +# +export FILELIST_ENTRY_JSON_AWK="$BIN_DIR/filelist.entry.json.awk" +if [[ ! -e $FILELIST_ENTRY_JSON_AWK ]]; then + echo "$0: ERROR: filelist.entry.json.awk does not exist: $FILELIST_ENTRY_JSON_AWK" 1>&2 + exit 6 +fi +if [[ ! -f $FILELIST_ENTRY_JSON_AWK ]]; then + echo "$0: ERROR: filelist.entry.json.awk is not a file: $FILELIST_ENTRY_JSON_AWK" 1>&2 + exit 6 +fi +if [[ ! -r $FILELIST_ENTRY_JSON_AWK ]]; then + echo "$0: ERROR: filelist.entry.json.awk is not a readable file: $FILELIST_ENTRY_JSON_AWK" 1>&2 + exit 6 +fi +if [[ ! -s $FILELIST_ENTRY_JSON_AWK ]]; then + echo "$0: ERROR: filelist.entry.json.awk is not a not a non-empty readable file: $FILELIST_ENTRY_JSON_AWK" 1>&2 + exit 6 +fi + +# verify we have non-empty readable ioccc.css file +# +export IOCCC_CSS="ioccc.css" +if [[ ! -e $IOCCC_CSS ]]; then + echo "$0: ERROR: ioccc.css does not exist: $IOCCC_CSS" 1>&2 + exit 8 +fi +if [[ ! -f $IOCCC_CSS ]]; then + echo "$0: ERROR: ioccc.css is not a file: $IOCCC_CSS" 1>&2 + exit 8 +fi +if [[ ! -r $IOCCC_CSS ]]; then + echo "$0: ERROR: ioccc.css is not a readable file: $IOCCC_CSS" 1>&2 + exit 8 +fi +if [[ ! -s $IOCCC_CSS ]]; then + echo "$0: ERROR: ioccc.css is not a not a non-empty readable file: $IOCCC_CSS" 1>&2 + exit 8 +fi + +# verify we have non-empty readable ioccc.css file +# +export VAR_MK="var.mk" +if [[ ! -e $VAR_MK ]]; then + echo "$0: ERROR: var.mk does not exist: $VAR_MK" 1>&2 + exit 8 +fi +if [[ ! -f $VAR_MK ]]; then + echo "$0: ERROR: var.mk is not a file: $VAR_MK" 1>&2 + exit 8 +fi +if [[ ! -r $VAR_MK ]]; then + echo "$0: ERROR: var.mk is not a readable file: $VAR_MK" 1>&2 + exit 8 +fi +if [[ ! -s $VAR_MK ]]; then + echo "$0: ERROR: var.mk is not a not a non-empty readable file: $VAR_MK" 1>&2 + exit 8 +fi + +# verify we have a non-empty readable .top file +# +export TOP_FILE=".top" +if [[ ! -e $TOP_FILE ]]; then + echo "$0: ERROR: .top does not exist: $TOP_FILE" 1>&2 + exit 5 +fi +if [[ ! -f $TOP_FILE ]]; then + echo "$0: ERROR: .top is not a regular file: $TOP_FILE" 1>&2 + exit 5 +fi +if [[ ! -r $TOP_FILE ]]; then + echo "$0: ERROR: .top is not an readable file: $TOP_FILE" 1>&2 + exit 5 +fi +if [[ ! -s $TOP_FILE ]]; then + echo "$0: ERROR: .top is not a non-empty readable file: $TOP_FILE" 1>&2 + exit 5 +fi + +# parameter debugging +# +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: VERSION=$VERSION" 1>&2 + echo "$0: debug[3]: NAME=$NAME" 1>&2 + echo "$0: debug[3]: V_FLAG=$V_FLAG" 1>&2 + echo "$0: debug[3]: GIT_TOOL=$GIT_TOOL" 1>&2 + echo "$0: debug[3]: GTAR_TOOL=$GTAR_TOOL" 1>&2 + echo "$0: debug[3]: TOPDIR=$TOPDIR" 1>&2 + echo "$0: debug[3]: REPO_URL=$REPO_URL" 1>&2 + echo "$0: debug[3]: NOOP=$NOOP" 1>&2 + echo "$0: debug[3]: DO_NOT_PROCESS=$DO_NOT_PROCESS" 1>&2 + echo "$0: debug[3]: CAP_W_FLAG_FOUND=$CAP_W_FLAG_FOUND" 1>&2 + echo "$0: debug[3]: EXIT_CODE=$EXIT_CODE" 1>&2 + echo "$0: debug[3]: REPO_NAME=$REPO_NAME" 1>&2 + echo "$0: debug[3]: BIN_PATH=$BIN_PATH" 1>&2 + echo "$0: debug[3]: BIN_DIR=$BIN_DIR" 1>&2 + echo "$0: debug[3]: YEAR_DIR=$YEAR_DIR" 1>&2 + echo "$0: debug[3]: TARBALL=$TARBALL" 1>&2 + echo "$0: debug[3]: FILELIST_ENTRY_JSON_AWK=$FILELIST_ENTRY_JSON_AWK" 1>&2 + echo "$0: debug[3]: IOCCC_CSS=$IOCCC_CSS" 1>&2 + echo "$0: debug[3]: VAR_MK=$VAR_MK" 1>&2 + echo "$0: debug[3]: FILELIST=$FILELIST" 1>&2 +fi + +# If -N, time to exit +# +if [[ -n $DO_NOT_PROCESS ]]; then + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: arguments parsed, -N given, exit 0" 1>&2 + fi + exit 0 +fi + +# create a temporary file manifest list +# +TMP_MANIFEST_LIST=".$NAME.$$.manifest.list" +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2 +fi +if [[ -z $NOOP ]]; then + trap 'rm -f $TMP_MANIFEST_LIST; exit' 0 1 2 3 15 + rm -f "$TMP_MANIFEST_LIST" + if [[ -e $TMP_MANIFEST_LIST ]]; then + echo "$0: ERROR: cannot remove temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2 + exit 227 + fi + :> "$TMP_MANIFEST_LIST" + if [[ ! -e $TMP_MANIFEST_LIST ]]; then + echo "$0: ERROR: cannot create temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2 + exit 228 + fi +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary file manifest list is not used: $TMP_MANIFEST_LIST" 1>&2 +fi + +# create a temporary sort list of files to tar +# +TMP_TAR_LIST=".$NAME.$$.tar.list" +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: temporary file tar list: $TMP_TAR_LIST" 1>&2 +fi +if [[ -z $NOOP ]]; then + trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST; exit' 0 1 2 3 15 + rm -f "$TMP_TAR_LIST" + if [[ -e $TMP_TAR_LIST ]]; then + echo "$0: ERROR: cannot remove temporary file tar list: $TMP_TAR_LIST" 1>&2 + exit 231 + fi + :> "$TMP_TAR_LIST" + if [[ ! -e $TMP_TAR_LIST ]]; then + echo "$0: ERROR: cannot create temporary file tar list: $TMP_TAR_LIST" 1>&2 + exit 232 + fi +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary file tar list is not used: $TMP_TAR_LIST" 1>&2 +fi + +# create a temporary exit code +# +# It is a pain to set the EXIT_CODE deep inside a loop, so we write the EXIT_CODE into a file +# and read the file (setting EXIT_CODE again) after the loop. A hack, but good enough for our needs. +# +TMP_EXIT_CODE=".$NAME.$$.exit.code" +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: temporary exit code: $TMP_EXIT_CODE" 1>&2 +fi +if [[ -z $NOOP ]]; then + trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE; exit' 0 1 2 3 15 + rm -f "$TMP_EXIT_CODE" + if [[ -e $TMP_EXIT_CODE ]]; then + echo "$0: ERROR: cannot remove temporary exit code: $TMP_EXIT_CODE" 1>&2 + exit 233 + fi + echo "$EXIT_CODE" > "$TMP_EXIT_CODE" + if [[ ! -e $TMP_EXIT_CODE ]]; then + echo "$0: ERROR: cannot create temporary exit code: $TMP_EXIT_CODE" 1>&2 + exit 234 + fi +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary exit code is not used: $TMP_EXIT_CODE" 1>&2 +fi + +# create a temporary tarball +# +TMP_TARBALL=".$NAME.$$.tar.bz2" +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: temporary tarball: $TMP_TARBALL" 1>&2 +fi +if [[ -z $NOOP ]]; then + trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE $TMP_TARBALL; exit' 0 1 2 3 15 + rm -f "$TMP_TARBALL" + if [[ -e $TMP_TARBALL ]]; then + echo "$0: ERROR: cannot remove temporary tarball: $TMP_TARBALL" 1>&2 + exit 235 + fi + :> "$TMP_TARBALL" + if [[ ! -e $TMP_TARBALL ]]; then + echo "$0: ERROR: cannot create temporary tarball: $TMP_TARBALL" 1>&2 + exit 236 + fi +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary tarball is not used: $TMP_TARBALL" 1>&2 +fi + +# add the top level top level files into the IOCCC year's manifest +# +{ + echo "$IOCCC_CSS" + echo "$VAR_MK" +} >> "$TMP_MANIFEST_LIST" + +# generate sorted list of entry files from the full IOCCC manifest +# +if [[ -z $NOOP ]]; then + + # process each IOCCC year + # + export YYYY + for YYYY in $(< "$TOP_FILE"); do + + # debug YYYY + # + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: starting to process year: $YYYY" 1>&2 + fi + + # verify we have non-empty readable year level .filelist file + # + export FILELIST="$YYYY/.filelist" + if [[ ! -e $FILELIST ]]; then + echo "$0: ERROR: .filelist for $YYYY does not exist: $FILELIST" 1>&2 + exit 8 + fi + if [[ ! -f $FILELIST ]]; then + echo "$0: ERROR: .filelist for $YYYY is not a file: $FILELIST" 1>&2 + exit 8 + fi + if [[ ! -r $FILELIST ]]; then + echo "$0: ERROR: .filelist for $YYYY is not a readable file: $FILELIST" 1>&2 + exit 8 + fi + if [[ ! -s $FILELIST ]]; then + echo "$0: ERROR: .filelist for $YYYY is not a not a non-empty readable file: $FILELIST" 1>&2 + exit 8 + fi + + # load the year level into the IOCCC year's manifest + # + grep -F -v "$YYYY/$YYYY.tar.bz2" "$FILELIST" >> "$TMP_MANIFEST_LIST" + + # verify that YYYY is a readable directory + # + if [[ ! -e $YYYY ]]; then + echo "$0: ERROR: YYYY does not exist: $YYYY" 1>&2 + exit 7 + fi + if [[ ! -d $YYYY ]]; then + echo "$0: ERROR: YYYY is not a directory: $YYYY" 1>&2 + exit 7 + fi + if [[ ! -r $YYYY ]]; then + echo "$0: ERROR: YYYY is not an readable directory: $YYYY" 1>&2 + exit 7 + fi + + # verify that YYYY has a non-empty readable .year file + # + export YEAR_FILE="$YYYY/.year" + if [[ ! -e $YEAR_FILE ]]; then + echo "$0: ERROR: YYYY/.year does not exist: $YEAR_FILE" 1>&2 + exit 7 + fi + if [[ ! -f $YEAR_FILE ]]; then + echo "$0: ERROR: YYYY/.year is not a regular file: $YEAR_FILE" 1>&2 + exit 7 + fi + if [[ ! -r $YEAR_FILE ]]; then + echo "$0: ERROR: YYYY/.year is not an readable file: $YEAR_FILE" 1>&2 + exit 7 + fi + if [[ ! -s $YEAR_FILE ]]; then + echo "$0: ERROR: YYYY/.year is not a non-empty readable file: $YEAR_FILE" 1>&2 + exit 7 + fi + + # process each entry directory under YYYY + # + export YYYY_DIR + for YYYY_DIR in $(< "$YEAR_FILE"); do + + # debug YYYY_DIR + # + if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: starting to process year/dir: $YYYY_DIR" 1>&2 + fi + + # parse YYYY_DIR + # + if [[ ! -d $YYYY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR is not a directory: $YYYY_DIR" 1>&2 + EXIT_CODE="7" # exit 7 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ ! -w $YYYY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR is not a writable directory: $YYYY_DIR" 1>&2 + EXIT_CODE="7" # exit 7 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + export YEAR_DIR=${YYYY_DIR%%/*} + if [[ -z $YEAR_DIR ]]; then + echo "$0: ERROR: YYYY_DIR not in YYYY/dir form: $YYYY_DIR" 1>&2 + EXIT_CODE="7" # exit 7 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + export ENTRY_DIR=${YYYY_DIR#*/} + if [[ -z $ENTRY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR not in $YEAR_DIR/dir form: $YYYY_DIR" 1>&2 + EXIT_CODE="7" # exit 7 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ $ENTRY_DIR = */* ]]; then + echo "$0: ERROR: YYYY_DIR: $YYYY_DIR dir contains a /: $ENTRY_DIR" 1>&2 + EXIT_CODE="7" # exit 7 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + + # verify that YYYY_DIR is a writable directory + # + if [[ ! -e $YYYY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR does not exist: $YYYY_DIR" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ ! -d $YYYY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR is not a directory: $YYYY_DIR" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ ! -w $YYYY_DIR ]]; then + echo "$0: ERROR: YYYY_DIR is not an writable directory: $YYYY_DIR" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + + # verify YYYY/dir/.path + # + export DOT_PATH="$YYYY_DIR/.path" + if [[ ! -s $DOT_PATH ]]; then + echo "$0: ERROR: not a non-empty file: $DOT_PATH" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + DOT_PATH_CONTENT=$(< "$DOT_PATH") + if [[ $YYYY_DIR != "$DOT_PATH_CONTENT" ]]; then + echo "$0: ERROR: arg: $YYYY_DIR does not match $DOT_PATH contents: $DOT_PATH_CONTENT" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + export ENTRY_JSON="$YYYY_DIR/.entry.json" + if [[ ! -e $ENTRY_JSON ]]; then + echo "$0: ERROR: .entry.json does not exist: $ENTRY_JSON" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ ! -f $ENTRY_JSON ]]; then + echo "$0: ERROR: .entry.json is not a file: $ENTRY_JSON" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + if [[ ! -r $ENTRY_JSON ]]; then + echo "$0: ERROR: .entry.json is not a readable file: $ENTRY_JSON" 1>&2 + EXIT_CODE="8" # exit 8 + echo "$0: Warning: EXIT_CODE set to: $EXIT_CODE" 1>&2 + continue + fi + + # use the entry's manifest to add files to the IOCCC year's manifest, excluding the entry's tarball file + # + awk -f "$FILELIST_ENTRY_JSON_AWK" "$ENTRY_JSON" >> "$TMP_MANIFEST_LIST" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR: awk -f $FILELIST_ENTRY_JSON_AWK $ENTRY_JSON >> $TMP_MANIFEST_LIST failed, error: $status" 1>&2 + exit 7 + fi + + # remove entry's tarball from the IOCCC year's manifest + # + export ENTRY_ID="${YEAR_DIR}_${ENTRY_DIR}" + sed -i '' -e "/$ENTRY_ID\.tar\.bz2$/d" "$TMP_MANIFEST_LIST" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR: sed -i '' -e '/$ENTRY_ID.tar.bz2/d' $TMP_MANIFEST_LIST failed, error: $status" 1>&2 + exit 7 + fi + done + + # sort the manifest list + # + sort -d -u "$TMP_MANIFEST_LIST" -o "$TMP_MANIFEST_LIST" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR: sort -d -u $TMP_MANIFEST_LIST -o $TMP_MANIFEST_LIST failed, error: $status" 1>&2 + exit 7 + fi + + done + +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary file manifest list was not formed: $TMP_MANIFEST_LIST" 1>&2 +fi + +# generate sorted list of found entry files +# +# We exclude the compressed tarball itself because we are writing it. +# +if [[ -z $NOOP ]]; then + + # debug YYYY + # + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: verifying that all files in the manifest exist" 1>&2 + fi + + # exclude the compressed tarball from the tarlist + # + grep -F -v "$TARBALL" < "$TMP_MANIFEST_LIST" | while read -r file; do + + # if file does not exist, warn + # + if [[ ! -e $file ]]; then + echo "$0: Warning: missing $YYYY_DIR file: $file" 1>&2 + # unless -W, missing files cause this tool to exit 1 + if [[ -z $CAP_W_FLAG_FOUND ]]; then + echo 1 > "$TMP_EXIT_CODE" # exit 1 + fi + else + echo "$file" + fi + done > "$TMP_TAR_LIST" + if [[ $V_FLAG -ge 7 ]]; then + echo "$0: debug[7]: list of files to tar start below" 1>&2 + cat "$TMP_TAR_LIST" 1>&2 + echo "$0: debug[7]: list of files to tar ends above" 1>&2 + fi +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary file tar list was not formed: $TMP_MANIFEST_LIST" 1>&2 +fi +if [[ ! -s "$TMP_TAR_LIST" ]]; then + echo "$0: ERROR: no files found to tar for: $ENTRY_JSON" 1>&2 + exit 1 +fi +EXIT_CODE=$(< "$TMP_EXIT_CODE") +if [[ -z $EXIT_CODE ]]; then + echo "$0: ERROR: temporary exit file is empty: $TMP_EXIT_CODE" 1>&2 + exit 233 +fi + +# form the tarball +# +# We use gnu tar to form the bzip2 compressed tarball with careful arguments +# so that the resulting tarball is the same, byte for byte. +# +if [[ -z $NOOP ]]; then + + # debug + # + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: about to form compressed tarball: $TMP_TARBALL" 1>&2 + fi + + # case: form the tarball verbosely if -v 3 or more + # + if [[ $V_FLAG -gt 3 ]]; then + echo "$0: debug[3]: about to execute:" \ + "$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \ + "--owner=501 --group=20 --numeric-owner --totals" \ + "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \ + "-jcvf $TMP_TARBALL < $TMP_TAR_LIST" 1>&2 + "$GTAR_TOOL" --files-from=- --sparse --no-acls --sort=name \ + --owner=501 --group=20 --numeric-owner --totals \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ + -jcvf "$TMP_TARBALL" < "$TMP_TAR_LIST" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR:" \ + "$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \ + "--owner=501 --group=20 --numeric-owner --totals" \ + "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \ + "-jcvf $TMP_TARBALL < $TMP_TAR_LIST failed, error: $status" 1>&2 + EXIT_CODE=9 # exit 9 + fi + + # case: form the tarball silently + # + else + "$GTAR_TOOL" --files-from=- --sparse --no-acls --sort=name \ + --owner=501 --group=20 --numeric-owner \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ + -jcf "$TMP_TARBALL" < "$TMP_TAR_LIST" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR:" \ + "$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \ + "--owner=501 --group=20 --numeric-owner" \ + "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \ + "-jcf $TMP_TARBALL < $TMP_TAR_LIST failed, error: $status" 1>&2 + EXIT_CODE=9 # exit 9 + fi + fi + + # verify the tarball is not empty + # + if [[ ! -s $TMP_TARBALL ]]; then + echo "$0: ERROR: tarball is missing os empty: $TMP_TARBALL" 1>&2 + EXIT_CODE=9 # exit 9 + fi + +# case: -n +# +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, did not execute:" \ + "$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \ + "--owner=501 --group=20 --numeric-owner --totals" \ + "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \ + "-jcvf $TMP_TARBALL < $TMP_TAR_LIST" 1>&2 +fi +EXIT_CODE=$(< "$TMP_EXIT_CODE") +if [[ -z $EXIT_CODE ]]; then + echo "$0: ERROR: temporary exit file has no contents: $TMP_EXIT_CODE" 1>&2 + exit 234 +fi + +# move the tarball in place only if different +# +if [[ -z $NOOP ]]; then + if cmp -s "$TMP_TARBALL" "$TARBALL"; then + + # case: tarball did not change + # + if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: file did not change: $TARBALL" 1>&2 + fi + + else + + # case: tarball changed, update the file + # + if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: mv -f -- $TMP_TARBALL $TARBALL" 1>&2 + fi + if [[ $V_FLAG -ge 3 ]]; then + mv -f -v -- "$TMP_TARBALL" "$TARBALL" + status="$?" + else + mv -f -- "$TMP_TARBALL" "$TARBALL" + status="$?" + fi + if [[ status -ne 0 ]]; then + echo "$0: ERROR: mv -f -- $TMP_TARBALL $TARBALL filed, error code: $status" 1>&2 + EXIT_CODE=9 # exit 9 + elif [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: built replaced HTML file: $TARBALL" 1>&2 + fi + if [[ ! -s $TARBALL ]]; then + echo "$0: ERROR: not a non-empty index HTML file: $TARBALL" 1>&2 + EXIT_CODE=9 # exit 9 + fi + fi + +elif [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: because of -n, temporary file manifest list was not formed: $TMP_MANIFEST_LIST" 1>&2 +fi + +# All Done!!! -- Jessica Noll, Age 2 +# +if [[ -z $NOOP ]]; then + rm -f "$TMP_MANIFEST_LIST" "$TMP_TAR_LIST" "$TMP_EXIT_CODE" "$TMP_TARBALL" +elif [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: -n disabled execution of: rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE $TMP_TARBALL" 1>&2 +fi +exit "$EXIT_CODE" diff --git a/ioccc.tar.bz2 b/ioccc.tar.bz2 new file mode 100644 index 000000000..acb012666 Binary files /dev/null and b/ioccc.tar.bz2 differ diff --git a/years.html b/years.html index 455648a27..381b6194c 100644 --- a/years.html +++ b/years.html @@ -105,8 +105,8 @@

IOCCC Winning Entries by Year

All IOCCC years

-

Download IOCCC all -entry source

+

Download IOCCC all entry +source

Jump to:

2020 | 2019 | 2018 | 2015 |