author | Lars Hjemli <hjemli@gmail.com> | 2007-05-14 21:40:33 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-05-14 21:40:33 (UTC) |
commit | 5ec6e02bd1cc0c05b7cfd0d53371e7d176daec39 (patch) (unidiff) | |
tree | 5c844c0ba53cfd2e838368ffbbd4583ac63d3608 /parsing.c | |
parent | 9ecde6568a9e39c942f4c5585ffa494c5df870e4 (diff) | |
download | cgit-5ec6e02bd1cc0c05b7cfd0d53371e7d176daec39.zip cgit-5ec6e02bd1cc0c05b7cfd0d53371e7d176daec39.tar.gz cgit-5ec6e02bd1cc0c05b7cfd0d53371e7d176daec39.tar.bz2 |
Add include-parameter to config files
This parameter can be used to include another config-file, like
a standalone repository listing.
Suggested in a patch by Kristian Høgsberg <krh@bitplanet.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | parsing.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -1,245 +1,247 @@ | |||
1 | /* config.c: parsing of config files | 1 | /* config.c: parsing of config files |
2 | * | 2 | * |
3 | * Copyright (C) 2006 Lars Hjemli | 3 | * Copyright (C) 2006 Lars Hjemli |
4 | * | 4 | * |
5 | * Licensed under GNU General Public License v2 | 5 | * Licensed under GNU General Public License v2 |
6 | * (see COPYING for full license text) | 6 | * (see COPYING for full license text) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | 10 | ||
11 | int next_char(FILE *f) | 11 | int next_char(FILE *f) |
12 | { | 12 | { |
13 | int c = fgetc(f); | 13 | int c = fgetc(f); |
14 | if (c=='\r') { | 14 | if (c=='\r') { |
15 | c = fgetc(f); | 15 | c = fgetc(f); |
16 | if (c!='\n') { | 16 | if (c!='\n') { |
17 | ungetc(c, f); | 17 | ungetc(c, f); |
18 | c = '\r'; | 18 | c = '\r'; |
19 | } | 19 | } |
20 | } | 20 | } |
21 | return c; | 21 | return c; |
22 | } | 22 | } |
23 | 23 | ||
24 | void skip_line(FILE *f) | 24 | void skip_line(FILE *f) |
25 | { | 25 | { |
26 | int c; | 26 | int c; |
27 | 27 | ||
28 | while((c=next_char(f)) && c!='\n' && c!=EOF) | 28 | while((c=next_char(f)) && c!='\n' && c!=EOF) |
29 | ; | 29 | ; |
30 | } | 30 | } |
31 | 31 | ||
32 | int read_config_line(FILE *f, char *line, const char **value, int bufsize) | 32 | int read_config_line(FILE *f, char *line, const char **value, int bufsize) |
33 | { | 33 | { |
34 | int i = 0, isname = 0; | 34 | int i = 0, isname = 0; |
35 | 35 | ||
36 | *value = NULL; | 36 | *value = NULL; |
37 | while(i<bufsize-1) { | 37 | while(i<bufsize-1) { |
38 | int c = next_char(f); | 38 | int c = next_char(f); |
39 | if (!isname && (c=='#' || c==';')) { | 39 | if (!isname && (c=='#' || c==';')) { |
40 | skip_line(f); | 40 | skip_line(f); |
41 | continue; | 41 | continue; |
42 | } | 42 | } |
43 | if (!isname && isspace(c)) | 43 | if (!isname && isspace(c)) |
44 | continue; | 44 | continue; |
45 | 45 | ||
46 | if (c=='=' && !*value) { | 46 | if (c=='=' && !*value) { |
47 | line[i] = 0; | 47 | line[i] = 0; |
48 | *value = &line[i+1]; | 48 | *value = &line[i+1]; |
49 | } else if (c=='\n' && !isname) { | 49 | } else if (c=='\n' && !isname) { |
50 | i = 0; | 50 | i = 0; |
51 | continue; | 51 | continue; |
52 | } else if (c=='\n' || c==EOF) { | 52 | } else if (c=='\n' || c==EOF) { |
53 | line[i] = 0; | 53 | line[i] = 0; |
54 | break; | 54 | break; |
55 | } else { | 55 | } else { |
56 | line[i]=c; | 56 | line[i]=c; |
57 | } | 57 | } |
58 | isname = 1; | 58 | isname = 1; |
59 | i++; | 59 | i++; |
60 | } | 60 | } |
61 | line[i+1] = 0; | 61 | line[i+1] = 0; |
62 | return i; | 62 | return i; |
63 | } | 63 | } |
64 | 64 | ||
65 | int cgit_read_config(const char *filename, configfn fn) | 65 | int cgit_read_config(const char *filename, configfn fn) |
66 | { | 66 | { |
67 | int ret = 0, len; | 67 | static int nesting; |
68 | int len; | ||
68 | char line[256]; | 69 | char line[256]; |
69 | const char *value; | 70 | const char *value; |
70 | FILE *f = fopen(filename, "r"); | 71 | FILE *f; |
71 | 72 | ||
72 | if (!f) | 73 | /* cancel the reading of yet another configfile after 16 invocations */ |
74 | if (nesting++ > 16) | ||
75 | return -1; | ||
76 | if (!(f = fopen(filename, "r"))) | ||
73 | return -1; | 77 | return -1; |
74 | |||
75 | while((len = read_config_line(f, line, &value, sizeof(line))) > 0) | 78 | while((len = read_config_line(f, line, &value, sizeof(line))) > 0) |
76 | (*fn)(line, value); | 79 | (*fn)(line, value); |
77 | |||
78 | fclose(f); | 80 | fclose(f); |
79 | return ret; | 81 | return 0; |
80 | } | 82 | } |
81 | 83 | ||
82 | char *convert_query_hexchar(char *txt) | 84 | char *convert_query_hexchar(char *txt) |
83 | { | 85 | { |
84 | int d1, d2; | 86 | int d1, d2; |
85 | if (strlen(txt) < 3) { | 87 | if (strlen(txt) < 3) { |
86 | *txt = '\0'; | 88 | *txt = '\0'; |
87 | return txt-1; | 89 | return txt-1; |
88 | } | 90 | } |
89 | d1 = hextoint(*(txt+1)); | 91 | d1 = hextoint(*(txt+1)); |
90 | d2 = hextoint(*(txt+2)); | 92 | d2 = hextoint(*(txt+2)); |
91 | if (d1<0 || d2<0) { | 93 | if (d1<0 || d2<0) { |
92 | strcpy(txt, txt+3); | 94 | strcpy(txt, txt+3); |
93 | return txt-1; | 95 | return txt-1; |
94 | } else { | 96 | } else { |
95 | *txt = d1 * 16 + d2; | 97 | *txt = d1 * 16 + d2; |
96 | strcpy(txt+1, txt+3); | 98 | strcpy(txt+1, txt+3); |
97 | return txt; | 99 | return txt; |
98 | } | 100 | } |
99 | } | 101 | } |
100 | 102 | ||
101 | int cgit_parse_query(char *txt, configfn fn) | 103 | int cgit_parse_query(char *txt, configfn fn) |
102 | { | 104 | { |
103 | char *t, *value = NULL, c; | 105 | char *t, *value = NULL, c; |
104 | 106 | ||
105 | if (!txt) | 107 | if (!txt) |
106 | return 0; | 108 | return 0; |
107 | 109 | ||
108 | t = txt = xstrdup(txt); | 110 | t = txt = xstrdup(txt); |
109 | 111 | ||
110 | while((c=*t) != '\0') { | 112 | while((c=*t) != '\0') { |
111 | if (c=='=') { | 113 | if (c=='=') { |
112 | *t = '\0'; | 114 | *t = '\0'; |
113 | value = t+1; | 115 | value = t+1; |
114 | } else if (c=='+') { | 116 | } else if (c=='+') { |
115 | *t = ' '; | 117 | *t = ' '; |
116 | } else if (c=='%') { | 118 | } else if (c=='%') { |
117 | t = convert_query_hexchar(t); | 119 | t = convert_query_hexchar(t); |
118 | } else if (c=='&') { | 120 | } else if (c=='&') { |
119 | *t = '\0'; | 121 | *t = '\0'; |
120 | (*fn)(txt, value); | 122 | (*fn)(txt, value); |
121 | txt = t+1; | 123 | txt = t+1; |
122 | value = NULL; | 124 | value = NULL; |
123 | } | 125 | } |
124 | t++; | 126 | t++; |
125 | } | 127 | } |
126 | if (t!=txt) | 128 | if (t!=txt) |
127 | (*fn)(txt, value); | 129 | (*fn)(txt, value); |
128 | return 0; | 130 | return 0; |
129 | } | 131 | } |
130 | 132 | ||
131 | char *substr(const char *head, const char *tail) | 133 | char *substr(const char *head, const char *tail) |
132 | { | 134 | { |
133 | char *buf; | 135 | char *buf; |
134 | 136 | ||
135 | buf = xmalloc(tail - head + 1); | 137 | buf = xmalloc(tail - head + 1); |
136 | strncpy(buf, head, tail - head); | 138 | strncpy(buf, head, tail - head); |
137 | buf[tail - head] = '\0'; | 139 | buf[tail - head] = '\0'; |
138 | return buf; | 140 | return buf; |
139 | } | 141 | } |
140 | 142 | ||
141 | struct commitinfo *cgit_parse_commit(struct commit *commit) | 143 | struct commitinfo *cgit_parse_commit(struct commit *commit) |
142 | { | 144 | { |
143 | struct commitinfo *ret; | 145 | struct commitinfo *ret; |
144 | char *p = commit->buffer, *t = commit->buffer; | 146 | char *p = commit->buffer, *t = commit->buffer; |
145 | 147 | ||
146 | ret = xmalloc(sizeof(*ret)); | 148 | ret = xmalloc(sizeof(*ret)); |
147 | ret->commit = commit; | 149 | ret->commit = commit; |
148 | ret->author = NULL; | 150 | ret->author = NULL; |
149 | ret->author_email = NULL; | 151 | ret->author_email = NULL; |
150 | ret->committer = NULL; | 152 | ret->committer = NULL; |
151 | ret->committer_email = NULL; | 153 | ret->committer_email = NULL; |
152 | ret->subject = NULL; | 154 | ret->subject = NULL; |
153 | ret->msg = NULL; | 155 | ret->msg = NULL; |
154 | 156 | ||
155 | if (strncmp(p, "tree ", 5)) | 157 | if (strncmp(p, "tree ", 5)) |
156 | die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); | 158 | die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); |
157 | else | 159 | else |
158 | p += 46; // "tree " + hex[40] + "\n" | 160 | p += 46; // "tree " + hex[40] + "\n" |
159 | 161 | ||
160 | while (!strncmp(p, "parent ", 7)) | 162 | while (!strncmp(p, "parent ", 7)) |
161 | p += 48; // "parent " + hex[40] + "\n" | 163 | p += 48; // "parent " + hex[40] + "\n" |
162 | 164 | ||
163 | if (!strncmp(p, "author ", 7)) { | 165 | if (!strncmp(p, "author ", 7)) { |
164 | p += 7; | 166 | p += 7; |
165 | t = strchr(p, '<') - 1; | 167 | t = strchr(p, '<') - 1; |
166 | ret->author = substr(p, t); | 168 | ret->author = substr(p, t); |
167 | p = t; | 169 | p = t; |
168 | t = strchr(t, '>') + 1; | 170 | t = strchr(t, '>') + 1; |
169 | ret->author_email = substr(p, t); | 171 | ret->author_email = substr(p, t); |
170 | ret->author_date = atol(++t); | 172 | ret->author_date = atol(++t); |
171 | p = strchr(t, '\n') + 1; | 173 | p = strchr(t, '\n') + 1; |
172 | } | 174 | } |
173 | 175 | ||
174 | if (!strncmp(p, "committer ", 9)) { | 176 | if (!strncmp(p, "committer ", 9)) { |
175 | p += 9; | 177 | p += 9; |
176 | t = strchr(p, '<') - 1; | 178 | t = strchr(p, '<') - 1; |
177 | ret->committer = substr(p, t); | 179 | ret->committer = substr(p, t); |
178 | p = t; | 180 | p = t; |
179 | t = strchr(t, '>') + 1; | 181 | t = strchr(t, '>') + 1; |
180 | ret->committer_email = substr(p, t); | 182 | ret->committer_email = substr(p, t); |
181 | ret->committer_date = atol(++t); | 183 | ret->committer_date = atol(++t); |
182 | p = strchr(t, '\n') + 1; | 184 | p = strchr(t, '\n') + 1; |
183 | } | 185 | } |
184 | 186 | ||
185 | while (*p == '\n') | 187 | while (*p == '\n') |
186 | p = strchr(p, '\n') + 1; | 188 | p = strchr(p, '\n') + 1; |
187 | 189 | ||
188 | t = strchr(p, '\n'); | 190 | t = strchr(p, '\n'); |
189 | if (t && *t) { | 191 | if (t && *t) { |
190 | ret->subject = substr(p, t); | 192 | ret->subject = substr(p, t); |
191 | p = t + 1; | 193 | p = t + 1; |
192 | 194 | ||
193 | while (*p == '\n') | 195 | while (*p == '\n') |
194 | p = strchr(p, '\n') + 1; | 196 | p = strchr(p, '\n') + 1; |
195 | ret->msg = p; | 197 | ret->msg = p; |
196 | } | 198 | } |
197 | return ret; | 199 | return ret; |
198 | } | 200 | } |
199 | 201 | ||
200 | 202 | ||
201 | struct taginfo *cgit_parse_tag(struct tag *tag) | 203 | struct taginfo *cgit_parse_tag(struct tag *tag) |
202 | { | 204 | { |
203 | void *data; | 205 | void *data; |
204 | enum object_type type; | 206 | enum object_type type; |
205 | unsigned long size; | 207 | unsigned long size; |
206 | char *p, *t; | 208 | char *p, *t; |
207 | struct taginfo *ret; | 209 | struct taginfo *ret; |
208 | 210 | ||
209 | data = read_sha1_file(tag->object.sha1, &type, &size); | 211 | data = read_sha1_file(tag->object.sha1, &type, &size); |
210 | if (!data || type != OBJ_TAG) { | 212 | if (!data || type != OBJ_TAG) { |
211 | free(data); | 213 | free(data); |
212 | return 0; | 214 | return 0; |
213 | } | 215 | } |
214 | 216 | ||
215 | ret = xmalloc(sizeof(*ret)); | 217 | ret = xmalloc(sizeof(*ret)); |
216 | ret->tagger = NULL; | 218 | ret->tagger = NULL; |
217 | ret->tagger_email = NULL; | 219 | ret->tagger_email = NULL; |
218 | ret->tagger_date = 0; | 220 | ret->tagger_date = 0; |
219 | ret->msg = NULL; | 221 | ret->msg = NULL; |
220 | 222 | ||
221 | p = data; | 223 | p = data; |
222 | 224 | ||
223 | while (p && *p) { | 225 | while (p && *p) { |
224 | if (*p == '\n') | 226 | if (*p == '\n') |
225 | break; | 227 | break; |
226 | 228 | ||
227 | if (!strncmp(p, "tagger ", 7)) { | 229 | if (!strncmp(p, "tagger ", 7)) { |
228 | p += 7; | 230 | p += 7; |
229 | t = strchr(p, '<') - 1; | 231 | t = strchr(p, '<') - 1; |
230 | ret->tagger = substr(p, t); | 232 | ret->tagger = substr(p, t); |
231 | p = t; | 233 | p = t; |
232 | t = strchr(t, '>') + 1; | 234 | t = strchr(t, '>') + 1; |
233 | ret->tagger_email = substr(p, t); | 235 | ret->tagger_email = substr(p, t); |
234 | ret->tagger_date = atol(++t); | 236 | ret->tagger_date = atol(++t); |
235 | } | 237 | } |
236 | p = strchr(p, '\n') + 1; | 238 | p = strchr(p, '\n') + 1; |
237 | } | 239 | } |
238 | 240 | ||
239 | while (p && (*p == '\n')) | 241 | while (p && (*p == '\n')) |
240 | p = strchr(p, '\n') + 1; | 242 | p = strchr(p, '\n') + 1; |
241 | if (p && *p) | 243 | if (p && *p) |
242 | ret->msg = xstrdup(p); | 244 | ret->msg = xstrdup(p); |
243 | free(data); | 245 | free(data); |
244 | return ret; | 246 | return ret; |
245 | } | 247 | } |