diff --git a/2004/vik2/.gitignore b/2004/vik2/.gitignore index 8e7994066..845c38fdc 100644 --- a/2004/vik2/.gitignore +++ b/2004/vik2/.gitignore @@ -1 +1,3 @@ vik2 +vik2_1.c +vik2_2.c diff --git a/2004/vik2/Makefile b/2004/vik2/Makefile index 84ef098e4..58b7e4a35 100644 --- a/2004/vik2/Makefile +++ b/2004/vik2/Makefile @@ -1,326 +1,3 @@ -#!/bin/make -# -# 2004 makefile -# -# Copyright (C) 2004, Landon Curt Noll, Simon Cooper, Peter Seebach -# and Leonid A. Broukhis. All Rights Reserved. Permission for personal, -# educational or non-profit use is granted provided this copyright and -# notice are included in its entirety and remains unaltered. All other -# uses must receive prior permission from the contest judges. - - -# tool locations -# -SHELL= /bin/sh -CP= cp -CPP= cpp -GUNZIP= gunzip -LD= ld -MAKE= make -RM= rm -SED= sed -TAR= tar -TRUE= true - - -# Special flags for the gavin entry -# -# FYI: Older versions of GCC have a bug in -O2 optimization, hence -O1 -# -GAVIN_OPT= -O1 -GAVIN_FLAGS=\ - '-DY(m)=*((int*)(m))'\ - '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)'\ - '-DM=for(D=0;D<786432;D++)'\ - '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D'\ - '-DV=0x90200'\ - '-DK=0'\ - '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){'\ - '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}' - - -# Set X11_LIBDIR to the directory where the X11 library resides -# -X11_LIBDIR= /usr/X11R6/lib - -#CINCLUDE= -I ${HOMEBREW_PREFIX}/include/SDL2 - -# optimization -# -# Most compiles will safely use -O2. Some can use only -O1 or -O. -# A few compilers have broken optimizers and thus you may -# not want anything. -# -#OPT= -#OPT= -O -#OPT= -O1 -OPT= -O2 - - -# flags for ANSI compiles -# -# NOTE: Some ANSI compilers make use of -Xa to turn on ANSI mode, -# others such as gcc may want -ansi, others (Compaq Tru64 Unix) -# want -std1, and others may want nothing at all. -# Adjust the CFLAGS line as needed. -# -# NOTE: Some compilers cannot optimize, or optimize some entries -# incorrectly. You might want to turn on -O to see if your -# compiler can handle them. -# -# -#CFLAGS= -Xa ${OPT} -#CFLAGS= -std1 $(OPT) -CFLAGS= -ansi ${OPT} - - -# ANSI compiler -# -# Set CC to the name of your ANSI compiler. -# -# Some entries seem to need gcc. If you have gcc, set -# both CC and MAY_NEED_GCC to gcc. -# -# If you do not have gcc, set CC to the name of your ANSI compiler, and -# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just : -# to disable such programs. -# -CC= cc -MAY_NEED_GCC= gcc - - -# 2004 winners -# -WINNERS= anonymous arachnid burley gavare gavin hibachi hoyle jdalbec \ - kopczynski newbern omoikane schnitzi sds vik1 vik2 -CLEAN= anonymous_clean arachnid_clean burley_clean gavare_clean gavin_clean \ - hibachi_clean hoyle_clean jdalbec_clean kopczynski_clean \ - newbern_clean omoikane_clean schnitzi_clean sds_clean vik1_clean \ - vik2_clean -CLOBBER= anonymous_clobber arachnid_clobber burley_clobber gavare_clobber \ - gavin_clobber hibachi_clobber hoyle_clobber jdalbec_clobber \ - kopczynski_clobber newbern_clobber omoikane_clobber schnitzi_clobber \ - sds_clobber vik1_clobber vik2_clobber -ALT_NAMES= hoyle.orig kopczynski.orig -DATA_FILES= arachnid_files gavin_files hibachi_files kopczynski_files \ - newbern_files omoikane_files schnitzi_files - - -# default build -# -all: ${WINNERS} - - -# Best use of "Precious" Lines -# -anonymous: anonymous.c - ${CC} anonymous.c -o anonymous - -anonymous_clean: - ${RM} -f anonymous.o - -anonymous_clobber: anonymous_clean - ${RM} -f anonymous - - -# Best use of Vision -# -arachnid: arachnid.c - ${CC} -o arachnid -DL=LINES -DS=COLS \ - -DW=mvwaddch\(w,v,u,acs_map\[l\[m\[u arachnid.c -lncurses - -arachnid_clean: - ${RM} -f arachnid.o - -arachnid_clobber: arachnid_clean - ${RM} -f arachnid - -arachnid_files: arachnid.info - - -# Best Calculated Risk -# -burley: burley.c - ${CC} -ansi burley.c -o burley - -burley_clean: - ${RM} -f burley.o - -burley_clobber: burley_clean - ${RM} -f burley - - -# Best Use of Light and Spheres -# -gavare: gavare.c - ${CC} -O3 gavare.c -o gavare - -gavare_clean: - ${RM} -f gavare.o - -gavare_clobber: gavare_clean - ${RM} -f gavare - - -# Best of Show -# -gavin: gavin.c - ${CC} ${GAVIN_OPT} -o gavin ${GAVIN_FLAGS} gavin.c - ${RM} -f kernel - ./gavin > kernel - ${CC} ${GAVIN_OPT} -c ${GAVIN_FLAGS} -DB=_start '-Dputchar(a)=' gavin.c - ${RM} -f sh - ${LD} -s -o sh gavin.o - ${RM} -f vi - ${CP} sh vi - ${RM} -f fs.tar - ${TAR} -cvf fs.tar sh vi gavin.c gavin.hint prim - -gavin_clean: - ${RM} -f sh vi kernel gavin.o - -gavin_clobber: gavin_clean - ${RM} -f gavin fs.tar - -gavin_files: boot.b lilo.conf prim gavin_install.txt - - -# Best Abuse of the Guidelines -# -hibachi: hibachi.tar.gz - ${RM} -f hibachi.tar - ${GUNZIP} < hibachi.tar.gz > hibachi.tar - ${TAR} -xvf hibachi.tar - ${RM} -f hibachi.tar - (cd hibachi && ${SHELL} ./configure) - ([ -f hibachi/makefile ] && cd hibachi && $(MAKE) -f makefile || true) - -hibachi_clean: - ${RM} -f hibachi/hibachi.o hibachi.tar - -hibachi_clobber: hibachi_clean - ${RM} -rf hibachi - -hibachi_files: hibachi.tar.gz - - -# Most Functional Output -# -hoyle: hoyle.c - ${CC} hoyle.c -o hoyle -lm - -hoyle.orig: hoyle.orig.c - ${CC} hoyle.orig.c -o hoyle.orig -lm - -hoyle_clean: - ${RM} -f hoyle.o hoyle.orig.o - -hoyle_clobber: hoyle_clean - ${RM} -f hoyle hoyle.orig - - -# Best Abuse of the Periodic Table -# -jdalbec: jdalbec.c - @${RM} -f jdalbec2.c - -${CC} -E jdalbec.c > jdalbec2.c - @${RM} -f jdalbec3.c - ${SED} -e 's/ (/(/g' < jdalbec2.c > jdalbec3.c - ${CC} -ansi jdalbec3.c -o jdalbec - -jdalbec_clean: - ${RM} -f jdalbec2.c jdalbec3.c jdalbec.o - -jdalbec_clobber: jdalbec_clean - ${RM} -f jdalbec - - -# Best one-liner -# -kopczynski: kopczynski.c - ${CC} -Dif=while kopczynski.c -o kopczynski - -kopczynski.orig: kopczynski.orig.c - ${CC} -Dif=while kopczynski.orig.c -o kopczynski.orig - -kopczynski_clean: - ${RM} -f kopczynski.o kopczynski.orig.o - -kopczynski_clobber: kopczynski_clean - ${RM} -f kopczynski kopczynski.orig - -kopczynski_files: kopczynski-10 kopczynski-11 kopczynski-8a kopczynski-8b \ - kopczynski-8c kopczynski-9 - - -# Best Font Engine -# -newbern: newbern.c - ${CC} newbern.c -o newbern - -newbern_clean: - ${RM} -f newbern.o - -newbern_clobber: newbern_clean - ${RM} -f newbern - -newbern_files: newbern.dat - - -# Best Utility -# -omoikane: omoikane.c - ${CC} -O omoikane.c -o omoikane - -omoikane_clean: - ${RM} -f omoikane.o - -omoikane_clobber: omoikane_clean - ${RM} -f omoikane - -omoikane_files: omoikane.info - - -# Best Non-Use of Curses -# -schnitzi: schnitzi.c - ${CC} schnitzi.c -o schnitzi - -schnitzi_clean: - ${RM} -f schnitzi.o - -schnitzi_clobber: schnitzi_clean - ${RM} -f schnitzi - -schnitzi_files: schnitzi.inp0 schnitzi.inp1 - - -# Best Abuse of Indentation -# -sds: sds.c - ${CC} -o sds sds.c - -sds_clean: - ${RM} -f sds_encoder.c sds_encoder.o sds.o - -sds_clobber: sds_clean - ${RM} -f sds sds_encoder - - -# Best X11 Game -# -vik1: vik1.c - ${CC} -ansi -O2 -o vik1 vik1.c -L${X11_LIBDIR} -lX11 - -vik1_clean: - ${RM} -f vik1.o - -vik1_clobber: vik1_clean - ${RM} -f vik1 - - -# Best Abuse of CPP -# vik2: vik2.c @${RM} -f vik2_1.c ${CC} -E '-DSTOP=_5' '-DFNAME="vik2_1.c"' vik2.c > vik2_1.c @@ -333,30 +10,333 @@ vik2_clean: vik2_clobber: vik2_clean ${RM} -f vik2 - - -# utility rules +#!/usr/bin/env make # -everything: ${WINNERS} ${ALT_NAMES} ${DATA_FILES} +# IOCCC 2004 winning entry - vik2 +################################################################################ +# +# Regarding individual entries: +# +# IOCCC winning entry code may not work on your system. Even with standards, +# conditions and build environments change, especially when it comes to more +# extreme code such you might find in an IOCCC winner. Moreover, what was +# allowed and liked in one IOCCC contest may no longer be liked/allowed in +# later IOCCC years. +# +# Corrections on winning author and fixing typos in remarks are VERY WELCOME. +# +# GitHub pull requests are welcome: +# +# If you have a patch that might make running an entry work in modern Unix-like +# environments, please create a GitHub pull request for the IOCCC judges to +# consider. +# +# Suggestions and corrections regarding Makefiles, winning author information, +# fixing typos in remarks, and code patches are welcome via opening a GitHub +# issue or better yet, by creating a GitHub pull request for the IOCCC judges +# to consider. To form a GitHub issue or GitHub pull, please visit: +# +# https://github.com/ioccc-src/winner +# +################################################################################ + +# This work by Landon Curt Noll and Leonid A. Broukhis is licensed under: +# +# Creative Commons Attribution-ShareAlike 3.0 Unported License. +# +# See: http://creativecommons.org/licenses/by-sa/3.0/ + + +############################# +# shell used by this Makefile +############################# +# +SHELL= bash + +####################### +# common tool locations +####################### +# +include ../../var.mk + +# Set X11_LIBDIR to the directory where the X11 library resides +# +#X11_LIBDIR= /usr/X11R6/lib +#X11_LIBDIR= /usr/X11/lib +X11_LIBDIR= /opt/X11/lib + +# Set X11_INCLUDEDIR to the directory where the X11 include files reside +# +#X11_INCDIR= /usr/X11R6/include +#X11_INCDIR= /usr/X11/include +X11_INCDIR= /opt/X11/include + +# Common C compiler warnings to silence +# +CSILENCE= +#CSILENCE= -Wno-implicit-int + +# Common C compiler warning flags +# +#CWARN= ${CSILENCE} +#CWARN= -Wall ${CSILENCE} +#CWARN= -Wall -Wextra ${CSILENCE} +CWARN= -Wall -Wextra -pedantic ${CSILENCE} + +# Compiler standard +# +#CSTD= +#CSTD= -ansi +CSTD= -std=gnu99 + +# Compiler bit architecture +# +# Some entries require 32-bitness: +# ARCH= -m32 +# +# Some entries require 64-bitness: +# ARCH= -m64 +# +# By default we assume nothing: +# +ARCH= + +# Defines that are needed to compile +# +CDEFINE= +#CDEFINE= -DIOCCC + +# Include files that are needed to compile +# +CINCLUDE= +#CINCLUDE= -include stdlib.h +#CINCLUDE= -include stdio.h +#CINCLUDE= -include stdlib.h -include stdio.h +#CINCLUDE= -I ${X11_INCDIR} -I ${X11_INCDIR}/X11 +#CINCLUDE= `${SDL2_CONFIG} --cflags` + +# Optimization +# +# Most compiles will safely use -O2. Some can use only -O1 or -O. +# A few compilers have broken optimizers or this entry make break +# under those buggy optimizers and thus you may not want anything. +# Reasonable compilers will allow for -O3. +# +#OPT= +#OPT= -O +#OPT= -O1 +#OPT= -O2 +OPT= -O3 + +# Default flags for ANSI C compilation +# +CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT} + +# Libraries needed to build +# +LIBS= +#LIBS= -lm +#LIBS= -L ${X11_LIBDIR} -lX11 +#LIBS= `${SDL2_CONFIG} --libs` + +# C compiler to use +# +CC= cc +#CC=clang +#CC=gcc + +# Compiler add-ons or replacements for clang only +# +ifeq ($(CC),clang) +# +CSILENCE+= -Wno-poison-system-directories +# +CWARN+= -Weverything +# +endif + +# Specific add-ons or replacements for gcc only +# +ifeq ($(CC),gcc) +# +#CSILENCE+= +# +#CWARN+= +# +endif + + +############################## +# Special flags for this entry +############################## +# +ENTRY= vik2 +PROG= ${ENTRY} +# +OBJ= ${PROG}.o +DATA= +TARGET= ${PROG} +# +ALT_OBJ= +ALT_TARGET= + + +################# +# build the entry +################# +# +all: data ${TARGET} + @${TRUE} + +.PHONY: all alt data everything clean clobber install \ + love haste waste maker easter_egg sandwich \ + supernova deep_magic magic charon pluto + +${PROG}: ${PROG}.c + ${RM} -f ${PROG}_1.c + ${CC} -E '-DSTOP=_5' '-DFNAME="${PROG}_1.c"' ${PROG}.c > ${PROG}_1.c + ${RM} -f ${PROG}_2.c + ${CC} -E ${PROG}_1.c > ${PROG}_2.c + ${CC} ${CFLAGS} ${PROG}_2.c -o ${PROG} + +# alternative executable +# +alt: data ${ALT_TARGET} + @${TRUE} + +# data files +# +data: ${DATA} + @${TRUE} + +# both all and alt +# +everything: all alt + + +############### +# utility rules +############### +# +clean: + ${RM} -f ${OBJ} ${ALT_OBJ} + @-if [ -f indent.c ]; then \ + echo ${RM} -f indent.c; \ + ${RM} -f indent.c; \ + fi + +clobber: clean + ${RM} -f ${TARGET} ${ALT_TARGET} + ${RM} -f ${PROG}_1.c ${PROG}_2.c + @-if [ -e sandwich ]; then \ + ${RM} -f sandwich; \ + echo 'ate sandwich'; \ + fi + +install: + @echo "Dr. Spock says that is not logical!" + @${TRUE} + +# you may be able to misunderstand the source by reading indent.c +# +indent.c: ${PROG}.c + @if which "${GINDENT}" >/dev/null 2>&1; then \ + echo ${RM} -f $@; \ + ${RM} -f $@; \ + echo "${GINDENT} < $< > $@"; \ + ${GINDENT} < $< > $@; \ + elif which "${INDENT}" >/dev/null 2>&1; then \ + echo ${RM} -f $@; \ + ${RM} -f $@; \ + echo "${INDENT} < $< > $@"; \ + ${INDENT} < $< > $@; \ + else \ + echo "no intent tool found, ident $< yourself, sorry"; \ + echo "exit 1"; \ + exit 1; \ + fi + + +################## +# 133t hacker rulz +################## +# love: @echo 'not war?' + @${TRUE} haste: $(MAKE) waste - -waste: - @echo 'waste' - -clean: ${CLEAN} - ${RM} -f a.out core - -clobber: ${CLOBBER} - ${RM} -f ${WINNERS} - ${RM} -f ${ALT_NAMES} - -nuke: clobber @${TRUE} -install: all - ${CAT} ${WINNERS} ${ALT_NAMES} > /dev/null +waste: + @echo 'haste' + @${TRUE} + +maker: + @echo 'Participate in a maker faire' + @${TRUE} + +easter_egg: + @echo "you expected to often misunderstand this $${RANDOM} magic" + @echo "chongo '' /\\oo/\\" + @echo "Eggy" + +sandwich: easter_egg + @if [ `id -u` -eq 0 ]; then \ + echo 'Okay.'; \ + echo "$${RANDOM}`date +%s`$${RANDOM}" > $@; \ + else \ + echo 'What? Make it yourself.'; \ + exit 1; \ + fi + +# Understand the history of the Homebrew Computer Club +# as well as the West Coast Computer Faire and +# you might be confused different. :-) +# +supernova: sandwich + @-if [ -r .code_anal ]; then \ + ${RM} -f .code_anal_v6; \ + else \ + echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \ + fi + @echo "A $@ helps ${MAKE} the elements that help form planets" + @${TRUE} + +deep_magic: supernova + @-if [ -r .code_anal ]; then \ + ccode_analysis --deep_magic 7889066cdbdf09b0408021754586e895be641cc9be29e7eafd3ca65359541f17 \ + --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ + else \ + echo "Wrong! Do it again!"; \ + sleep 2; \ + echo "Wrong! Do it again!"; \ + sleep 2; \ + echo "Wrong! Do it again!"; \ + fi + @${TRUE} + +magic: deep_magic + @-if [ -r .code_anal ]; then \ + ccode_analysis --level 20003 --mode 5717175 --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ + else \ + echo "If you don't eat yer meat, you can't have any pudding!"; \ + echo "How can you have any pudding if you don't eat yer meat?!"; \ + fi + @${TRUE} + +# The IOCCC resident astronomer states +# +charon: magic + @echo "$@ is a dwarf planet" + @echo "dwarf is a type of planet" + @echo "therefore IAU, $@ is a planet" + +pluto: charon + ${MAKE} charon + @echo "$@ is a dwarf planet" + @echo "dwarf is a type of planet" + @echo "therefore, $@ is a planet" + @echo "having lots of planets is good feature because supernovae can help ${MAKE} a lot of them" diff --git a/2004/vik2/README.md b/2004/vik2/README.md index 799308a45..0310ee4fb 100644 --- a/2004/vik2/README.md +++ b/2004/vik2/README.md @@ -1,4 +1,4 @@ -Best Abuse of CPP: +# Best Abuse of CPP: Daniel Vik 926 Genter Street @@ -7,201 +7,204 @@ Best Abuse of CPP: http://www.vik.cc/ +# To build: -Judges' Comments: +```sh +make +``` - To build: +### To run: - make vik2 +```sh +./prog +``` - To run: +### Try: - ./vik2 +```sh +echo "Do or do not. There is no try." +``` - The fun thing about CPP abuses is that, in most cases, running the - preprocessor on them doesn't help you decipher the obfuscated code. - That's assuming your preprocessor can take it at all. +## Judges' comments: +The fun thing about CPP abuses is that, in most cases, running the +preprocessor on them doesn't help you decipher the obfuscated code. +That's assuming your preprocessor can take it at all. -Selected Author's Comments: +## Author's comments: - Introduction - ============ +### Introduction - It's been a while since the last pre-processor killer won the ioccc. - I thought it was time to relive hour long compile times so I made a - program that does (almost) all computation in the pre-processor. The - program even causes gcc (and other pre-processors) to crash when - configured to do maximum number of computations. - The default configuration of the makefile is set to make the program - compile in a not too long time. +It's been a while since the last pre-processor killer won the ioccc. +I thought it was time to relive hour long compile times so I made a +program that does (almost) all computation in the pre-processor. The +program even causes gcc (and other pre-processors) to crash when +configured to do maximum number of computations. +The default configuration of the makefile is set to make the program +compile in a not too long time. - I've got cpp to crash in a couple of diffenent ways. Most common is to - get a segmentation fault, but a couple of times it just got stuck in - some infinite loop. +I've got cpp to crash in a couple of diffenent ways. Most common is to +get a segmentation fault, but a couple of times it just got stuck in +some infinite loop. - I actually had to write my own pre-processor to verify that the program - was doing the right thing... +I actually had to write my own pre-processor to verify that the program +was doing the right thing... - Since it takes a very long time to compile the program, there is a - symbol that can be defined to shorten the compile time and avoid - compiler errors. +Since it takes a very long time to compile the program, there is a +symbol that can be defined to shorten the compile time and avoid +compiler errors. +### Features - Features - ======== +The program implements an 11-bit ALU in the pre-processor. The ALU has +two registers, X and Y, for calculations and one status register SR. +Each bit in the registers are represented by one symbol that are either +defined or undefined. - The program implements an 11-bit ALU in the pre-processor. The ALU has - two registers, X and Y, for calculations and one status register SR. - Each bit in the registers are represented by one symbol that are either - defined or undefined. + The ALU has six instructions: - The ALU has six instructions: + CLR_X - Clear register X - CLR_X - Clear register X + CLR_Y - Clear register Y - CLR_Y - Clear register Y + ADD - Calculates X + Y and stores the result in X. If the result + is larger than 11 bits, the CARRY bit in SR is set otherwise + the CARRY bit is cleared. - ADD - Calculates X + Y and stores the result in X. If the result - is larger than 11 bits, the CARRY bit in SR is set otherwise - the CARRY bit is cleared. + SUB - Calculates X - Y and stores the result in X. If Y was larger + than X, the CARRY bit in SR is set otherwise the CARRY bit + is cleared. - SUB - Calculates X - Y and stores the result in X. If Y was larger - than X, the CARRY bit in SR is set otherwise the CARRY bit - is cleared. + TST - If X == Y the EQ bit in SR is set, otherwise the EQ bit is + cleared. If X < Y the LT bit in SR is set, othervise the LT + bit is cleared. - TST - If X == Y the EQ bit in SR is set, otherwise the EQ bit is - cleared. If X < Y the LT bit in SR is set, othervise the LT - bit is cleared. + INC2 - Calculates X + 2 and stores the result in X. The CARRY bit + is handled as in the ADD instruction. - INC2 - Calculates X + 2 and stores the result in X. The CARRY bit - is handled as in the ADD instruction. +Internally the ALU implements a one bit adder with a carry in and carry +out. This adder is the core of the ALU. The ADD instruction uses the one +bit adder to create the 11-bit adder. The SUB instruction is implemented +by adding ~Y to X and then add 1. Finally the TST instruction calculates +X-Y and checks the result and the CARRY bit in the SR register to set +the EQ and LT bits. - Internally the ALU implements a one bit adder with a carry in and carry - out. This adder is the core of the ALU. The ADD instruction uses the one - bit adder to create the 11-bit adder. The SUB instruction is implemented - by adding ~Y to X and then add 1. Finally the TST instruction calculates - X-Y and checks the result and the CARRY bit in the SR register to set - the EQ and LT bits. +All calculations are made using only the #ifdef, #infdef, #else, #endif, +#define and #undef. I never assign a value to a defined symbol. The +logic is done by assuming that a defined symbol is 1 and an undefined +symbol is 0. (I guess this means that I have unlimited memory as long as +I only store zeroes (!)). - All calculations are made using only the #ifdef, #infdef, #else, #endif, - #define and #undef. I never assign a value to a defined symbol. The - logic is done by assuming that a defined symbol is 1 and an undefined - symbol is 0. (I guess this means that I have unlimited memory as long as - I only store zeroes (!)). +The application that uses the pre-processor ALU is a prime number +generator. The application uses the same pre-processor directives. +Needed variables are stored in memory represended by one defined or +undefined symbol per bit. When doing arithmetics, the variables are +loaded into the X and Y registers by defining / undefining the X and Y +register bits. Then the calcualtion is made and the result is moved back +to the memory. - The application that uses the pre-processor ALU is a prime number - generator. The application uses the same pre-processor directives. - Needed variables are stored in memory represended by one defined or - undefined symbol per bit. When doing arithmetics, the variables are - loaded into the X and Y registers by defining / undefining the X and Y - register bits. Then the calcualtion is made and the result is moved back - to the memory. +The choice of application may be a bit unfortunate since we've already +seen a winning entry calculating prime nubmers in the pre-processor. +There is a big difference though. The 1988 applin entry uses pre- +processor arithmethic (in a very nice way though). This program only +defines and undefines symbols in a well defined ;) way and doesn't do +any pre-processor arithmetics. - The choice of application may be a bit unfortunate since we've already - seen a winning entry calculating prime nubmers in the pre-processor. - There is a big difference though. The 1988 applin entry uses pre- - processor arithmethic (in a very nice way though). This program only - defines and undefines symbols in a well defined ;) way and doesn't do - any pre-processor arithmetics. +The reason why I choosed to do a prime number application is that the +algorithm can be written to do a lot of calculations without a lot of +nesting (gnu cpp allows only 200 nested includes). - The reason why I choosed to do a prime number application is that the - algorithm can be written to do a lot of calculations without a lot of - nesting (gnu cpp allows only 200 nested includes). +### Build and Run +First, do a first pre processing of the initial definitions. The FNAME +symbol must be defined to the name of the output file. If you want to +speed up the compilation, define the STOP symbol to anything from _3 to +_10. (The default value is _10 which will make the compilation take some +time.) Prime numbers up to 2^STOP will be calculated. - Build and Run - ============= +```sh +cpp '-DSTOP=_5' '-DFNAME="tmp1.c"' prog.c tmp1.c +``` - First, do a first pre processing of the initial definitions. The FNAME - symbol must be defined to the name of the output file. If you want to - speed up the compilation, define the STOP symbol to anything from _3 to - _10. (The default value is _10 which will make the compilation take some - time.) Prime numbers up to 2^STOP will be calculated. +Then use cpp or any other pre-processor to do the actual work. This will +take some time.... - $ cpp '-DSTOP=_5' '-DFNAME="tmp1.c"' prog.c tmp1.c +```sh +cpp tmp1.c > tmp2.c +``` - Then use cpp or any other pre-processor to do the actual work. This will - take some time.... +Finally compile the pre processed file - $ cpp tmp1.c > tmp2.c +```sh +cc -O tmp2.c -o prog +``` - Finally compile the pre processed file +Then run the program to reveil all prime numbers up to 32 (if you used +STOP=_5 as above): - $ cc -O tmp2.c -o prog +```sh +./prog +``` - Then run the program to reveil all prime numbers up to 32 (if you used - STOP=_5 as above): +### Verification - $ ./prog +I wasn't able to compile the full program which calculates prime numbers +up to 1024 using gnu cpp (or any other pre-processor) so I had to write +my own. Knowing how the program works it was quite easy to reduce the +compilation time from several hours to about one second. I also added +some statistics to my home made pre-processor and I found that +calculating prime numbers up to 1024 makes the program include itself +over 6.8 million times (see the statistics table below). +### Obfuscation - Verification - ============ +Well, since 98.5% of the program is preprocessor directives, the main +obfuscation is the use of preprocessor directives. - I wasn't able to compile the full program which calculates prime numbers - up to 1024 using gnu cpp (or any other pre-processor) so I had to write - my own. Knowing how the program works it was quite easy to reduce the - compilation time from several hours to about one second. I also added - some statistics to my home made pre-processor and I found that - calculating prime numbers up to 1024 makes the program include itself - over 6.8 million times (see the statistics table below). +Doing arithmetics without acutally using any arithmetic operations makes +the program quite hard to follow. +In order to actually do the calculations, the program includes itself a +lot. - Obfuscation - =========== +The symbol names are made as short as possible to meet the space limits. +This of course adds to the obfuscation (even though the program is +quite obfuscated with longer, readable macro names. - Well, since 98.5% of the program is preprocessor directives, the main - obfuscation is the use of preprocessor directives. +Finally, I made the 1.5% c code a bit harder to read by breaking all +lines after three characters. - Doing arithmetics without acutally using any arithmetic operations makes - the program quite hard to follow. +The program has 1029 lines which makes it the longest entry (so far). - In order to actually do the calculations, the program includes itself a - lot. +Even though the pre-processed and indented output is easier to read, it +is quite hard to find the code in it. The size of the pre-processed file +is several Mb when using gnu cpp. - The symbol names are made as short as possible to meet the space limits. - This of course adds to the obfuscation (even though the program is - quite obfuscated with longer, readable macro names. +### Limitations - Finally, I made the 1.5% c code a bit harder to read by breaking all - lines after three characters. +In order to fit the program within the space limits, I had to define the +#define, #endif, and some other directives as single character symbols. +This does not compile on all pre-processors but using gnu cpp as a first +compilation step solves this. - The program has 1029 lines which makes it the longest entry (so far). +### Statistics - Even though the pre-processed and indented output is easier to read, it - is quite hard to find the code in it. The size of the pre-processed file - is several Mb when using gnu cpp. +The table below contains some interesting statistics about the +compilation of the program. The intermediate file size is the size of +the output file of the cpp pre-processor. The time taken to pre process +the program were measured using gnu cpp on my 2.0MHz P4 with 512Mb ram +and a lot of disk. + Generated Recursive Max nest Intermediate +Level prime nrs includes count file size Time - Limitations - =========== + _3 < 8 2 322 9 74 748 4" + _4 < 16 4 672 9 182 652 9" + _5 < 32 14 237 9 629 121 32" + _6 < 64 43 748 9 1 998 134 1'41" + _7 < 128 149 851 11 6 823 575 5'50" + _8 < 256 526 874 17 24 028 933 20'37" + _9 < 512 1 920 272 38 65 527 808(*) 1h 42'19"(*) + _10 < 1024 6 826 389 114 63 782 912(*) 2h 47'58"(*) - In order to fit the program within the space limits, I had to define the - #define, #endif, and some other directives as single character symbols. - This does not compile on all pre-processors but using gnu cpp as a first - compilation step solves this. - - - Statistics - ========== - - The table below contains some interesting statistics about the - compilation of the program. The intermediate file size is the size of - the output file of the cpp pre-processor. The time taken to pre process - the program were measured using gnu cpp on my 2.0MHz P4 with 512Mb ram - and a lot of disk. - - Generated Recursive Max nest Intermediate - Level prime nrs includes count file size Time - - _3 < 8 2 322 9 74 748 4" - _4 < 16 4 672 9 182 652 9" - _5 < 32 14 237 9 629 121 32" - _6 < 64 43 748 9 1 998 134 1'41" - _7 < 128 149 851 11 6 823 575 5'50" - _8 < 256 526 874 17 24 028 933 20'37" - _9 < 512 1 920 272 38 65 527 808(*) 1h 42'19"(*) - _10 < 1024 6 826 389 114 63 782 912(*) 2h 47'58"(*) - - (*) Before cpp crashed. + (*) Before cpp crashed.