From 319c7568828a01fa5ba8ded0b560d852124ffb84 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Mon, 25 Apr 2022 19:45:31 -0400 Subject: add support for setting flags in source --- Makefile | 6 ++++++ flags.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ list.c | 43 ++++++++++++++++++++++++++++++++++++++++ maje.h | 10 ++++++++++ make.c | 37 ++++++++++++++++++++++++++++++----- 5 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 flags.c diff --git a/Makefile b/Makefile index 8f057b7..3853a27 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,12 @@ $(OBJDIR)/make.o: $(SRCDIR)/make.c @mkdir -p $(@D) $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/make.c +$(BINDIR)/maje: $(OBJDIR)/flags.o +$(OBJDIR)/flags.o: $(SRCDIR)/maje.h +$(OBJDIR)/flags.o: $(SRCDIR)/flags.c + @mkdir -p $(@D) + $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/flags.c + $(BINDIR)/maje: $(OBJDIR)/includes.o $(OBJDIR)/includes.o: $(SRCDIR)/maje.h $(OBJDIR)/includes.o: $(SRCDIR)/includes.c diff --git a/flags.c b/flags.c new file mode 100644 index 0000000..2cd7b13 --- /dev/null +++ b/flags.c @@ -0,0 +1,68 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include + +#include "maje.h" + +#define MAX_MATCHES (2) + +static struct majeflag * find_flags(const struct majefile *file, const regex_t * restrict re, struct majeflag *flags) +{ + int fd = open(file->path, O_RDONLY); + if (fd == -1) { + return NULL; + } + + void *map = mmap(NULL, (size_t)file->st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) { + close(fd); + return NULL; + } + + regmatch_t match[MAX_MATCHES]; + + void *base = map; + while (regexec(re, base, MAX_MATCHES, match, 0) == 0) { + if (match[1].rm_so == -1) { + break; + } + char flag[FILENAME_MAX] = { 0 }; + char *start = (char*)base + match[1].rm_so; + memcpy(flag, start, match[1].rm_eo - match[1].rm_so); + flags = insert_flag(flags, flag); + base = start + match[1].rm_eo; + } + + munmap(map, file->st.st_size); + close(fd); + + return flags; +} + +struct majeflag *add_flags(const struct majefile *source, struct majeflag *flags) +{ + static regex_t re = { .re_nsub = (size_t)-1 }; + if (re.re_nsub == (size_t)-1) { + if (regcomp(&re, + "(MAJE_[[:upper:]]+=[^[:space:]]+)", + REG_EXTENDED | REG_NEWLINE) != 0) { + fprintf(stderr, "maje: regcomp(MAJE) failed\n"); + abort(); + } + } + + struct majeflag *ret = find_flags(source, &re, flags); + + if (ret != NULL) { + while (ret->prev != NULL) { + ret = ret->prev; + } + } + + return ret; +} diff --git a/list.c b/list.c index 24d265c..2fa06ab 100644 --- a/list.c +++ b/list.c @@ -1,4 +1,5 @@ #define _XOPEN_SOURCE 700 +#include #include #include @@ -34,3 +35,45 @@ struct majefile *insert_file(struct majefile *list, const char *path, const stru } return tmp; } + +struct majeflag *insert_flag(struct majeflag *list, char *flag) +{ + char *eq = strchr(flag, '='); + *eq = '\0'; + eq++; + + int type = 0; + if (!strcmp(flag, "MAJE_CFLAG")) { + type = MAJE_CFLAG; + } else if (!strcmp(flag, "MAJE_LDFLAG")) { + type = MAJE_LDFLAG; + } else if (!strcmp(flag, "MAJE_LDLIB")) { + type = MAJE_LDLIB; + } else { + fprintf(stderr, "maje: unkonwn directive '%s'\n", flag); + return list; + } + + struct majeflag *tmp = malloc(sizeof(*tmp) + strlen(flag) + 1); + if (tmp == NULL) { + return NULL; + } + + tmp->next = NULL; + tmp->prev = NULL; + + tmp->type = type; + strcpy(tmp->flag, eq); + + if (list == NULL) { + return tmp; + } + + tmp->next = list->next; + tmp->prev = list; + list->next = tmp; + if (tmp->next != NULL) { + tmp->next->prev = tmp; + } + return tmp; +} diff --git a/maje.h b/maje.h index 6f0af8d..ae62e0e 100644 --- a/maje.h +++ b/maje.h @@ -10,10 +10,20 @@ struct majefile { char path[]; }; +struct majeflag { + struct majeflag *next; + struct majeflag *prev; + enum { MAJE_CFLAG, MAJE_LDFLAG, MAJE_LDLIB } type; + char flag[]; +}; + struct majefile *find_source_files(const char *path); char *find_main(struct majefile *sources); struct majefile *find_includes(const struct majefile *file); void make_makefile(const char *makefile, struct majefile *sources, const char *target); struct majefile *insert_file(struct majefile *list, const char *path, const struct stat *st); +struct majeflag *insert_flag(struct majeflag *list, char *flag); +struct majeflag *add_flags(const struct majefile *source, struct majeflag *flags); + #endif diff --git a/make.c b/make.c index 5d2c808..13bc7eb 100644 --- a/make.c +++ b/make.c @@ -6,7 +6,7 @@ #include "maje.h" -static void make_header(FILE *makefile, const char *target) +static void make_header(FILE *makefile, const char *target, struct majeflag *flags) { fprintf(makefile, ".POSIX:\n\n"); fprintf(makefile, "# This Makefile was generated by maje\n"); @@ -15,9 +15,31 @@ static void make_header(FILE *makefile, const char *target) fprintf(makefile, "CC=c99\n"); fprintf(makefile, "LD=$(CC)\n"); - fprintf(makefile, "CFLAGS=-Wall -Wextra -Wpedantic -Werror -g\n"); - fprintf(makefile, "LDFLAGS=\n"); - fprintf(makefile, "LDLIBS=\n"); + + fprintf(makefile, "CFLAGS=-Wall -Wextra -Wpedantic -Werror -g"); + for (struct majeflag *flag = flags; flag != NULL; flag = flag->next) { + if (flag->type == MAJE_CFLAG) { + fprintf(makefile, " %s", flag->flag); + } + } + fprintf(makefile, "\n"); + + fprintf(makefile, "LDFLAGS="); + for (struct majeflag *flag = flags; flag != NULL; flag = flag->next) { + if (flag->type == MAJE_LDFLAG) { + fprintf(makefile, " %s", flag->flag); + } + } + fprintf(makefile, "\n"); + + fprintf(makefile, "LDLIBS="); + for (struct majeflag *flag = flags; flag != NULL; flag = flag->next) { + if (flag->type == MAJE_LDLIB) { + fprintf(makefile, " %s", flag->flag); + } + } + fprintf(makefile, "\n"); + fprintf(makefile, "SRCDIR=.\n"); fprintf(makefile, "OBJDIR=.\n"); fprintf(makefile, "BINDIR=$(OBJDIR)\n"); @@ -60,7 +82,12 @@ void make_makefile(const char *makepath, struct majefile *sources, const char *t return; } - make_header(makefile, target); + struct majeflag *flags = NULL; + for (struct majefile *src = sources; src != NULL; src = src->next) { + flags = add_flags(src, flags); + } + + make_header(makefile, target, flags); for (struct majefile *src = sources; src != NULL; src = src->next) { add_object(makefile, src, target); } -- cgit v1.2.1