icosa.gif

[] Home
henry12t.jpg Introduction
[] The Labyrinth
[] Social Media
[] Terms
[] Contact

get in shape
Hits: 81656

random hull

audio
bio
decal4linux
diet
dictionary

electronic
find-target
fixboot
halloween
home
hosting
installation
isoedit
kernel
links
nVidia
oldies
pollution
playcd
playdvd
quines
rpmsign
scite
shortcuts
social media
software
terms
the labyrinth
wine
zotero

TheNerdShow.com

Quines: Self-replicating Programsor A Crash Cource in C

by Henry Kroll

I was in the #Fedora chatroom on IRC when somebody introduced me to the concept of self-replicating programs: ACM Classic: Reflections on Trusting Trust. The article stuck in my mind all evening. It inspired me to try to make one of my own.

My first attempt

main(){printf("main(){printf(\"main(){printf(\"Arrrrrrgh!!!!\");}

As you can see, there has to be some expansion. A program can't just print itself that easily, although this program comes close (albeit with some compiler warnings):

main(p){printf(p,34,p="main(p){printf(p,34,p=%c%s%c,34); }",34); }

This looks like a simple program to me now but I couldn't understand it back then so I went looking at ways others had solved the problem, which led me to The Quine Page. I browsed through language after language. None of them made any sense. There had to be at least one of them simple enough that I could understand. I also wanted it to not generate compiler warnings. Finally I found Dolly!

The reason I have always wanted to learn C is because it integrates well with so many free (unencumbered, in that I don't have to pay to use or distribute them) development libraries. Many other languages can use C libraries however. According to this Wikipedia article, the language maps efficiently to machine code instructions and has therefore been used as a replacement for machine code in most applications. C programs are also very portable. They can be compiled for many different operating systems. Despite being an imperative language, structured programming is not too difficult in C. since there are no objects per se, I have been using polymorphic functions as objects. A single function (object) can perform various tasks depending on what values (methods) are passed to it. In this way, and by creatively naming functions, a C program can have a very object oriented look to it.

I decided to convert Dolly to C. It was going to be tough though. I would need to learn the C basics. I would have to have a good grasp of pointers and arrays. And find out even more about poitners and arrays. I would also need to disabuse myself of some of my confusion with printf. I recommend that you read the links if you are getting started in C. I needed a lightweight IDE for linux, not something as bloated as Eclipse. I chose SciTE. It is one of the few text editors, and the only one I know of, that is distributed under an open license, is cross-platform, can select and paste columns of text, which saves lots of typing. It also lets you put regular expressions as well as tabs or end of line characters into search and replace which is invaluable for escaping code, a technique that makes it possible for a program to print itself. Plus, SciTE has code highlighting, code folding, code completion, and can be extended with scripts. I scripted an extension that builds simple programs for me and added it to SciTEUser.properties.

command.name.16.*=Compile and Link
command.16.*=\
gcc -Wall -pedantic -O2 "$(FileName).c" -o "$(FileName)"  -std=c99
command.shortcut.16.*=Ctrl+Shift+F7

Finally, I added some rough Makefile templates for the various cross-compilers I'm using and also a skeletal program.c into my Templates folder. (This allows me to create new documents based on a template.)

Dolly is originally a Pascal program written by Daniel Martin. Click the link and scroll down to find the original. I think it's worth looking at because it shows just how similar my version looks after porting it to C. I did my best to make it as close as possible to the original. I had done some Pascal programming in High School, so Pascal makes sense to me. I took it as a sort of personal exam. I knew that if I could translate this progam into C that I would have proven to myself a certain level of competence with strings. Compile on linux with "gcc dolly.c -o dolly"

If you plan to build this, use the download link in case there is HTML formatting corruption. Not all browsers render correctly. Here are some of my other early attempts at C.

#include <stdio.h>
#include <string.h>
int main(){
    int prelines = 9;
    int numlines = 23;

    char* myself[100];
    int i,j;

    myself[ 1]="#include <stdio.h>";
    myself[ 2]="#include <string.h>";
    myself[ 3]="int main(){";
    myself[ 4]="    int prelines = 9;";
    myself[ 5]="    int numlines = 23;";
    myself[ 6]="";
    myself[ 7]="    char* myself[100];";
    myself[ 8]="    int i,j;";
    myself[ 9]="";
    myself[10]="    for (i=1;i<=prelines;i++) printf(\"%s\\n\",myself[i]);";
    myself[11]="    for (i=1;i<=numlines;i++){";
    myself[12]="        printf(\"\\tmyself[%2d]=\\\"\",i);";
    myself[13]="        for (j=0;j<strlen(myself[i]);j++){";
    myself[14]="            if (myself[i][j]=='\\\\' || myself[i][j]=='\\\"') printf(\"\\\\\");";
    myself[15]="            printf(\"%c\",myself[i][j]);";
    myself[16]="        }";
    myself[17]="        printf(\"\\\";\\n\");";
    myself[18]="    }";
    myself[19]="    for (i=prelines;i<numlines;i++)";
    myself[20]="        printf(\"%s\\n\",myself[i]);";
    myself[21]="    return 0;";
    myself[22]="}";
    myself[23]="";

    for (i=1;i<=prelines;i++) printf("%s\n",myself[i]);
    for (i=1;i<=numlines;i++){
        printf("\tmyself[%2d]=\"",i);
        for (j=0;j<strlen(myself[i]);j++){
            if (myself[i][j]=='\\' || myself[i][j]=='\"') printf("\\");
            printf("%c",myself[i][j]);
        }
        printf("\";\n");
    }
    for (i=prelines;i<numlines;i++)
        printf("%s\n",myself[i]);
    return 0;
}