aboutsummaryrefslogtreecommitdiffstats
path: root/libfonts_get_output_rendering_settings.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libfonts_get_output_rendering_settings.c108
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
}