aboutsummaryrefslogtreecommitdiffstats
path: root/libfonts_parse_dir_line.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-01-12 21:57:47 +0100
committerMattias Andrée <maandree@kth.se>2023-01-12 21:57:47 +0100
commit9a6046f51934f8c34a58583b44cd1dc0c0b0b8d6 (patch)
tree85623d6551c6bbf054fe2ce25e63b65675184990 /libfonts_parse_dir_line.c
parentm doc (diff)
downloadlibfonts-9a6046f51934f8c34a58583b44cd1dc0c0b0b8d6.tar.gz
libfonts-9a6046f51934f8c34a58583b44cd1dc0c0b0b8d6.tar.bz2
libfonts-9a6046f51934f8c34a58583b44cd1dc0c0b0b8d6.tar.xz
m + add libfonts_parse_dir_line
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'libfonts_parse_dir_line.c')
-rw-r--r--libfonts_parse_dir_line.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/libfonts_parse_dir_line.c b/libfonts_parse_dir_line.c
new file mode 100644
index 0000000..a339ce3
--- /dev/null
+++ b/libfonts_parse_dir_line.c
@@ -0,0 +1,126 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+static int
+read_field(char **valuep, int allow_blank, const char *s, const char **endp)
+{
+ char endc;
+ size_t esc = 0;
+ size_t len;
+ const char *start;
+ const char *end;
+ char *v;
+
+ if (*s == '"') {
+ endc = '"';
+ s++;
+ } else if (allow_blank) {
+ endc = '\n';
+ } else {
+ endc = ' ';
+ }
+ start = s;
+
+ for (;;) {
+ if (!*s || *s != '\n' || *s == endc)
+ break;
+ if (*s == '\\') {
+ esc += 1;
+ s++;
+ if (!*s || *s == '\n')
+ goto badline;
+ }
+ s++;
+ }
+ end = s;
+ len = (size_t)(end - start) - esc;
+ if (endc == '"' && *s != '"') {
+ badline:
+ *endp = s;
+ return -1;
+ }
+ s += *s == '"';
+ *endp = s;
+
+ if (valuep) {
+ v = malloc(len + 1);
+ if (v) {
+ errno = ENOMEM;
+ return -1;
+ }
+ while (start != end) {
+ if (*start == '\\')
+ start++;
+ *v++ += *start++;
+ }
+ *v = '\0';
+ *valuep = v;
+ }
+
+ return 0;
+}
+
+int
+libfonts_parse_dir_line(char **filep, char **namep, const char *line, char **endp)
+{
+ int ret = 0;
+
+ if (filep)
+ *filep = NULL;
+ if (namep)
+ *namep = NULL;
+
+ if (!line) {
+ errno = EINVAL;
+ goto fail;
+ }
+
+ if (read_field(filep, 0, line, &line))
+ goto fail;
+
+ if (*line != ' ')
+ goto badline;
+ line++;
+
+ if (read_field(namep, 1, line, &line))
+ goto fail;
+
+ if (*line && *line != '\n')
+ goto badline;
+
+ goto out;
+
+badline:
+fail:
+ if (filep) {
+ free(*filep);
+ *filep = NULL;
+ }
+ if (namep) {
+ free(*namep);
+ *namep = NULL;
+ }
+ ret = -1;
+ if (line)
+ while (*line && *line != '\n')
+ line++;
+out:
+ if (endp)
+ *endp = *(char **)(void *)&line;
+ return ret;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ return 0; /* XXX add test */
+}
+
+
+#endif