b7091c585f46e2faa01696f311218bcfd7fb290c
[claws.git] / src / plugins / vcalendar / libical / libical / icalyacc.y
1 %{
2 /* -*- Mode: C -*-
3   ======================================================================
4   FILE: icalitip.y
5   CREATOR: eric 10 June 1999
6   
7   DESCRIPTION:
8   
9   $Id$
10   $Locker$
11
12   (C) COPYRIGHT 1999 Eric Busboom 
13   http://www.softwarestudio.org
14
15   The contents of this file are subject to the Mozilla Public License
16   Version 1.0 (the "License"); you may not use this file except in
17   compliance with the License. You may obtain a copy of the License at
18   http://www.mozilla.org/MPL/
19  
20   Software distributed under the License is distributed on an "AS IS"
21   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
22   the License for the specific language governing rights and
23   limitations under the License.
24
25   The original author is Eric Busboom
26   The original code is icalitip.y
27
28
29
30   =======================================================================*/
31
32 #include <stdlib.h>
33 #include <string.h> /* for strdup() */
34 #include "icalparser.h"
35 #include "pvl.h"
36
37 icalvalue *icalparser_yy_value; /* Current Value */
38
39 void ical_yyerror(char* s);
40 void icalparser_clear_flex_input();  
41 int ical_yy_lex(void);
42
43 /* Globals for UTCOFFSET values */
44 int utc; 
45 int utc_b; 
46 int utcsign;
47
48 /* Globals for DURATION values */
49 struct icaldurationtype duration;
50
51 /* Globals for TRIGGER values */
52 struct icaltriggertype trigger;
53
54 void copy_list(short* array, size_t size);
55 void add_prop(icalproperty_kind);
56 void icalparser_fill_date(struct tm* t, char* dstr);
57 void icalparser_fill_time(struct tm* t, char* tstr);
58 void set_value_type(icalvalue_kind kind);
59 void set_parser_value_state();
60 struct icaltimetype fill_datetime(char* d, char* t);
61 void ical_yy_error(char *s); /* Don't know why I need this.... */
62 int yylex(void); /* Or this. */
63
64
65
66 /* Set the state of the lexer so it will interpret values ( iCAL
67    VALUEs, that is, ) correctly. */
68
69 %}
70
71 %union {
72         float v_float;
73         int   v_int;
74         char* v_string;
75 }
76
77
78   /* Renaming hack */
79
80 /*
81 #define    yymaxdepth ical_yy_maxdepth
82 #define    yyparse ical_yy_parse
83 #define    yyerror ical_yy_error
84 #define    yylval  ical_yy_lval
85 #define    yychar  ical_yy_char
86 #define    yydebug ical_yy_debug
87 #define    yypact  ical_yy_pact
88 #define    yyr1    ical_yy_r1
89 #define    yyr2    ical_yy_r2
90 #define    yydef   ical_yy_def
91 #define    yychk   ical_yy_chk
92 #define    yypgo   ical_yy_pgo
93 #define    yyact   ical_yy_act
94 #define    yyexca  ical_yy_exca
95 #define yyerrflag ical_yy_errflag
96 #define yynerrs    ical_yy_nerrs
97 #define    yyps    ical_yy_ps
98 #define    yypv    ical_yy_pv
99 #define    yys     ical_yy_s
100 #define    yy_yys  ical_yy_yys
101 #define    yystate ical_yy_state
102 #define    yytmp   ical_yy_tmp
103 #define    yyv     ical_yy_v
104 #define    yy_yyv  ical_yy_yyv
105 #define    yyval   ical_yy_val
106 #define    yylloc  ical_yy_lloc
107 #define yyreds     ical_yy_reds
108 #define yytoks     ical_yy_toks
109 #define yylhs      ical_yy_yylhs
110 #define yylen      ical_yy_yylen
111 #define yydefred ical_yy_yydefred
112 #define yydgoto    ical_yy_yydgoto
113 #define yydefred ical_yy_yydefred
114 #define yydgoto    ical_yy_yydgoto
115 #define yysindex ical_yy_yysindex
116 #define yyrindex ical_yy_yyrindex
117 #define yygindex ical_yy_yygindex
118 #define yytable     ical_yy_yytable
119 #define yycheck     ical_yy_yycheck
120 #define yyname   ical_yy_yyname
121 #define yyrule   ical_yy_yyrule
122 #define yy_scan_bytes ical_yy_scan_bytes
123 #define yy_scan_string ical_yy_scan_string
124 #define yy_scan_buffer ical_yy_scan_buffer
125 */
126
127 /* These are redefined with the -P option to flex */
128 /*
129 #define yy_create_buffer  ical_yy_create_buffer 
130 #define yy_delete_buffer ical_yy_delete_buffer
131 #define yy_flex_debug ical_yy_flex_debug
132 #define yy_init_buffer ical_yy_init_buffer
133 #define yy_flush_buffer ical_yy_flush_buffer
134 #define yy_load_buffer_state ical_yy_load_buffer_state
135 #define yy_switch_to_buffer ical_yy_switch_to_buffer
136 #define yyin ical_yyin
137 #define yyleng ical_yyleng
138 #define yylex ical_yylex
139 #define yylineno ical_yylineno
140 #define yyout ical_yyout
141 #define yyrestart ical_yyrestart
142 #define yytext ical_yytext
143 #define yywrap ical_yywrap             
144 */
145
146
147 %token <v_string> DIGITS
148 %token <v_int> INTNUMBER
149 %token <v_float> FLOATNUMBER
150 %token <v_string> STRING   
151 %token EOL EQUALS CHARACTER COLON COMMA SEMICOLON MINUS TIMESEPERATOR 
152
153 %token TRUE FALSE
154
155 %token FREQ BYDAY BYHOUR BYMINUTE BYMONTH BYMONTHDAY BYSECOND BYSETPOS BYWEEKNO
156 %token BYYEARDAY DAILY MINUTELY MONTHLY SECONDLY WEEKLY HOURLY YEARLY
157 %token INTERVAL COUNT UNTIL WKST MO SA SU TU WE TH FR 
158
159 %token BIT8 ACCEPTED ADD AUDIO BASE64 BINARY BOOLEAN BUSY BUSYTENTATIVE
160 %token BUSYUNAVAILABLE CALADDRESS CANCEL CANCELLED CHAIR CHILD COMPLETED
161 %token CONFIDENTIAL CONFIRMED COUNTER DATE DATETIME DECLINECOUNTER DECLINED
162 %token DELEGATED DISPLAY DRAFT DURATION EMAIL END FINAL FLOAT FREE GREGORIAN
163 %token GROUP INDIVIDUAL INPROCESS INTEGER NEEDSACTION NONPARTICIPANT
164 %token OPAQUE OPTPARTICIPANT PARENT PERIOD PRIVATE PROCEDURE PUBLIC PUBLISH
165 %token RECUR REFRESH REPLY REQPARTICIPANT REQUEST RESOURCE ROOM SIBLING
166 %token START TENTATIVE TEXT THISANDFUTURE THISANDPRIOR TIME TRANSPAENT
167 %token UNKNOWN UTCOFFSET XNAME
168
169 %token ALTREP CN CUTYPE DAYLIGHT DIR ENCODING EVENT FBTYPE FMTTYPE LANGUAGE 
170 %token MEMBER PARTSTAT RANGE RELATED RELTYPE ROLE RSVP SENTBY STANDARD URI
171 %token CHARSET
172
173 %token TIME_CHAR UTC_CHAR
174
175
176 %%
177
178 value:
179         date_value
180         | datetime_value
181         | duration_value
182         | period_value
183         | utcoffset_value
184         | error { 
185                   icalparser_yy_value = 0;
186                   icalparser_clear_flex_input();
187                   yyclearin;
188                   }
189
190
191 date_value: DIGITS
192         {
193             struct icaltimetype stm;
194
195             stm = fill_datetime($1,0);
196
197             stm.hour = -1;
198             stm.minute = -1;
199             stm.second = -1;
200             stm.is_utc = 0;
201             stm.is_date = 1;
202
203             icalparser_yy_value = icalvalue_new_date(stm);
204         }
205
206 utc_char: 
207         /*empty*/  {utc = 0;}
208         | UTC_CHAR {utc = 1;}
209
210 /* This is used in the period_value, where there may be two utc characters per rule. */
211 utc_char_b: 
212         /*empty*/  {utc_b = 0;}
213         | UTC_CHAR {utc_b = 1;}
214
215 datetime_value: 
216         DIGITS TIME_CHAR DIGITS utc_char
217         {
218             struct  icaltimetype stm;
219             stm = fill_datetime($1, $3);
220             stm.is_utc = utc;
221             stm.is_date = 0;
222
223             icalparser_yy_value = 
224                 icalvalue_new_datetime(stm);
225         }
226
227
228 /* Duration */
229
230
231 dur_date: dur_day
232         | dur_day dur_time
233
234 dur_week: DIGITS 'W'
235         {
236             duration.weeks = atoi($1);
237         }
238
239 dur_time: TIME_CHAR dur_hour 
240         {
241         }
242         | TIME_CHAR dur_minute
243         {
244         }
245         | TIME_CHAR dur_second
246         {
247         }
248
249 dur_hour: DIGITS 'H'
250         {
251             duration.hours = atoi($1);
252         }
253         | DIGITS 'H' dur_minute
254         {
255             duration.hours = atoi($1);
256         }
257
258 dur_minute: DIGITS 'M'
259         {
260             duration.minutes = atoi($1);
261         }
262         | DIGITS 'M' dur_second
263         {
264             duration.minutes = atoi($1);
265         }
266
267 dur_second: DIGITS 'S'
268         {
269             duration.seconds = atoi($1);
270         }
271
272 dur_day: DIGITS 'D'
273         {
274             duration.days = atoi($1);
275         }
276
277 dur_prefix: /* empty */
278         {
279             duration.is_neg = 0;
280         } 
281         | '+'
282         {
283             duration.is_neg = 0;
284         }
285         | '-'
286         { 
287             duration.is_neg = 1;
288         }
289
290 duration_value: dur_prefix 'P' dur_date
291         { 
292             icalparser_yy_value = icalvalue_new_duration(duration); 
293             memset(&duration,0, sizeof(duration));
294         }
295         | dur_prefix 'P' dur_time
296         { 
297             icalparser_yy_value = icalvalue_new_duration(duration); 
298             memset(&duration,0, sizeof(duration));
299         }
300         | dur_prefix 'P' dur_week
301         { 
302             icalparser_yy_value = icalvalue_new_duration(duration); 
303             memset(&duration,0, sizeof(duration));
304         }
305
306
307 /* Period */
308
309 period_value:  DIGITS TIME_CHAR DIGITS utc_char '/'  DIGITS TIME_CHAR DIGITS utc_char_b
310         {
311             struct icalperiodtype p;
312         
313             p.start = fill_datetime($1,$3);
314             p.start.is_utc = utc;
315             p.start.is_date = 0;
316
317
318             p.end = fill_datetime($6,$8);
319             p.end.is_utc = utc_b;
320             p.end.is_date = 0;
321                 
322             p.duration.days = -1;
323             p.duration.weeks = -1;
324             p.duration.hours = -1;
325             p.duration.minutes = -1;
326             p.duration.seconds = -1;
327
328             icalparser_yy_value = icalvalue_new_period(p);
329         }
330         | DIGITS TIME_CHAR DIGITS utc_char '/'  duration_value
331         {
332             struct icalperiodtype p;
333             
334             p.start = fill_datetime($1,$3);
335             p.start.is_utc = utc;
336             p.start.is_date = 0;
337
338             p.end.year = -1;
339             p.end.month = -1;
340             p.end.day = -1;
341             p.end.hour = -1;
342             p.end.minute = -1;
343             p.end.second = -1;
344                    
345             /* The duration_value rule setes the global 'duration'
346                variable, but it also creates a new value in
347                icalparser_yy_value. So, free that, then copy
348                'duration' into the icalperiodtype struct. */
349
350             p.duration = icalvalue_get_duration(icalparser_yy_value);
351             icalvalue_free(icalparser_yy_value);
352             icalparser_yy_value = 0;
353
354             icalparser_yy_value = icalvalue_new_period(p);
355
356         }
357
358
359 trigger: 
360         
361
362
363 /* UTC Offset */
364
365 plusminus: '+' { utcsign = 1; }
366         | '-' { utcsign = -1; }
367
368 utcoffset_value: 
369         plusminus INTNUMBER INTNUMBER
370         {
371             icalparser_yy_value = icalvalue_new_utcoffset( utcsign * ($2*3600) + ($3*60) );
372         }
373
374         | plusminus INTNUMBER INTNUMBER INTNUMBER
375         {
376             icalparser_yy_value = icalvalue_new_utcoffset(utcsign * ($2*3600) + ($3*60) +($4));
377         }
378
379 %%
380
381 struct icaltimetype fill_datetime(char* datestr, char* timestr)
382 {
383             struct icaltimetype stm;
384
385             memset(&stm,0,sizeof(stm));
386
387             if (datestr != 0){
388                 sscanf(datestr,"%4d%2d%2d",&(stm.year), &(stm.month), 
389                        &(stm.day));
390             }
391
392             if (timestr != 0){
393                 sscanf(timestr,"%2d%2d%2d", &(stm.hour), &(stm.minute), 
394                        &(stm.second));
395             }
396
397             return stm;
398
399 }
400
401 void ical_yyerror(char* s)
402 {
403     /*fprintf(stderr,"Parse error \'%s\'\n", s);*/
404 }
405