/[CvsGraph]/cvsgraph/rcsy.y
ViewVC logotype

Annotate of /cvsgraph/rcsy.y

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations)
Fri Jul 16 13:07:58 2004 UTC (13 years, 3 months ago) by bertho
Branch: MAIN
CVS Tags: REL_1_4_1
Changes since 1.5: +8 -2 lines
Fix the CVSNT habbit of adding info to the tag in symbols.
The trailing data is skipped for now. We might use it later on
(it contains a date and comments) on tags.
1 /*
2 * CvsGraph graphical representation generator of brances and revisions
3 * of a file in cvs/rcs.
4 *
5 * Copyright (C) 2001 B. Stultiens
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 %{
23 #define YYERROR_VERBOSE 1
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #include <gd.h> /* For gdFontPtr in cvsgraph.h */
31 #include "cvsgraph.h"
32 #include "utils.h"
33 #include "rcs.h"
34
35 rcsfile_t *rcsfile;
36
37 static tag_t *new_tag(char *s, char *r);
38 static tags_t *new_tags(tag_t *s);
39 static tags_t *add_tags(tags_t *s, tag_t *t);
40 static idrev_t *new_idrev(char *s, char *r);
41 static idrevs_t *new_idrevs(idrev_t *s);
42 static idrevs_t *add_idrevs(idrevs_t *s, idrev_t *t);
43 static ids_t *new_ids(char *s);
44 static ids_t *add_ids(ids_t *s, char *t);
45 static revs_t *new_revs(char *s);
46 static revs_t *add_revs(revs_t *s, char *t);
47 static dtext_t *new_dtext(char *n, char *l, char *t);
48 static dtexts_t *add_dtexts(dtexts_t *s, dtext_t *t);
49 static delta_t *new_delta(char *rev, char *date, char *author, char *state, revs_t *branches, char *next);
50 static deltas_t *add_deltas(deltas_t *s, delta_t *t);
51 static rcsfile_t *new_rcsfile(char *head, char *branch, ids_t *access, tags_t *tags,
52 idrevs_t *locks, int strict, char *comment, char *expand);
53
54 %}
55
56 %union{
57 int i;
58 char *str;
59 tag_t *tag;
60 tags_t *tags;
61 idrev_t *idrev;
62 idrevs_t *idrevs;
63 ids_t *ids;
64 revs_t *revs;
65 dtext_t *dtext;
66 dtexts_t *dtexts;
67 delta_t *delta;
68 deltas_t *deltas;
69 rcsfile_t *rcsfile;
70 }
71
72 %token tHEAD tBRANCH tACCESS tSYMBOLS tLOCKS tSTRICT tCOMMENT
73 %token tEXPAND tDATE tAUTHOR tSTATE tBRANCHES tNEXT
74 %token tDESC tLOG tTEXT
75 %token tOWNER tGROUP tPERMISSIONS tSPECIAL tSYMLINK tHARDLINKS
76 %token tNAMESPACE tDEAD
77 %token <str> tNEWPHRASE
78 %token <str> tSTRING tREV tID tSYM
79
80
81 %type <str> ostr orev oid obranch ocomment oexpand desc idorstr
82 %type <tag> tag
83 %type <tags> tags otags
84 %type <idrev> idrev
85 %type <idrevs> idrevs oidrevs
86 %type <ids> ids oids
87 %type <revs> revs orevs
88 %type <i> ostrict
89 %type <dtext> dtext
90 %type <dtexts> dtexts
91 %type <delta> delta
92 %type <deltas> deltas
93 %type <rcsfile> admin
94
95 %%
96 rcsfile : admin deltas desc {
97 rcsfile = $1;
98 rcsfile->deltas = $2;
99 rcsfile->desc = $3;
100 rcsfile->dtexts = NULL;
101 if(rcsfile->head)
102 {
103 char *h = xstrdup("HEAD");
104 char *r = xstrdup(rcsfile->head->rev);
105 tag_t *t = new_tag(h, r);
106 rcsfile->tags = add_tags(rcsfile->tags, t);
107 }
108 if(rcsfile->branch)
109 {
110 char *h = xstrdup("MAIN");
111 char *r = xstrdup(rcsfile->branch->rev);
112 tag_t *t = new_tag(h, r);
113 t->rev->isbranch = 1;
114 rcsfile->tags = add_tags(rcsfile->tags, t);
115 }
116 /* Else we need to add the main tag later because the
117 * trunk is reversed in order and the primary revision
118 * numbers can vary.
119 */
120 if(!conf.parse_logs)
121 {
122 /* Return from the yyparse() call early to avoid parsing
123 * of the possibly extremely large deltatext. This speeds
124 * up parsing of binary files by a very large factor.
125 */
126 return 0;
127 }
128 }
129
130 /* This is trailing deltatext context and possibly ignored */
131 dtexts { rcsfile->dtexts = $5; }
132 ;
133
134 admin : tHEAD orev ';'
135 obranch
136 tACCESS { set_id(); } oids ';'
137 tSYMBOLS { set_sym(); } otags ';'
138 tLOCKS { set_id(); } oidrevs ';' ostrict
139 ocomment
140 oexpand
141 ophrases { $$ = new_rcsfile($2, $4, $7, $11, $15, $17, $18, $19); }
142 ;
143
144 ostrict : /* Empty */ { $$ = 0; }
145 | tSTRICT ';' { $$ = 1; }
146 ;
147
148 obranch : /* Empty */ { $$ = NULL; }
149 | tBRANCH orev ';' { $$ = $2; }
150 ;
151
152 ocomment: /* Empty */ { $$ = NULL; }
153 | tCOMMENT ostr ';' { $$ = $2; }
154 ;
155
156 oexpand : /* Empty */ { $$ = NULL; }
157 | tEXPAND ostr ';' { $$ = $2; }
158 ;
159
160 deltas : /* Empty */ { $$ = NULL; }
161 | deltas delta { $$ = add_deltas($1, $2); }
162 ;
163
164 delta : tREV
165 tDATE tREV ';'
166 tAUTHOR { set_author(); } idorstr ';'
167 tSTATE { set_id(); } oid ';'
168 tBRANCHES orevs ';'
169 tNEXT orev ';'
170 ophrases { $$ = new_delta($1, $3, $7, $11, $14, $17); }
171 ;
172
173 idorstr : tID { $$ = $1; }
174 | tSTRING { $$ = $1; }
175 ;
176
177 desc : tDESC tSTRING { $$ = $2; }
178 ;
179
180 dtexts : /* Empty */ { $$ = NULL; }
181 | dtexts dtext { $$ = add_dtexts($1, $2); }
182 ;
183
184 dtext : tREV
185 tLOG tSTRING
186 ophrases
187 tTEXT { set_skipstr(); } tSTRING { $$ = new_dtext($1, $3, $7); }
188 ;
189
190 ophrases: /* Empty */
191 | ophrases phrase
192 ;
193
194 phrase : tNEWPHRASE { set_skip(); } ';' {
195 yywarning("Unrecognised `newphrase´ keyword '%s' skipped", $1);
196 xfree($1);
197 }
198 | cvskw { set_skip(); } ';' { yywarning("CVS extended keyword skipped"); }
199 | otherkw { set_skip(); } ';' { yywarning("Other extended keyword"); }
200 ;
201
202 cvskw : tOWNER
203 | tGROUP
204 | tPERMISSIONS
205 | tSPECIAL
206 | tSYMLINK
207 | tHARDLINKS
208 ;
209
210 otherkw : tNAMESPACE
211 | tDEAD
212 ;
213
214 ostr : /* Empty */ { $$ = NULL; }
215 | tSTRING { $$ = $1; }
216 ;
217
218 orev : /* Empty */ { $$ = NULL; }
219 | tREV { $$ = $1; }
220 ;
221
222 orevs : /* Empty */ { $$ = NULL; }
223 | revs { $$ = $1; }
224 ;
225
226 revs : tREV { $$ = new_revs($1); }
227 | revs tREV { $$ = add_revs($1, $2); }
228 ;
229
230 oid : /* Empty */ { $$ = NULL; }
231 | tID { $$ = $1; }
232 ;
233
234 oids : /* Empty */ { $$ = NULL; }
235 | ids { $$ = $1; }
236 ;
237
238 ids : tID { $$ = new_ids($1); }
239 | ids tID { set_id(); $$ = add_ids($1, $2); }
240 ;
241
242 oidrevs : /* Empty */ { $$ = NULL; }
243 | idrevs { $$ = $1; }
244 ;
245
246 idrevs : idrev { $$ = new_idrevs($1); }
247 | idrevs idrev { $$ = add_idrevs($1, $2); }
248 ;
249
250 idrev : tID ':' tREV { set_id(); $$ = new_idrev($1, $3); }
251 ;
252
253 otags : /* Empty */ { $$ = NULL; }
254 | tags { $$ = $1; }
255 ;
256
257 tags : tag { if($1) $$ = new_tags($1); else $$ = NULL; }
258 | tags tag { if($1 && $2) $$ = add_tags($1, $2); else if($2) $$ = new_tags($2); else $$ = $1; }
259 ;
260
261 tag : tSYM ':' tREV { set_sym(); $$ = new_tag($1, $3); }
262 /* Zap the additional tag-info from CVSNT */
263 /* This is a bit of a hack, but it is necessary to do like this */
264 /* because the parser is not allowed to do any look-ahead on ':'. */
265 /* Otherwise, we would have a tNEWPHRASE hit because we cannot set */
266 /* set_sym() before the lexer gets the next token. */
267 | ':' tREV ':' tSTRING { set_sym(); $$ = NULL; }
268 ;
269
270 %%
271 static rev_t *make_rev(char *s)
272 {
273 char *cptr;
274 int dots = 0;
275 rev_t *r;
276
277 if(!s)
278 return NULL;
279
280 r = xmalloc(sizeof(*r));
281
282 for(cptr = s; *cptr; cptr++)
283 {
284 if(*cptr == '.')
285 dots++;
286 }
287 if(!dots)
288 {
289 r->rev = xstrdup("");
290 r->branch = xstrdup(s);
291 r->isbranch = 1;
292 }
293 else if(!*s)
294 {
295 r->rev = xstrdup("?.?");
296 r->branch = xstrdup("?");
297 }
298 else if(dots & 1)
299 {
300 char *t;
301 r->rev = s;
302 r->branch = xstrdup(s);
303 cptr = strrchr(r->branch, '.');
304 assert(cptr != NULL);
305 *cptr = '\0';
306 t = strrchr(r->branch, '.');
307 if((t&& !strcmp(t+1, "0")) || (!t && !strcmp(r->branch, "0")))
308 {
309 /* Magic branch numbers "x.x.0.x" */
310 r->isbranch = 1;
311 if(t)
312 strcpy(t+1, cptr+1);
313 else
314 strcpy(r->branch, cptr+1);
315 }
316 }
317 else
318 {
319 r->isbranch = 1;
320 r->branch = s;
321 r->rev = xmalloc(strlen(s) + 3);
322 strcpy(r->rev, s);
323 strcat(r->rev, ".?");
324 }
325 return r;
326 }
327
328
329 static tag_t *new_tag(char *s, char *r)
330 {
331 tag_t *t = xmalloc(sizeof(*t));
332 t->tag = s;
333 t->rev = make_rev(r);
334 return t;
335 }
336
337 static tags_t *new_tags(tag_t *s)
338 {
339 tags_t *t = xmalloc(sizeof(*t));
340 t->ntags = 1;
341 t->tags = xmalloc(sizeof(t->tags[0]));
342 t->tags[0] = s;
343 return t;
344 }
345
346 static tags_t *add_tags(tags_t *s, tag_t *t)
347 {
348 if(!s)
349 return new_tags(t);
350 s->tags = xrealloc(s->tags, (s->ntags+1) * sizeof(s->tags[0]));
351 s->tags[s->ntags] = t;
352 s->ntags++;
353 return s;
354 }
355
356 static idrev_t *new_idrev(char *s, char *r)
357 {
358 idrev_t *t = xmalloc(sizeof(*t));
359 t->id = s;
360 t->rev = make_rev(r);
361 return t;
362 }
363
364 static idrevs_t *new_idrevs(idrev_t *s)
365 {
366 idrevs_t *t = xmalloc(sizeof(*t));
367 t->nidrevs = 1;
368 t->idrevs = xmalloc(sizeof(t->idrevs[0]));
369 t->idrevs[0] = s;
370 return t;
371 }
372
373 static idrevs_t *add_idrevs(idrevs_t *s, idrev_t *t)
374 {
375 if(!s)
376 return new_idrevs(t);
377 s->idrevs = xrealloc(s->idrevs, (s->nidrevs+1) * sizeof(s->idrevs[0]));
378 s->idrevs[s->nidrevs] = t;
379 s->nidrevs++;
380 return s;
381 }
382
383 static ids_t *new_ids(char *s)
384 {
385 ids_t *t = xmalloc(sizeof(*t));
386 t->nids = 1;
387 t->ids = xmalloc(sizeof(t->ids[0]));
388 t->ids[0] = s;
389 return t;
390 }
391
392 static ids_t *add_ids(ids_t *s, char *t)
393 {
394 s->ids = xrealloc(s->ids, (s->nids+1) * sizeof(s->ids[0]));
395 s->ids[s->nids] = t;
396 s->nids++;
397 return s;
398 }
399
400 static revs_t *new_revs(char *s)
401 {
402 revs_t *t = xmalloc(sizeof(*t));
403 t->nrevs = 1;
404 t->revs = xmalloc(sizeof(t->revs[0]));
405 t->revs[0] = make_rev(s);
406 return t;
407 }
408
409 static revs_t *add_revs(revs_t *s, char *t)
410 {
411 s->revs = xrealloc(s->revs, (s->nrevs+1) * sizeof(s->revs[0]));
412 s->revs[s->nrevs] = make_rev(t);
413 s->nrevs++;
414 return s;
415 }
416
417 static dtext_t *new_dtext(char *n, char *l, char *t)
418 {
419 dtext_t *d = xmalloc(sizeof(*d));
420 d->rev = make_rev(n);
421 d->log = l;
422 d->text = t;
423 return d;
424 }
425
426 static dtexts_t *add_dtexts(dtexts_t *s, dtext_t *t)
427 {
428 if(!s)
429 s = xmalloc(sizeof(*s));
430 s->dtexts = xrealloc(s->dtexts, (s->ndtexts+1) * sizeof(s->dtexts[0]));
431 s->dtexts[s->ndtexts] = t;
432 s->ndtexts++;
433 return s;
434 }
435
436 static delta_t *new_delta(char *rev, char *date, char *author, char *state, revs_t *branches, char *next)
437 {
438 delta_t *d = xmalloc(sizeof(*d));
439 d->rev = make_rev(rev);
440 d->date = date;
441 d->author = author;
442 d->state = state;
443 d->branches = branches;
444 d->next = make_rev(next);
445 return d;
446 }
447
448 static deltas_t *add_deltas(deltas_t *s, delta_t *t)
449 {
450 if(!s)
451 s = xmalloc(sizeof(*s));
452 s->deltas = xrealloc(s->deltas, (s->ndeltas+1) * sizeof(s->deltas[0]));
453 s->deltas[s->ndeltas] = t;
454 s->ndeltas++;
455 return s;
456 }
457
458 static rcsfile_t *new_rcsfile(char *head, char *branch, ids_t *access, tags_t *tags,
459 idrevs_t *locks, int strict, char *comment, char *expand)
460 {
461 rcsfile_t *r = xmalloc(sizeof(*r));
462 r->head = make_rev(head);
463 r->branch = make_rev(branch);
464 r->access = access;
465 r->tags = tags;
466 r->locks = locks;
467 r->strict = strict;
468 r->comment = comment;
469 r->expand = expand;
470 return r;
471 }
472

  ViewVC Help
Powered by ViewVC 1.1.0 with CvsGraph 1.7.0