From e8d7ee3b6a08e742202e92b1be652d391b696d19 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Tue, 5 Jan 2021 19:10:19 +0900 Subject: [PATCH] Add 2013/rules.txt, iocccsize.c, and iocccsize.mk These files are extracted from 2013/2013.tar.bz2. --- 2013/iocccsize.c | 411 ++++++++++++++++++++++++++++++++++++++++++++++ 2013/iocccsize.mk | 71 ++++++++ 2013/rules.txt | 217 ++++++++++++++++++++++++ 3 files changed, 699 insertions(+) create mode 100644 2013/iocccsize.c create mode 100644 2013/iocccsize.mk create mode 100644 2013/rules.txt diff --git a/2013/iocccsize.c b/2013/iocccsize.c new file mode 100644 index 000000000..4beb79068 --- /dev/null +++ b/2013/iocccsize.c @@ -0,0 +1,411 @@ +/* + * iocccsize - IOCCC Source Secondary Size + * + * Public Domain 1992, 2013 by Anthony Howe. All rights released. + * With IOCCC mods in 2013 by chongo (Landon Curt Noll) /\oo/\ + * + * This IOCCC size tool source file is version 2013-07-30-v17. + * + * SYNOPSIS + * + * ioccc [-ikrs] < input + * + * -i print official IOCCC size to standard out + * NOTE: -i implies -r -s + * -k keep comments + * -r count C reserved words as 1 byte + * -s silence; do not output source code, only final count + * + * DESCRIPION + * + * Taking input from standard input, apply the IOCCC Source Size Rule + * for 2001. The program's offical length is written to standard error. + * Also filter out C comment blocks (-k to keep) sending the modified + * source to standard output. + * + * The 2001 Source Size Rule was: + * + * Your entry must be <= 4096 bytes in length. The number of octets + * excluding whitespace (tab, space, newline, formfeed, return), and + * excluding any ';', '{' or '}' followed by whitespace or end of file, + * must be <= 2048. + * + * NOTE: The above descipion is NOT the official IOCCC size tool algorithm! + */ + +/* + * The official IOCCC rule 2 secondary limit on C code size + * + * The IOCCC size tool should be compiled as: + * + * cc -pedantic -Wall -std=c99 iocccsize.c -o iocccsize + * + * This tool computes a 2nd size C code. To check your program source + * against the 2nd limit of rule 2, use the -i command line option. + * + * For example: + * + * ./iocccsize -i < prog.c + * + * The IOCCC size tool, when using the -i option, may be summarized as: + * + * The size tool counts C language keywords (primary, secondary, and + * selected preprocessor keywords) as 1. The size tool counts all + * other octets as 1 excluding ASCII whitespace, and excluding any + * ';', '{' or '}' followed by ASCII whitespace, and excluding any + * ';', '{' or '}' octet immediately before the end of file. + * + * ASCII whitespace includes ASCII tab, ASCII space, ASCII newline, + * ASCII formfeed, and ASCII carriage return. + * + * In cases where the above summary and the algorithm implemented by + * the IOCCC size tool source code conflict, the algorithm implemented + * by the IOCCC size tool source code is preferred by the judges. + * + * See the current IOCCC rules and guidelines for more information. + * In particular, see the current IOCCC size rule for information about + * the maximum value that this tool should print for an entry to be valid. + */ + +/* + * HINT: The algorithm implemented by this code may or not be obfuscated. + * The algorithm may not or may appear to be obfuscated. + * + * In particular: + * + * We did not invent the algorithm. + * The algorithm consistently finds Obfuscation. + * The algorithm killed Obfuscation. + * The algorithm is banned in C. + * The algorithm is from Bell Labs in Jersey. + * The algorithm constantly finds Obfuscation. + * This is not the algorithm. + * This is close. + */ + +#include +#include +#include +#include +#include + +#define FLAG_SILENCE 1 +#define FLAG_KEEP 2 +#define FLAG_RESERVED 4 +#define FLAG_IOCCC_SIZE 8 + +char usage[] = +"usage: ioccc [-ikrs] < prog.c\n" +"\n" +"-i\t\tprint just the official secondary IOCCC size to stdout\n" +"\t\t NOTE: -i implies -r -s\n" +"-k\t\tkeep block comments\n" +"-r\t\tcount C reserved words as 1 byte\n" +"-s\t\tsilence; do not output source code, only final count\n"; + +#define STRLEN(s) (sizeof (s)-1) + +typedef struct { + size_t length; + const char *word; +} Word; + +/* + * C reserved words, plus a few #preprocessor tokens, that count as 1 + * + * NOTE: For a good list of reserved words in C, see: + * + * http://www.bezem.de/pdf/ReservedWordsInC.pdf + * + * by Johan Bezem of JB Enterprises: + * + * See http://www.bezem.de/en/ + */ +static Word cwords[] = { + /* Yes Virginia, we left #define off the list on purpose! */ + { STRLEN("#elif"), "#elif" }, + { STRLEN("#else"), "#else" }, + { STRLEN("#endif"), "#endif" }, + { STRLEN("#error"), "#error" }, + { STRLEN("#ident"), "#ident" }, + { STRLEN("#if"), "#if" }, + { STRLEN("#ifdef"), "#ifdef" }, + { STRLEN("#include"), "#include" }, + { STRLEN("#line"), "#line" }, + { STRLEN("#pragma"), "#pragma" }, + { STRLEN("#sccs"), "#sccs" }, + { STRLEN("#warning"), "#warning" }, + /**/ + { STRLEN("_Alignas"), "_Alignas" }, + { STRLEN("_Alignof"), "_Alignof" }, + { STRLEN("_Atomic"), "_Atomic" }, + { STRLEN("_Bool"), "_Bool" }, + { STRLEN("_Complex"), "_Complex" }, + { STRLEN("_Generic"), "_Generic" }, + { STRLEN("_Imaginary"), "_Imaginary" }, + { STRLEN("_Noreturn"), "_Noreturn" }, + { STRLEN("_Pragma"), "_Pragma" }, + { STRLEN("_Static_assert"), "_Static_assert" }, + { STRLEN("_Thread_local"), "_Thread_local" }, + /**/ + { STRLEN("alignas"), "alignas" }, + { STRLEN("alignof"), "alignof" }, + { STRLEN("and"), "and" }, + { STRLEN("and_eq"), "and_eq" }, + { STRLEN("auto"), "auto" }, + { STRLEN("bitand"), "bitand" }, + { STRLEN("bitor"), "bitor" }, + { STRLEN("bool"), "bool" }, + { STRLEN("break"), "break" }, + { STRLEN("case"), "case" }, + { STRLEN("char"), "char" }, + { STRLEN("compl"), "compl" }, + { STRLEN("const"), "const" }, + { STRLEN("continue"), "continue" }, + { STRLEN("default"), "default" }, + { STRLEN("do"), "do" }, + { STRLEN("double"), "double" }, + { STRLEN("else"), "else" }, + { STRLEN("enum"), "enum" }, + { STRLEN("extern"), "extern" }, + { STRLEN("false"), "false" }, + { STRLEN("float"), "float" }, + { STRLEN("for"), "for" }, + { STRLEN("goto"), "goto" }, + { STRLEN("I"), "I" }, + { STRLEN("if"), "if" }, + { STRLEN("inline"), "inline" }, + { STRLEN("int"), "int" }, + { STRLEN("long"), "long" }, + { STRLEN("noreturn"), "noreturn" }, + { STRLEN("not"), "not" }, + { STRLEN("not_eq"), "not_eq" }, + { STRLEN("or"), "or" }, + { STRLEN("or_eq"), "or_eq" }, + { STRLEN("register"), "register" }, + { STRLEN("restrict"), "restrict" }, + { STRLEN("return"), "return" }, + { STRLEN("short"), "short" }, + { STRLEN("signed"), "signed" }, + { STRLEN("sizeof"), "sizeof" }, + { STRLEN("static"), "static" }, + { STRLEN("static_assert"), "static_assert" }, + { STRLEN("struct"), "struct" }, + { STRLEN("switch"), "switch" }, + { STRLEN("thread_local"), "thread_local" }, + { STRLEN("true"), "true" }, + { STRLEN("typedef"), "typedef" }, + { STRLEN("union"), "union" }, + { STRLEN("unsigned"), "unsigned" }, + { STRLEN("void"), "void" }, + { STRLEN("volatile"), "volatile" }, + { STRLEN("while"), "while" }, + { STRLEN("xor"), "xor" }, + { STRLEN("xor_eq"), "xor_eq" }, + /**/ + { 0, NULL } +}; + +Word * +find_member(Word *table, const char *string) +{ + Word *w; + for (w = table; w->length != 0; w++) { + if (strncmp(string, w->word, w->length) == 0 + && !isalnum(string[w->length]) && string[w->length] != '_') + return w; + } + return NULL; +} + +/* + * Count octets and strip comments. The stripped C input is sent to + * standard output. If -s is set, then suppress the source output. + * The various counters are sent to standard error (see below), unless + * -i is given in which case source output is suppressed and only the + * IOCCC size rule count is sent to standard out. + * + * The counter output format is: + * + * lcount wcount bcount icount isaved rcount rsaved + * + * where + * lcount line count (same as wc) + * wcount word count (same as wc) + * bcount byte count (same as wc) + * icount IOCCC secondary size rule count + * isaved bytes saved by secondary size rule (bcount - icount) + * rcount number of C reserved words + * rsaved number of octets saved with -r + */ +int +count(int flags) +{ + Word *w; + int span; + char *p, buf[256]; + int lcount, wcount, bcount; + int is_comment, is_word, dquote; + int count, keywords, saved, kw_saved; + + /* Start of buffer sentinel. */ + buf[0] = ' '; + + count = saved = 0; + keywords = kw_saved = 0; + lcount = wcount = bcount = 0; + is_comment = is_word = dquote = 0; + + /* + * "no matter how well you may think you understand this code, + * you don't, so don't mess with it." :-) + */ + for ( ; fgets(buf+1, sizeof (buf)-1, stdin) != NULL;) { + if (!(flags & FLAG_KEEP)) { + /* Leading whitespace before comment block? */ + span = strspn(buf+1, "\t "); + if (buf[1+span] == '/' && buf[2+span] == '*') { + /* Strip leading whitespace before comment block. */ + is_comment = 1; + } + } + + for (p = buf+1; *p != '\0'; p++) { + /* In C comment block? */ + if (is_comment) { + /* End of comment block? */ + if (*p == '*' && p[1] == '/') { + is_comment = 0; + + if (!(flags & FLAG_KEEP)) { + /* Strip whitespace and newline + * trailing closing comment. + */ + p += 1 + strspn(p+2, " \t\r\n"); + } + } + + if (!(flags & FLAG_KEEP)) { + /* Strip octets in comment block. */ + continue; + } + } + + /* Start of comment block? */ + else if (!dquote && *p == '/' && p[1] == '*') { + /* Begin comment block. */ + is_comment = 1; + + if (!(flags & FLAG_KEEP)) { + /* Strip comment block. */ + p++; + continue; + } + } + + /* Toggle start/end of double-quote string. */ + else if (*p == '"' && p[-1] != '\\' && p[-1] != '\'') + dquote = !dquote; + + /* C reserved word? */ + else if (!dquote + && !isalnum(p[-1]) && p[-1] != '_' + && (w = find_member(cwords, p)) != NULL) { + keywords++; + if (flags & FLAG_RESERVED) { + bcount += w->length; + if (!is_word) { + is_word = 1; + wcount++; + } + + if (!(flags & FLAG_SILENCE)) + fputs(w->word, stdout); + + /* Count reserved word as one. */ + kw_saved += w->length - 1; + p += w->length - 1; + count++; + continue; + } + } + + /* Everything above here is stripped from the input. */ + if (!(flags & FLAG_SILENCE)) + fputc(*p, stdout); + + bcount++; + if (*p == '\n') + lcount++; + + /* Ignore all whitespace. */ + if (isspace(*p)) { + is_word = 0; + saved++; + continue; + } else if (!is_word) { + is_word = 1; + wcount++; + } + + /* Ignore curly braces and semicolons when followed + * by any whitspace or EOF. + */ + if (strchr("{;}", *p) != NULL + && (isspace(p[1]) || p[1] == '\0')) { + saved++; + continue; + } + + /* Count this octet. */ + count++; + } + } + + /* final count */ + if (flags & FLAG_IOCCC_SIZE) { + /* output the official IOCCC size tool size to standard out */ + printf("%d\n", count); + } else { + fprintf(stderr, "%d %d %d %d %d %d %d\n", + lcount, wcount, bcount, count, saved, + keywords, kw_saved); + } + return count; +} + +int +main(int argc, char **argv) +{ + int ch; + int flags = 0; + + /* parse args */ + while ((ch = getopt(argc, argv, "ikrs")) != -1) { + switch (ch) { + case 'i': + /* "You are not expected to understand this" :-) */ + flags |= (FLAG_RESERVED | FLAG_SILENCE | + FLAG_IOCCC_SIZE); + break; + case 'k': + flags |= FLAG_KEEP; + break; + case 'r': + flags |= FLAG_RESERVED; + break; + case 's': + flags |= FLAG_SILENCE; + break; + default: + fprintf(stderr, "%s\n", usage); + return 2; + } + } + + /* count as directed by flags */ + (void) count(flags); + + /* All Done!!! All Done!!! -- Jessical Noll, age 2 */ + return 0; +} diff --git a/2013/iocccsize.mk b/2013/iocccsize.mk new file mode 100644 index 000000000..f4f4cee69 --- /dev/null +++ b/2013/iocccsize.mk @@ -0,0 +1,71 @@ +.POSIX : + +####################################################################### + +CFLAGS := -pedantic -Wall -std=c99 -g +LDFLAGS := +LIBS := +IT := iocccsize + +####################################################################### + +all: ${IT}$E + +${IT}$E: ${IT}.c + ${CC} ${CFLAGS} -o ${IT}$E ${IT}.c + +# +# Exercise the IOCCC size tool. +# +test: test-k test-wc test-rcount + +# +# -k should pass through the source with block comments intact. +# +test-k: ${IT}$E + @{ t="-k keep comments" ;\ + if ./${IT} -k <${IT}.c 2>/dev/null | diff - ${IT}.c ; then echo "-OK- $$t" ; else echo "FAIL $$t" ; fi ;\ + } + +# +# First 3 counters should match wc(1) +# +test-wc: ${IT}$E + @{ t="wc counts" ;\ + a=$$(./${IT} -s -k <${IT}.c 2>&1 | cut -d' ' -f1-3) ;\ + b=$$(wc ${IT}.c | sed -e's/^ *//; s/ */ /g' | cut -d' ' -f1-3) ;\ + if [ "$$a" = "$$b" ]; then echo "-OK- $$t"; else echo "FAIL $$t: expected '$$b', got '$$a'"; fi ;\ + } + +# +# Show counters for different option combinations. +# +test-show: ${IT}$E + ./${IT} -s <${IT}.c + ./${IT} -s -r <${IT}.c + ./${IT} -s -k <${IT}.c + ./${IT} -s -r -k <${IT}.c + +# +# Reserved word counter should be same for all option combinations. +# +test-rcount: ${IT}$E + @{ t="rcount" ;\ + ./${IT} -s <${IT}.c 2>&1 | cut -d" " -f 6 >/tmp/$$$$.tmp ;\ + ./${IT} -s -r <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\ + ./${IT} -s -k <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\ + ./${IT} -s -r -k <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\ + n=$$(sort -u /tmp/$$$$.tmp | wc -l | sed -e's/^ *//') ;\ + if [ $$n -eq 1 ]; then echo "-OK- $$t"; else echo "FAIL $$t: expected 1 unique line, got $$n"; echo "see make test-show"; fi ;\ + rm -f /tmp/$$$$.tmp ;\ + } + +clean: + rm -f iocccsize.o + rm -rf iocccsize.dSYM + +clobber: clean + rm -f iocccsize + +install: + @echo "no thank you on the install :-)" diff --git a/2013/rules.txt b/2013/rules.txt new file mode 100644 index 000000000..4b7bc1f3e --- /dev/null +++ b/2013/rules.txt @@ -0,0 +1,217 @@ +| 22nd International Obfuscated C Code Contest Official Rules + +| Copyright (C) 2006-2013 Leonid A. Broukhis, Simon Cooper, Landon Curt Noll + +All Rights Reserved. Permission for personal, education 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 in +writing from the contest judges. + + Obfuscate: tr.v. -cated, -cating, -cates. 1. a. To render obscure. + b. To darken. 2. To confuse: his emotions obfuscated his + judgment. [LLat. obfuscare, to darken : ob(intensive) + + Lat. fuscare, to darken < fuscus, dark.] -obfuscation n. + obfuscatory adj. + + +| This rules file is version 2013-07-30-v17. + +| Most of the changes from the previous IOCCC rules +| been marked with a "|" on the left hand side of the line. + + +GOALS OF THE CONTEST: + + * To write the most Obscure/Obfuscated C program under the rules below. + * To show the importance of programming style, in an ironic way. + * To stress C compilers with unusual code. + * To illustrate some of the subtleties of the C language. + * To provide a safe forum for poor C code. :-) + +| The 22nd IOCCC contest entry window is: + +| 2013-Aug-01 3:14:15 UTC to 2013-Oct-03 9:26:53 UTC + + +RULES: + + To help us with the volume of entries, we ask that you follow these rules: + + 1) Your entry must be a complete program. + + 2) The size of your program source must be <= 4096 bytes in length. + +| When your program source is fed as input to the current IOCCC size +| tool, and the IOCCC size tool -i command line option is used, the value +| printed should be <= 2053. + +| The source to the current IOCCC size tool is found at this URL: + +| http://www.ioccc.org/2013/iocccsize.c + + 3) Submissions should be performed using the instructions outlined at: + + https://submit.ioccc.org/ + +| That URL should be active on or slightly before 2013-Aug-01 3:14:15 UTC. + + 4) If your entry is selected as a winner, it will be modified as follows: + + Your 'build' instructions will be incorporated into a makefile. + + Your source code will be renamed from prog.c to a name + of our choice (usually related to your family name or + anonymous) followed by a optional digit if there are conflicting + winning entries. The resulting binary will be renamed from prog to a + equivalent of our choice. + + If needed, indicate in your remarks file how your entry + must be changed to accommodate the above. + + 5) Your entry must not modify the content or filename of any part of your + original entry including, but not limited to prog.c, the Makefile + (we create from your how to build instructions), as well as any data + files you submit. + + If you entry wishes to modify such content, it must first copy the + file to a new filename and then modify that copy. + + 6) There is NO rule 6! OK, there is a rule 6, but we intend to ignore it. + +| while (!understand(ioccc(rule(6)))); + + 7) The obfuscated C program must be an original work that you own. + + You (the authors) must own the contents of your submission OR + you must have permission from the owners to submit their content + under the Creative Commons Attribution-ShareAlike 3.0 Unported + (CC BY-SA 3.0) license (see rule 18). + + If you submit any content that is owned by others, you MUST + detail that ownership (i.e., who owns what) and document the + permission you obtained. + +| 8) Entries must be received prior to 2013-Oct-03 9:26:53 UTC. + + A confirmation of submission will be sent to the submitter's + email address before the close of the contest. + +| 9) Each person may submit up to and including 8.0 entries per contest. +| Each entry must be submitted separately. + +| 10) Entries requiring human interaction to be initially compiled are +| not permitted. + + 11) Programs that require special privileges (setuid, setgid, super-user, +| special owner, special group, etc.) are highly discouraged. + + 12) Legal abuse of the rules is somewhat encouraged. An entry that, in + the opinion of the judges, violates the rules will be disqualified. + Entries that attempt to abuse the rules must try to justify why + their rule abuse is legal in the remarks file. + +| 13) Any C source that fails to compile because of unescaped octets with +| the high bit set (octet value >= 128) will be rejected. + + 14) Any C source that fails to compile because of lines with trailing + control-M's (i.e., lines with a tailing octet 015) will be rejected. + + Please do not put trailing control-M's in your remarks file. + + 15) When you submit your entry you must have a valid email address + that can both send and receive email. The online submission + method is a two phase process that requires the use of an + approval code. This code will be emailed to you as part of + phase 1. + + Entries submitted without a working or valid email address will + be disqualified. + + The judges are not responsible for delays in email, please plan + enough time for one automated exchange of email as part of your + submission. + + 16) You are STRONGLY encouraged to submit an original entry. + Submissions that are similar to previous entries are discouraged. + + 17) The total size of your submission: the sum of the size of the program, +| hints, comments, build and info files MUST be less than or equal +| to 1048576 octets in size. + + 18) The entirety of your entry must be submitted under the Creative Commons + Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0): + + http://creativecommons.org/licenses/by-sa/3.0/ + + You must not submit anything that cannot be submitted under that license. + +| 19) The remarks file must be written in markdown format. See: + + http://daringfireball.net/projects/markdown/basics + + for more information. + + 20) The how to build instructions must be in make form. + + The target of the make file must be called prog. The original + C source file must be called prog.c. + + To invoke the C compiler, use ${CC}. + To invoke the C preprocessor use ${CPP}. + + Do not assume that . (the current working directory) is in the $PATH. + + Use a shell command syntax that is compatible with bash. + +| Assume that commands commonly found in POSIX-like / Linux-like systems + are available in the search path. + + Do not assume any particular given value of ${CFLAGS} or other + commonly used make variables. + + 21) Your entry must not create nor modify files above the current directory + with the exception of the /tmp and the /var/tmp directories. Your entry +| may create subdirectories below the current directory, or in /tmp, +| or in /var/tmp provided that "." is not the first octet in any +| directory name. + + +FOR MORE INFORMATION: + + The judging will be done by Leonid A. Broukhis, Simon Cooper, Landon + Curt Noll. + + Please send questions or comments about the contest, to: + +| q.2013@ioccc.org (for questions only!) + +| You must include the words: + +| ioccc 2013 question + +| in the subject of your EMail message when sending EMail to the judges. + + The rules and the guidelines may (and often do) change from year to + year. You should be sure you have the current rules and guidelines + prior to submitting entries. To obtain them, visit the IOCCC web page: + + http://www.ioccc.org + + It has rules, guidelines and winners of previous contests (1984 to date). + +| For the updates and breaking IOCCC news, you are encouraged to follow +| the twitter handle: + +| @IOCCC + +| You do not have to be a twitter user to follow @IOCCC. Non-twitter +| users should access: + +| https://twitter.com/ioccc + +| Non-twitter users should force their browsers to reload the above URL +| to be sure they are seeing the most recent tweets. + +Leonid A. Broukhis +Simon Cooper +chongo (Landon Curt Noll) /\cc/\