diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | flags.c | 68 | ||||
-rw-r--r-- | list.c | 43 | ||||
-rw-r--r-- | maje.h | 10 | ||||
-rw-r--r-- | make.c | 37 |
5 files changed, 159 insertions, 5 deletions
@@ -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 @@ -0,0 +1,68 @@ +#define _XOPEN_SOURCE 700 +#include <fcntl.h> +#include <regex.h> +#include <sys/mman.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#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; +} @@ -1,4 +1,5 @@ #define _XOPEN_SOURCE 700 +#include <stdio.h> #include <string.h> #include <stdlib.h> @@ -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; +} @@ -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 @@ -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); } |