diff options
author | Jakob Kaivo <jkk@ung.org> | 2020-03-27 16:53:14 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2020-03-27 16:53:14 -0400 |
commit | 1a21f9e690a5e5b334a5c5fbc2b4d1f71d00d43d (patch) | |
tree | ad9b6733871fc075315c6512d8509df5066303e4 | |
parent | 2a15bdb94ea913b361c026541eff3cfdcffccde6 (diff) |
initial support for adding local headers as dependencies
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | includes.c | 74 | ||||
-rw-r--r-- | list.c | 36 | ||||
-rw-r--r-- | maje.h | 3 | ||||
-rw-r--r-- | make.c | 16 | ||||
-rw-r--r-- | sources.c | 26 |
6 files changed, 156 insertions, 28 deletions
@@ -10,27 +10,42 @@ CC=c99 LD=$(CC) CFLAGS=-Wall -Wextra -Wpedantic -Werror -g LDFLAGS= +LDLIBS= all: maje clean: rm -f maje *.o -maje: make.o -make.o: make.c - $(CC) $(CFLAGS) -c make.c +maje: includes.o +includes.o: maje.h +includes.o: includes.c + $(CC) $(CFLAGS) -c includes.c -maje: sources.o -sources.o: sources.c - $(CC) $(CFLAGS) -c sources.c +maje: list.o +list.o: maje.h +list.o: list.c + $(CC) $(CFLAGS) -c list.c maje: main.o +main.o: maje.h main.o: main.c $(CC) $(CFLAGS) -c main.c maje: maje.o +maje.o: maje.h maje.o: maje.c $(CC) $(CFLAGS) -c maje.c +maje: make.o +make.o: maje.h +make.o: make.c + $(CC) $(CFLAGS) -c make.c + +maje: sources.o +sources.o: maje.h +sources.o: sources.c + $(CC) $(CFLAGS) -c sources.c + maje: - $(LD) $(LDFLAGS) -o $@ *.o + $(LD) $(LDFLAGS) -o $@ *.o $(LDLIBS) diff --git a/includes.c b/includes.c new file mode 100644 index 0000000..103c8fd --- /dev/null +++ b/includes.c @@ -0,0 +1,74 @@ +#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) + +/* TODO: recurse through headers */ +/* TODO: avoid loops */ + +static struct majefile * find_inc(const struct majefile *file, const regex_t * restrict re) +{ + 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; + } + + struct majefile *inc = 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 header[FILENAME_MAX] = { 0 }; + char *start = (char*)base + match[1].rm_so; + memcpy(header, start, match[1].rm_eo - match[1].rm_so); + inc = insert_file(inc, header, NULL); + base = start + match[1].rm_eo; + } + + munmap(map, file->st.st_size); + close(fd); + + return inc; +} + +struct majefile *find_includes(const struct majefile *source) +{ + regex_t re; + int rc = regcomp(&re, + "#[[:space:]]*include[[:space:]]+.*\"(.*)\"", + REG_EXTENDED | REG_NEWLINE); + if (rc != 0) { + fprintf(stderr, "maje: regcomp() failed\n"); + abort(); + } + + struct majefile *ret = find_inc(source, &re); + + regfree(&re); + + if (ret != NULL) { + while (ret->prev != NULL) { + ret = ret->prev; + } + } + + return ret; +} @@ -0,0 +1,36 @@ +#define _XOPEN_SOURCE 700 +#include <string.h> +#include <stdlib.h> + +#include "maje.h" + +struct majefile *insert_file(struct majefile *list, const char *path, const struct stat *st) +{ + struct majefile *tmp = malloc(sizeof(*tmp) + strlen(path) + 1); + if (tmp == NULL) { + return NULL; + } + + tmp->next = NULL; + tmp->prev = NULL; + + if (st) { + tmp->st = *st; + } else { + tmp->st = (struct stat) { 0 }; + } + + strcpy(tmp->path, path); + + 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; +} @@ -5,12 +5,15 @@ struct majefile { struct majefile *next; + struct majefile *prev; struct stat st; char path[]; }; 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); #endif @@ -19,6 +19,7 @@ static void make_header(FILE *makefile, const char *target) fprintf(makefile, "LD=$(CC)\n"); fprintf(makefile, "CFLAGS=-Wall -Wextra -Wpedantic -Werror -g\n"); fprintf(makefile, "LDFLAGS=\n"); + fprintf(makefile, "LDLIBS=\n"); fprintf(makefile, "\n"); fprintf(makefile, "all: %s\n\n", target); @@ -27,15 +28,18 @@ static void make_header(FILE *makefile, const char *target) fprintf(makefile, "\trm -f %s *.o\n\n", target); } -static void add_object(FILE *makefile, const char *src, const char *target) +static void add_object(FILE *makefile, const struct majefile *src, const char *target) { - char *fullobj = strdup(src); + char *fullobj = strdup(src->path); char *obj = basename(fullobj); obj[strlen(obj) - 1] = 'o'; fprintf(makefile, "%s: %s\n", target, obj); - fprintf(makefile, "%s: %s\n", obj, src); - fprintf(makefile, "\t$(CC) $(CFLAGS) -c %s\n\n", src); + for (struct majefile *inc = find_includes(src); inc != NULL; inc = inc->next) { + fprintf(makefile, "%s: %s\n", obj, inc->path); + } + fprintf(makefile, "%s: %s\n", obj, src->path); + fprintf(makefile, "\t$(CC) $(CFLAGS) -c %s\n\n", src->path); free(fullobj); } @@ -50,11 +54,11 @@ void make_makefile(const char *makepath, struct majefile *sources, const char *t make_header(makefile, target); for (struct majefile *src = sources; src != NULL; src = src->next) { - add_object(makefile, src->path, target); + add_object(makefile, src, target); } fprintf(makefile, "%s:\n", target); - fprintf(makefile, "\t$(LD) $(LDFLAGS) -o $@ *.o\n"); + fprintf(makefile, "\t$(LD) $(LDFLAGS) -o $@ *.o $(LDLIBS)\n"); fclose(makefile); } @@ -6,7 +6,6 @@ #include "maje.h" static struct majefile *filelist = NULL; -static struct majefile *tail = NULL; static int add_source(const char *path, const struct stat *st, int flags, struct FTW *ft) { @@ -17,22 +16,10 @@ static int add_source(const char *path, const struct stat *st, int flags, struct } if (strcmp(path + strlen(path) - 2, ".c") == 0) { - struct majefile *tmp = malloc(sizeof(*filelist) + strlen(path) + 1); - if (tmp == NULL) { + filelist = insert_file(filelist, path, st); + if (filelist == NULL) { return 1; } - - tmp->next = NULL; - tmp->st = *st; - strcpy(tmp->path, path); - - if (tail == NULL) { - filelist = tmp; - tail = filelist; - } else { - tail->next = tmp; - tail = tail->next; - } } return 0; @@ -41,5 +28,14 @@ static int add_source(const char *path, const struct stat *st, int flags, struct struct majefile * find_source_files(const char *dir) { nftw(dir, add_source, -1, 0); + + if (filelist == NULL) { + return NULL; + } + + while (filelist->prev != NULL) { + filelist = filelist->prev; + } + return filelist; } |