diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-04-25 19:45:31 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-04-25 19:45:31 -0400 |
commit | 319c7568828a01fa5ba8ded0b560d852124ffb84 (patch) | |
tree | 7ca966f27a06885ae6451e730128f70994355a4a /flags.c | |
parent | 0c72419d193ca13edc8302cd8c151bbe80a4716f (diff) |
add support for setting flags in source
Diffstat (limited to 'flags.c')
-rw-r--r-- | flags.c | 68 |
1 files changed, 68 insertions, 0 deletions
@@ -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; +} |