]> gitweb.ps.run Git - ps-cgit/blob - parsing.c
Add a favicon option to cgitrc
[ps-cgit] / 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 }