]>
git.cameronkatri.com Git - cgit.git/blob - parsing.c
c7310847561d8d2a7edc11912c2991d12600fef9
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)
13 int next_char(FILE *f
)
26 void skip_line(FILE *f
)
30 while((c
=next_char(f
)) && c
!='\n' && c
!=EOF
)
34 int read_config_line(FILE *f
, char *line
, const char **value
, int bufsize
)
36 int i
= 0, isname
= 0;
41 if (!isname
&& (c
=='#' || c
==';')) {
45 if (!isname
&& isspace(c
))
48 if (c
=='=' && !*value
) {
51 } else if (c
=='\n' && !isname
) {
54 } else if (c
=='\n' || c
==EOF
) {
67 int cgit_read_config(const char *filename
, configfn fn
)
75 /* cancel deeply nested include-commands */
78 if (!(f
= fopen(filename
, "r")))
81 while((len
= read_config_line(f
, line
, &value
, sizeof(line
))) > 0)
88 char *convert_query_hexchar(char *txt
)
91 if (strlen(txt
) < 3) {
95 d1
= hextoint(*(txt
+1));
96 d2
= hextoint(*(txt
+2));
102 strcpy(txt
+1, txt
+3);
107 int cgit_parse_query(char *txt
, configfn fn
)
109 char *t
, *value
= NULL
, c
;
114 t
= txt
= xstrdup(txt
);
116 while((c
=*t
) != '\0') {
123 t
= convert_query_hexchar(t
);
138 * url syntax: [repo ['/' cmd [ '/' path]]]
139 * repo: any valid repo url, may contain '/'
140 * cmd: log | commit | diff | tree | view | blob | snapshot
141 * path: any valid path, may contain '/'
144 void cgit_parse_url(const char *url
)
149 if (!url
|| url
[0] == '\0')
152 cgit_repo
= cgit_get_repoinfo(url
);
154 cgit_query_repo
= cgit_repo
->url
;
158 cmd
= strchr(url
, '/');
159 while (!cgit_repo
&& cmd
) {
161 cgit_repo
= cgit_get_repoinfo(url
);
162 if (cgit_repo
== NULL
) {
164 cmd
= strchr(cmd
+ 1, '/');
168 cgit_query_repo
= cgit_repo
->url
;
169 p
= strchr(cmd
+ 1, '/');
173 cgit_query_path
= trim_end(p
+ 1, '/');
175 cgit_cmd
= cgit_get_cmd_index(cmd
+ 1);
176 cgit_query_page
= xstrdup(cmd
+ 1);
181 static char *iconv_msg(char *msg
, const char *encoding
)
183 iconv_t msg_conv
= iconv_open(PAGE_ENCODING
, encoding
);
184 size_t inlen
= strlen(msg
);
194 if(msg_conv
== (iconv_t
)-1)
198 buf
= xmalloc(buf_sz
+1);
205 iconv(msg_conv
, &in
, &inleft
, &out
, &outleft
);
210 } else if(inleft
!= 0 && errno
== E2BIG
) {
216 buf
= xmalloc(buf_sz
+1);
221 } while(again
&& !fail
);
227 buf
= xrealloc(buf
, out
- buf
);
232 iconv_close(msg_conv
);
237 char *substr(const char *head
, const char *tail
)
241 buf
= xmalloc(tail
- head
+ 1);
242 strncpy(buf
, head
, tail
- head
);
243 buf
[tail
- head
] = '\0';
247 struct commitinfo
*cgit_parse_commit(struct commit
*commit
)
249 struct commitinfo
*ret
;
250 char *p
= commit
->buffer
, *t
= commit
->buffer
;
252 ret
= xmalloc(sizeof(*ret
));
253 ret
->commit
= commit
;
255 ret
->author_email
= NULL
;
256 ret
->committer
= NULL
;
257 ret
->committer_email
= NULL
;
260 ret
->msg_encoding
= NULL
;
265 if (strncmp(p
, "tree ", 5))
266 die("Bad commit: %s", sha1_to_hex(commit
->object
.sha1
));
268 p
+= 46; // "tree " + hex[40] + "\n"
270 while (!strncmp(p
, "parent ", 7))
271 p
+= 48; // "parent " + hex[40] + "\n"
273 if (!strncmp(p
, "author ", 7)) {
275 t
= strchr(p
, '<') - 1;
276 ret
->author
= substr(p
, t
);
278 t
= strchr(t
, '>') + 1;
279 ret
->author_email
= substr(p
, t
);
280 ret
->author_date
= atol(++t
);
281 p
= strchr(t
, '\n') + 1;
284 if (!strncmp(p
, "committer ", 9)) {
286 t
= strchr(p
, '<') - 1;
287 ret
->committer
= substr(p
, t
);
289 t
= strchr(t
, '>') + 1;
290 ret
->committer_email
= substr(p
, t
);
291 ret
->committer_date
= atol(++t
);
292 p
= strchr(t
, '\n') + 1;
295 if (!strncmp(p
, "encoding ", 9)) {
297 t
= strchr(p
, '\n') + 1;
298 ret
->msg_encoding
= substr(p
, t
);
301 ret
->msg_encoding
= xstrdup(PAGE_ENCODING
);
303 while (*p
&& (*p
!= '\n'))
304 p
= strchr(p
, '\n') + 1; // skip unknown header fields
307 p
= strchr(p
, '\n') + 1;
312 ret
->subject
= "** empty **";
314 ret
->subject
= substr(p
, t
);
318 p
= strchr(p
, '\n') + 1;
319 ret
->msg
= xstrdup(p
);
321 ret
->subject
= substr(p
, p
+strlen(p
));
323 if(strcmp(ret
->msg_encoding
, PAGE_ENCODING
)) {
324 t
= iconv_msg(ret
->subject
, ret
->msg_encoding
);
330 t
= iconv_msg(ret
->msg
, ret
->msg_encoding
);
341 struct taginfo
*cgit_parse_tag(struct tag
*tag
)
344 enum object_type type
;
349 data
= read_sha1_file(tag
->object
.sha1
, &type
, &size
);
350 if (!data
|| type
!= OBJ_TAG
) {
355 ret
= xmalloc(sizeof(*ret
));
357 ret
->tagger_email
= NULL
;
358 ret
->tagger_date
= 0;
367 if (!strncmp(p
, "tagger ", 7)) {
369 t
= strchr(p
, '<') - 1;
370 ret
->tagger
= substr(p
, t
);
372 t
= strchr(t
, '>') + 1;
373 ret
->tagger_email
= substr(p
, t
);
374 ret
->tagger_date
= atol(++t
);
376 p
= strchr(p
, '\n') + 1;
379 while (p
&& *p
&& (*p
!= '\n'))
380 p
= strchr(p
, '\n') + 1; // skip unknown tag fields
382 while (p
&& (*p
== '\n'))
383 p
= strchr(p
, '\n') + 1;
385 ret
->msg
= xstrdup(p
);