summaryrefslogtreecommitdiffabout
path: root/libical/src/libicalss/icalgauge.c
Unidiff
Diffstat (limited to 'libical/src/libicalss/icalgauge.c') (more/less context) (show whitespace changes)
-rw-r--r--libical/src/libicalss/icalgauge.c162
1 files changed, 122 insertions, 40 deletions
diff --git a/libical/src/libicalss/icalgauge.c b/libical/src/libicalss/icalgauge.c
index b958ecf..f4854c7 100644
--- a/libical/src/libicalss/icalgauge.c
+++ b/libical/src/libicalss/icalgauge.c
@@ -31,15 +31,17 @@
31#include "icalgaugeimpl.h" 31#include "icalgaugeimpl.h"
32#include <stdlib.h> 32#include <stdlib.h>
33 33
34extern char* input_buffer; 34#include "icalssyacc.h"
35extern char* input_buffer_p;
36int ssparse(void);
37 35
38struct icalgauge_impl *icalss_yy_gauge; 36typedef void* yyscan_t;
39 37
40icalgauge* icalgauge_new_from_sql(char* sql) 38int ssparse(yyscan_t );
39
40
41icalgauge* icalgauge_new_from_sql(char* sql, int expand)
41{ 42{
42 struct icalgauge_impl *impl; 43 struct icalgauge_impl *impl;
44 yyscan_t yy_globals = NULL;
43 45
44 int r; 46 int r;
45 47
@@ -52,60 +54,82 @@ icalgauge* icalgauge_new_from_sql(char* sql)
52 impl->select = pvl_newlist(); 54 impl->select = pvl_newlist();
53 impl->from = pvl_newlist(); 55 impl->from = pvl_newlist();
54 impl->where = pvl_newlist(); 56 impl->where = pvl_newlist();
57 impl->expand = expand;
58
59 sslex_init(&yy_globals);
55 60
56 icalss_yy_gauge = impl; 61 ssset_extra(impl, yy_globals);
57 62
58 input_buffer_p = input_buffer = sql; 63 ss_scan_string(sql, yy_globals);
59 r = ssparse();
60 64
65 r = ssparse(yy_globals);
66 sslex_destroy(yy_globals);
67
68 if (r == 0) {
61 return impl; 69 return impl;
62} 70}
71 else {
72 icalgauge_free(impl);
73 return NULL;
74 }
75}
63 76
77int icalgauge_get_expand(icalgauge* gauge)
78{
79return (gauge->expand);
80
81}
64 82
65void icalgauge_free(icalgauge* gauge) 83void icalgauge_free(icalgauge* gauge)
66{ 84{
67 struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge;
68 struct icalgauge_where *w; 85 struct icalgauge_where *w;
69 86
70 assert(impl->select != 0); 87 assert(gauge->select != 0);
71 assert(impl->where != 0); 88 assert(gauge->where != 0);
72 assert(impl->from != 0); 89 assert(gauge->from != 0);
73 90
74 if(impl->select){ 91 if(gauge->select){
75 while( (w=pvl_pop(impl->select)) != 0){ 92 while( (w=pvl_pop(gauge->select)) != 0){
76 if(w->value != 0){ 93 if(w->value != 0){
77 free(w->value); 94 free(w->value);
78 } 95 }
79 free(w); 96 free(w);
80 } 97 }
81 pvl_free(impl->select); 98 pvl_free(gauge->select);
99 gauge->select = 0;
82 } 100 }
83 101
84 if(impl->where){ 102 if(gauge->where){
85 while( (w=pvl_pop(impl->where)) != 0){ 103 while( (w=pvl_pop(gauge->where)) != 0){
86 104
87 if(w->value != 0){ 105 if(w->value != 0){
88 free(w->value); 106 free(w->value);
89 } 107 }
90 free(w); 108 free(w);
91 } 109 }
92 pvl_free(impl->where); 110 pvl_free(gauge->where);
111 gauge->where = 0;
93 } 112 }
94 113
95 if(impl->from){ 114 if(gauge->from){
96 pvl_free(impl->from); 115 pvl_free(gauge->from);
116 gauge->from = 0;
97 } 117 }
98 118
119 free(gauge);
120
99} 121}
100 122
101/* Convert a VQUERY component into a gauge */ 123
124/** Convert a VQUERY component into a gauge */
102icalcomponent* icalgauge_make_gauge(icalcomponent* query); 125icalcomponent* icalgauge_make_gauge(icalcomponent* query);
103 126
104/* icaldirset_test compares a component against a gauge, and returns 127/**
128 icaldirset_test compares a component against a gauge, and returns
105 true if the component passes the test 129 true if the component passes the test
106 130
107 The gauge is a VCALENDAR component that specifies how to test the 131 The gauge is a VCALENDAR component that specifies how to test the
108 target components. The guage holds a collection of VEVENT, VTODO or 132 target components. The gauge holds a collection of VEVENT, VTODO or
109 VJOURNAL sub-components. Each of the sub-components has a 133 VJOURNAL sub-components. Each of the sub-components has a
110 collection of properties that are compared to corresponding 134 collection of properties that are compared to corresponding
111 properties in the target component, according to the 135 properties in the target component, according to the
@@ -252,26 +276,45 @@ int icalgauge_compare_recurse(icalcomponent* comp, icalcomponent* gauge)
252int icalgauge_compare(icalgauge* gauge,icalcomponent* comp) 276int icalgauge_compare(icalgauge* gauge,icalcomponent* comp)
253{ 277{
254 278
255 struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge;
256 icalcomponent *inner; 279 icalcomponent *inner;
257 int local_pass = 0; 280 int local_pass = 0;
258 int last_clause = 1, this_clause = 1; 281 int last_clause = 1, this_clause = 1;
259 pvl_elem e; 282 pvl_elem e;
283 icalcomponent_kind kind;
284 icalproperty *rrule;
285 int compare_recur = 0;
286
260 287
261 icalerror_check_arg_rz( (comp!=0), "comp"); 288 icalerror_check_arg_rz( (comp!=0), "comp");
262 icalerror_check_arg_rz( (gauge!=0), "gauge"); 289 icalerror_check_arg_rz( (gauge!=0), "gauge");
263 290
291 if (gauge == 0 || comp == 0) return 0;
292
264 inner = icalcomponent_get_first_real_component(comp); 293 inner = icalcomponent_get_first_real_component(comp);
265 294
266 if(inner == 0){ 295 if(inner == 0){
296 /* Wally Yau: our component is not always wrapped with
297 * a <VCALENDAR>. It's not an error.
298 * icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
299 * return 0; */
300 kind = icalcomponent_isa(comp);
301 if(kind == ICAL_VEVENT_COMPONENT ||
302 kind == ICAL_VTODO_COMPONENT ||
303 kind == ICAL_VJOURNAL_COMPONENT ||
304 kind == ICAL_VQUERY_COMPONENT ||
305 kind == ICAL_VAGENDA_COMPONENT){
306 inner = comp;
307 }
308 else {
267 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); 309 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
268 return 0; 310 return 0;
269 } 311 }
270 312 inner = comp;
313 }
271 314
272 /* Check that this component is one of the FROM types */ 315 /* Check that this component is one of the FROM types */
273 local_pass = 0; 316 local_pass = 0;
274 for(e = pvl_head(impl->from);e!=0;e=pvl_next(e)){ 317 for(e = pvl_head(gauge->from);e!=0;e=pvl_next(e)){
275 icalcomponent_kind k = (icalcomponent_kind)pvl_data(e); 318 icalcomponent_kind k = (icalcomponent_kind)pvl_data(e);
276 319
277 if(k == icalcomponent_isa(inner)){ 320 if(k == icalcomponent_isa(inner)){
@@ -284,8 +327,8 @@ int icalgauge_compare(icalgauge* gauge,icalcomponent* comp)
284 } 327 }
285 328
286 329
287 /* Check each where clause against the component */ 330 /**** Check each where clause against the component ****/
288 for(e = pvl_head(impl->where);e!=0;e=pvl_next(e)){ 331 for(e = pvl_head(gauge->where);e!=0;e=pvl_next(e)){
289 struct icalgauge_where *w = pvl_data(e); 332 struct icalgauge_where *w = pvl_data(e);
290 icalcomponent *sub_comp; 333 icalcomponent *sub_comp;
291 icalvalue *v; 334 icalvalue *v;
@@ -305,6 +348,9 @@ int icalgauge_compare(icalgauge* gauge,icalcomponent* comp)
305 return 0; 348 return 0;
306 } 349 }
307 350
351 if (w->compare == ICALGAUGECOMPARE_ISNULL || w->compare == ICALGAUGECOMPARE_ISNOTNULL)
352 v = icalvalue_new(vk);
353 else
308 v = icalvalue_new_from_string(vk,w->value); 354 v = icalvalue_new_from_string(vk,w->value);
309 355
310 if (v == 0){ 356 if (v == 0){
@@ -324,14 +370,46 @@ int icalgauge_compare(icalgauge* gauge,icalcomponent* comp)
324 } 370 }
325 } 371 }
326 372
373 /* check if it is a recurring */
374 rrule = icalcomponent_get_first_property(sub_comp,ICAL_RRULE_PROPERTY);
375
376 if (gauge->expand
377 && rrule) {
378
379 if (w->prop == ICAL_DTSTART_PROPERTY ||
380 w->prop == ICAL_DTEND_PROPERTY ||
381 w->prop == ICAL_DUE_PROPERTY){
382 /** needs to use recurrence-id to do comparison */
383 compare_recur = 1;
384 }
385
386 }
387
388
327 this_clause = 0; 389 this_clause = 0;
328 local_pass = 0; 390 local_pass = (w->compare == ICALGAUGECOMPARE_ISNULL) ? 1 : 0;
391
329 for(prop = icalcomponent_get_first_property(sub_comp,w->prop); 392 for(prop = icalcomponent_get_first_property(sub_comp,w->prop);
330 prop != 0; 393 prop != 0;
331 prop = icalcomponent_get_next_property(sub_comp,w->prop)){ 394 prop = icalcomponent_get_next_property(sub_comp,w->prop)){
332 icalvalue* prop_value; 395 icalvalue* prop_value;
333 icalgaugecompare relation; 396 icalgaugecompare relation;
334 397
398 if (w->compare == ICALGAUGECOMPARE_ISNULL) {
399 local_pass = 0;
400 break;
401 }
402
403 if (w->compare == ICALGAUGECOMPARE_ISNOTNULL) {
404 local_pass = 1;
405 break;
406 }
407
408 if (compare_recur) {
409 icalproperty *p = icalcomponent_get_first_property(sub_comp, ICAL_RECURRENCEID_PROPERTY);
410 prop_value = icalproperty_get_value(p);
411 }
412 else /* prop value from this component */
335 prop_value = icalproperty_get_value(prop); 413 prop_value = icalproperty_get_value(prop);
336 414
337 relation = (icalgaugecompare)icalvalue_compare(prop_value,v); 415 relation = (icalgaugecompare)icalvalue_compare(prop_value,v);
@@ -355,34 +433,40 @@ int icalgauge_compare(icalgauge* gauge,icalcomponent* comp)
355 } 433 }
356 } 434 }
357 435
436
358 this_clause = local_pass > 0 ? 1 : 0; 437 this_clause = local_pass > 0 ? 1 : 0;
359 438
439
360 /* Now look at the logic operator for this clause to see how 440 /* Now look at the logic operator for this clause to see how
361 the value should be merge with the previous clause */ 441 the value should be merge with the previous clause */
362 442
363 if(w->logic == ICALGAUGELOGIC_AND){ 443 if(w->logic == ICALGAUGELOGIC_AND){
364 last_clause = this_clause && last_clause; 444 last_clause = this_clause && last_clause;
365 } else if(w->logic == ICALGAUGELOGIC_AND) { 445 } else if(w->logic == ICALGAUGELOGIC_OR) {
366 last_clause = this_clause || last_clause; 446 last_clause = this_clause || last_clause;
367 } else { 447 } else {
368 last_clause = this_clause; 448 last_clause = this_clause;
369 } 449 }
370 } 450
451 icalvalue_free(v);
452
453 }/**** check next one in where clause ****/
371 454
372 return last_clause; 455 return last_clause;
373 456
374} 457}
375 458
459/** @brief Debug
460 * Print gauge information to stdout.
461 */
376 462
377void icalgauge_dump(icalcomponent* gauge) 463void icalgauge_dump(icalgauge* gauge)
378{ 464{
379 465
380 pvl_elem *p; 466 pvl_elem p;
381 struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge;
382
383 467
384 printf("--- Select ---\n"); 468 printf("--- Select ---\n");
385 for(p = pvl_head(impl->select);p!=0;p=pvl_next(p)){ 469 for(p = pvl_head(gauge->select);p!=0;p=pvl_next(p)){
386 struct icalgauge_where *w = pvl_data(p); 470 struct icalgauge_where *w = pvl_data(p);
387 471
388 if(w->comp != ICAL_NO_COMPONENT){ 472 if(w->comp != ICAL_NO_COMPONENT){
@@ -407,14 +491,14 @@ void icalgauge_dump(icalcomponent* gauge)
407 } 491 }
408 492
409 printf("--- From ---\n"); 493 printf("--- From ---\n");
410 for(p = pvl_head(impl->from);p!=0;p=pvl_next(p)){ 494 for(p = pvl_head(gauge->from);p!=0;p=pvl_next(p)){
411 icalcomponent_kind k = (icalcomponent_kind)pvl_data(p); 495 icalcomponent_kind k = (icalcomponent_kind)pvl_data(p);
412 496
413 printf("%s\n",icalenum_component_kind_to_string(k)); 497 printf("%s\n",icalenum_component_kind_to_string(k));
414 } 498 }
415 499
416 printf("--- Where ---\n"); 500 printf("--- Where ---\n");
417 for(p = pvl_head(impl->where);p!=0;p=pvl_next(p)){ 501 for(p = pvl_head(gauge->where);p!=0;p=pvl_next(p)){
418 struct icalgauge_where *w = pvl_data(p); 502 struct icalgauge_where *w = pvl_data(p);
419 503
420 if(w->logic != ICALGAUGELOGIC_NONE){ 504 if(w->logic != ICALGAUGELOGIC_NONE){
@@ -441,7 +525,5 @@ void icalgauge_dump(icalcomponent* gauge)
441 525
442 printf("\n"); 526 printf("\n");
443 } 527 }
444
445
446} 528}
447 529