*
* Licensed under the GNU Public License version 3 only, see LICENSE.
*
- * @BAKE cc -std=c89 -O2 -I. @FILENAME -o @SHORT @ARGS @STOP
+ * @BAKE cc -std=c89 -O2 @FILENAME -o @SHORT @ARGS @STOP
*/
-/*#define POSIXLY_CORRECT*/
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#define FILENAME_LIMIT (FILENAME_MAX)
+#define BAKE_ERROR 127
+
+enum {
+ BAKE_UNRECOGNIZED,
+ BAKE_MISSING_SUFFIX,
+};
+
#define ARRLEN(a) (sizeof(a) / sizeof(a[0]))
#if INCLUDE_AUTONOMOUS_COMPILE
-__attribute__((__section__(".text"))) static char autonomous_compile[] = "@BAKE cc -std=c89 $@.c -o $@ $+ @STOP";
+__attribute__((__section__(".text"))) static char autonomous_compile[] = "@BAKE cc -std=c89 -O2 $@.c -o $@ $+ @STOP";
#endif
-static char * argv0;
-
-static char * global[4];
-
-#define g_filename global[0]
-#define g_short global[1]
-#define g_all global[2]
-#define g_stop global[3]
+static int bake_errno;
typedef struct {
- char * str;
+ char * buf;
size_t len;
} map_t;
&& s.st_mode & S_IFREG
&& s.st_size) {
m.len = (size_t) s.st_size;
- m.str = (char *) mmap(NULL, m.len, PROT_READ, MAP_SHARED, fd, 0);
+ m.buf = (char *) mmap(NULL, m.len, PROT_READ, MAP_SHARED, fd, 0);
}
close(fd);
}
static char *
find_region(map_t m, char * findstart, char * findstop) {
- char * buf = NULL, * start, * stop, * end = m.len + m.str;
- start = find(m.str, findstart, end);
+ char * buf = NULL, * start, * stop, * end = m.len + m.buf;
+ start = find(m.buf, findstart, end);
if (start) {
start += strlen(findstart);
#ifdef REQUIRE_SPACE
if (!isspace(*start)) {
- fprintf(stderr, BOLD RED "%s" RESET ": '" BOLD "%s" RESET "' Found start without suffix spacing.\n", argv0, g_filename);
- return buf;
+ bake_errno = BAKE_MISSING_SUFFIX;
+ return NULL;
}
#endif /* REQUIRE_SPACE */
}
if (stop)
- { buf = strndup(start, (size_t) (stop - m.str) - (start - m.str)); }
+ { buf = strndup(start, (size_t) (stop - m.buf) - (start - m.buf)); }
}
return buf;
}
file_find_region(char * fn, char * start, char * stop) {
char * buf = NULL;
map_t m = map(fn);
- if (m.str) {
+ if (m.buf) {
buf = find_region(m, start, stop);
- munmap(m.str, m.len);
+ munmap(m.buf, m.len);
}
return buf;
}
+/*** g_short, g_all ***/
+
+static char *
+shorten(char * fn) {
+ size_t i, last, len;
+ static char sh[FILENAME_LIMIT];
+ len = strlen(fn);
+ for (last = i = 0; i < len; ++i) {
+ if (fn[i] == '.') { last = i; }
+ }
+ last = last ? last : i;
+ strncpy(sh, fn, last);
+ sh[last] = '\0';
+ return sh;
+}
+
+static char *
+all_args(size_t argc, char ** argv) {
+ char * all = NULL;
+ if (argc > 2) {
+ size_t i, len = argc;
+
+ for (i = 2; i < argc; ++i)
+ { len += strlen(argv[i]); }
+ all = malloc(len + 1);
+ all[len] = '\0';
+ for (len = 0, i = 2; i < argc; ++i) {
+ strcpy(all + len, argv[i]);
+ len += strlen(argv[i]) + 1;
+ if (i + 1 < argc) { all[len - 1] = ' '; }
+ }
+ }
+ return all ? all : calloc(1,1);
+}
+
/*** insert, expand, bake_expand ***/
static void
}
static char *
-bake_expand(char * buf) {
+bake_expand(char * buf, char * filename, int argc, char ** argv) {
enum {
MACRO_FILENAME,
MACRO_SHORT,
macro_old[MACRO_SHORT ] = "$*";
macro_old[MACRO_ARGS ] = "$+";
+ char * global[4];
+
+ global[MACRO_FILENAME] = filename;
+ global[MACRO_SHORT ] = shorten(filename);
+ global[MACRO_ARGS ] = all_args((size_t) argc, argv);
+ global[MACRO_STOP ] = "";
+
#if NEW_MACROS
for (i = 0; i < ARRLEN(macro); ++i) {
buf = expand(buf, macro[i], global[i]);
}
#endif
- return buf;
-}
-
-/*** g_short, g_all ***/
+ free(global[MACRO_ARGS]);
-static char *
-shorten(char * fn) {
- size_t i, last, len;
- static char sh[FILENAME_LIMIT];
- len = strlen(fn);
- for (last = i = 0; i < len; ++i) {
- if (fn[i] == '.') { last = i; }
- }
- last = last ? last : i;
- strncpy(sh, fn, last);
- sh[last] = '\0';
- return sh;
-}
-
-static char *
-all_args(size_t argc, char ** argv) {
- char * all = NULL;
- if (argc > 2) {
- size_t i, len = argc;
-
- for (i = 2; i < argc; ++i)
- { len += strlen(argv[i]); }
- all = malloc(len + 1);
- all[len] = '\0';
- for (len = 0, i = 2; i < argc; ++i) {
- strcpy(all + len, argv[i]);
- len += strlen(argv[i]) + 1;
- if (i + 1 < argc) { all[len - 1] = ' '; }
- }
- }
- return all ? all : calloc(1,1);
+ return buf;
}
/*** strip, run ***/
}
static int
-run(char * buf) {
+run(char * buf, char * argv0) {
fputs(BOLD GREEN "output" RESET ":\n", stderr);
- pid_t pid = fork();
- if (pid == 0) {
- if (execl("/bin/sh", "sh", "-c", buf, NULL) == -1) {
- fprintf(stderr, BOLD RED "%s" RESET ": %s, %s\n", argv0, "Exec Error", strerror(errno));
- }
- return 0;
+ pid_t pid;
+ if ((pid = fork()) == 0) {
+ execl("/bin/sh", "sh", "-c", buf, NULL);
+ return 0; /* execl overwrites the process anyways */
} else if (pid == -1) {
fprintf(stderr, BOLD RED "%s" RESET ": %s, %s\n", argv0, "Fork Error", strerror(errno));
- return -1;
+ return BAKE_ERROR;
} else {
int status;
if (waitpid(pid, &status, 0) < 0) {
fprintf(stderr, BOLD RED "%s" RESET ": %s, %s\n", argv0, "Wait PID Error", strerror(errno));
- return -1;
+ return BAKE_ERROR;
}
- if (!WIFEXITED(status)) { return -1; }
+ if (!WIFEXITED(status)) { return BAKE_ERROR; }
return WEXITSTATUS(status);
}
}
int
main(int argc, char ** argv) {
int ret = 0;
- char * buf = NULL;
+ char * buf = NULL,
+ * filename,
+ * argv0;
argv0 = argv[0];
else { goto help; }
}
- g_filename = argv[1];
- if (strlen(g_filename) > FILENAME_LIMIT) { goto fnerr; }
+ filename = argv[1];
+ if (strlen(filename) > FILENAME_LIMIT) {
+ fprintf(stderr, BOLD RED "%s" RESET ": Filename too long (exceeds %d)\n", argv0, FILENAME_LIMIT);
+ return BAKE_ERROR;
+ }
+
+ root(&filename);
+ buf = file_find_region(filename, START, STOP);
- root(&g_filename);
- buf = file_find_region(g_filename, START, STOP);
+ char * error[2];
+ error[0] = "File Unrecognized";
+ error[1] = "Found start without suffix spacing";
if (!buf) {
- if (errno)
- { fprintf(stderr, BOLD RED "%s" RESET ": '" BOLD "%s" RESET "' %s\n", argv0, g_filename, strerror(errno)); }
- else
- { fprintf(stderr, BOLD RED "%s" RESET ": '" BOLD "%s" RESET "' File unrecognized.\n", argv0, g_filename); }
- return 1;
+ printf("%d\n", bake_errno);
+ fprintf(stderr, BOLD RED "%s" RESET ": '" BOLD "%s" RESET "' %s.\n",
+ argv0, filename, errno ? strerror(errno) : error[bake_errno]);
+ return BAKE_ERROR;
}
- g_short = shorten(g_filename);
- g_all = all_args((size_t) argc, argv);
- g_stop = "";
-
- buf = bake_expand(buf);
-
- free(g_all);
+ buf = bake_expand(buf, filename, argc, argv);
fprintf(stderr, BOLD GREEN "%s" RESET ": %s\n", argv0, buf + strip(buf));
- ret = ret ? 0 : run(buf);
+ ret = ret ? 0 : run(buf,argv0);
if (ret)
{ fprintf(stderr, BOLD RED "result" RESET ": " BOLD "%d\n" RESET, ret); }
return ret;
help:
fprintf(stderr, YELLOW "%s" RESET ": %s", argv0, HELP DESC);
- return 1;
-fnerr:
- fprintf(stderr, BOLD RED "%s" RESET ": Filename too long (exceeds %d)\n", argv0, FILENAME_LIMIT);
+ return BAKE_ERROR;
}