Gracefuly handle spaces around the equal sign in the Authors file.
[parsecvs.git] / lex.l
blob2a42ed968968c853062145596f989261159edf04
1 %{
2 /*
3  *  Copyright © 2006 Keith Packard <keithp@keithp.com>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or (at
8  *  your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful, but
11  *  WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18  */
19 #include "cvs.h"
20 #include "y.tab.h"
21     
22 static char *
23 parse_data (int strip);
25 #define YY_INPUT(buf,result,max_size) { \
26     int c = getc (yyin); \
27     result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
29     
31 %s CONTENT SKIP COMMIT
33 <INITIAL>head                   BEGIN(CONTENT); return HEAD;
34 <INITIAL>branch                 BEGIN(CONTENT); return BRANCH;
35 <INITIAL>access                 BEGIN(CONTENT); return ACCESS;
36 <INITIAL>symbols                BEGIN(CONTENT); return SYMBOLS;
37 <INITIAL>locks                  BEGIN(CONTENT); return LOCKS;
38 <INITIAL>comment                BEGIN(CONTENT); return COMMENT;
39 <INITIAL>expand                 BEGIN(CONTENT); return EXPAND;
40 <INITIAL>date                   BEGIN(CONTENT); return DATE;
41 <INITIAL>branches               BEGIN(CONTENT); return BRANCHES;
42 <INITIAL>next                   BEGIN(CONTENT); return NEXT;
43 <INITIAL>commitid               BEGIN(COMMIT); return COMMITID;
44 <INITIAL>strict                 BEGIN(CONTENT); return STRICT;
45 <INITIAL>author                 BEGIN(CONTENT); return AUTHOR;
46 <INITIAL>state                  BEGIN(CONTENT); return STATE;
47 <INITIAL>desc                   return DESC;
48 <INITIAL>log                    return LOG;
49 <INITIAL>text                   BEGIN(SKIP); return TEXT;
50 <SKIP>@                         {
51                                         yylval.s = parse_data (0);
52                                         BEGIN(INITIAL);
53                                         return TEXT_DATA;
54                                 }
55 <CONTENT>[-a-zA-Z_+%][-a-zA-Z_0-9+/%.]* {
56                                         yylval.s = atom (yytext);
57                                         return NAME;
58                                 }
59 <COMMIT>[0-9a-zA-Z]+            {
60                                         yylval.s = atom (yytext);
61                                         return NAME;
62                                 }
63 [0-9]+\.[0-9.]*                 {
64                                         yylval.number = lex_number (yytext);
65                                         return NUMBER;
66                                 }
67 ;                               BEGIN(INITIAL); return SEMI;
68 :                               return COLON;
69 <INITIAL,CONTENT>@              {
70                                         yylval.s = parse_data (1);
71                                         return DATA;
72                                 }
73 " "                             ;
74 \t                              ;
75 \n                              ;
76 1                               return BRAINDAMAGED_NUMBER;
77 .                               { 
78                                     fprintf (stderr, "%s: (%d) ignoring %c\n", 
79                                              yyfilename, yylineno,
80                                              yytext[0]);
81                                 }
83 int yywrap (void) { return 1; }
85 struct varbuf {
86         int len, cur;
87         char *string;
90 static inline void addbuf(struct varbuf *buf, char c)
92         if (buf->cur == buf->len) 
93                 buf->string = realloc(buf->string, buf->len *= 2);
94         buf->string[buf->cur++] = c;
97 static char *
98 parse_data (int strip)
100     int c;
101     char *ret;
102     struct varbuf buf;
104     buf.cur = 0;
105     buf.len = 256;
106     buf.string = malloc(buf.len);
108     if (!strip)
109         addbuf(&buf, '@');
110     for(;;) {
111         c = getc (yyin);
112         if (c == '@') {
113             if (!strip)
114                 addbuf(&buf, c);
115             c = getc (yyin);
116             if (c != '@') 
117                 break;
118         }
119         addbuf(&buf, c);
120     }
121     ungetc (c, yyin);
122     addbuf(&buf, 0);
123     if (strip) {
124        ret = atom (buf.string);
125        free (buf.string);
126     } else {
127        ret = buf.string;
128     }
129     return ret;
132 cvs_number
133 lex_number (char *s)
135     cvs_number  n;
136     char        *next;
138     n.c = 0;
139     while (*s) {
140         n.n[n.c] = (int) strtol(s, &next, 10);
141         if (next == s)
142             break;
143         if (*next == '.')
144             next++;
145         s = next;
146         n.c++;
147     }
148     return n;
151 time_t
152 lex_date (cvs_number *n)
154         struct tm       tm;
155         time_t          d;
156         
157         tm.tm_year = n->n[0];
158         if (tm.tm_year > 1900)
159            tm.tm_year -= 1900;
160         tm.tm_mon = n->n[1] - 1;
161         tm.tm_mday = n->n[2];
162         tm.tm_hour = n->n[3];
163         tm.tm_min = n->n[4];
164         tm.tm_sec = n->n[5];
165         tm.tm_isdst = 0;
166         tm.tm_zone = 0;
167         d = mktime (&tm);
168         if (d == 0) {
169             int i;
170             fprintf (stderr, "%s: (%d) unparsable date: ", yyfilename,
171                      yylineno);
172             for (i = 0; i < n->c; i++) {
173                 if (i) fprintf (stderr, ".");
174                 fprintf (stderr, "%d", n->n[i]);
175             }
176             fprintf (stderr, "\n");
177         }
178         return d;
181 char *
182 lex_text (void)
184     return yytext;