summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-04-25 19:45:31 -0400
committerJakob Kaivo <jkk@ung.org>2022-04-25 19:45:31 -0400
commit319c7568828a01fa5ba8ded0b560d852124ffb84 (patch)
tree7ca966f27a06885ae6451e730128f70994355a4a
parent0c72419d193ca13edc8302cd8c151bbe80a4716f (diff)
add support for setting flags in source
-rw-r--r--Makefile6
-rw-r--r--flags.c68
-rw-r--r--list.c43
-rw-r--r--maje.h10
-rw-r--r--make.c37
5 files changed, 159 insertions, 5 deletions
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 <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;
+}
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 <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;
+}
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);
}