{"thread":{"id":"36087","subject":"[PATCH v7 05/11] trailer: parse trailers from stdin","startedAt":"2014-03-06T22:14:02Z","lastAt":"2014-03-06T22:14:02Z","messageCount":1,"participants":["Christian Couder"],"isPatch":true,"patchVersion":7,"patchTotal":11},"messages":[{"id":"236239","messageId":"20140306221409.29648.94530.chriscool@tuxfamily.org","threadId":"36087","inReplyTo":null,"subject":"[PATCH v7 05/11] trailer: parse trailers from stdin","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2014-03-06T22:14:02Z","receivedAt":"2014-03-06T22:14:02Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Read trailers from stdin, parse them and put the result into a doubly linked\nlist.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n trailer.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 76 insertions(+)\n\ndiff --git a/trailer.c b/trailer.c\nindex 43cbf10..910eddb 100644\n--- a/trailer.c\n+++ b/trailer.c\n@@ -50,6 +50,14 @@ static size_t alnum_len(const char *buf, size_t len)\n \treturn len;\n }\n \n+static inline int contains_only_spaces(const char *str)\n+{\n+\tconst char *s = str;\n+\twhile (*s && isspace(*s))\n+\t\ts++;\n+\treturn !*s;\n+}\n+\n static void free_trailer_item(struct trailer_item *item)\n {\n \tfree(item->conf.name);\n@@ -476,3 +484,71 @@ static struct trailer_item *process_command_line_args(int argc, const char **arg\n \n \treturn arg_tok_first;\n }\n+\n+static struct strbuf **read_stdin(void)\n+{\n+\tstruct strbuf **lines;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n+\tif (strbuf_read(&sb, fileno(stdin), 0) < 0)\n+\t\tdie_errno(_(\"could not read from stdin\"));\n+\n+\tlines = strbuf_split(&sb, '\\n');\n+\n+\tstrbuf_release(&sb);\n+\n+\treturn lines;\n+}\n+\n+/*\n+ * Return the the (0 based) index of the first trailer line\n+ * or the line count if there are no trailers.\n+ */\n+static int find_trailer_start(struct strbuf **lines)\n+{\n+\tint start, empty = 1, count = 0;\n+\n+\t/* Get the line count */\n+\twhile (lines[count])\n+\t\tcount++;\n+\n+\t/*\n+\t * Get the start of the trailers by looking starting from the end\n+\t * for a line with only spaces before lines with one ':'.\n+\t */\n+\tfor (start = count - 1; start >= 0; start--) {\n+\t\tif (contains_only_spaces(lines[start]->buf)) {\n+\t\t\tif (empty)\n+\t\t\t\tcontinue;\n+\t\t\treturn start + 1;\n+\t\t}\n+\t\tif (strchr(lines[start]->buf, ':')) {\n+\t\t\tif (empty)\n+\t\t\t\tempty = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t\treturn count;\n+\t}\n+\n+\treturn empty ? count : start + 1;\n+}\n+\n+static void process_stdin(struct trailer_item **in_tok_first,\n+\t\t\t  struct trailer_item **in_tok_last)\n+{\n+\tstruct strbuf **lines = read_stdin();\n+\tint start = find_trailer_start(lines);\n+\tint i;\n+\n+\t/* Print non trailer lines as is */\n+\tfor (i = 0; lines[i] && i < start; i++)\n+\t\tprintf(\"%s\", lines[i]->buf);\n+\n+\t/* Parse trailer lines */\n+\tfor (i = start; lines[i]; i++) {\n+\t\tstruct trailer_item *new = create_trailer_item(lines[i]->buf);\n+\t\tadd_trailer_item(in_tok_first, in_tok_last, new);\n+\t}\n+\n+\tstrbuf_list_free(lines);\n+}\n-- \n1.8.5.2.204.gcfe299d.dirty\n"}]}