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 %x xSTR
23 %x xID
24 %x xSYM
25 %x xSKIP
26 %x xSKIPSTR
27 %x xAUTHOR
28
29 %option nounput
30 %option noinput
31
32 %{
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #include <gd.h>
39
40 #include "utils.h"
41 #include "cvsgraph.h"
42 #include "readconf.h"
43 #include "rcs.h"
44 #include "rcsy.h"
45
46 #define SKIP_DELTATEXT 1
47
48 static void reset_str(void);
49 static void add_str(const char *s, int l);
50 static char *get_str(void);
51
52 static int skip_string = 0;
53
54 #define YY_NO_UNPUT 1
55
56 %}
57
58 ws [\b\t\v\f\r ]
59 num [0-9.]+
60 digit [0-9]
61 idchar [!-#%-+\-/<-?A-~\240-\377]
62 special [$,.:;@]
63
64 %%
65 /* RCS keywords */
66 head return tHEAD;
67 branch return tBRANCH;
68 access return tACCESS;
69 symbols return tSYMBOLS;
70 locks return tLOCKS;
71 strict return tSTRICT;
72 comment return tCOMMENT;
73 expand return tEXPAND;
74 date return tDATE;
75 author return tAUTHOR;
76 state return tSTATE;
77 branches return tBRANCHES;
78 next return tNEXT;
79 desc return tDESC;
80 log return tLOG;
81 text return tTEXT;
82 /* CVS extensions */
83 owner return tOWNER;
84 group return tGROUP;
85 permissions return tPERMISSIONS;
86 special return tSPECIAL;
87 symlnk return tSYMLINK;
88 hardlinks return tHARDLINKS;
89 /* Other known extensions */
90 namespace return tNAMESPACE;
91 dead return tDEAD;
92 /* CVSNT extensions */
93 mergepoint1 return tMERGEPOINT;
94 deltatype return tDELTATYPE;
95 commitid return tCOMMITID;
96 kopt return tKOPT;
97 filename return tFILENAME;
98 properties return tPROPERTIES;
99
100 /* Here come any other 'newphrase' constructs */
101 {num}?{idchar}({idchar}|{num})* {
102 yylval.str = xstrdup(yytext);
103 return tNEWPHRASE;
104 }
105
106 /* Special rules for skipping everything after a 'newphrase' part */
107 <xSKIP>[^;@\n]+ ;
108 <xSKIP>\n line_number++;
109 <xSKIP>@ BEGIN(xSKIPSTR);
110 <xSKIP>; BEGIN(INITIAL); return *yytext;
111
112 <xSKIPSTR>[^\n@]+ ;
113 <xSKIPSTR>\n line_number++;
114 <xSKIPSTR>@@ ;
115 <xSKIPSTR>@ BEGIN(xSKIP);
116
117 {num} yylval.str = xstrdup(yytext); return tREV;
118 [:;$] return *yytext;
119
120 <xID>{ws}+ ;
121 <xID>\n line_number++;
122 <xID>{special} BEGIN(INITIAL); return *yytext;
123 <xID>{num}?{idchar}({idchar}|{num})* {
124 yylval.str = xstrdup(yytext);
125 BEGIN(INITIAL);
126 return tID;
127 }
128 <xID>{num}?. rcserror("Invalid character in ID '%s' (0x%02x)", yytext, yytext[yyleng-1]);
129
130 <xSYM>{ws}+ ;
131 <xSYM>\n line_number++;
132 <xSYM>{special} BEGIN(INITIAL); return *yytext;
133 <xSYM>{digit}*{idchar}({idchar}|{digit})* {
134 yylval.str = xstrdup(yytext);
135 BEGIN(INITIAL);
136 return tSYM;
137 }
138 <xSYM>{digit}*. rcserror("Invalid character in SYMBOL '%s' (0x%02x)", yytext, yytext[yyleng-1]);
139
140 @ reset_str(); BEGIN(xSTR);
141 <xSTR>[^@\n]+ add_str(yytext, yyleng);
142 <xSTR>\n line_number++; add_str(yytext, yyleng);
143 <xSTR>@@ add_str(yytext, 1);
144 <xSTR>@ yylval.str = get_str(); BEGIN(INITIAL); skip_string = 0; return tSTRING;
145
146 <xAUTHOR>@ reset_str(); BEGIN(xSTR);
147 <xAUTHOR>{ws}+ ;
148 <xAUTHOR>\n line_number++;
149 <xAUTHOR>{special} BEGIN(INITIAL); return *yytext;
150 <xAUTHOR>({idchar}|{num}|{ws})+ {
151 yylval.str = xstrdup(yytext);
152 BEGIN(INITIAL);
153 return tID;
154 }
155 <xAUTHOR>. rcserror("Invalid character in AUTHOR '%s' (0x%02x)", yytext, yytext[yyleng-1]);
156
157 {ws}+ ; /* Ignore whitespace */
158 \n line_number++;
159
160 . rcserror("Unknown char/unmatched text '%c' (0x%02x)", isprint((int)((unsigned char)*yytext)) ? *yytext : ' ', *yytext);
161
162 %%
163
164 int yywrap(void)
165 {
166 return 1;
167 }
168
set_id(void)169 void set_id(void)
170 {
171 BEGIN(xID);
172 }
173
set_author(void)174 void set_author(void)
175 {
176 BEGIN(xAUTHOR);
177 }
178
set_sym(void)179 void set_sym(void)
180 {
181 BEGIN(xSYM);
182 }
183
set_skip(void)184 void set_skip(void)
185 {
186 BEGIN(xSKIP);
187 }
188
set_skipstr(void)189 void set_skipstr(void)
190 {
191 skip_string = 1;
192 }
193
194 #define STRALLOCSIZE 256
195 static char *str;
196 static int nstr;
197 static int nastr;
198
reset_str(void)199 static void reset_str(void)
200 {
201 nstr = 0;
202 }
203
add_str(const char * s,int l)204 static void add_str(const char *s, int l)
205 {
206 #ifdef SKIP_DELTATEXT
207 if(skip_string)
208 return;
209 #endif
210 if(nstr + l + 1 > nastr)
211 {
212 str = xrealloc(str, nastr+STRALLOCSIZE);
213 nastr += STRALLOCSIZE;
214 }
215 memcpy(str+nstr, s, l);
216 nstr += l;
217 }
218
get_str(void)219 static char *get_str(void)
220 {
221 #ifdef SKIP_DELTATEXT
222 if(skip_string)
223 return xstrdup("");
224 #endif
225 if(str)
226 {
227 str[nstr] = '\0';
228 return xstrdup(str);
229 }
230 else
231 return xstrdup("");
232 }
233
234