diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Restyle the sources and fix the audit's findings
Diffstat (limited to '')
| -rw-r--r-- | source/config.c | 113 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 113 insertions, 0 deletions
diff --git a/source/config.c b/source/config.c new file mode 100644 index 0000000..6a5d136 --- /dev/null +++ b/source/config.c @@ -0,0 +1,113 @@ +/* + * The reader for cgit's config files, which are the main cgitrc, any file it + * pulls in with an include line, the cgitrc that sits beside a scanned + * repository, and the cached repolist. A file is a sequence of name=value + * lines, and each pair is handed to a callback that decides what it means, so + * nothing here knows a single key by name. A value runs to the end of its line + * and keeps whatever spacing it has, there is no quoting. A line whose first + * non blank character is a hash or a semicolon is a comment, and blank lines + * are ignored. + */ + +#include "cgit.h" +#include "config.h" + +#define MAX_INCLUDE_NESTING 8 + +/* + * Folds away a carriage return that sits right before a newline so a file + * saved with DOS line endings parses the same as one saved with Unix endings. + */ +static int next_char(FILE *f) +{ + int c = fgetc(f); + + if (c == '\r') { + c = fgetc(f); + if (c != '\n') { + ungetc(c, f); + c = '\r'; + } + } + return c; +} + +static void skip_line(FILE *f) +{ + int c; + + while ((c = next_char(f)) && c != '\n' && c != EOF) + ; +} + +static int next_content_char(FILE *f) +{ + int c = next_char(f); + + for (;;) { + if (c == EOF) + return EOF; + if (c == '#' || c == ';') + skip_line(f); + else if (!isspace(c)) + return c; + c = next_char(f); + } +} + +static int read_entry(FILE *f, struct strbuf *name, struct strbuf *value) +{ + int c; + + strbuf_reset(value); + + for (;;) { + c = next_content_char(f); + if (c == EOF) + return 0; + + strbuf_reset(name); + while (c != '=' && c != '\n' && c != EOF) { + strbuf_addch(name, c); + c = next_char(f); + } + if (c == EOF) + return 0; + // Dropping just the line with no equals sign keeps one typo + // from hiding the rest of the file. + if (c != '=') + continue; + + c = next_char(f); + while (c != '\n' && c != EOF) { + strbuf_addch(value, c); + c = next_char(f); + } + + return 1; + } +} + +int config_file_parse(const char *filename, config_file_value_fn fn) +{ + static int nesting; + struct strbuf name = STRBUF_INIT; + struct strbuf value = STRBUF_INIT; + FILE *f; + + // An include line calls back into here, so a file that includes itself, + // directly or round a longer loop, would recurse until the stack gave + // out. + if (nesting > MAX_INCLUDE_NESTING) + return -1; + if (!(f = fopen(filename, "r"))) + return -1; + nesting++; + while (read_entry(f, &name, &value)) + fn(name.buf, value.buf); + nesting--; + fclose(f); + strbuf_release(&name); + strbuf_release(&value); + return 0; +} |
