Diff options
Diffstat (limited to 'source/config.c')
| -rw-r--r-- | source/config.c | 44 |
1 file changed, 42 insertions, 2 deletions
diff --git a/source/config.c b/source/config.c index ca7c688..bfd31b6 100644 --- a/source/config.c +++ b/source/config.c @@ -11,6 +11,12 @@ #define MAX_INCLUDE_NESTING 8 +struct config_origin config_origin; + +// The newlines read so far from the file being parsed, which place each entry +// on its line. +static int lines_read; + /* * 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. @@ -26,6 +32,8 @@ static int next_char(FILE *f) c = '\r'; } } + if (c == '\n') + lines_read++; return c; } @@ -52,7 +60,7 @@ static int next_content_char(FILE *f) } } -static int read_entry(FILE *f, struct strbuf *name, struct strbuf *value) +static int read_entry(FILE *f, struct strbuf *name, struct strbuf *value, int *line) { int c; @@ -63,6 +71,7 @@ static int read_entry(FILE *f, struct strbuf *name, struct strbuf *value) if (c == EOF) return 0; + *line = lines_read + 1; strbuf_reset(name); while (c != '=' && c != '\n' && c != EOF) { strbuf_addch(name, c); @@ -88,6 +97,10 @@ static int read_entry(FILE *f, struct strbuf *name, struct strbuf *value) int config_file_parse(const char *filename, config_file_value_fn fn) { static int nesting; + // An include is parsed from inside a line of the file that names it, + // which carries on from that line once the include is done. + struct config_origin outer = config_origin; + int outer_lines_read = lines_read; struct strbuf name = STRBUF_INIT; struct strbuf value = STRBUF_INIT; FILE *f; @@ -99,15 +112,42 @@ int config_file_parse(const char *filename, config_file_value_fn fn) return 0; if (!(f = fopen(filename, "r"))) return errno; + config_origin.file = filename; + lines_read = 0; nesting++; - while (read_entry(f, &name, &value)) + while (read_entry(f, &name, &value, &config_origin.line)) fn(name.buf, value.buf); // A directory opens like a file and fails only once it is read. if (ferror(f)) err = errno; nesting--; fclose(f); + config_origin = outer; + lines_read = outer_lines_read; strbuf_release(&name); strbuf_release(&value); return err; } + +int config_int(const char *name, const char *value) +{ + int number = atoi(value); + char *end; + + // Space may follow the digits strtol finds, but nothing else. + strtol(value, &end, 10); + while (end != value && isspace(*end)) + end++; + if (end != value && !*end) + return number; + // The first line alone, since a git config value can hold a newline + // that would forge a log line of its own. + if (config_origin.file) + fprintf(stderr, "[cgit] Reading %s=%.*s in %s line %d as %d, since it is not a whole number\n", + name, (int)strcspn(value, "\n"), value, config_origin.file, + config_origin.line, number); + else + fprintf(stderr, "[cgit] Reading %s=%.*s as %d, since it is not a whole number\n", + name, (int)strcspn(value, "\n"), value, number); + return number; +} |
