X-Git-Url: https://gitweb.ps.run/ps-cgit/blobdiff_plain/2ffeecb7a6827dcf0f81cf543ed312155f6e8f83..6f9e8a9659996281248c9002497148d489003bce:/parsing.c diff --git a/parsing.c b/parsing.c index 151c0fe..53c29bb 100644 --- a/parsing.c +++ b/parsing.c @@ -1,6 +1,6 @@ -/* config.c: parsing of config files +/* parsing.c: parsing of config files * - * Copyright (C) 2006 Lars Hjemli + * Copyright (C) 2006-2014 cgit Development Team * * Licensed under GNU General Public License v2 * (see COPYING for full license text) @@ -17,7 +17,8 @@ */ void cgit_parse_url(const char *url) { - char *cmd, *p; + char *c, *cmd, *p; + struct cgit_repo *repo; ctx.repo = NULL; if (!url || url[0] == '\0') @@ -29,16 +30,20 @@ void cgit_parse_url(const char *url) return; } - cmd = strchr(url, '/'); - while (!ctx.repo && cmd) { - cmd[0] = '\0'; - ctx.repo = cgit_get_repoinfo(url); - if (ctx.repo == NULL) { - cmd[0] = '/'; - cmd = strchr(cmd + 1, '/'); - continue; + cmd = NULL; + c = strchr(url, '/'); + while (c) { + c[0] = '\0'; + repo = cgit_get_repoinfo(url); + if (repo) { + ctx.repo = repo; + cmd = c; } + c[0] = '/'; + c = strchr(c + 1, '/'); + } + if (ctx.repo) { ctx.qry.repo = ctx.repo->url; p = strchr(cmd + 1, '/'); if (p) { @@ -52,54 +57,45 @@ void cgit_parse_url(const char *url) } } -char *substr(const char *head, const char *tail) +static char *substr(const char *head, const char *tail) { char *buf; + if (tail < head) + return xstrdup(""); buf = xmalloc(tail - head + 1); strncpy(buf, head, tail - head); buf[tail - head] = '\0'; return buf; } -char *parse_user(char *t, char **name, char **email, unsigned long *date) +static const char *parse_user(const char *t, char **name, char **email, unsigned long *date) { - char *p = t; - int mode = 1; + const char *line_end = strchrnul(t, '\n'); + struct ident_split ident; + unsigned email_len; - while (p && *p) { - if (mode == 1 && *p == '<') { - *name = substr(t, p - 1); - t = p; - mode++; - } else if (mode == 1 && *p == '\n') { - *name = substr(t, p); - p++; - break; - } else if (mode == 2 && *p == '>') { - *email = substr(t, p + 1); - t = p; - mode++; - } else if (mode == 2 && *p == '\n') { - *email = substr(t, p); - p++; - break; - } else if (mode == 3 && isdigit(*p)) { - *date = atol(p); - mode++; - } else if (*p == '\n') { - p++; - break; - } - p++; + if (!split_ident_line(&ident, t, line_end - t)) { + *name = substr(ident.name_begin, ident.name_end); + + email_len = ident.mail_end - ident.mail_begin; + *email = xmalloc(strlen("<") + email_len + strlen(">") + 1); + sprintf(*email, "<%.*s>", email_len, ident.mail_begin); + + if (ident.date_begin) + *date = strtoul(ident.date_begin, NULL, 10); } - return p; + + if (*line_end) + return line_end + 1; + else + return line_end; } #ifdef NO_ICONV #define reencode(a, b, c) #else -const char *reencode(char **txt, const char *src_enc, const char *dst_enc) +static const char *reencode(char **txt, const char *src_enc, const char *dst_enc) { char *tmp; @@ -110,7 +106,7 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc) return *txt; /* no encoding needed if src_enc equals dst_enc */ - if(!strcasecmp(src_enc, dst_enc)) + if (!strcasecmp(src_enc, dst_enc)) return *txt; tmp = reencode_string(*txt, dst_enc, src_enc); @@ -125,7 +121,8 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc) struct commitinfo *cgit_parse_commit(struct commit *commit) { struct commitinfo *ret; - char *p = commit->buffer, *t = commit->buffer; + const char *p = get_cached_commit_buffer(commit, NULL); + const char *t; ret = xmalloc(sizeof(*ret)); ret->commit = commit; @@ -140,25 +137,25 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) if (p == NULL) return ret; - if (strncmp(p, "tree ", 5)) + if (!starts_with(p, "tree ")) die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); else p += 46; // "tree " + hex[40] + "\n" - while (!strncmp(p, "parent ", 7)) + while (starts_with(p, "parent ")) p += 48; // "parent " + hex[40] + "\n" - if (p && !strncmp(p, "author ", 7)) { + if (p && starts_with(p, "author ")) { p = parse_user(p + 7, &ret->author, &ret->author_email, &ret->author_date); } - if (p && !strncmp(p, "committer ", 9)) { - p = parse_user(p + 9, &ret->committer, &ret->committer_email, + if (p && starts_with(p, "committer ")) { + p = parse_user(p + 10, &ret->committer, &ret->committer_email, &ret->committer_date); } - if (p && !strncmp(p, "encoding ", 9)) { + if (p && starts_with(p, "encoding ")) { p += 9; t = strchr(p, '\n'); if (t) { @@ -168,7 +165,7 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) } /* if no special encoding is found, assume UTF-8 */ - if(!ret->msg_encoding) + if (!ret->msg_encoding) ret->msg_encoding = xstrdup("UTF-8"); // skip unknown header fields @@ -216,7 +213,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag) void *data; enum object_type type; unsigned long size; - char *p; + const char *p; struct taginfo *ret; data = read_sha1_file(tag->object.sha1, &type, &size); @@ -237,7 +234,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag) if (*p == '\n') break; - if (!strncmp(p, "tagger ", 7)) { + if (starts_with(p, "tagger ")) { p = parse_user(p + 7, &ret->tagger, &ret->tagger_email, &ret->tagger_date); } else {