summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-03-27 16:53:14 -0400
committerJakob Kaivo <jkk@ung.org>2020-03-27 16:53:14 -0400
commit1a21f9e690a5e5b334a5c5fbc2b4d1f71d00d43d (patch)
treead9b6733871fc075315c6512d8509df5066303e4
parent2a15bdb94ea913b361c026541eff3cfdcffccde6 (diff)
initial support for adding local headers as dependencies
-rw-r--r--Makefile29
-rw-r--r--includes.c74
-rw-r--r--list.c36
-rw-r--r--maje.h3
-rw-r--r--make.c16
-rw-r--r--sources.c26
6 files changed, 156 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index cb52921..42f869c 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
+}
diff --git a/list.c b/list.c
new file mode 100644
index 0000000..24d265c
--- /dev/null
+++ b/list.c
@@ -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;
+}
diff --git a/maje.h b/maje.h
index 5a3cc89..6f0af8d 100644
--- a/maje.h
+++ b/maje.h
@@ -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
diff --git a/make.c b/make.c
index d8ea00e..f926dd5 100644
--- a/make.c
+++ b/make.c
@@ -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);
}
diff --git a/sources.c b/sources.c
index 22d71a2..6255750 100644
--- a/sources.c
+++ b/sources.c
@@ -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;
}