Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!lll-winken!uunet!wucs1!wugate!wupost!kuhub.cc.ukans.edu!huxtable From: huxtable@kuhub.cc.ukans.edu (Kathryn Huxtable) Newsgroups: comp.std.c Subject: Re: Portable Self-Replicating C Contest Message-ID: <4739@kuhub.cc.ukans.edu> Date: 8 Apr 89 00:15:03 GMT References: <4244@kuhub.cc.ukans.edu> Organization: University of Kansas Academic Computing Services Lines: 208 Jerry Schwarz writes (through E-Mail): > In article <4244@kuhub.cc.ukans.edu> you write: > >char a[] = "char a[] = %c%s%c; main() { printf( a, 34, a, 34 ); }"; main() { > >printf( a, 34, a, 34 ); } > Not portable. The code for " does not have to be 34. I answered with a variant of the following: Aw....You're right, of course. No one has pointed out that it doesn't print a trailing newline, either. Actually, Stan Switzer at sjs@bellcore.whatever_it_is has made a study of what he calls "Quine" programs. He calls them Quine programs after Willard van Orman Quine, who said: "Yields falsehood when preceded by itself in quotations," yields falsehood when preceded by itself in quotations. Stan had a program when he was a student here at KU (1981) which was extremely clean. It wasn't particularly terse, though. I say clean, because the method generalized to a program of arbitrary complexity. -Kathryn Huxtable huxtable@kuhub.cc.ukans.edu Reconstructing from memory: ------------------------- Cut here ------------------------- /* * Quine -- Self replicating program. * * Just compile, link and go. * * Written by Kathryn Huxtable, after a memory of a similar * program written by Stan Switzer. */ #include char *first[] = { "/*", " * Quine -- Self replicating program.", " *", " * Just compile, link and go.", " *", " * Written by Kathryn Huxtable, after a memory of a similar", " * program written by Stan Switzer.", " */", "", "#include ", NULL }; char *last[] = { "/*", " * Print a vector of lines one line at a time.", " */", "", "print_norm( char *lines[] )", "{", " int i;", "", " for( i = 0; lines[i] != NULL; i++ )", " printf( \"%s\\n\", lines[i] );", "", "} /* print_norm */", "", "", "/*", " * Print a quoted string, enclosing it in quotes", " * and escaping quote and backslash.", " */", "", "puts_quoted( char *str )", "{", " int i;", "", " putchar( '\"' );", "", " for( i = 0; str[i] != '\\0'; ++i ) {", " if( str[i] == '\"' || str[i] == '\\\\' )", " putchar( '\\\\' );", " putchar( str[i] );", " }", "", " putchar( '\"' );", "", "} /* puts_quoted */", "", "", "/*", " * Print a vector of lines, in the format", " * in which it was declared.", " */", "", "print_quoted( char *name, char *lines[] )", "{", " int i;", "", " printf( \"char *%s[] = {\\n\", name );", "", " for( i = 0; lines[i] != NULL; i++ ) {", " printf( \" \" );", " puts_quoted( lines[i] );", " printf( \",\\n\" );", " }", "", " printf( \" NULL\\n\" );", " printf( \"};\\n\" );", " printf( \"\\n\" );", "", "} /* print_quoted */", "", "", "/*", " * Print a copy of my source, reconstructed", " * from the vectors first and last.", " */", "", "main()", "{", " print_norm( first );", " printf( \"\\n\" );", " print_quoted( \"first\", first );", " print_quoted( \"last\", last );", " printf( \"\\n\" );", " print_norm( last );", "", "} /* main */", NULL }; /* * Print a vector of lines one line at a time. */ print_norm( char *lines[] ) { int i; for( i = 0; lines[i] != NULL; i++ ) printf( "%s\n", lines[i] ); } /* print_norm */ /* * Print a quoted string, enclosing it in quotes * and escaping quote and backslash. */ puts_quoted( char *str ) { int i; putchar( '"' ); for( i = 0; str[i] != '\0'; ++i ) { if( str[i] == '"' || str[i] == '\\' ) putchar( '\\' ); putchar( str[i] ); } putchar( '"' ); } /* puts_quoted */ /* * Print a vector of lines, in the format * in which it was declared. */ print_quoted( char *name, char *lines[] ) { int i; printf( "char *%s[] = {\n", name ); for( i = 0; lines[i] != NULL; i++ ) { printf( " " ); puts_quoted( lines[i] ); printf( ",\n" ); } printf( " NULL\n" ); printf( "};\n" ); printf( "\n" ); } /* print_quoted */ /* * Print a copy of my source, reconstructed * from the vectors first and last. */ main() { print_norm( first ); printf( "\n" ); print_quoted( "first", first ); print_quoted( "last", last ); printf( "\n" ); print_norm( last ); } /* main */