dtcm: make it build
[oweals/cde.git] / cde / lib / csa / rescan.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: rescan.c /main/1 1996/04/21 19:24:17 drk $ */
24 /*
25  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
26  *  (c) Copyright 1993, 1994 International Business Machines Corp.
27  *  (c) Copyright 1993, 1994 Novell, Inc.
28  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
29  */
30
31 #include <EUSCompat.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <time.h>
37
38 #include "rerule.h"
39 #include "reparser.h"
40
41 #define EOL                     0
42
43 #define ENDMARKERSYMBOL         '$'
44 #define DURATIONSYMBOL          '#'
45 #define FRONTWEEKSYMBOL         '+'
46 #define REARWEEKSYMBOL          '-'
47 #define MINUTESYMBOL            'M'
48 #define DAILYSYMBOL             'D'
49 #define WEEKLYSYMBOL            'W'
50 #define LASTDAYSYMBOL           "LD"
51 #define MONTHPOSSYMBOL          "MP"
52 #define MONTHDAYSYMBOL          "MD"
53 #define YEARDAYSYMBOL           "YD"
54 #define YEARMONTHSYMBOL         "YM"
55 #define SUNSYMBOL               "SU"
56 #define MONSYMBOL               "MO"
57 #define TUESYMBOL               "TU"
58 #define WEDSYMBOL               "WE"
59 #define THUSYMBOL               "TH"
60 #define FRISYMBOL               "FR"
61 #define SATSYMBOL               "SA"
62
63 static int scanbuf(char **inbuf, char *, int *);
64
65 /* The rule that needs to be parsed is passed to yylex() through this var */
66 char     *_DtCm_rule_buf;
67
68 char      _DtCm_yytext[128];
69
70 int
71 _DtCm_yylex(void)
72 {
73         int       token = 0;
74         int       yylen = 128;
75
76         _DtCm_yylval.number = 0;
77
78         token = scanbuf(&_DtCm_rule_buf, _DtCm_yytext, &yylen);
79         if (token == NUMBER)
80                 sscanf(_DtCm_yytext, "%d", &_DtCm_yylval.number);
81         if (token == DATE)
82                 strcpy(_DtCm_yylval.date, _DtCm_yytext);
83
84         return (token);
85 }
86
87 static int
88 scanbuf(
89         char     **buf,
90         char     *yytext,
91         int      *yylen)
92 {
93         int       token = 0;
94         int       state = 0;
95         char      c = '\0';
96         char      lastchar = '\0';
97         char     *yystart = yytext;
98
99         memset(yytext, '\0', *yylen);
100         yytext[*yylen - 1] = '\0';
101         (*yylen)--;  /* Leave room for trailing '\0' */
102
103         while (token == 0) {
104                 
105                 lastchar = c;
106                 c = *(*buf)++;
107
108                 if (*yylen > 0) {
109                         *yytext++ = c;
110                         (*yylen)--;
111                 }
112
113                 switch (state) {
114
115                 /* State 0 */
116                 case 0:
117                         if (isspace(c)) {
118                                 /* Keep whitespace out of text */
119                                 yytext--;
120                                 (*yylen)++;
121                                 /* State remains 0 */
122                         } else if (isdigit(c)) {
123                                 if (**buf == '+' || **buf == '-') /* 1+ or 2- */
124                                         state = 3;
125                                 else 
126                                         state = 1;
127                         } else if (isalpha(c)) {
128                                 if (isalpha(**buf))
129                                         state = 2;
130                                 else 
131                                         state = 4;
132                         } else if (c == ENDMARKERSYMBOL) {
133                                 return(ENDMARKER);
134                         } else if (c == DURATIONSYMBOL) {
135                                 return(DURATION);
136                         } else if (c == '\0') {
137                                 return(EOL);
138                         } else
139                                 return(ERROR);
140                         
141                         break;
142                 
143                 case 1:
144                         /* Get number */
145                         if (isdigit(c)) {
146                                 /* Stay in state 1 and get rest of number */
147                                 ;
148                         } else if (isspace(c) || c == '\0') {
149                                 /* Hit a delimiter.  Put it back into the
150                                  * input buffer and keep it out of the token
151                                  * text.
152                                  */
153                                  (*buf)--;
154                                  yytext--; (*yylen)++;
155                                  *yytext = '\0'; 
156                                  return(NUMBER);
157                         } else
158                                 state = 5;
159                         break;
160                 
161                 case 2:
162                         /* Get a command or weekday */
163                         if (strcmp(yystart, MONTHPOSSYMBOL) == 0) { 
164                                 return(MONTHPOSCOMMAND);
165                         } else if (strcmp(yystart, MONTHDAYSYMBOL) == 0) { 
166                                 return(MONTHDAYCOMMAND);
167                         } else if (strcmp(yystart, YEARDAYSYMBOL) == 0) { 
168                                 return(YEARDAYCOMMAND);
169                         } else if (strcmp(yystart, YEARMONTHSYMBOL) == 0) { 
170                                 return(YEARMONTHCOMMAND);
171                         } else if (strcmp(yystart, LASTDAYSYMBOL) == 0) { 
172                                 return(LASTDAY);
173                         } else if (strcmp(yystart, SUNSYMBOL) == 0) { 
174                                 return(SUNDAY);
175                         } else if (strcmp(yystart, MONSYMBOL) == 0) { 
176                                 return(MONDAY);
177                         } else if (strcmp(yystart, TUESYMBOL) == 0) { 
178                                 return(TUESDAY);
179                         } else if (strcmp(yystart, WEDSYMBOL) == 0) { 
180                                 return(WEDNESDAY);
181                         } else if (strcmp(yystart, THUSYMBOL) == 0) { 
182                                 return(THURSDAY);
183                         } else if (strcmp(yystart, FRISYMBOL) == 0) { 
184                                 return(FRIDAY);
185                         } else if (strcmp(yystart, SATSYMBOL) == 0) { 
186                                 return(SATURDAY);
187                         } else
188                                 return(ERROR);
189
190                 case 3:
191                         /* Get a weeknumber */
192                         if (c == FRONTWEEKSYMBOL) {
193                                 int     num = lastchar - '0';
194
195                                 switch (num) {
196
197                                 case 1: 
198                                         return(FIRSTWEEK);
199                                 case 2: 
200                                         return(SECONDWEEK);
201                                 case 3: 
202                                         return(THIRDWEEK);
203                                 case 4: 
204                                         return(FOURTHWEEK);
205                                 case 5: 
206                                         return(FIFTHWEEK);
207                                 default:
208                                         return(ERROR);
209                                 }
210                         } else if (c == REARWEEKSYMBOL) {
211                                 int     num = lastchar - '0';
212
213                                 switch (num) {
214
215                                 case 1: 
216                                         return(LASTWEEK);
217                                 case 2: 
218                                         return(SECONDLAST);
219                                 case 3: 
220                                         return(THIRDLAST);
221                                 case 4: 
222                                         return(FOURTHLAST);
223                                 case 5: 
224                                         return(FIFTHLAST);
225                                 default:
226                                         return(ERROR);
227                                 }
228                         }
229
230                 case 4:
231                         /* Found a single letter...probably a command */
232
233                         /* We expect an interval to follow a command */
234                         if (isdigit(c) == 0) return(ERROR);
235
236                         /* Backup to before digit */
237                         (*buf)--;
238                         yytext--; (*yylen)++;
239                         *yytext = '\0'; 
240
241                         switch (lastchar) {
242
243                         case DAILYSYMBOL:
244                                 return(DAILYCOMMAND);
245                         case MINUTESYMBOL:
246                                 return(MINUTECOMMAND);
247                         case WEEKLYSYMBOL:
248                                 return(WEEKLYCOMMAND);
249                         default:
250                                 return(ERROR);
251                         }
252                 case 5:
253                         /* Reading an ISO 8601 date */
254                         if (isspace(c) || c == '\0') {
255                                 /* Hit a delimiter.  Put it back into the
256                                  * input buffer and keep it out of the token
257                                  * text.
258                                  */
259                                  (*buf)--;
260                                  yytext--; (*yylen)++;
261                                  *yytext = '\0'; 
262                                  return(DATE);
263                         }
264                         break;
265                 }
266         }
267
268         /* Should never get to */
269         return (ERROR);
270 }