]> git.cameronkatri.com Git - cgit.git/blob - parsing.c
Fix commitdiff annoyance
[cgit.git] / parsing.c
1 /* config.c: parsing of config files
2 *
3 * Copyright (C) 2006 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
9 #include "cgit.h"
10
11 /*
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 '/'
16 *
17 */
18 void cgit_parse_url(const char *url)
19 {
20 char *cmd, *p;
21
22 ctx.repo = NULL;
23 if (!url || url[0] == '\0')
24 return;
25
26 ctx.repo = cgit_get_repoinfo(url);
27 if (ctx.repo) {
28 ctx.qry.repo = ctx.repo->url;
29 return;
30 }
31
32 cmd = strchr(url, '/');
33 while (!ctx.repo && cmd) {
34 cmd[0] = '\0';
35 ctx.repo = cgit_get_repoinfo(url);
36 if (ctx.repo == NULL) {
37 cmd[0] = '/';
38 cmd = strchr(cmd + 1, '/');
39 continue;
40 }
41
42 ctx.qry.repo = ctx.repo->url;
43 p = strchr(cmd + 1, '/');
44 if (p) {
45 p[0] = '\0';
46 if (p[1])
47 ctx.qry.path = trim_end(p + 1, '/');
48 }
49 if (cmd[1])
50 ctx.qry.page = xstrdup(cmd + 1);
51 return;
52 }
53 }
54
55 char *substr(const char *head, const char *tail)
56 {
57 char *buf;
58
59 buf = xmalloc(tail - head + 1);
60 strncpy(buf, head, tail - head);
61 buf[tail - head] = '\0';
62 return buf;
63 }
64
65 struct commitinfo *cgit_parse_commit(struct commit *commit)
66 {
67 struct commitinfo *ret;
68 char *p = commit->buffer, *t = commit->buffer;
69
70 ret = xmalloc(sizeof(*ret));
71 ret->commit = commit;
72 ret->author = NULL;
73 ret->author_email = NULL;
74 ret->committer = NULL;
75 ret->committer_email = NULL;
76 ret->subject = NULL;
77 ret->msg = NULL;
78 ret->msg_encoding = NULL;
79
80 if (p == NULL)
81 return ret;
82
83 if (strncmp(p, "tree ", 5))
84 die("Bad commit: %s", sha1_to_hex(commit->object.sha1));
85 else
86 p += 46; // "tree " + hex[40] + "\n"
87
88 while (!strncmp(p, "parent ", 7))
89 p += 48; // "parent " + hex[40] + "\n"
90
91 if (!strncmp(p, "author ", 7)) {
92 p += 7;
93 t = strchr(p, '<') - 1;
94 ret->author = substr(p, t);
95 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;
100 }
101
102 if (!strncmp(p, "committer ", 9)) {
103 p += 9;
104 t = strchr(p, '<') - 1;
105 ret->committer = substr(p, t);
106 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;
111 }
112
113 if (!strncmp(p, "encoding ", 9)) {
114 p += 9;
115 t = strchr(p, '\n') + 1;
116 ret->msg_encoding = substr(p, t);
117 p = t;
118 } else
119 ret->msg_encoding = xstrdup(PAGE_ENCODING);
120
121 while (*p && (*p != '\n'))
122 p = strchr(p, '\n') + 1; // skip unknown header fields
123
124 while (*p == '\n')
125 p = strchr(p, '\n') + 1;
126
127 t = strchr(p, '\n');
128 if (t) {
129 if (*t == '\0')
130 ret->subject = "** empty **";
131 else
132 ret->subject = substr(p, t);
133 p = t + 1;
134
135 while (*p == '\n')
136 p = strchr(p, '\n') + 1;
137 ret->msg = xstrdup(p);
138 } else
139 ret->subject = substr(p, p+strlen(p));
140
141 if(strcmp(ret->msg_encoding, PAGE_ENCODING)) {
142 t = reencode_string(ret->subject, PAGE_ENCODING,
143 ret->msg_encoding);
144 if(t) {
145 free(ret->subject);
146 ret->subject = t;
147 }
148
149 t = reencode_string(ret->msg, PAGE_ENCODING,
150 ret->msg_encoding);
151 if(t) {
152 free(ret->msg);
153 ret->msg = t;
154 }
155 }
156
157 return ret;
158 }
159
160
161 struct taginfo *cgit_parse_tag(struct tag *tag)
162 {
163 void *data;
164 enum object_type type;
165 unsigned long size;
166 char *p, *t;
167 struct taginfo *ret;
168
169 data = read_sha1_file(tag->object.sha1, &type, &size);
170 if (!data || type != OBJ_TAG) {
171 free(data);
172 return 0;
173 }
174
175 ret = xmalloc(sizeof(*ret));
176 ret->tagger = NULL;
177 ret->tagger_email = NULL;
178 ret->tagger_date = 0;
179 ret->msg = NULL;
180
181 p = data;
182
183 while (p && *p) {
184 if (*p == '\n')
185 break;
186
187 if (!strncmp(p, "tagger ", 7)) {
188 p += 7;
189 t = strchr(p, '<') - 1;
190 ret->tagger = substr(p, t);
191 p = t;
192 t = strchr(t, '>') + 1;
193 ret->tagger_email = substr(p, t);
194 ret->tagger_date = atol(t+1);
195 }
196 p = strchr(p, '\n') + 1;
197 }
198
199 while (p && *p && (*p != '\n'))
200 p = strchr(p, '\n') + 1; // skip unknown tag fields
201
202 while (p && (*p == '\n'))
203 p = strchr(p, '\n') + 1;
204 if (p && *p)
205 ret->msg = xstrdup(p);
206 free(data);
207 return ret;
208 }