2024-01-25 15:23:13 +01:00
2024-01-25 13:55:17 +01:00
2024-01-23 10:57:51 +01:00
2024-01-25 13:55:17 +01:00
2024-01-23 16:25:03 +01:00
2024-01-23 16:14:28 +01:00
2024-01-25 14:12:49 +01:00
2024-01-25 14:12:49 +01:00

DR QUINE

2. GRACE

2.1 constructing a quine with macro :


a quine could be this structure basically :

int main()
{
	char *quine = THE_WHOLE_PROGRAM;
	printf(quine);
	return 0;
}

in one line :

int main(){ char *quine = THIS_LINE_&_THE_LINES_AROUND; printf(quine); return 0; }

whole code idea :

#include <stdio.h>
#define MAIN() int main() { char *quine = "BEFORE" "THIS_MACRO_ITSELF" "AFTER"; printf(quine); return 0; }

MAIN()

2.2 let's try it


#include <stdio.h>
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

MAIN(s)

expansions : -> int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }

exploded view :

int main()
{
	char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))";
	printf(quine);
	return 0;
}

problem : the char *quine string should contain a copy of the whole code in place of "s"

2.3 second try, macro calling itself : MAIN(MAIN)


#include <stdio.h>
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s"\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }

MAIN(MAIN(s))

expansions : -> int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))"; printf(quine); return 0; }"\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }

exploded view :

int main()
{
	char *quine = "#include <stdio.h>\n#define MAIN(s) "int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))"; printf(quine); return 0; }"\n\nMAIN(MAIN(s))\n";
	printf(quine);
	return 0;
}

problem : almost there, but the content of the string quine should be a litteral string instead of code

2.4 lets stringify the content of the inner MAIN


the previous can be written with an extra step :

#define str(s) s
#define MAIN(s) content s content
MAIN(str(MAIN(s)))

/* EQUIVALENT */

#define MAIN(s) content s content
MAIN((MAIN(s)))

we can use this extra step to stringify the content :

#include <stdio.h>
#define str(s) #s
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define str(s) #s\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

MAIN(str(MAIN(s)))

expansions : -> int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) ""MAIN(s)""\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

exploded view :

int main()
{
	char *quine = "#include <stdio.h>\n#define MAIN(s) ""MAIN(s)""\n\nMAIN(str(MAIN(s)))";
	printf(quine);
	return 0;
}

problem : oops, it stringified the parameter name, not it's expanded version, see https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html

2.5 working stringification


#include <stdio.h>
#define xstr(s) #s
#define str(s) xstr(s)
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

MAIN(str(MAIN(s)))

expansions : -> int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) ""int main() { char *quine = \"#include <stdio.h>\\n#define xstr(s) #s\\n#define str(s) xstr(s)\\n#define MAIN(s) \"s\"\\n\\nMAIN(str(MAIN(s)))\\n\"; printf(quine); return 0; }""\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

exploded view :

int main()
{
	char *quine =
		"#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "
		"int main() { char *quine = \"#include <stdio.h>\\n#define xstr(s) #s\\n#define str(s) xstr(s)\\n#define MAIN(s) \"s\"\\n\\nMAIN(str(MAIN(s)))\\n\"; printf(quine); return 0; }"
		"\n\nMAIN(str(MAIN(s)))\n";
	printf(quine);
	return 0;
}

output :

#include <stdio.h>
#define xstr(s) #s
#define str(s) xstr(s)
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }

MAIN(str(MAIN(s)))

victory ;)

Description
No description provided
Readme 2.4 MiB
Languages
C 60.1%
Makefile 39.9%