diff options
author | Matthew Sotoudeh <matthew@masot.net> | 2024-04-20 17:08:04 -0700 |
---|---|---|
committer | Matthew Sotoudeh <matthew@masot.net> | 2024-04-20 17:08:04 -0700 |
commit | ee0ea049f6bae5d1ffc137e17b1858cb1e154b13 (patch) | |
tree | 45db7626cd4dfe0ca32d9e665c648ad38f66ea1a | |
parent | 3d808effbdb543c92db815a112c786b44c8a9e12 (diff) |
support --gamma-to-c flag
-rw-r--r-- | README.txt | 3 | ||||
-rw-r--r-- | gamma_version/Makefile | 3 | ||||
-rw-r--r-- | gamma_version/fakeobj.c | 8 | ||||
-rw-r--r-- | gamma_version/gamma.h | 3 | ||||
-rw-r--r-- | gamma_version/main.c | 25 | ||||
-rw-r--r-- | gamma_version/utils.c | 26 |
6 files changed, 59 insertions, 9 deletions
@@ -33,6 +33,9 @@ Selling points include: relatively easy to port as a preprocessor for other languages, e.g., Hare. + - The gamma version of gamma allows you to pass --gamma-to-c, which will + create the directory "c.out" and write a C version of the codebase to it. + ####### Code Samples ####### > uint32_t vector_push::[type T](struct vector::[T] *vector, T item) { diff --git a/gamma_version/Makefile b/gamma_version/Makefile index 81bd4e5..afd265c 100644 --- a/gamma_version/Makefile +++ b/gamma_version/Makefile @@ -18,7 +18,8 @@ OBJS=build/main.o \ build/hashmap.o \ build/hash_functions.o \ build/vector.o \ - build/debug.o + build/debug.o \ + build/utils.o build/gc: $(OBJS) $(CC) $(CFLAGS) -o $@ $^ diff --git a/gamma_version/fakeobj.c b/gamma_version/fakeobj.c index 544ada1..10fae7a 100644 --- a/gamma_version/fakeobj.c +++ b/gamma_version/fakeobj.c @@ -37,6 +37,7 @@ void preproc(char *src, char *dst) { if (str_ends_with(ARGV[i], ".c")) continue; if (str_ends_with(ARGV[i], ".a")) continue; if (str_ends_with(ARGV[i], ".o")) continue; + if (!strcmp(ARGV[i], "--gamma-to-c")) continue; if (!strcmp(ARGV[i], "-c")) continue; if (!strcmp(ARGV[i], "-o")) { i++; continue; } new_argv[new_argc++] = ARGV[i]; @@ -57,6 +58,7 @@ void write_fakeobj(char *src, char *dst, int i) { if (str_ends_with(ARGV[j], ".c")) continue; if (str_ends_with(ARGV[j], ".o")) continue; if (str_ends_with(ARGV[j], ".a")) continue; + if (!strcmp(ARGV[j], "--gamma-to-c")) continue; if (!strcmp(ARGV[j], "-c")) continue; if (!strcmp(ARGV[j], "-o")) { j++; continue; } new_argv[new_argc++] = ARGV[j]; @@ -73,6 +75,7 @@ void write_fakeobj(char *src, char *dst, int i) { goto fake_obj; real_obj: + if (GAMMA_TO_C) goto fake_obj; // rewrite the args and call new_argv[new_argc++] = "-c"; new_argv[new_argc++] = src; @@ -137,12 +140,9 @@ char **read_fakeobj(char *path, char *c_dst) { assert(len == read(fd, argv[i], len)); } - struct stat statbuf; - fstat(fd, &statbuf); - int out_fd = open(c_dst, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); assert(out_fd >= 0); - sendfile(out_fd, fd, NULL, statbuf.st_size); + gamma_sendfile(out_fd, fd); close(out_fd); close(fd); diff --git a/gamma_version/gamma.h b/gamma_version/gamma.h index 673636b..d1937e7 100644 --- a/gamma_version/gamma.h +++ b/gamma_version/gamma.h @@ -100,7 +100,10 @@ struct call *replace_variables(struct call *container, struct call *container_in void fprint_string(FILE *out, struct uniq_string *string); char **read_fakeobj(char *path, char *c_dst); void write_fakeobj(char *src, char *dst, int i); +void gamma_sendfile(int dst_fd, int src_fd); +void copy_file(char *dst, char *src); extern char **ARGV; extern int ARGC; extern char *TMPDIR; +extern int GAMMA_TO_C; diff --git a/gamma_version/main.c b/gamma_version/main.c index a402e1b..780c80f 100644 --- a/gamma_version/main.c +++ b/gamma_version/main.c @@ -35,6 +35,7 @@ char **get_object_files(char *dir, size_t *n_object_files) { char **ARGV; int ARGC; char *TMPDIR; +int GAMMA_TO_C; int main(int argc, char **argv) { // ======= Make a working copy of argv ======= @@ -48,6 +49,12 @@ int main(int argc, char **argv) { strcpy(TMPDIR, "/tmp/gamma.XXXXXX"); assert(mkdtemp(TMPDIR)); + // ======= Handle --gamma-to-c ... ======= + // If "--gamma-to-c" in args, then set the GAMMA_TO_C global. + for (int i = 0; i < ARGC; i++) + if (!strcmp(ARGV[i], "--gamma-to-c")) + GAMMA_TO_C = 1; + // ======= Handle -c ... ======= // If "-c" in args, then check if there are any templates/etc. and compile // either a .o or a fake-.o @@ -172,12 +179,22 @@ int main(int argc, char **argv) { fflush(c_file); fclose(c_file); - assert(fake_argvs[file->id]); - int pid = fork(); - if (!pid) execvp(fake_argvs[file->id][0], fake_argvs[file->id]); - waitpid(pid, 0, 0); + if (GAMMA_TO_C) { + // move every C file from the arguments to the out directory + mkdir("c.out", 0755); + char out_name[128] = {0}; + sprintf(out_name, "c.out/%ld.c", file->id); + copy_file(out_name, c_path); + } else { + assert(fake_argvs[file->id]); + int pid = fork(); + if (!pid) execvp(fake_argvs[file->id][0], fake_argvs[file->id]); + waitpid(pid, 0, 0); + } } + if (GAMMA_TO_C) goto cleanup; + // NOW all the arguments should be set up properly, so just run the command execvp(ARGV[0], ARGV); diff --git a/gamma_version/utils.c b/gamma_version/utils.c new file mode 100644 index 0000000..8877974 --- /dev/null +++ b/gamma_version/utils.c @@ -0,0 +1,26 @@ +#include "gamma.h" +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/sendfile.h> + +void gamma_sendfile(int dst_fd, int src_fd) { + // sendfile(out_fd, fd, NULL, statbuf.st_size); + struct stat stat; + fstat(src_fd, &stat); + + size_t n_bytes = stat.st_size - lseek(src_fd, 0, SEEK_CUR); + + char *data = malloc(n_bytes); + assert(read(src_fd, data, n_bytes) == n_bytes); + write(dst_fd, data, n_bytes); +} + +void copy_file(char *dst, char *src) { + int s = open(src, O_RDONLY), + d = open(dst, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + gamma_sendfile(d, s); + close(s); + close(d); +} |