/[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.10 - (show annotations)
Thu Oct 21 21:40:35 2004 UTC (12 years, 11 months ago) by bertho
Branch: MAIN
CVS Tags: REL_1_5_1
Changes since 1.9: +7 -2 lines
- Remove warning on known extended phrases
- Add known CVSNT extended phrases to be ignored
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 phrase_t *new_phrase(phrase_type_e pt, char *t);
50 static phrases_t *add_phrases(phrases_t *s, phrase_t *t);
51 static delta_t *new_delta(char *rev, char *date, char *author, char *state, revs_t *branches, char *next, phrases_t *phrases);
52 static deltas_t *add_deltas(deltas_t *s, delta_t *t);
53 static rcsfile_t *new_rcsfile(char *head, char *branch, ids_t *access, tags_t *tags,
54 idrevs_t *locks, int strict, char *comment, char *expand);
55
56 %}
57
58 %union{
59 int i;
60 char *str;
61 tag_t *tag;
62 tags_t *tags;
63 idrev_t *idrev;
64 idrevs_t *idrevs;
65 ids_t *ids;
66 revs_t *revs;
67 dtext_t *dtext;
68 dtexts_t *dtexts;
69 delta_t *delta;
70 deltas_t *deltas;
71 rcsfile_t *rcsfile;
72 phrases_t *phrases;
73 phrase_t *phrase;
74 }
75
76 %token tHEAD tBRANCH tACCESS tSYMBOLS tLOCKS tSTRICT tCOMMENT
77 %token tEXPAND tDATE tAUTHOR tSTATE tBRANCHES tNEXT
78 %token tDESC tLOG tTEXT
79 %token tOWNER tGROUP tPERMISSIONS tSPECIAL tSYMLINK tHARDLINKS
80 %token tNAMESPACE tDEAD tMERGEPOINT
81 %token tDELTATYPE tCOMMITID tKOPT tFILENAME
82 %token <str> tNEWPHRASE
83 %token <str> tSTRING tREV tID tSYM
84
85
86 %type <str> ostr orev oid obranch ocomment oexpand desc idorstr
87 %type <tag> tag
88 %type <tags> tags otags
89 %type <idrev> idrev
90 %type <idrevs> idrevs oidrevs
91 %type <ids> ids oids
92 %type <revs> revs orevs
93 %type <i> ostrict
94 %type <dtext> dtext
95 %type <dtexts> dtexts
96 %type <delta> delta
97 %type <deltas> deltas
98 %type <rcsfile> admin
99 %type <phrases> ophrases
100 %type <phrase> phrase
101
102 %%
103 rcsfile : admin deltas desc {
104 rcsfile = $1;
105 rcsfile->deltas = $2;
106 rcsfile->desc = $3;
107 rcsfile->dtexts = NULL;
108 if(rcsfile->head)
109 {
110 char *h = xstrdup("HEAD");
111 char *r = xstrdup(rcsfile->head->rev);
112 tag_t *t = new_tag(h, r);
113 t->ignore = -1; /* Make sure it doesn't get zapped */
114 rcsfile->tags = add_tags(rcsfile->tags, t);
115 }
116 if(rcsfile->branch)
117 {
118 char *h = xstrdup("MAIN");
119 char *r = xstrdup(rcsfile->branch->rev);
120 tag_t *t = new_tag(h, r);
121 t->rev->isbranch = 1;
122 rcsfile->tags = add_tags(rcsfile->tags, t);
123 }
124 /* Else we need to add the main tag later because the
125 * trunk is reversed in order and the primary revision
126 * numbers can vary.
127 */
128 if(!conf.parse_logs)
129 {
130 /* Return from the yyparse() call early to avoid parsing
131 * of the possibly extremely large deltatext. This speeds
132 * up parsing of binary files by a very large factor.
133 */
134 return 0;
135 }
136 }
137
138 /* This is trailing deltatext context and possibly ignored */
139 dtexts { rcsfile->dtexts = $5; }
140 ;
141
142 admin : tHEAD orev ';'
143 obranch
144 tACCESS { set_id(); } oids ';'
145 tSYMBOLS { set_sym(); } otags ';'
146 tLOCKS { set_id(); } oidrevs ';' ostrict
147 ocomment
148 oexpand
149 ophrases { $$ = new_rcsfile($2, $4, $7, $11, $15, $17, $18, $19); }
150 ;
151
152 ostrict : /* Empty */ { $$ = 0; }
153 | tSTRICT ';' { $$ = 1; }
154 ;
155
156 obranch : /* Empty */ { $$ = NULL; }
157 | tBRANCH orev ';' { $$ = $2; }
158 ;
159
160 ocomment: /* Empty */ { $$ = NULL; }
161 | tCOMMENT ostr ';' { $$ = $2; }
162 ;
163
164 oexpand : /* Empty */ { $$ = NULL; }
165 | tEXPAND ostr ';' { $$ = $2; }
166 ;
167
168 deltas : /* Empty */ { $$ = NULL; }
169 | deltas delta { $$ = add_deltas($1, $2); }
170 ;
171
172 delta : tREV
173 tDATE tREV ';'
174 tAUTHOR { set_author(); } idorstr ';'
175 tSTATE { set_id(); } oid ';'
176 tBRANCHES orevs ';'
177 tNEXT orev ';'
178 ophrases { $$ = new_delta($1, $3, $7, $11, $14, $17, $19); }
179 ;
180
181 idorstr : tID { $$ = $1; }
182 | tSTRING { $$ = $1; }
183 ;
184
185 desc : tDESC tSTRING { $$ = $2; }
186 ;
187
188 dtexts : /* Empty */ { $$ = NULL; }
189 | dtexts dtext { $$ = add_dtexts($1, $2); }
190 ;
191
192 dtext : tREV
193 tLOG tSTRING
194 ophrases
195 tTEXT { set_skipstr(); } tSTRING { $$ = new_dtext($1, $3, $7); }
196 ;
197
198 ophrases: /* Empty */ { $$ = NULL; }
199 | ophrases phrase { $$ = add_phrases($1, $2); }
200 ;
201
202 phrase : tNEWPHRASE { set_skip(); } ';' {
203 yywarning("Unrecognised `newphrase´ keyword '%s' skipped", $1);
204 xfree($1);
205 $$ = NULL;
206 }
207 | cvskw { set_skip(); } ';' { $$ = NULL; /* yywarning("CVS extended keyword skipped"); */ }
208 | otherkw { set_skip(); } ';' { $$ = NULL; /* yywarning("Other extended keyword"); */ }
209 | tMERGEPOINT tSTRING ';' { $$ = new_phrase(PT_MERGEPOINT, $2); }
210 ;
211
212 cvskw : tOWNER
213 | tGROUP
214 | tPERMISSIONS
215 | tSPECIAL
216 | tSYMLINK
217 | tHARDLINKS
218 ;
219
220 otherkw : tNAMESPACE
221 | tDEAD
222 | tDELTATYPE
223 | tCOMMITID
224 | tKOPT
225 | tFILENAME
226 ;
227
228 ostr : /* Empty */ { $$ = NULL; }
229 | tSTRING { $$ = $1; }
230 ;
231
232 orev : /* Empty */ { $$ = NULL; }
233 | tREV { $$ = $1; }
234 ;
235
236 orevs : /* Empty */ { $$ = NULL; }
237 | revs { $$ = $1; }
238 ;
239
240 revs : tREV { $$ = new_revs($1); }
241 | revs tREV { $$ = add_revs($1, $2); }
242 ;
243
244 oid : /* Empty */ { $$ = NULL; }
245 | tID { $$ = $1; }
246 ;
247
248 oids : /* Empty */ { $$ = NULL; }
249 | ids { $$ = $1; }
250 ;
251
252 ids : tID { $$ = new_ids($1); }
253 | ids tID { set_id(); $$ = add_ids($1, $2); }
254 ;
255
256 oidrevs : /* Empty */ { $$ = NULL; }
257 | idrevs { $$ = $1; }
258 ;
259
260 idrevs : idrev { $$ = new_idrevs($1); }
261 | idrevs idrev { $$ = add_idrevs($1, $2); }
262 ;
263
264 idrev : tID ':' tREV { set_id(); $$ = new_idrev($1, $3); }
265 ;
266
267 otags : /* Empty */ { $$ = NULL; }
268 | tags { $$ = $1; }
269 ;
270
271 tags : tag { if($1) $$ = new_tags($1); else $$ = NULL; }
272 | tags tag { if($1 && $2) $$ = add_tags($1, $2); else if($2) $$ = new_tags($2); else $$ = $1; }
273 ;
274
275 tag : tSYM ':' tREV { set_sym(); $$ = new_tag($1, $3); }
276 /* Zap the additional tag-info from CVSNT */
277 /* This is a bit of a hack, but it is necessary to do like this */
278 /* because the parser is not allowed to do any look-ahead on ':'. */
279 /* Otherwise, we would have a tNEWPHRASE hit because we cannot set */
280 /* set_sym() before the lexer gets the next token. */
281 | ':' tREV ':' tSTRING { set_sym(); $$ = NULL; }
282 ;
283
284 %%
285 static rev_t *make_rev(char *s, int isrev)
286 {
287 char *cptr;
288 int dots = 0;
289 rev_t *r;
290
291 if(!s)
292 return NULL;
293
294 r = xmalloc(sizeof(*r));
295
296 for(cptr = s; *cptr; cptr++)
297 {
298 if(*cptr == '.')
299 dots++;
300 }
301 if(!dots)
302 {
303 r->rev = xstrdup("");
304 r->branch = xstrdup(s);
305 r->isbranch = 1;
306 }
307 else if(!*s)
308 {
309 r->rev = xstrdup("?.?");
310 r->branch = xstrdup("?");
311 }
312 else if(dots & 1)
313 {
314 char *t;
315 r->rev = s;
316 r->branch = xstrdup(s);
317 cptr = strrchr(r->branch, '.');
318 assert(cptr != NULL);
319 *cptr = '\0';
320 t = strrchr(r->branch, '.');
321 if(!isrev && ((t && !strcmp(t+1, "0")) || (!t && !strcmp(r->branch, "0"))))
322 {
323 /* Magic branch numbers "x.x.0.x" */
324 r->isbranch = 1;
325 if(t)
326 strcpy(t+1, cptr+1);
327 else
328 strcpy(r->branch, cptr+1);
329 }
330 }
331 else
332 {
333 r->isbranch = 1;
334 r->branch = s;
335 r->rev = xmalloc(strlen(s) + 3);
336 strcpy(r->rev, s);
337 strcat(r->rev, ".?");
338 }
339 return r;
340 }
341
342
343 static tag_t *new_tag(char *s, char *r)
344 {
345 tag_t *t = xmalloc(sizeof(*t));
346 t->tag = s;
347 t->rev = make_rev(r, 0);
348 return t;
349 }
350
351 static tags_t *new_tags(tag_t *s)
352 {
353 tags_t *t = xmalloc(sizeof(*t));
354 t->ntags = 1;
355 t->tags = xmalloc(sizeof(t->tags[0]));
356 t->tags[0] = s;
357 return t;
358 }
359
360 static tags_t *add_tags(tags_t *s, tag_t *t)
361 {
362 if(!s)
363 return new_tags(t);
364 s->tags = xrealloc(s->tags, (s->ntags+1) * sizeof(s->tags[0]));
365 s->tags[s->ntags] = t;
366 s->ntags++;
367 return s;
368 }
369
370 static idrev_t *new_idrev(char *s, char *r)
371 {
372 idrev_t *t = xmalloc(sizeof(*t));
373 t->id = s;
374 t->rev = make_rev(r, 1);
375 return t;
376 }
377
378 static idrevs_t *new_idrevs(idrev_t *s)
379 {
380 idrevs_t *t = xmalloc(sizeof(*t));
381 t->nidrevs = 1;
382 t->idrevs = xmalloc(sizeof(t->idrevs[0]));
383 t->idrevs[0] = s;
384 return t;
385 }
386
387 static idrevs_t *add_idrevs(idrevs_t *s, idrev_t *t)
388 {
389 if(!s)
390 return new_idrevs(t);
391 s->idrevs = xrealloc(s->idrevs, (s->nidrevs+1) * sizeof(s->idrevs[0]));
392 s->idrevs[s->nidrevs] = t;
393 s->nidrevs++;
394 return s;
395 }
396
397 static ids_t *new_ids(char *s)
398 {
399 ids_t *t = xmalloc(sizeof(*t));
400 t->nids = 1;
401 t->ids = xmalloc(sizeof(t->ids[0]));
402 t->ids[0] = s;
403 return t;
404 }
405
406 static ids_t *add_ids(ids_t *s, char *t)
407 {
408 s->ids = xrealloc(s->ids, (s->nids+1) * sizeof(s->ids[0]));
409 s->ids[s->nids] = t;
410 s->nids++;
411 return s;
412 }
413
414 static revs_t *new_revs(char *s)
415 {
416 revs_t *t = xmalloc(sizeof(*t));
417 t->nrevs = 1;
418 t->revs = xmalloc(sizeof(t->revs[0]));
419 t->revs[0] = make_rev(s, 1);
420 return t;
421 }
422
423 static revs_t *add_revs(revs_t *s, char *t)
424 {
425 s->revs = xrealloc(s->revs, (s->nrevs+1) * sizeof(s->revs[0]));
426 s->revs[s->nrevs] = make_rev(t, 1);
427 s->nrevs++;
428 return s;
429 }
430
431 static dtext_t *new_dtext(char *n, char *l, char *t)
432 {
433 dtext_t *d = xmalloc(sizeof(*d));
434 d->rev = make_rev(n, 1);
435 d->log = l;
436 d->text = t;
437 return d;
438 }
439
440 static dtexts_t *add_dtexts(dtexts_t *s, dtext_t *t)
441 {
442 if(!s)
443 s = xmalloc(sizeof(*s));
444 s->dtexts = xrealloc(s->dtexts, (s->ndtexts+1) * sizeof(s->dtexts[0]));
445 s->dtexts[s->ndtexts] = t;
446 s->ndtexts++;
447 return s;
448 }
449
450 static phrase_t *new_phrase(phrase_type_e pt, char *t)
451 {
452 phrase_t *d = xmalloc(sizeof(*d));
453 d->type = pt;
454 d->rev = make_rev(t, 1);
455 return d;
456 }
457
458 static phrases_t *add_phrases(phrases_t *s, phrase_t *t)
459 {
460 if(!t)
461 return s;
462 if(!s)
463 s = xmalloc(sizeof(*s));
464 if(t)
465 {
466 s->phrases = xrealloc(s->phrases, (s->nphrases + 1) * sizeof(s->phrases[0]));
467 s->phrases[s->nphrases] = t;
468 s->nphrases++;
469 }
470 return s;
471 }
472
473 static phrase_t *find_mergepoint(phrases_t *p)
474 {
475 int i;
476
477 if(!p)
478 return NULL;
479
480 for(i = 0; i < p->nphrases; i++)
481 {
482 if(p->phrases[i]->type == PT_MERGEPOINT)
483 return p->phrases[i];
484 }
485 return NULL;
486 }
487
488 static delta_t *new_delta(char *rev, char *date, char *author, char *state, revs_t *branches, char *next, phrases_t *phrases)
489 {
490 delta_t *d = xmalloc(sizeof(*d));
491 d->rev = make_rev(rev, 1);
492 d->date = date;
493 d->author = author;
494 d->state = state;
495 d->branches = branches;
496 d->next = make_rev(next, 1);
497 d->phrases = phrases;
498 d->mergepoint = find_mergepoint(phrases);
499 return d;
500 }
501
502 static deltas_t *add_deltas(deltas_t *s, delta_t *t)
503 {
504 if(!s)
505 s = xmalloc(sizeof(*s));
506 s->deltas = xrealloc(s->deltas, (s->ndeltas+1) * sizeof(s->deltas[0]));
507 s->deltas[s->ndeltas] = t;
508 s->ndeltas++;
509 return s;
510 }
511
512 static rcsfile_t *new_rcsfile(char *head, char *branch, ids_t *access, tags_t *tags,
513 idrevs_t *locks, int strict, char *comment, char *expand)
514 {
515 rcsfile_t *r = xmalloc(sizeof(*r));
516 r->head = make_rev(head, 1);
517 r->branch = make_rev(branch, 0);
518 r->access = access;
519 r->tags = tags;
520 r->locks = locks;
521 r->strict = strict;
522 r->comment = comment;
523 r->expand = expand;
524 return r;
525 }
526

  ViewVC Help
Powered by ViewVC 1.1.0 with CvsGraph 1.7.0