]> gitweb.ps.run Git - ps-cgit/blob - configfile.c
ui-patch.c: Fix signature delimiter
[ps-cgit] / configfile.c
1 /* configfile.c: parsing of config files
2  *
3  * Copyright (C) 2008 Lars Hjemli
4  *
5  * Licensed under GNU General Public License v2
6  *   (see COPYING for full license text)
7  */
8
9 #include <ctype.h>
10 #include <stdio.h>
11 #include "configfile.h"
12
13 static int next_char(FILE *f)
14 {
15         int c = fgetc(f);
16         if (c == '\r') {
17                 c = fgetc(f);
18                 if (c != '\n') {
19                         ungetc(c, f);
20                         c = '\r';
21                 }
22         }
23         return c;
24 }
25
26 static void skip_line(FILE *f)
27 {
28         int c;
29
30         while ((c = next_char(f)) && c != '\n' && c != EOF)
31                 ;
32 }
33
34 static int read_config_line(FILE *f, struct strbuf *name, struct strbuf *value)
35 {
36         int c = next_char(f);
37
38         strbuf_reset(name);
39         strbuf_reset(value);
40
41         /* Skip comments and preceding spaces. */
42         for(;;) {
43                 if (c == '#' || c == ';')
44                         skip_line(f);
45                 else if (!isspace(c))
46                         break;
47                 c = next_char(f);
48         }
49
50         /* Read variable name. */
51         while (c != '=') {
52                 if (c == '\n' || c == EOF)
53                         return 0;
54                 strbuf_addch(name, c);
55                 c = next_char(f);
56         }
57
58         /* Read variable value. */
59         c = next_char(f);
60         while (c != '\n' && c != EOF) {
61                 strbuf_addch(value, c);
62                 c = next_char(f);
63         }
64
65         return 1;
66 }
67
68 int parse_configfile(const char *filename, configfile_value_fn fn)
69 {
70         static int nesting;
71         struct strbuf name = STRBUF_INIT;
72         struct strbuf value = STRBUF_INIT;
73         FILE *f;
74
75         /* cancel deeply nested include-commands */
76         if (nesting > 8)
77                 return -1;
78         if (!(f = fopen(filename, "r")))
79                 return -1;
80         nesting++;
81         while (read_config_line(f, &name, &value))
82                 fn(name.buf, value.buf);
83         nesting--;
84         fclose(f);
85         strbuf_release(&name);
86         strbuf_release(&value);
87         return 0;
88 }
89