- [interactions between MACRO and comments](https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#:~:text=the%20stringized%20result.-,Comments,-are%20replaced%20by) - [preprocessor strip comments before exapnding macros](https://stackoverflow.com/questions/1510869/does-the-c-preprocessor-strip-comments-or-expand-macros-first) - [create an include with a macro OR NOT](https://stackoverflow.com/questions/1135822/escaping-a-symbol-in-a-define-macro) --- ## make rules : - make in root will make all projects - make in each project will compile this project - make diff : compile if necessary, and run the program then compare the output - make concat : create the concatenated version, finale version, of the quine ## folder structure > Each programs will have to be coded in C and in Assembly, and respectivly in a folder named C and ASM, each folders containing its own Makefile with the usual rules. ``` dr_quine/ | C/ | | Colleen.c | | Grace.c | | Sully.c | | Makefile | | ... | ASM/ | | Colleen.asm | | Grace.asm | | Sully.asm | | Makefile | | ... ``` --- ## Grace --- #### 1 : a string containing itself, almost --- ``` #define xstr(s) str(s) #define str(s) char *quine = #s ; printf(quine); xstr(str()) ``` **expansions :** -> `xstr ( char *quine = "" ; printf(quine); )` -> `char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine);` **problem :** `\"\"` instead of `#s` : -> `char *quine = "char *quine = #s ; printf(quine);" ; printf(quine);` #### 1.2 : the output, first try --- ``` #include #define MAIN(s) int main(){ s return 0; } #define xstr(s) str(s) #define str(s) char *quine = #s ; printf(quine); MAIN(xstr(str())) ``` **expansions :** -> `MAIN( xstr( char *quine = "" ; printf(quine); ))` -> `MAIN( char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); )` -> `int main(){ char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); return 0; }` **exploded view :** ``` int main(){ char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); return 0; } ``` **output :** ``` char *quine = "" ; printf(quine); ``` **problem 1 :** missing the main function around the content **problem 2 :** quine does not contain itself, but an empty string #### 1.3 : the output, second try --- ``` #include #define MAIN(s) int main(){ s return 0; } #define xstr(s) str(s) #define str(s) char *quine = #s ; printf(quine); MAIN(xstr(MAIN(xstr(str())))) ``` **expansions :** -> `MAIN( xstr( MAIN( xstr( char *quine = "" ; printf(quine); ))))` -> `MAIN( xstr( MAIN( char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); )))` -> `MAIN( xstr( int main(){ char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); return 0; } ))` -> `MAIN( char *quine = "int main(){ char *quine = \"char *quine = \\\"\\\" ; printf(quine);\" ; printf(quine); return 0; }" ; printf(quine); )` -> `int main(){ char *quine = "int main(){ char *quine = \"char *quine = \\\"\\\" ; printf(quine);\" ; printf(quine); return 0; }" ; printf(quine); return 0; }` **exploded view :** ``` int main() { char *quine = " int main() { char *quine = \"char *quine = \\\"\\\" ; printf(quine);\" ; printf(quine); return 0; } "; printf(quine); return 0; } ``` **output :** ``` int main(){ char *quine = "char *quine = \"\" ; printf(quine);" ; printf(quine); return 0; }% ``` **exploded view :** ``` int main() { char *quine = "char *quine = \"\" ; printf(quine);"; printf(quine); return 0; } ``` **problem :** this new program will only print : `char *quine = "" ; printf(quine);` #### 1.3 : the output, third try --- ``` #include #define MAIN(s) int main(){ s return 0; } #define xstr(s) str(s) #define str(s) char *quine = #s ; printf(quine); MAIN(xstr(MAIN(xstr(MAIN(xstr()))))) ``` **output :** `int main(){ char *quine = "int main(){ char *quine = \"\" ; printf(quine); return 0; }" ; printf(quine); return 0; }` **exploded view :** ``` int main() { char *quine = " int main() { char *quine = \"\"; printf(quine); return 0; } "; printf(quine); return 0; } ``` **problem :** we cannot gon on like this, there will always be one level missing **idea :** changing the inner `char* quine =` content to '%s' and printing `printf(quine, quine)` #### 2 : second approach --- **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 #define MAIN() int main() { char *quine = "BEFORE" "THIS_MACRO_ITSELF" "AFTER"; printf(quine); return 0; } MAIN() ``` #### 2.1 : let's try it --- ``` #include #define MAIN(s) int main() { char *quine = "#include \n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; } MAIN(s) ``` **expansions :** -> `int main() { char *quine = "#include \n#define MAIN(s) "s "\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }` **exploded view :** ``` int main() { char *quine = "#include \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.2 : second try, macro calling itself : MAIN(MAIN) --- ``` #include #define MAIN(s) int main() { char *quine = "#include \n#define MAIN(s) "s"\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; } MAIN(MAIN(s)) ``` **expansions :** -> `int main() { char *quine = "#include \n#define MAIN(s) "int main() { char *quine = "#include \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 \n#define MAIN(s) "int main() { char *quine = "#include \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.3 : 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 #define str(s) #s #define MAIN(s) int main() { char *quine = "#include \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 \n#define MAIN(s) ""MAIN(s)""\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }` **exploded view :** ``` int main() { char *quine = "#include \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.4 : working stringification --- ``` #include #define xstr(s) #s #define str(s) xstr(s) #define MAIN(s) int main() { char *quine = "#include \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 \n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) ""int main() { char *quine = \"#include \\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 \n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) " "int main() { char *quine = \"#include \\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 #define xstr(s) #s #define str(s) xstr(s) #define MAIN(s) int main() { char *quine = "#include \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 ;)**