#define _XOPEN_SOURCE 700 #include #include #include #include #include #include #include #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; }