diff --git a/2018/burton2/.gitignore b/2018/burton2/.gitignore index e2df8645d..be74df98e 100644 --- a/2018/burton2/.gitignore +++ b/2018/burton2/.gitignore @@ -1,6 +1,7 @@ # # sort with: sort -d -u *.dSYM +fixed_iocccsize indent indent.c indent.o @@ -8,3 +9,4 @@ keywords manpage prog prog.orig +tac diff --git a/2018/burton2/.winner.json b/2018/burton2/.winner.json index 298c94d2d..3269f61bc 100644 --- a/2018/burton2/.winner.json +++ b/2018/burton2/.winner.json @@ -70,7 +70,7 @@ "winners_text" : "field-by-field difference between iocccsize and ion" }, { - "file_path" : "freqcount", + "file_path" : "freqcount.sh", "winners_rank" : 100, "created_by" : null, "prog" : null, @@ -190,7 +190,7 @@ "winners_text" : "turns ASCII versions of man into real man pages" }, { - "file_path" : "mkkeywords", + "file_path" : "mkkeywords.sh", "winners_rank" : 150, "created_by" : null, "prog" : null, @@ -500,7 +500,7 @@ "winners_text" : "results without -k" }, { - "file_path" : "runtest", + "file_path" : "runtest.sh", "winners_rank" : 200, "created_by" : null, "prog" : null, @@ -510,7 +510,7 @@ "winners_text" : "test suite" }, { - "file_path" : "spotcheck", + "file_path" : "spotcheck.sh", "winners_rank" : 200, "created_by" : null, "prog" : null, @@ -530,14 +530,14 @@ "winners_text" : "reserved words for a given C standard" }, { - "file_path" : "spotdiff", + "file_path" : "spotdiff.sh", "winners_rank" : 250, "created_by" : null, "prog" : null, "filetype" : "shellscript", "winners_show" : true, "display_via" : "github", - "winners_text" : "summarize the results of spotcheck" + "winners_text" : "summarize the results of spotcheck.sh" }, { "file_path" : "2018_burton2.tar.bz2", diff --git a/2018/burton2/Makefile b/2018/burton2/Makefile index ce697b39e..b16659e86 100644 --- a/2018/burton2/Makefile +++ b/2018/burton2/Makefile @@ -114,7 +114,7 @@ PROG= prog # OBJ= ${PROG}.o CSRC= ${PROG}.o -DATA= READ_ME.txt manpage java8 kandr kandr2 v7unix +DATA= author-README.txt manpage java8 kandr kandr2 v7unix TARGET= ${PROG} # ALT_OBJ= @@ -124,9 +124,9 @@ EXTRA_DATA= ansi c++11 c++14 c++98 c11 c99 discrepancies.md \ test01.c test02.c test03.c test04.c test05.c test06.c test07.c \ test08.c test09.c test10.c test11.c test12.c test13.c test14.c \ iocccbug01.c iocccbug02.c iocccbug03.c iocccbug04.c iocccbug05.c \ - iocccbug06.c results results.k src.doc.txt patch tac.man author-README.txt \ + iocccbug06.c results results.k src.doc.txt patch tac.1 author-README.txt \ ioc_without_quote -UTILITIES= unob.sh tokenfix spotcheck spotdiff freqcount +UTILITIES= unob.sh tokenfix.sh spotcheck.sh spotdiff.sh freqcount.sh USAGE="\"prog [-tcksri] < file.c\ntokenize and count stdin\n\t-t\ttokens only\n\t-c\tcompatible counts\n\t-k\tkeep comments\n\t-s\tsuppress output\n\t-r\treserved words count as 1\n\t-i\tioccc count only\n\"" # this tool requires -trigraphs @@ -164,17 +164,17 @@ data: ${DATA} ${EXTRA_DATA} @${TRUE} # keywords: c11 -keywords: ioccc.kw.freq mkkeywords - ./mkkeywords $< > keywords +keywords: ioccc.kw.freq mkkeywords.sh + ./mkkeywords.sh $< > keywords fixed_iocccsize: fixed_iocccsize.c ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} -test: prog tac runtest fixed_iocccsize ${EXTRA_DATA} - -./runtest | diff - results - -opt=kcrs ./runtest | diff - results.k - -opt=rs prog=tac ./runtest | diff - results - -opt=rsk prog=tac ./runtest | diff - results.k +test: prog tac runtest.sh fixed_iocccsize ${EXTRA_DATA} + -./runtest.sh | diff - results + -opt=kcrs ./runtest.sh | diff - results.k + -opt=rs prog=./tac ./runtest.sh | diff - results + -opt=rsk prog=tac ./runtest.sh | diff - results.k ./fixed_iocccsize -rs < prog.c ./tac -rs prog.c diff --git a/2018/burton2/README.md b/2018/burton2/README.md index 09eca863f..4414200aa 100644 --- a/2018/burton2/README.md +++ b/2018/burton2/README.md @@ -15,117 +15,114 @@ make ### Try: ```sh -./prog -i < prog.c -./prog -s < prog.c -./prog -sk < prog.c -``` - -If you get stuck, try: - -```sh -make test +./try.sh ``` If you get really stuck, try: ```sh -man ./tac.man +man ./tac.1 ``` ## Judges' remarks: -They say size isn't everything, and in the case of IOCCC [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) -that is saying something! What is this program weighing and how much does it weigh? +They say size isn't everything, and in the case of IOCCC +[iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) that is saying something! +What is this program weighing and how much does it weigh? ## Author's remarks: ### tac - tokenize and count C and derivative languages: -``` -tac computes C program size -(obfuscated / otherwise) -by splitting code as tokens small, -ignoring space, then counting all. +`tac` computes C program size\ +(obfuscated / otherwise)\ +by splitting code as tokens small,\ +ignoring space, then counting all.\ -It tries quite hard to act the same -as counting tool of I-OCCC fame. -Some bugs were fixed, it's faster too, -and does more things, just add some glue! +It tries quite hard to act the same\ +as counting tool of I-OCCC fame.\ +Some bugs were fixed, it's faster too,\ +and does more things, just add some glue!\ -It does far more than print the size: -the token part's a better prize! -With each upon on a single line, -how many things can you design? +It does far more than print the size:\ +the token part's a better prize!\ +With each upon on a single line,\ +how many things can you design?\ -Included is a keyword sorter, -de-obfuscator, freq reporter. -With code produced as little parts, -just add your own creative arts. +Included is a keyword sorter,\ +de-obfuscator, freq reporter.\ +With code produced as little parts,\ +just add your own creative arts.\ -But first you have to figure out -the braces part, without a doubt! -And then the code - it isn't easy: -for as else? That's rather cheesy! +But first you have to figure out\ +the braces part, without a doubt!\ +And then the code - it isn't easy:\ +for as else? That's rather cheesy!\ -The rest of it is standard fare: -expressions strange, the globals bare, -confusing symbols one and oh, -and precedence you have to know. +The rest of it is standard fare:\ +expressions strange, the globals bare,\ +confusing symbols one and oh,\ +and precedence you have to know.\ -The keyword list was made external, -because of standards change eternal. -Thus other languages can now, -be counted just like C, somehow! +The keyword list was made external,\ +because of standards change eternal.\ +Thus other languages can now,\ +be counted just like C, somehow!\ + +I hope you find this code obscure\ +enough to win, and thus procure\ +a public place for all to see\ +how badly I can butcher C!\ -I hope you find this code obscure -enough to win, and thus procure -a public place for all to see -how badly I can butcher C! -``` ### Said another way.... `tac` is the inverse of `cat`(1): it un-concatenates its input into C tokens, -writing the token stream to `stdout`. There are options to suppress the token ids, -summarize the token counts, and several options to allow it to be compatible -with `iocccsize`. +writing the token stream to `stdout`. There are options to suppress the token +ids, summarize the token counts, and several options to allow it to be +compatible with `iocccsize`. The token-based output is quite useful in analyzing source code (see below), and the counter is more accurate than `iocccsize` (see below); but this can be -fixed by using the -c compatibility flag, restoring the following problems as +fixed by using the `-c` compatibility flag, restoring the following problems as in the official tool: -* whitespace **within** a string is **not** counted; - this seems wrong, as these chars **are** significant -* "`{;}`" is not counted within a double-quoted string -* whitespace preceding a comment is char-counted, unless the comment starts a line -* `-k` processes the reserved words within `//` comments(!), but not `/*`, changing the counts +* Whitespace **within** a string is **not** counted; + this seems wrong, as these chars **are** significant. +* "`{;}`" is not counted within a double-quoted string. +* Whitespace preceding a comment is `char`-counted, unless the comment starts a +line. +* `-k` processes the reserved words within `//` comments(!), but not `/*`, +changing the counts. The following bugs are always corrected: -* treats `/*/` as a complete comment (`/*/int if for/*/` has three keywords) +* Treats `/*/` as a complete comment (`/*/int if for/*/` has three keywords) * `-k` enables `//*` or within a line comment `/*` to initiate a comment block until following `*/` * `-k` processes double quote characters in `//` comments - thus a solitary quote consumes everything until the next quote -* single quotes are not handled correctly (`'"'` starts a dquote in `iocccsize`) +* Single quotes are not handled correctly (`'"'` starts a double quote in `iocccsize`) * `#ifndef` is omitted as a keyword (but `#ifdef` is allowed?) * `I` is not a reserved word. * `tac` correctly penetrates [23rd century cloaking technology][1]. ;-) There is one (known) remaining problem with detection: -* comments between preprocessor hash and keyword are not replaced with whitespace; +* Comments between preprocessor hash and keyword are not replaced with whitespace; the following counts #include as two tokens, `#` and `include` (not as a reserved word): - #/*this will not be counted*/include/*correctly*/ +```c +#/*this will not be counted*/include/*correctly*/ +``` Fixing this properly hampers backwards compatibility in counting. This requires eliding comments during the translation phases (ISO 5.1.1.2, phase 3), and yet still counting words correctly absent `-k`. -[1]: http://ioccc.org/2014/birken/hint.html "Best use of port 1701" +[1]: /2014/birken/README.md "Best use of port 1701" + ### Backwards Compatibility: @@ -135,10 +132,11 @@ counting words correctly absent `-k`. find ~/src/obc -type f -name \*.c | wc ``` -The discrepancies found are documented and explained in the file "discrepancies". +The discrepancies found are documented and explained in the file +[discrepancies.md](discrepancies.md). ```sh -find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck ./prog | ./spotdiff | +find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck.sh ./prog | ./spotdiff.sh | grep -v keep | diff -bw - discrep* | grep "[<>] cl " ``` @@ -159,17 +157,17 @@ designed to allow exhaustive, hand-counted values for comparison with the tool v These test cases were vital in debugging and regression testing, and provided a way to determine which tool was correct when there were differences. -> A version of this tool in more clearly written C (tac.c) +> A version of this tool in more clearly written C ([tac.c](tac.c)) > is presented for the Judge's consideration as a more accurate replacement for `iocccsize`. > This obfuscated entry is derived from (and compatible with) that code, > but due to obfuscation, has had some significant, deep changes for the contest. > Nevertheless, the more clearly written code remains a spoiler for this entry. NB: `iocccsize` gets a different answer from `tac` on its own -([iocccsize.c]([iocccsize.c](https://www.ioccc.org/2018/iocccsize.c)) source code; +([iocccsize.c](/2018/iocccsize.c)) source code; `tac` gets the correct answer. This is due to the aforementioned bugs within `iocccsize`, proved by fixing -[iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) with the included patch, so `iocccsize` reports +[iocccsize.c](/2018/iocccsize.c) with the included patch, so `iocccsize` reports the correct answer for itself. ### But wait... There's More! @@ -201,25 +199,27 @@ cat $* | ./prog -t | iskeyword | sort -k1nr This script was used to "optimize" the reserved word order so the most frequent IOCCC winning entry keywords are checked first. -> An interesting aside: as might be expected, obfuscation has changed the frequency of -> keyword distribution over time. The top five for the decades: ->\ -> 1980s 1990s 2000s 2010s -> ----- ----- ----- ----- -> 94 if 532 char 375 if 254 int -> 69 for 524 if 372 char 217 for -> 59 while 417 int 332 int 198 if -> 48 char 223 for 184 for 121 return -> 43 int 223 void 165 return 104 char +An interesting aside: as might be expected, obfuscation has changed the frequency of +keyword distribution over time. The top five for the decades: + +``` +1980s 1990s 2000s 2010s +----- ----- ----- ----- +94 if 532 char 375 if 254 int +69 for 524 if 372 char 217 for +59 while 417 int 332 int 198 if +48 char 223 for 184 for 121 return +43 int 223 void 165 return 104 char +``` The keyword list is external to the program, and is easily changed, sorted, checked, verified. This allows such additional programs in concert with the tool's primary operation. -A poor-man's de-obfuscator can be based upon the output of `tac -t` and a handful of -simple rules (and another use of the external keyword file). -A more refined version of this is included in the file `unob.sh`, -but the simple code below is a serviceable obfuscated C de-obfuscator in a _scripting language_. -It really is this easy with `tac`: +A poor-man's de-obfuscator can be based upon the output of `tac -t` and a +handful of simple rules (and another use of the external keyword file). A more +refined version of this is included in the file [unob.sh](unob.sh), but the +simple code below is a serviceable obfuscated C de-obfuscator in a _scripting +language_. It really is this easy with `tac`: ```sh @@ -277,22 +277,22 @@ sed 's/^# .*$//' | sed 's/^#//' | * Keywords follow the 2010s top five, without the `if`, for interesting flow control. * Sometimes a `for` can be an `else` - [inconceivable][3]! -* I see the `getopt`. But "[where's the beef?][4]" -* No character constants, several int constants, and one string +* I see the `getopt(3)`. But "[where's the beef?][4]" +* No character constants, several `int` constants, and one string (hint: which does not encode letters) -- how does this code parse code? -> Interesting aside: how many is "several int constants"? -> -> ./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}' -> ... | wc -> -> Which numbers are most often used? -> -> ... | sort -k2nr | sed 5q + - Interesting aside: how many is "several `int` constants"? + + ./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}' + ... | wc + + Which numbers are most often used? + + ... | sort -k2nr | sed 5q * The code describes its function by careful arrangement of variables up front... * ...coupled with a description of the typical IOCCC contestant, or at least the author * Why shouldn't trigraph parsing be written in trigraph? -* Where [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c) mocks, this code flaunts: +* Where [iocccsize.c](/2018/iocccsize.c) mocks, this code flaunts: "_no matter how well you may think you understand this code, you don't, so don't mess with it. :-)_" * `O,0,l,1` are used to confusing effect, local names obscure global names. * Globals are used to pass information between routines: don't reorder "unrelated" statements.... @@ -304,6 +304,7 @@ sed 's/^# .*$//' | sed 's/^#//' | [3]: https://www.youtube.com/watch?v=OHVjs4aobqs "Inconceivable" [4]: https://www.youtube.com/watch?v=Ug75diEyiA0 "Where's the beef?" + ### Rule 2: The keyword list is externalized as an include file. This presents a useful @@ -312,27 +313,28 @@ produced, but the tool can be rebuilt with any set of reserved words, just by using a different list. For instance: removing all the secondary keywords; removing all the C11 keywords; trying just K&R C. Since C++ and Java share the same operators as C, just change the keyword list and `tac` will correctly -tokenize both of these; the tokens >>> and :: can be handled with a short +tokenize both of these; the tokens `>>>` and `::` can be handled with a short post-filter ([tokenfix.sh](tokenfix.sh), included). -I believe this entry may also satisfy the request for gratuitous use of all the C11 keywords? -Whether this context satisfies "intended C language context" is a matter of interpretation. ;-) -And `tac` is ready for the IOCCC++ contest. And the IOJCC trashcan. +I believe this entry may also satisfy the request for gratuitous use of all the +C11 keywords? Whether this context satisfies "intended C language context" is a +matter of interpretation. ;-) And `tac` is ready for the IOCCC++ contest. And +the IOJCC trash can. The following reserved word files are included: - kandr from my venerable 1978 18th printing "The C Programming Language" - v7unix 7th edition Unix source code, extracted from c00.c - kandr2 from my 1988 1st printing "The C Programming Language", 2e - ansi ANS X3.159-1989 - c99 ISO/IEC 9899:1999(E) - c11 ISO/IEC 9899:201x(E) N1570 - c++98 http://en.cppreference.com/w/cpp/keyword - c++11 ISO/IEC 14882:2011(E) N3337 2012-01-16 - c++14 ISO/IEC 14882:2014(E) N4296 2014-11-09 - java8 http://docs.oracle.com/javase/specs/index.html - ioccc.kw.freq c11 + additional words, sorted on frequency of occurrence in ioccc winners +* [kandr](kandr) from my venerable 1978 18th printing "The C Programming Language" +* [v7unix](v7unix) 7th edition Unix source code, extracted from c00.c +* [kandr2](kandr2) from my 1988 1st printing "The C Programming Language", 2e +* [ansi](ansi) ANSI X3.159-1989 +* [c99](c99) ISO/IEC 9899:1999(E) +* [c11](c11) ISO/IEC 9899:201x(E) N1570 +* [c++98](c++98) http://en.cppreference.com/w/cpp/keyword +* [c++11](c++11) ISO/IEC 14882:2011(E) N3337 2012-01-16 +* [c++14](c++14) ISO/IEC 14882:2014(E) N4296 2014-11-09 +* [java8](java8) +* [ioccc.kw.freq](ioccc.kw.freq) c11 + additional words, sorted on frequency of occurrence in IOCCC winners NB: The keyword file used in this code is derived from the list in [iocccsize.c](https://www.ioccc.org/2018/iocccsize.c), @@ -354,11 +356,12 @@ This also allows the builder to configure the amount of help a utility should pr ([you want a manpage? Because that's how you get a manpage.][5]) -- a rather significant point of contention made moot. -There is definitely abuse of the Rule2 counter, exploiting a "feature" of `iocccsize`: -`iocccsize` does not Rule2 count {, } and ; when followed by whitespace -- even within a string! -Thus: Freecode, a simple, uncounted, highly obfuscated encoding of a central part -of this program. (The reserved word list is not Freecoded, both because it is useful -apart from the program, and because Freecode is not entirely free.*) +There is definitely abuse of the Rule2 counter, exploiting a "feature" of +`iocccsize`: `iocccsize` does not Rule2 count `{`, `}` and `;` when followed by +whitespace -- even within a string! Thus: Freecode, a simple, uncounted, highly +obfuscated encoding of a central part of this program. (The reserved word list +is not Freecoded, both because it is useful apart from the program, and because +Freecode is not entirely free.) * Some restrictions apply. Not approved for all uses. Some assembly required. @@ -370,12 +373,12 @@ The code is ANSI compliant, but it does have a string longer than 509 characters It has been tested on OSX and Linux, Clang and GCC. The code uses trigraphs, ironically: it parses trigraphs with trigraph code. -Because that's funny. And it remains obscure after, so trigraphs are not used for obfuscation. -Thus `-trigraphs -Wno-trigraphs` (which is also humorous). +Because that's funny. And it remains obscure after, so trigraphs are not used +for obfuscation. Thus `-trigraphs -Wno-trigraphs` (which is also humorous). It's obfuscated C. Thus `-Wno-parentheses -Wno-empty-body -Wno-char-subscripts`. -The code uses unsigned chars, but C strings are signed. Thus `-Wno-pointer-sign`. +The code uses `unsigned char`s, but C strings are `signed`. Thus `-Wno-pointer-sign`. NB: This is *not* a portability concern, the one string holds only printable ASCII characters. Thus: @@ -387,9 +390,9 @@ cc -ansi -Wall -trigraphs -Wno-trigraphs -Wno-parentheses -Wno-empty-body -Wno-c ### Coda: [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) was relentless in his pursuit of bugs. -Thanks to his reports, the version of `unob.sh` is stronger, -`tac` groks digraphs, `tokenfix` corrects for missing digraphs in `prog.c`, -and the program `manpage` was added to the corpus. +Thanks to his reports, the version of [unob.sh](unob.sh) is stronger, +`tac` groks digraphs, [tokenfix.sh](tokenfix.sh) corrects for missing digraphs +in [prog.c](prog.c), and the program [manpage.sh](manpage.sh) was added to the corpus. [manpage.sh](manpage.sh) is a useful program that turns ASCII versions of man pages (e.g. [tac.man](tac.man)) into real man pages. It works for C and C-like @@ -401,14 +404,17 @@ are not recognised when written as `-rs` in prose). Try: ```sh -./manpage tac +./manpage.sh tac -./manpage -h -./manpage -h | ./manpage -./manpage -h | ./manpage -R | less -./manpage -h | ./manpage -P | lpr +./manpage.sh -h +./manpage.sh -h | ./manpage.sh +./manpage.sh -h | ./manpage.sh -R | less +./manpage.sh -h | ./manpage.sh -P | lpr ``` +NOTE: in 2023 the `tac.man` was updated to proper man format and renamed +[tac.1](tac.1). + ## Copyright and CC BY-SA 4.0 License: diff --git a/2018/burton2/READ_ME.txt b/2018/burton2/READ_ME.txt deleted file mode 100644 index 959ecccdc..000000000 --- a/2018/burton2/READ_ME.txt +++ /dev/null @@ -1,71 +0,0 @@ -tac comes with a small suite of support programs to test and validate against. -Untar tests and variations in the same dir as the sources, -or change runtest and unob.sh to look elsewhere for the keyword and test files. - -keywords is a critical file, created from ioccc.kw.freq by mkkeywords. -Only ioccc.kw.freq produces results compatible with iocccsize.c; -however, any of the variations can be used instead: - - mkkeywords c11 > keywords - -unob.sh uses the same input file as mkkeywords to control spaces after keywords. -The script allows an environment variable, KW, to override this. -Use it simply: - - unob.sh prog.c | less - unob.sh -p prog.c | less - KW=c11 unob.sh prog.c | less - -To handle obscure command line defines, use the environment variable DEF: - - DEF="-D'g(o)'='goto o;'" KW=c11 unob.sh -p prog.c | less - -It does an amazingly good job for such a simple script. - -Manifest - -prog.c the reason for this README -keywords the file #included in prog.c, output of mkkeywords -mkkeywords reads one of the files from variations, produces string for prog.c -ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners -unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir -tokenfix patches up prog -t output for ::, >>>, ... -src.doc.txt the answers, or at least significant help -tac.c more clearly written code, offered as a replacement of iocccsize.c -patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I" -fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added - -tests/* -runtest script to run the tests; ./runtest | diff results - -results results without -k -results.k results with -k; opt=kcrs ./runtest | diff results.k - -test*.c various test cases looking for compatability -iocccbug*.c various test cases demonstrating problems with iocccsize -spotcheck script to test a lot of files vs iocccsize -spotdiff summarize the results of spotcheck, showing only differences -discrepancies text file of the differences found using all the ioccc winning entries - -to test prog: - - runtest | diff - results - opt=kcrs runtest | diff - results.k - find ~/src/obc -type f -a -name "*.c" | xargs spotcheck prog - [ | spotdiff | diff -bw - discrepancies ] - -to test tac: - - prog=tac runtest | diff - results - prog=tac opt=krs runtest | diff - results.k - find ~/src/obc -type f -a -name "*.c" | xargs spotcheck tac - -variations/* as described in the remarks, and in each file below -ansi -c++11 -c++14 -c++98 -c11 -c99 -java8 -kandr -kandr2 -v7unix diff --git a/2018/burton2/author-README.txt b/2018/burton2/author-README.txt index 959ecccdc..ac26f2152 100644 --- a/2018/burton2/author-README.txt +++ b/2018/burton2/author-README.txt @@ -1,14 +1,14 @@ tac comes with a small suite of support programs to test and validate against. Untar tests and variations in the same dir as the sources, -or change runtest and unob.sh to look elsewhere for the keyword and test files. +or change runtest.sh and unob.sh to look elsewhere for the keyword and test files. -keywords is a critical file, created from ioccc.kw.freq by mkkeywords. +keywords is a critical file, created from ioccc.kw.freq by mkkeywords.sh. Only ioccc.kw.freq produces results compatible with iocccsize.c; however, any of the variations can be used instead: - mkkeywords c11 > keywords + mkkeywords.sh c11 > keywords -unob.sh uses the same input file as mkkeywords to control spaces after keywords. +unob.sh uses the same input file as mkkeywords.sh to control spaces after keywords. The script allows an environment variable, KW, to override this. Use it simply: @@ -25,38 +25,38 @@ It does an amazingly good job for such a simple script. Manifest prog.c the reason for this README -keywords the file #included in prog.c, output of mkkeywords -mkkeywords reads one of the files from variations, produces string for prog.c +keywords the file #included in prog.c, output of mkkeywords.sh +mkkeywords.sh reads one of the files from variations, produces string for prog.c ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir -tokenfix patches up prog -t output for ::, >>>, ... +tokenfix.sh patches up prog -t output for ::, >>>, ... src.doc.txt the answers, or at least significant help tac.c more clearly written code, offered as a replacement of iocccsize.c patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I" fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added tests/* -runtest script to run the tests; ./runtest | diff results - +runtest.sh script to run the tests; ./runtest.sh | diff results - results results without -k -results.k results with -k; opt=kcrs ./runtest | diff results.k - -test*.c various test cases looking for compatability +results.k results with -k; opt=kcrs ./runtest.sh | diff results.k - +test*.c various test cases looking for compatibility iocccbug*.c various test cases demonstrating problems with iocccsize -spotcheck script to test a lot of files vs iocccsize -spotdiff summarize the results of spotcheck, showing only differences -discrepancies text file of the differences found using all the ioccc winning entries +spotcheck.sh script to test a lot of files vs iocccsize +spotdiff.sh summarize the results of spotcheck.sh, showing only differences +discrepancies.md markdown file of the differences found using all the ioccc winning entries to test prog: - runtest | diff - results - opt=kcrs runtest | diff - results.k - find ~/src/obc -type f -a -name "*.c" | xargs spotcheck prog - [ | spotdiff | diff -bw - discrepancies ] + runtest.sh | diff - results + opt=kcrs runtest.sh | diff - results.k + find ~/src/obc -type f -a -name "*.c" | xargs spotcheck.sh prog + [ | spotdiff.sh | diff -bw - discrepancies ] to test tac: - prog=tac runtest | diff - results - prog=tac opt=krs runtest | diff - results.k - find ~/src/obc -type f -a -name "*.c" | xargs spotcheck tac + prog=tac runtest.sh | diff - results + prog=tac opt=krs runtest.sh | diff - results.k + find ~/src/obc -type f -a -name "*.c" | xargs spotcheck.sh tac variations/* as described in the remarks, and in each file below ansi diff --git a/2018/burton2/freqcount b/2018/burton2/freqcount.sh similarity index 100% rename from 2018/burton2/freqcount rename to 2018/burton2/freqcount.sh diff --git a/2018/burton2/inventory.html b/2018/burton2/inventory.html index 786a1adee..25d59c409 100644 --- a/2018/burton2/inventory.html +++ b/2018/burton2/inventory.html @@ -230,7 +230,7 @@ href="https://ioccc-src.github.io/temp-test-ioccc/2018/burton2/discrepancies.htm frequency count utility freqcount +href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/freqcount.sh">freqcount.sh tokenize and count man page @@ -299,7 +299,7 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/manp reads a file from variations produces string for prog.c mkkeywords +href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/mkkeywords.sh">mkkeywords.sh results with -k @@ -454,13 +454,13 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/resu test suite runtest +href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/runtest.sh">runtest.sh script to test a lot of files vs iocccsize spotcheck +href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotcheck.sh">spotcheck.sh reserved words for a given C standard @@ -468,9 +468,9 @@ href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spot href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/v7unix">v7unix -summarize the results of spotcheck +summarize the results of spotcheck.sh spotdiff +href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/burton2/spotdiff.sh">spotdiff.sh download winning source diff --git a/2018/burton2/mkkeywords b/2018/burton2/mkkeywords.sh similarity index 100% rename from 2018/burton2/mkkeywords rename to 2018/burton2/mkkeywords.sh diff --git a/2018/burton2/runtest b/2018/burton2/runtest.sh old mode 100644 new mode 100755 similarity index 100% rename from 2018/burton2/runtest rename to 2018/burton2/runtest.sh diff --git a/2018/burton2/spotcheck b/2018/burton2/spotcheck.sh similarity index 100% rename from 2018/burton2/spotcheck rename to 2018/burton2/spotcheck.sh diff --git a/2018/burton2/spotdiff b/2018/burton2/spotdiff.sh similarity index 100% rename from 2018/burton2/spotdiff rename to 2018/burton2/spotdiff.sh diff --git a/2018/burton2/tac.1 b/2018/burton2/tac.1 new file mode 100644 index 000000000..353db93ff --- /dev/null +++ b/2018/burton2/tac.1 @@ -0,0 +1,139 @@ +.TH tac 1 "01 April 2018" "tac" "IOCCC 2018" +.SH NAME +tac \- tokenize and count C-like program source code +.SH SYNOPSIS +\fBtac\fP [\-t] [\-c] [\-k] [\-r] [\-s] [\-i] [file] +.SH DESCRIPTION +\fBtac\fP reads C or C-like source code from \fBstdin\fP or file, breaking it into tokens (lexemes), +counting these according to the rules of the IOCCC, and outputting the tokens, +counts, or source code as directed by the command line options. +The default output is the source code with comments removed on \fBstdout\fP, +and the counts on \fBstderr\fP. +The count format is a set of integer values in the following order: +.RS +.TP +.B lines +number of newlines +.TQ +.B words +number of words +.TQ +.B chars +number of characters +.TQ +.B ioccc +number of IOCCC countable tokens; the IOCCC rule 2 value +.TQ +.B saved +number of characters not counted due to rules and keywords +.TQ +.B kwcnt +number of keywords +.TQ +.B kwlen +number of characters saved by counting keyword length as 1 +.RE +.PP +For the following code: +.sp +.RS 4 +.nf +#include +int main() { + /* example for loop */ + for (int ac=1; ac<10; ++ac) + printf("%d\n", ac); + return 0; +} +.fi +.RE +\fBtac\fP prints the code to \fBstdout\fP, and to \fBstderr\fP: '6 15 96 71 25 5 0' +which means 6 lines, 15 words, 96 chars, 71 IOCCC counts, 25 chars saved, +5 \fBkwcnt\fP, and no characters saved from \fBkwlen\fP. (By default, comments are not +counted.) +.SH OPTIONS +The following options are supported: +.TP +.B \-t +Output just the token stream. +.TP +.B \-c +Correct the accounting bugs in \fBiocccsize(1)\fP, output the token id and the token. +.TP +.B \-k +Keep the comments. +.TP +.B \-r +Reserved words count as size 1. +.TP +.B \-s +Suppress the source code, summarize counts only. +.TP +.B \-i +Report only the official IOCCC rule 2 size: number of octets (implies \fB\-r\fP and \fB\-s\fP). +.PP +Counts are impacted by the \fB\-k\fP, \fB\-r\fP and \fB\-c\fP options. +By default, the counts do not include comments, words are counted as in \fBwc(1)\fP, and reserved words count in full. +Using the example code above, the options change the counts as follows: +.PP +.TP +\fB\-r\fP +6 15 96 53 25 5 18 +.TQ +\fB\-k\fP +7 20 120 89 31 5 0 +.TQ +\fB\-c\fP +7 36 98 71 27 5 0 +.PP +The \fB\-c\fP option counts tokens instead of words, and is therefore more accurate for source code. +Note the aberration for line count with \fB\-r\fP; it is as\-if the comment never existed. +.PP +The \fB\-c\fP and \fB\-t\fP options change the output, instead writing a stream of tokens to \fBstdout\fP, one token per line. +The \fB\-t\fP option suppresses both the counts and the token ids, writing only the tokens. +.SH EXAMPLES +.PP +Summarize the source code counts: +.sp +.RS +.ft B +tac -rs tac.c +.ft R +.RE +.PP +Count the 10 most frequently used unique tokens in the source code: +.sp +.RS +.ft B +tac -t tac.c 2>/dev/null | sort | uniq -c | sort -k1nr | sed 10q +.ft R +.RE +.PP +Count the unique constants in the source: +.sp +.RS +.ft B +tac -c tac.c 2>/dev/null | grep ^300 | sort | uniq -c | sort -k1nr | awk '{print $1,$3}' +.ft R +.RE +.SH BUGS +\fBtac\fP does not properly count preprocessor tokens with embedded space or comments as reserved words: +.sp +.RS +.ft B +echo '#/*comment*/include/*comment*/' | tac -i +.br +echo '# include' | tac -i +.br +echo '#include' | tac -i +.ft R +.RE +.sp +report no reserved words on the first two inputs, and thus 17 as the IOCCC size, although 10 is the correct answer (as in the final example). +.PP +The original meaning of the \fB\-c\fP option was "become compatible with \fBiocccsize(1)\fP". +Its meaning was flipped so the default behavior is now compatible. +.SH SEE ALSO +\fBiocccsize(1)\fP, \fBwc(1)\fP +.br +\ diff --git a/2018/burton2/tac.c b/2018/burton2/tac.c index bdee4037e..6cced437b 100644 --- a/2018/burton2/tac.c +++ b/2018/burton2/tac.c @@ -37,7 +37,7 @@ awk '/^[^$]/{l=length;m=m>l?m:l;a[l]=a[l]$1} * * DO NOT EDIT the string kw; instead: * - * mkkeywords < my.list > my.keywords + * mkkeywords.sh < my.list > my.keywords * cc -DW=\"my.keywords\" -o tac tac.c */ diff --git a/2018/burton2/tac.man b/2018/burton2/tac.man deleted file mode 100644 index 6e4071836..000000000 --- a/2018/burton2/tac.man +++ /dev/null @@ -1,96 +0,0 @@ -NAME - tac - tokenize and count C-like program source code - -SYNOPSIS - tac [-t] [-c] [-k] [-r] [-s] [-i] [file] - -DESCRIPTION - tac reads C or C-like source code from stdin or file, breaking it into tokens (lexemes), - counting these according to the rules of the IOCCC, and outputting the tokens, - counts, or source code as directed by the command line options. - The default output is the source code with comments removed on stdout, - and the counts on stderr. - - The count format is a set of integer values in the following order: - - lines number of newlines - words number of words - chars number of characters - ioccc number of IOCCC countable tokens; the IOCCC rule 2 value - saved number of characters not counted due to rules and keywords - kwcnt number of keywords - kwlen number of characters saved by counting keyword length as 1 - - For the following code: - - #include - int main() { - /* example for loop */ - for (int ac=1; ac<10; ++ac) - printf("%d\n", ac); - return 0; - } - - tac prints the code to stdout, and to stderr: - - 6 15 96 71 25 5 0 - - which means 6 lines, 15 words, 96 chars, 71 IOCCC counts, 25 chars saved, - 5 kwcnt, and no characters saved from kwlen. (By default, comments are not - counted.) - - The following options are supported: - - -t output just the token stream - -c correct the accounting bugs in iocccsize(1), output the token id and the token - -k keep the comments - -r reserved words count as size 1 - -s suppress the source code, summarize counts only - -i report only the official IOCCC rule 2 size: number of octets (implies -r and -s) - - Counts are impacted by the -k, -r and -c options. - By default, the counts do not include comments, words are counted as in wc(1), - and reserved words count in full. - Using the example code above, the options change the counts as follows: - - -r 6 15 96 53 25 5 18 - -k 7 20 120 89 31 5 0 - -c 7 36 98 71 27 5 0 - - The -c option counts tokens instead of words, and is therefore more accurate for source code. - Note the aberration for line count with -r; it is as-if the comment never existed. - - The -c and -t options change the output, instead writing a stream of tokens to stdout, - one token per line. - The -t option suppresses both the counts and the token ids, writing only the tokens. - -EXAMPLES - Summarize the source code counts: - - tac -rs tac.c - - Count the 10 most frequently used unique tokens in the source code: - - tac -t tac.c 2>/dev/null | sort | uniq -c | sort -k1nr | sed 10q - - Count the unique constants in the source: - - tac -c tac.c 2>/dev/null | grep ^300 | sort | uniq -c | sort -k1nr | awk '{print $1,$3}' - -BUGS - tac does not properly count preprocessor tokens with embedded space or - comments as reserved words: - - echo '#/*comment*/include/*comment*/' | tac -i - echo '# include' | tac -i - echo '#include' | tac -i - - reports no reserved words on the first two inputs, and thus 17 as the IOCCC size, - although 10 is the correct answer (as in the final example). - - The original meaning of the -c option was "become compatible with iocccsize(1)". - Its meaning was flipped so the default behavior is now compatible. - -SEE ALSO - iocccsize(1), wc(1) - http://ioccc.org/2015/rules.txt diff --git a/2018/burton2/tokcount.sh b/2018/burton2/tokcount.sh new file mode 100644 index 000000000..c10a278be --- /dev/null +++ b/2018/burton2/tokcount.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +cat $* | ./prog -t | sort | uniq -c | sort -k1nr diff --git a/2018/burton2/try.sh b/2018/burton2/try.sh new file mode 100755 index 000000000..f69d7001b --- /dev/null +++ b/2018/burton2/try.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2018/burton2 +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" all >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + + +echo "$ ./prog -i < prog.c" 1>&2 +./prog -i < prog.c + +echo "$ ./prog -s < prog.c" 1>&2 +./prog -s < prog.c + +echo "$ ./prog -sk < prog.c" 1>&2 +./prog -sk < prog.c + +read -r -n 1 -p "Press any key to run: make test (space = next page, q = quit): " +echo 1>&2 +make test | less -EXF diff --git a/2018/burton2/unob.sh b/2018/burton2/unob.sh index e20c461dc..547895c89 100755 --- a/2018/burton2/unob.sh +++ b/2018/burton2/unob.sh @@ -108,4 +108,4 @@ tern && /^:/ { newline(); show($0); --tern; --n; next } { show($0) } ' -pp $* | $PROG -t | ./tokenfix | awk "$script" # sed 's/""//g' +pp $* | $PROG -t | ./tokenfix.sh | awk "$script" # sed 's/""//g' diff --git a/thanks-for-help.md b/thanks-for-help.md index e6d587549..9f38f1991 100644 --- a/thanks-for-help.md +++ b/thanks-for-help.md @@ -3972,6 +3972,40 @@ Cody also added [alt code](/2018/bellard/README.md#alternate-code) that should work for Windows, based on the author's remarks. +## [2018/burton1](/2018/burton1/prog.c) ([README.md](/2018/burton1/README.md)) + +[Cody](#cody) fixed the `scripthd` script (referred to `prog` not `./prog`) and +renamed it to [scripthd.sh](/2018/burton1/scripthd.sh) to help browsers and +GitHub as far as downloading/displaying goes. + +Cody also added the [try.sh](/2018/burton1/try.sh) script which also uses +`scripthd.sh` to show how it differs from `prog` itself. + + +## [2018/burton2](/2018/burton2/prog.c) ([README.md](/2018/burton2/README.md)) + +[Cody](#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](/2018/burton2/tokcount.sh) script which was +included in the remarks of the author but not an included file. + +Finally Cody added the [try.sh](/2018/burton2/try.sh) script. + + ## [2018/ciura](/2018/ciura/prog.c) ([README.md](/2018/ciura/README.md)) [Cody](#cody) added the [try.sh](/2018/ciura/try.sh) script and the PDF file,