diff --git a/Grace_Kid.c b/Grace_Kid.c deleted file mode 100644 index f3fd9ea..0000000 --- a/Grace_Kid.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include - -#define SRC "#include \n#include \n#include \n#include \n#include \n\n#define SRC \"$\"\n#define KID \"Grace_Kid.c\"\n#define MAIN \\\nstatic inline void cleanup_fd(int *fd) { \\\n if (*fd >= 0) close(*fd); \\\n} \\\nint \\\nmain(void) \\\n{ \\\n\tchar\t*src = SRC; \\\n\tint\t\tfd __attribute__ ((__cleanup__(cleanup_fd))) = open(KID, O_CREAT | O_RDWR | O_TRUNC, 0664); \\\n\tint\t\tsaved_errno = errno; \\\n\tchar\tbuff[1024] = {0}; \\\n\tsize_t\tlen = 0; \\\n\tsize_t\tbuff_max = sizeof(buff) - 1; \\\n\tif (0 != saved_errno) \\\n\t\treturn 1; \\\n\tfor (size_t i = 0; src[i]; ++i) \\\n\t{ \\\n\t\tif (36 == src[i]) \\\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\tswitch (src[j]) \\\n\t\t\t\t{ \\\n\t\t\t\t\tcase 10:\tmemcpy(buff + len, \"\\\\n\", 2); len += 2; break; \\\n\t\t\t\t\tcase 9:\t\tmemcpy(buff + len, \"\\\\t\", 2); len += 2; break; \\\n\t\t\t\t\tcase '\\\\':\tmemcpy(buff + len, \"\\\\\\\\\", 2); len += 2; break; \\\n\t\t\t\t\tcase '\"':\tmemcpy(buff + len, \"\\\\\\\"\", 2); len += 2; break; \\\n\t\t\t\t\tdefault:\tbuff[len++] = src[j]; break; \\\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[i]; \\\n\t\t} \\\n\t} \\\n\tif (len > 0) write(fd, buff, len); \\\n\treturn 0; \\\n}\n\n// One comments must be present\n\nMAIN\n" -#define KID "Grace_Kid.c" -#define MAIN \ -static inline void cleanup_fd(int *fd) { \ - if (*fd >= 0) close(*fd); \ -} \ -int \ -main(void) \ -{ \ - char *src = SRC; \ - int fd __attribute__ ((__cleanup__(cleanup_fd))) = open(KID, O_CREAT | O_RDWR | O_TRUNC, 0664); \ - int saved_errno = errno; \ - char buff[1024] = {0}; \ - size_t len = 0; \ - size_t buff_max = sizeof(buff) - 1; \ - if (0 != saved_errno) \ - return 1; \ - for (size_t i = 0; src[i]; ++i) \ - { \ - if (36 == src[i]) \ - { \ - for (size_t j = 0; src[j]; ++j) \ - { \ - if (len + 2 > buff_max) { write(fd, buff, len); len = 0; } \ - switch (src[j]) \ - { \ - case 10: memcpy(buff + len, "\\n", 2); len += 2; break; \ - case 9: memcpy(buff + len, "\\t", 2); len += 2; break; \ - case '\\': memcpy(buff + len, "\\\\", 2); len += 2; break; \ - case '"': memcpy(buff + len, "\\\"", 2); len += 2; break; \ - default: buff[len++] = src[j]; break; \ - } \ - } \ - } \ - else \ - { \ - if (len + 1 > buff_max) { write(fd, buff, len); len = 0; } \ - buff[len++] = src[i]; \ - } \ - } \ - if (len > 0) write(fd, buff, len); \ - return 0; \ -} - -// One comments must be present - -MAIN diff --git a/Makefile b/Makefile index 9365cd0..7b3a721 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,11 @@ SRC_DIR = src COLLEEN_SRCS = $(SRC_DIR)/Colleen.c GRACE_SRCS = $(SRC_DIR)/Grace.c +SULLY_SRCS = $(SRC_DIR)/Sully.c COLLEEN = Colleen GRACE = Grace +SULLY = Sully .DEFAULT_GOAL := all MAKEFLAGS += --no-print-directory @@ -21,14 +23,20 @@ COLLEEN_DEPS = $(COLLEEN_OBJS:.o=.d) GRACE_OBJS = $(GRACE_SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) GRACE_DEPS = $(GRACE_OBJS:.o=.d) +SULLY_OBJS = $(SULLY_SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) +SULLY_DEPS = $(SULLY_OBJS:.o=.d) + .PHONY: all -all: $(COLLEEN) $(GRACE) +all: $(COLLEEN) $(GRACE) $(SULLY) $(GRACE): $(GRACE_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(COLLEEN): $(COLLEEN_OBJS) $(CC) $(LDFLAGS) -o $@ $^ + +$(SULLY): $(SULLY_OBJS) + $(CC) $(LDFLAGS) -o $@ $^ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c @mkdir -p $(dir $@) @@ -36,6 +44,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c -include $(COLLEEN_DEPS) -include $(GRACE_DEPS) +-include $(SULLY_DEPS) .PHONY: clean clean: @@ -43,7 +52,7 @@ clean: .PHONY: fclean fclean: clean - $(RM) $(COLLEEN) $(GRACE) + $(RM) $(COLLEEN) $(GRACE) $(SULLY) .PHONY: re re: fclean diff --git a/src/Sully.c b/src/Sully.c new file mode 100644 index 0000000..a2fc266 --- /dev/null +++ b/src/Sully.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include +#include + +#define QUOTE_ME(x) #x +#define STR(x) QUOTE_ME(x) + +#ifndef CC +# define CC cc +#endif + +static const char * const escape_map[256] = +{ + [9] = "\\t", + [10] = "\\n", + ['\\'] = "\\\\", + ['"'] = "\\\"", +}; + +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" + +static inline void +cleanup_fd(int *fd) +{ + if (*fd >= 0) close(*fd); +} + +static int +do_quine(void) +{ + char name[32]; + char buff[1024]; + size_t len = 0; + size_t buff_max = sizeof(buff) - 1; + snprintf(name, sizeof(name), "Sully_%d.c", i - 1); + int fd __attribute__((__cleanup__(cleanup_fd))) = open(name, O_CREAT | O_RDWR | O_TRUNC, 0664); + int saved_errno = errno; + if (fd < 0 || saved_errno) + return 1; + for (size_t k = 0; SRC[k]; ++k) + { + if (64 == SRC[k]) + { + 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; } + memcpy(buff + len, num, (size_t)n); + len += (size_t)n; + } + else if (36 == SRC[k]) + { + for (size_t j = 0; SRC[j]; ++j) + { + if (len + 2 > buff_max) { write(fd, buff, len); len = 0; } + if (escape_map[(unsigned char)SRC[j]]) + { + memcpy(buff + len, escape_map[(unsigned char)SRC[j]], 2); + len += 2; + } + else + { + buff[len++] = SRC[j]; + } + } + } + else + { + if (len + 1 > buff_max) { write(fd, buff, len); len = 0; } + buff[len++] = SRC[k]; + } + } + if (len > 0) write(fd, buff, len); + return 0; +} + +static int +build(void) +{ + char cmd[256]; + snprintf(cmd, sizeof(cmd), STR(CC) " Sully_%d.c -o Sully_%d", i - 1, i - 1); + return system(cmd); +} + +int +main(void) +{ + char path[32]; + if (i - 1 < 0) + return 0; + if (do_quine()) + return 1; + if (build()) + return 1; + snprintf(path, sizeof(path), "./Sully_%d", i - 1); + return execl(path, path, NULL); + /* + This program will print its own source when run. + */ +}