[PATCH v8 06/12] trailer: parse trailers from stdin
From: Christian Couder <hidden>
Date: 2016-06-15 23:00:33
Subsystem:
the rest · Maintainer:
Linus Torvalds
Read trailers from stdin, parse them and put the result into a doubly linked list. Signed-off-by: Christian Couder <redacted> --- trailer.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/trailer.c b/trailer.c
index 1871843..3993840 100644
--- a/trailer.c
+++ b/trailer.c@@ -50,6 +50,14 @@ static size_t alnum_len(const char *buf, size_t len) return len; } +static inline int contains_only_spaces(const char *str) +{ + const char *s = str; + while (*s && isspace(*s)) + s++; + return !*s; +} + static void free_trailer_item(struct trailer_item *item) { free(item->conf.name);
@@ -501,3 +509,71 @@ static struct trailer_item *process_command_line_args(int argc, const char **arg return arg_tok_first; } + +static struct strbuf **read_stdin(void) +{ + struct strbuf **lines; + struct strbuf sb = STRBUF_INIT; + + if (strbuf_read(&sb, fileno(stdin), 0) < 0) + die_errno(_("could not read from stdin")); + + lines = strbuf_split(&sb, '\n'); + + strbuf_release(&sb); + + return lines; +} + +/* + * Return the the (0 based) index of the first trailer line + * or the line count if there are no trailers. + */ +static int find_trailer_start(struct strbuf **lines) +{ + int start, empty = 1, count = 0; + + /* Get the line count */ + while (lines[count]) + count++; + + /* + * Get the start of the trailers by looking starting from the end + * for a line with only spaces before lines with one ':'. + */ + for (start = count - 1; start >= 0; start--) { + if (contains_only_spaces(lines[start]->buf)) { + if (empty) + continue; + return start + 1; + } + if (strchr(lines[start]->buf, ':')) { + if (empty) + empty = 0; + continue; + } + return count; + } + + return empty ? count : start + 1; +} + +static void process_stdin(struct trailer_item **in_tok_first, + struct trailer_item **in_tok_last) +{ + struct strbuf **lines = read_stdin(); + int start = find_trailer_start(lines); + int i; + + /* Print non trailer lines as is */ + for (i = 0; lines[i] && i < start; i++) + printf("%s", lines[i]->buf); + + /* Parse trailer lines */ + for (i = start; lines[i]; i++) { + struct trailer_item *new = create_trailer_item(lines[i]->buf); + add_trailer_item(in_tok_first, in_tok_last, new); + } + + strbuf_list_free(lines); +}
--
1.9.0.164.g3aa33cd.dirty