1 /* config.c: parsing of config files
3 * Copyright (C) 2006 Lars Hjemli
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
12 * url syntax: [repo ['/' cmd [ '/' path]]]
13 * repo: any valid repo url, may contain '/'
14 * cmd: log | commit | diff | tree | view | blob | snapshot
15 * path: any valid path, may contain '/'
18 void cgit_parse_url(const char *url)
23 if (!url || url[0] == '\0')
26 ctx.repo = cgit_get_repoinfo(url);
28 ctx.qry.repo = ctx.repo->url;
32 cmd = strchr(url, '/');
33 while (!ctx.repo && cmd) {
35 ctx.repo = cgit_get_repoinfo(url);
36 if (ctx.repo == NULL) {
38 cmd = strchr(cmd + 1, '/');
42 ctx.qry.repo = ctx.repo->url;
43 p = strchr(cmd + 1, '/');
47 ctx.qry.path = trim_end(p + 1, '/');
50 ctx.qry.page = xstrdup(cmd + 1);
55 char *substr(const char *head, const char *tail)
59 buf = xmalloc(tail - head + 1);
60 strncpy(buf, head, tail - head);
61 buf[tail - head] = '\0';
65 struct commitinfo *cgit_parse_commit(struct commit *commit)
67 struct commitinfo *ret;
68 char *p = commit->buffer, *t = commit->buffer;
70 ret = xmalloc(sizeof(*ret));
73 ret->author_email = NULL;
74 ret->committer = NULL;
75 ret->committer_email = NULL;
78 ret->msg_encoding = NULL;
83 if (strncmp(p, "tree ", 5))
84 die("Bad commit: %s", sha1_to_hex(commit->object.sha1));
86 p += 46; // "tree " + hex[40] + "\n"
88 while (!strncmp(p, "parent ", 7))
89 p += 48; // "parent " + hex[40] + "\n"
91 if (!strncmp(p, "author ", 7)) {
93 t = strchr(p, '<') - 1;
94 ret->author = substr(p, t);
96 t = strchr(t, '>') + 1;
97 ret->author_email = substr(p, t);
98 ret->author_date = atol(t+1);
99 p = strchr(t, '\n') + 1;
102 if (!strncmp(p, "committer ", 9)) {
104 t = strchr(p, '<') - 1;
105 ret->committer = substr(p, t);
107 t = strchr(t, '>') + 1;
108 ret->committer_email = substr(p, t);
109 ret->committer_date = atol(t+1);
110 p = strchr(t, '\n') + 1;
113 if (!strncmp(p, "encoding ", 9)) {
115 t = strchr(p, '\n') + 1;
116 ret->msg_encoding = substr(p, t);
119 ret->msg_encoding = xstrdup(PAGE_ENCODING);
121 while (*p && (*p != '\n'))
122 p = strchr(p, '\n') + 1; // skip unknown header fields
125 p = strchr(p, '\n') + 1;
130 ret->subject = "** empty **";
132 ret->subject = substr(p, t);
136 p = strchr(p, '\n') + 1;
137 ret->msg = xstrdup(p);
139 ret->subject = substr(p, p+strlen(p));
141 if(strcmp(ret->msg_encoding, PAGE_ENCODING)) {
142 t = reencode_string(ret->subject, PAGE_ENCODING,
149 t = reencode_string(ret->msg, PAGE_ENCODING,
161 struct taginfo *cgit_parse_tag(struct tag *tag)
164 enum object_type type;
169 data = read_sha1_file(tag->object.sha1, &type, &size);
170 if (!data || type != OBJ_TAG) {
175 ret = xmalloc(sizeof(*ret));
177 ret->tagger_email = NULL;
178 ret->tagger_date = 0;
187 if (!strncmp(p, "tagger ", 7)) {
189 t = strchr(p, '<') - 1;
190 ret->tagger = substr(p, t);
192 t = strchr(t, '>') + 1;
193 ret->tagger_email = substr(p, t);
194 ret->tagger_date = atol(t+1);
196 p = strchr(p, '\n') + 1;
199 while (p && *p && (*p != '\n'))
200 p = strchr(p, '\n') + 1; // skip unknown tag fields
202 while (p && (*p == '\n'))
203 p = strchr(p, '\n') + 1;
205 ret->msg = xstrdup(p);