diff options
Diffstat (limited to 'libfonts_get_output_rendering_settings.c')
-rw-r--r-- | libfonts_get_output_rendering_settings.c | 108 |
1 files changed, 103 insertions, 5 deletions
diff --git a/libfonts_get_output_rendering_settings.c b/libfonts_get_output_rendering_settings.c index f634550..2cecf3c 100644 --- a/libfonts_get_output_rendering_settings.c +++ b/libfonts_get_output_rendering_settings.c @@ -9,6 +9,15 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, { size_t file_part2_len = strlen(file_part2); char *path; + int fd; + ssize_t len; + char *line, *buf = NULL; + size_t size = 0, off = 0, avail = 0; + int found = 0; + int in_the_section = 0; + int in_a_section = 0; + char *value; + unsigned int found_fields = 0; if (file_part1_len > SIZE_MAX - file_part2_len - 1) goto enomem; @@ -23,12 +32,101 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, memcpy(path, file_part1, file_part1_len); memcpy(&path[file_part1_len], file_part2, file_part2_len + 1); - /* TODO aliases should be declarable above the first "[$name]" */ - /* TODO look for "[$name]" */ - /* TODO (use LIST_RENDERING_SETTINGS) */ +open_again: + fd = open(path, O_RDONLY); + if (fd < 0) { + switch (errno) { + case EINTR: + goto open_again; + case EMFILE: + case ENFILE: + case ENOMEM: + case ENOSPC: + free(path); + return -1; + case EFBIG: + case EOVERFLOW: + case EISDIR: + case ELOOP: + case ENODEV: + case ENOTDIR: + case ENXIO: + /* TODO print warning using `ctx` */ + goto out; + default: + goto out; + } + } + + for (;;) { + len = libfonts_getline__(fd, &line, &buf, &size, &off, &avail); + if (len < 0) { + if (errno == EINTR) + continue; + free(buf); + free(path); + close(fd); + return -1; + } + if (!len) + break; + line[len -= 1] = '\0'; + + while (isblank(*line)) { + line++; + len--; + } + if (!*line || *line == '#') + continue; + while (len && isblank(line[len - 1])) + len -= 1; + line[len] = '\0'; + + if (line[0] == '[' && line[len - 1] == ']') { + in_a_section = 1; + line = &line[1]; + len -= 2; + line[len] = '\0'; + found |= in_the_section = !strcmp(line, name); + found_fields = 0; + + } else if (!in_a_section) { + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } + /* TODO aliases should be declarable above the first "[%s]" */ + + } else if (in_the_section) { + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER)\ + if (!strcmp(line, CONFNAME)) {\ + if (found_fields & (1U << INDEX)) {\ + /* TODO warning */\ + }\ + found_fields |= (1U << INDEX);\ + if (!PARSER(&settings->CNAME, value)) {\ + /* TODO warning */\ + }\ + } else + LIST_RENDERING_SETTINGS(X,) { + /* TODO warning */ + } +#undef X + } + } + + free(buf); + close(fd); +out: free(path); - return 1; + return found; } static int @@ -54,7 +152,7 @@ libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *setti } if (settings) { -#define X(CONFNAME, CNAME, DEFVAL) settings->CNAME = DEFVAL +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER) settings->CNAME = DEFVAL LIST_RENDERING_SETTINGS(X, ;); #undef X } |