all repos — cgit @ 2cecf839a06ce951db0d5d95abf79004eff33ca7

a hyperfast web frontend for git written in c

parsing.c (view raw)

  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 */
 18void 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
 55char *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
 65struct 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
161struct 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}