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

  ViewVC Help
Powered by ViewVC 1.1.0 with CvsGraph 1.7.0