diff --git a/src/Sully.c b/src/Sully.c index a2fc266..638c5ba 100644 --- a/src/Sully.c +++ b/src/Sully.c @@ -13,6 +13,12 @@ # define CC cc #endif +#define FLUSH(buff, fd, len) do \ +{ \ + write(fd, buff, len); \ + len = 0; \ +} while (0) + static const char * const escape_map[256] = { [9] = "\\t", @@ -23,7 +29,7 @@ static const char * const escape_map[256] = int i = 5; -#define SRC "#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#define QUOTE_ME(x) #x\n#define STR(x) QUOTE_ME(x)\n\n#ifndef CC\n# define CC cc\n#endif\n\nstatic const char * const escape_map[256] =\n{\n [9] = \"\\\\t\",\n [10] = \"\\\\n\",\n ['\\\\'] = \"\\\\\\\\\",\n ['\"'] = \"\\\\\\\"\",\n};\n\nint i = @;\n\n#define SRC \"$\"\n\nstatic inline void\ncleanup_fd(int *fd)\n{\n\tif (*fd >= 0) close(*fd);\n}\n\nstatic int\ndo_quine(void)\n{\n\tchar\tname[32];\n\tchar\tbuff[1024];\n\tsize_t\tlen = 0;\n\tsize_t\tbuff_max = sizeof(buff) - 1;\n\tsnprintf(name, sizeof(name), \"Sully_%d.c\", i - 1);\n\tint\t\tfd __attribute__((__cleanup__(cleanup_fd))) = open(name, O_CREAT | O_RDWR | O_TRUNC, 0664);\n\tint\t\tsaved_errno = errno;\n\tif (fd < 0 || saved_errno)\n\t\treturn 1;\n\tfor (size_t k = 0; SRC[k]; ++k)\n\t{\n\t\tif (64 == SRC[k])\n\t\t{\n\t\t\tchar\tnum[12];\n\t\t\tint\t\tn = snprintf(num, sizeof(num), \"%d\", i - 1);\n\t\t\tif (len + (size_t)n > buff_max) { write(fd, buff, len); len = 0; }\n\t\t\tmemcpy(buff + len, num, (size_t)n);\n\t\t\tlen += (size_t)n;\n\t\t}\n\t\telse if (36 == SRC[k])\n\t\t{\n\t\t\tfor (size_t j = 0; SRC[j]; ++j)\n\t\t\t{\n\t\t\t\tif (len + 2 > buff_max) { write(fd, buff, len); len = 0; }\n\t\t\t\tif (escape_map[(unsigned char)SRC[j]])\n\t\t\t\t{\n\t\t\t\t\tmemcpy(buff + len, escape_map[(unsigned char)SRC[j]], 2);\n\t\t\t\t\tlen += 2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbuff[len++] = SRC[j];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (len + 1 > buff_max) { write(fd, buff, len); len = 0; }\n\t\t\tbuff[len++] = SRC[k];\n\t\t}\n\t}\n\tif (len > 0) write(fd, buff, len);\n\treturn 0;\n}\n\nstatic int\nbuild(void)\n{\n\tchar\tcmd[256];\n\tsnprintf(cmd, sizeof(cmd), STR(CC) \" Sully_%d.c -o Sully_%d\", i - 1, i - 1);\n\treturn system(cmd);\n}\n\nint\nmain(void)\n{\n\tchar\tpath[32];\n\tif (i - 1 < 0)\n\t\treturn 0;\n\tif (do_quine())\n\t\treturn 1;\n\tif (build())\n\t\treturn 1;\n\tsnprintf(path, sizeof(path), \"./Sully_%d\", i - 1);\n\treturn execl(path, path, NULL);\n\t/*\n\t This program will print its own source when run.\n\t */\n}\n" +#define SRC "#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#define QUOTE_ME(x) #x\n#define STR(x) QUOTE_ME(x)\n\n#ifndef CC\n# define CC cc\n#endif\n\n#define FLUSH(buff, fd, len) do \\\n{ \\\n\twrite(fd, buff, len); \\\n\tlen = 0; \\\n} while (0)\n\nstatic const char * const escape_map[256] =\n{\n [9] = \"\\\\t\",\n [10] = \"\\\\n\",\n ['\\\\'] = \"\\\\\\\\\",\n ['\"'] = \"\\\\\\\"\",\n};\n\nint i = @;\n\n#define SRC \"$\"\n\nstatic inline void\ncleanup_fd(int *fd)\n{\n\tif (*fd >= 0) close(*fd);\n}\n\nstatic int\ndo_quine(void)\n{\n\tchar\tname[32];\n\tchar\tbuff[1024];\n\tsize_t\tlen = 0;\n\tsize_t\tbuff_max = sizeof(buff) - 1;\n\tsnprintf(name, sizeof(name), \"Sully_%d.c\", i - 1);\n\tint\t\tfd __attribute__((__cleanup__(cleanup_fd))) = open(name, O_CREAT | O_RDWR | O_TRUNC, 0664);\n\tint\t\tsaved_errno = errno;\n\tif (fd < 0 || saved_errno)\n\t\treturn 1;\n\tfor (size_t k = 0; SRC[k]; ++k)\n\t{\n\t\tif (64 == SRC[k])\n\t\t{\n\t\t\tchar\tnum[12];\n\t\t\tint\t\tn = snprintf(num, sizeof(num), \"%d\", i - 1);\n\t\t\tif (len + (size_t)n > buff_max)\n\t\t\t\tFLUSH(buff, fd, len); \n\t\t\tmemcpy(buff + len, num, (size_t)n);\n\t\t\tlen += (size_t)n;\n\t\t}\n\t\telse if (36 == SRC[k])\n\t\t{\n\t\t\tfor (size_t j = 0; SRC[j]; ++j)\n\t\t\t{\n\t\t\t\tif (len + 2 > buff_max)\n\t\t\t\t\tFLUSH(buff, fd, len); \n\t\t\t\tif (escape_map[(unsigned char)SRC[j]])\n\t\t\t\t{\n\t\t\t\t\tmemcpy(buff + len, escape_map[(unsigned char)SRC[j]], 2);\n\t\t\t\t\tlen += 2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbuff[len++] = SRC[j];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (len + 1 > buff_max)\n\t\t\t\tFLUSH(buff, fd, len); \n\t\t\tbuff[len++] = SRC[k];\n\t\t}\n\t}\n\tif (len > 0)\n\t\tFLUSH(buff, fd, len);\n\treturn 0;\n}\n\nstatic int\nbuild(void)\n{\n\tchar\tcmd[256];\n\tsnprintf(cmd, sizeof(cmd), STR(CC) \" Sully_%d.c -o Sully_%d\", i - 1, i - 1);\n\treturn system(cmd);\n}\n\nint\nmain(void)\n{\n\tchar\tpath[32];\n\tif (i - 1 < 0)\n\t\treturn 0;\n\tif (do_quine())\n\t\treturn 1;\n\tif (build())\n\t\treturn 1;\n\tsnprintf(path, sizeof(path), \"./Sully_%d\", i - 1);\n\treturn execl(path, path, NULL);\n\t/*\n\t This program will print its own source when run.\n\t */\n}\n" static inline void cleanup_fd(int *fd) @@ -49,7 +55,8 @@ do_quine(void) { char num[12]; int n = snprintf(num, sizeof(num), "%d", i - 1); - if (len + (size_t)n > buff_max) { write(fd, buff, len); len = 0; } + if (len + (size_t)n > buff_max) + FLUSH(buff, fd, len); memcpy(buff + len, num, (size_t)n); len += (size_t)n; } @@ -57,7 +64,8 @@ do_quine(void) { for (size_t j = 0; SRC[j]; ++j) { - if (len + 2 > buff_max) { write(fd, buff, len); len = 0; } + if (len + 2 > buff_max) + FLUSH(buff, fd, len); if (escape_map[(unsigned char)SRC[j]]) { memcpy(buff + len, escape_map[(unsigned char)SRC[j]], 2); @@ -71,11 +79,13 @@ do_quine(void) } else { - if (len + 1 > buff_max) { write(fd, buff, len); len = 0; } + if (len + 1 > buff_max) + FLUSH(buff, fd, len); buff[len++] = SRC[k]; } } - if (len > 0) write(fd, buff, len); + if (len > 0) + FLUSH(buff, fd, len); return 0; }