[net.sources] 66 char C self-reproducer

daves@ios.UUCP (David B. Schnepper) (08/24/84)

>> Somebody must not be reading the EUUG Newsletter either:
>> 
>> 	From EUUGN Vol 3. No. 4
>> 
>> 	extracted from 'Some Self-Reproducing Programs' by Theo de Ridder
>> 	....
>> 	....
>> 	selfcopy2.c
>> 
>> 	char p[]="char p[]=%c%s%c;%cmain(){printf(p,042,p,042,012,012);}%c";
>> 	main(){printf(p,042,p,042,012,012);}
>> 	....
>> 	....
>> So, have fun with this SOURCE code. As usual, any comments, bug-fixes,
>> improvements......
>> 
>> Jim McKie  Centrum voor Wiskunde en Informatica, Amsterdam  mcvax!jim

----------The last? word------------
Ok, here's some more versions.  Without the "cheating" I did on
the "self-reproducer" I posted yesterday.

Just taking the above and modifying:
(replace octal by decimal, put on one line, make p char * not char [])

---------cut here, 87 char version------------
char *p="char *p=%c%s%c;main(){printf(p,34,p,34,10);}%c";main(){printf(p,34,p,34,10);}
---------end cut------------------------------

The following versions have increasing dependency on our compiler.  Though
it is arguable that these programs are "correct" C.  We run 4.1BSD on
a Vax 750.  Standard "cc" as supplied in 4.1.

"cc"  (and C?) doesn't require a newline at the end of a program.
Put the following in a file, but WITHOUT a newline!

---------cut here, 78 char version-----------
char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
---------end cut-----------------------------

Now, with just a "little" bit of cheating.  Make "char" an "int".  This
gives "cc" warnings, but it works (at this site anyway).

---------cut here, 76 char version-----------
int *p="int *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
---------end cut-----------------------------

Finally, make use of undeclared variables are considered int's.  Again,
at least with this compiler.

---------cut here, 68 char version-----------
*p="*p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
---------end cut-----------------------------

Finally, here sizeof( int ) == sizeof( int * ) so:

---------cut here, 66 char version-----------
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
---------end cut-----------------------------

Enjoy!

Dave Schnepper
Integrated Office Systems
ios!daves

Here's an archive version to extract files "f1.c" ... "f5.c" with
each version above.  And a csh script "test.repro" to test the
reproduction.

=====================CUT HERE AND RUN THROUGH CSH===============
#
#

cat >f1.c <<DAVES
char *p="char *p=%c%s%c;main(){printf(p,34,p,34,10);}%c";main(){printf(p,34,p,34,10);}
DAVES

cat >temp <<DAVES
char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
DAVES
tr -d '\012' <temp >f2.c

cat >temp <<DAVES
int *p="int *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
DAVES
tr -d '\012' <temp >f3.c

cat >temp <<DAVES
*p="*p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
DAVES
tr -d '\012' <temp >f4.c

cat >temp <<DAVES
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
DAVES
tr -d '\012' <temp >f5.c

set file = '$file'
cat >test.repro <<DAVES
#!/bin/csh
foreach file (f?.c)
    echo testing $file
    (rm -f a.out)
    cc $file
    a.out >$file
    (rm -f a.out)
    cc $file
    a.out >$file:r
    cmp $file $file:r
    if ($status == 0) then
	echo $file reproduces itself.
    else
	echo $file does NOT reproduce itself.
    endif
    wc $file
end
DAVES
chmod +x test.repro