summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalparser.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalparser.c') (more/less context) (show whitespace changes)
-rw-r--r--libical/src/libical/icalparser.c333
1 files changed, 163 insertions, 170 deletions
diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c
index b5824d5..5c4296b 100644
--- a/libical/src/libical/icalparser.c
+++ b/libical/src/libical/icalparser.c
@@ -1,9 +1,9 @@
1/* -*- Mode: C -*- 1/* -*- Mode: C; tab-width: 4; c-basic-offset: 8; -*-
2 ====================================================================== 2 ======================================================================
3 FILE: icalparser.c 3 FILE: icalparser.c
4 CREATOR: eric 04 August 1999 4 CREATOR: eric 04 August 1999
5 5
6 $Id$ 6 $Id$
7 $Locker$ 7 $Locker$
8 8
9 The contents of this file are subject to the Mozilla Public License 9 The contents of this file are subject to the Mozilla Public License
@@ -33,37 +33,50 @@
33 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org 33 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
34 ======================================================================*/ 34 ======================================================================*/
35 35
36#ifdef HAVE_CONFIG_H 36#ifdef HAVE_CONFIG_H
37#include "config.h" 37#include "config.h"
38#endif 38#endif
39 39
40 40
41#include "icalparser.h"
42#include "pvl.h" 41#include "pvl.h"
43#include "icalmemory.h"
44#include "icalerror.h" 42#include "icalerror.h"
45#include "icalvalue.h" 43#include "icalvalue.h"
46#include "icalderivedparameter.h" 44#include "icalderivedparameter.h"
47#include "icalparameter.h" 45#include "icalparameter.h"
48#include "icalproperty.h" 46#include "icalproperty.h"
49#include "icalcomponent.h" 47#include "icalcomponent.h"
50 48
51#include <string.h> /* For strncpy & size_t */ 49#include <string.h> /* For strncpy & size_t */
52#include <stdio.h> /* For FILE and fgets and sprintf */ 50#include <stdio.h> /* For FILE and fgets and sprintf */
53#include <stdlib.h> /* for free */ 51#include <stdlib.h> /* for free */
54 52
55int snprintf(char *str, size_t n, char const *fmt, ...); 53#include "icalmemory.h"
54#include "icalparser.h"
55
56#ifdef HAVE_WCTYPE_H
57# include <wctype.h>
58/* Some systems have an imcomplete implementation on wctype (FreeBSD,
59 * Darwin). Cope with that. */
60# ifndef HAVE_ISWSPACE
61# define iswspace isspace
62# endif
63#else
64# ifndef HAVE_ISWSPACE
65# define iswspace isspace
66# endif
67#endif
56 68
57extern icalvalue* icalparser_yy_value; 69#ifdef WIN32
58void set_parser_value_state(icalvalue_kind kind); 70#define snprintf _snprintf
59int ical_yyparse(void); 71#define strcasecmp stricmp
72#endif
60 73
61char* icalparser_get_next_char(char c, char *str); 74char* icalparser_get_next_char(char c, char *str, int qm);
62char* icalparser_get_next_parameter(char* line,char** end); 75char* icalparser_get_next_parameter(char* line,char** end);
63char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind); 76char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind);
64char* icalparser_get_prop_name(char* line, char** end); 77char* icalparser_get_prop_name(char* line, char** end);
65char* icalparser_get_param_name(char* line, char **end); 78char* icalparser_get_param_name(char* line, char **end);
66 79
67#define TMP_BUF_SIZE 80 80#define TMP_BUF_SIZE 80
68 81
69struct icalparser_impl 82struct icalparser_impl
@@ -95,161 +108,113 @@ icalparser* icalparser_new(void)
95 } 108 }
96 109
97 impl->root_component = 0; 110 impl->root_component = 0;
98 impl->components = pvl_newlist(); 111 impl->components = pvl_newlist();
99 impl->level = 0; 112 impl->level = 0;
100 impl->state = ICALPARSER_SUCCESS; 113 impl->state = ICALPARSER_SUCCESS;
101 impl->tmp_buf_size = TMP_BUF_SIZE; 114 impl->tmp_buf_size = TMP_BUF_SIZE;
102 impl->buffer_full = 0; 115 impl->buffer_full = 0;
116 impl->continuation_line = 0;
103 impl->lineno = 0; 117 impl->lineno = 0;
104 impl->continuation_line = 0; 118 impl->continuation_line = 0;
105 memset(impl->temp,0, TMP_BUF_SIZE); 119 memset(impl->temp,0, TMP_BUF_SIZE);
106 120
107 return (icalparser*)impl; 121 return (icalparser*)impl;
108} 122}
109 123
110 124
111void icalparser_free(icalparser* parser) 125void icalparser_free(icalparser* parser)
112{ 126{
113 struct icalparser_impl* impl = (struct icalparser_impl*)parser;
114 icalcomponent *c; 127 icalcomponent *c;
115 128
116 if (impl->root_component != 0){ 129 if (parser->root_component != 0){
117 icalcomponent_free(impl->root_component); 130 icalcomponent_free(parser->root_component);
118 } 131 }
119 132
120 while( (c=pvl_pop(impl->components)) != 0){ 133 while( (c=pvl_pop(parser->components)) != 0){
121 icalcomponent_free(c); 134 icalcomponent_free(c);
122 } 135 }
123 136
124 pvl_free(impl->components); 137 pvl_free(parser->components);
125 138
126 free(impl); 139 free(parser);
127} 140}
128 141
129void icalparser_set_gen_data(icalparser* parser, void* data) 142void icalparser_set_gen_data(icalparser* parser, void* data)
130{ 143{
131 struct icalparser_impl* impl = (struct icalparser_impl*)parser; 144 parser->line_gen_data = data;
132
133 impl->line_gen_data = data;
134} 145}
135 146
136 147
137icalvalue* icalvalue_new_From_string_with_error(icalvalue_kind kind, 148icalvalue* icalvalue_new_From_string_with_error(icalvalue_kind kind,
138 char* str, 149 char* str,
139 icalproperty **error); 150 icalproperty **error);
140 151
141 152
142 153
143char* icalparser_get_next_char(char c, char *str) 154char* icalparser_get_next_char(char c, char *str, int qm)
144{ 155{
145 int quote_mode = 0; 156 int quote_mode = 0;
146 char* p; 157 char* p;
147 158
148
149 for(p=str; *p!=0; p++){ 159 for(p=str; *p!=0; p++){
150 160 if (qm == 1) {
151 if ( quote_mode == 0 && *p=='"' && *(p-1) != '\\' ){ 161 if ( quote_mode == 0 && *p=='"' && *(p-1) != '\\' ){
152 quote_mode =1; 162 quote_mode =1;
153 continue; 163 continue;
154 } 164 }
155 165
156 if ( quote_mode == 1 && *p=='"' && *(p-1) != '\\' ){ 166 if ( quote_mode == 1 && *p=='"' && *(p-1) != '\\' ){
157 quote_mode =0; 167 quote_mode =0;
158 continue; 168 continue;
159 } 169 }
170 }
160 171
161 if (quote_mode == 0 && *p== c && *(p-1) != '\\' ){ 172 if (quote_mode == 0 && *p== c && *(p-1) != '\\' ){
162 return p; 173 return p;
163 } 174 }
164 175
165 } 176 }
166 177
167 return 0; 178 return 0;
168} 179}
169 180
170/* make a new tmp buffer out of a substring */ 181
171char* make_segment(char* start, char* end) 182/** make a new tmp buffer out of a substring */
183static char* make_segment(char* start, char* end)
172{ 184{
173 char *buf; 185 char *buf, *tmp;
174 size_t size = (size_t)end - (size_t)start; 186 size_t size = (size_t)end - (size_t)start;
175 187
176 buf = icalmemory_tmp_buffer(size+1); 188 buf = icalmemory_tmp_buffer(size+1);
177 189
178 190
179 strncpy(buf,start,size); 191 strncpy(buf,start,size);
180 *(buf+size) = 0; 192 *(buf+size) = 0;
181 193
182 return buf; 194 tmp = (buf+size);
183 195 while ( *tmp == '\0' || iswspace(*tmp) )
184}
185
186const char* input_buffer;
187const char* input_buffer_p;
188//#define min(a,b) ((a) < (b) ? (a) : (b))
189
190int icalparser_flex_input(char* buf, int max_size)
191{
192 int n = max_size; // = min(max_size,strlen(input_buffer_p));
193 if ( n < ((int )strlen(input_buffer_p)) )
194 n = strlen(input_buffer_p);
195 if (n > 0){
196 memcpy(buf, input_buffer_p, n);
197 input_buffer_p += n;
198 return n;
199 } else {
200 return 0;
201 }
202}
203
204void icalparser_clear_flex_input(void)
205{ 196{
206 input_buffer_p = input_buffer+strlen(input_buffer); 197 *tmp = 0;
198 tmp--;
207} 199}
208 200
209/* Call the flex/bison parser to parse a complex value */ 201 return buf;
210
211icalvalue* icalparser_parse_value(icalvalue_kind kind,
212 const char* str, icalproperty** error)
213{
214 int r;
215 input_buffer_p = input_buffer = str;
216
217 set_parser_value_state(kind);
218 icalparser_yy_value = 0;
219
220 r = ical_yyparse();
221
222 /* Error. Parse failed */
223 if( icalparser_yy_value == 0 || r != 0){
224
225 if(icalparser_yy_value !=0){
226 icalvalue_free(icalparser_yy_value);
227 icalparser_yy_value = 0;
228 }
229
230 return 0;
231 }
232
233 if (error != 0){
234 *error = 0;
235 } 202 }
236 203
237 return icalparser_yy_value;
238}
239 204
240char* icalparser_get_prop_name(char* line, char** end) 205char* icalparser_get_prop_name(char* line, char** end)
241{ 206{
242 char* p; 207 char* p;
243 char* v; 208 char* v;
244 char *str; 209 char *str;
245 210
246 p = icalparser_get_next_char(';',line); 211 p = icalparser_get_next_char(';',line,1);
247 v = icalparser_get_next_char(':',line); 212 v = icalparser_get_next_char(':',line,1);
248 if (p== 0 && v == 0) { 213 if (p== 0 && v == 0) {
249 return 0; 214 return 0;
250 } 215 }
251 216
252 /* There is no ';' or, it is after the ';' that marks the beginning of 217 /* There is no ';' or, it is after the ';' that marks the beginning of
253 the value */ 218 the value */
254 if (v!=0 && ( p == 0 || p > v)){ 219 if (v!=0 && ( p == 0 || p > v)){
255 str = make_segment(line,v); 220 str = make_segment(line,v);
@@ -257,73 +222,83 @@ char* icalparser_get_prop_name(char* line, char** end)
257 } else { 222 } else {
258 str = make_segment(line,p); 223 str = make_segment(line,p);
259 *end = p+1; 224 *end = p+1;
260 } 225 }
261 226
262 return str; 227 return str;
263} 228}
264 229
230
265char* icalparser_get_param_name(char* line, char **end) 231char* icalparser_get_param_name(char* line, char **end)
266{ 232{
267
268 char* next; 233 char* next;
269 char *str; 234 char *str;
270 235
271 next = icalparser_get_next_char('=',line); 236 next = icalparser_get_next_char('=',line,1);
272 237
273 if (next == 0) { 238 if (next == 0) {
274 return 0; 239 return 0;
275 } 240 }
276 241
277 str = make_segment(line,next); 242 str = make_segment(line,next);
278 *end = next+1; 243 *end = next+1;
279 return str; 244 if (**end == '"') {
245 *end = *end+1;
246 next = icalparser_get_next_char('"',*end,0);
247 if (next == 0) {
248 return 0;
249 }
280 250
251 *end = make_segment(*end,next);
252 }
253
254 return str;
281} 255}
282 256
257
283char* icalparser_get_next_paramvalue(char* line, char **end) 258char* icalparser_get_next_paramvalue(char* line, char **end)
284{ 259{
285
286 char* next; 260 char* next;
287 char *str; 261 char *str;
288 262
289 next = icalparser_get_next_char(',',line); 263 next = icalparser_get_next_char(',',line,1);
290 264
291 if (next == 0){ 265 if (next == 0){
292 next = (char*)(size_t)line+(size_t)strlen(line);\ 266 next = (char*)(size_t)line+(size_t)strlen(line);\
293 } 267 }
294 268
295 if (next == line){ 269 if (next == line){
296 return 0; 270 return 0;
297 } else { 271 } else {
298 str = make_segment(line,next); 272 str = make_segment(line,next);
299 *end = next+1; 273 *end = next+1;
300 return str; 274 return str;
301 } 275 }
302
303} 276}
304 277
305/* A property may have multiple values, if the values are seperated by 278
279/**
280 A property may have multiple values, if the values are seperated by
306 commas in the content line. This routine will look for the next 281 commas in the content line. This routine will look for the next
307 comma after line and will set the next place to start searching in 282 comma after line and will set the next place to start searching in
308 end. */ 283 end. */
309 284
310char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind) 285char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind)
311{ 286{
312 287
313 char* next; 288 char* next;
314 char *p; 289 char *p;
315 char *str; 290 char *str;
316 size_t length = strlen(line); 291 size_t length = strlen(line);
317 292
318 p = line; 293 p = line;
319 while(1){ 294 while(1){
320 295
321 next = icalparser_get_next_char(',',p); 296 next = icalparser_get_next_char(',',p,1);
322 297
323 /* Unforunately, RFC2445 says that for the RECUR value, COMMA 298 /* Unforunately, RFC2445 says that for the RECUR value, COMMA
324 can both seperate digits in a list, and it can seperate 299 can both seperate digits in a list, and it can seperate
325 multiple recurrence specifications. This is not a friendly 300 multiple recurrence specifications. This is not a friendly
326 part of the spec. This weirdness tries to 301 part of the spec. This weirdness tries to
327 distinguish the two uses. it is probably a HACK*/ 302 distinguish the two uses. it is probably a HACK*/
328 303
329 if( kind == ICAL_RECUR_VALUE ) { 304 if( kind == ICAL_RECUR_VALUE ) {
@@ -335,16 +310,25 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind)
335 /* Fall through */ 310 /* Fall through */
336 } else if (next != 0){ 311 } else if (next != 0){
337 /* Not real, get the next COMMA */ 312 /* Not real, get the next COMMA */
338 p = next+1; 313 p = next+1;
339 next = 0; 314 next = 0;
340 continue; 315 continue;
341 } 316 }
342 } 317 }
318 /* ignore all , for query value. select dtstart, dtend etc ... */
319 else if( kind == ICAL_QUERY_VALUE) {
320 if ( next != 0) {
321 p = next+1;
322 continue;
323 }
324 else
325 break;
326 }
343 327
344 /* If the comma is preceeded by a '\', then it is a literal and 328 /* If the comma is preceeded by a '\', then it is a literal and
345 not a value seperator*/ 329 not a value seperator*/
346 330
347 if ( (next!=0 && *(next-1) == '\\') || 331 if ( (next!=0 && *(next-1) == '\\') ||
348 (next!=0 && *(next-3) == '\\') 332 (next!=0 && *(next-3) == '\\')
349 ) 333 )
350 /*second clause for '/' is on prev line. HACK may be out of bounds */ 334 /*second clause for '/' is on prev line. HACK may be out of bounds */
@@ -374,109 +358,109 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind)
374} 358}
375 359
376char* icalparser_get_next_parameter(char* line,char** end) 360char* icalparser_get_next_parameter(char* line,char** end)
377{ 361{
378 char *next; 362 char *next;
379 char *v; 363 char *v;
380 char *str; 364 char *str;
381 365
382 v = icalparser_get_next_char(':',line); 366 v = icalparser_get_next_char(':',line,1);
383 next = icalparser_get_next_char(';', line); 367 next = icalparser_get_next_char(';', line,1);
384 368
385 /* There is no ';' or, it is after the ':' that marks the beginning of 369 /* There is no ';' or, it is after the ':' that marks the beginning of
386 the value */ 370 the value */
387 371
388 if (next == 0 || next > v) { 372 if (next == 0 || next > v) {
389 next = icalparser_get_next_char(':', line); 373 next = icalparser_get_next_char(':', line,1);
390 } 374 }
391 375
392 if (next != 0) { 376 if (next != 0) {
393 str = make_segment(line,next); 377 str = make_segment(line,next);
394 *end = next+1; 378 *end = next+1;
395 return str; 379 return str;
396 } else { 380 } else {
397 *end = line; 381 *end = line;
398 return 0; 382 return 0;
399 } 383 }
400} 384}
401 385
402/* Get a single property line, from the property name through the
403 final new line, and include any continuation lines */
404 386
387/**
388 * Get a single property line, from the property name through the
389 * final new line, and include any continuation lines
390 */
405char* icalparser_get_line(icalparser *parser, 391char* icalparser_get_line(icalparser *parser,
406 char* (*line_gen_func)(char *s, size_t size, void *d)) 392 char* (*line_gen_func)(char *s, size_t size, void *d))
407{ 393{
408 char *line; 394 char *line;
409 char *line_p; 395 char *line_p;
410 struct icalparser_impl* impl = (struct icalparser_impl*)parser; 396 size_t buf_size = parser->tmp_buf_size;
411 size_t buf_size = impl->tmp_buf_size;
412
413 397
414 line_p = line = icalmemory_new_buffer(buf_size); 398 line_p = line = icalmemory_new_buffer(buf_size);
415 line[0] = '\0'; 399 line[0] = '\0';
416 400
417 /* Read lines by calling line_gen_func and putting the data into 401 /* Read lines by calling line_gen_func and putting the data into
418 impl->temp. If the line is a continuation line ( begins with a 402 parser->temp. If the line is a continuation line ( begins with a
419 space after a newline ) then append the data onto line and read 403 space after a newline ) then append the data onto line and read
420 again. Otherwise, exit the loop. */ 404 again. Otherwise, exit the loop. */
421 405
422 while(1) { 406 while(1) {
423 407
424 /* The first part of the loop deals with the temp buffer, 408 /* The first part of the loop deals with the temp buffer,
425 which was read on he last pass through the loop. The 409 which was read on he last pass through the loop. The
426 routine is split like this because it has to read lone line 410 routine is split like this because it has to read lone line
427 ahead to determine if a line is a continuation line. */ 411 ahead to determine if a line is a continuation line. */
428 412
429 413
430 /* The tmp buffer is not clear, so transfer the data in it to the 414 /* The tmp buffer is not clear, so transfer the data in it to the
431 output. This may be left over from a previous call */ 415 output. This may be left over from a previous call */
432 if (impl->temp[0] != '\0' ) { 416 if (parser->temp[0] != '\0' ) {
433 417
434 /* If the last position in the temp buffer is occupied, 418 /* If the last position in the temp buffer is occupied,
435 mark the buffer as full. The means we will do another 419 mark the buffer as full. The means we will do another
436 read later, because the line is not finished */ 420 read later, because the line is not finished */
437 if (impl->temp[impl->tmp_buf_size-1] == 0 && 421 if (parser->temp[parser->tmp_buf_size-1] == 0 &&
438 impl->temp[impl->tmp_buf_size-2] != '\n'&& 422 parser->temp[parser->tmp_buf_size-2] != '\n'&&
439 impl->temp[impl->tmp_buf_size-2] != 0 ){ 423 parser->temp[parser->tmp_buf_size-2] != 0 ){
440 impl->buffer_full = 1; 424 parser->buffer_full = 1;
441 } else { 425 } else {
442 impl->buffer_full = 0; 426 parser->buffer_full = 0;
443 } 427 }
444 428
445 /* Copy the temp to the output and clear the temp buffer. */ 429 /* Copy the temp to the output and clear the temp buffer. */
446 if(impl->continuation_line==1){ 430 if(parser->continuation_line==1){
447 /* back up the pointer to erase the continuation characters */ 431 /* back up the pointer to erase the continuation characters */
448 impl->continuation_line = 0; 432 parser->continuation_line = 0;
449 line_p--; 433 line_p--;
450 434
451 if ( *(line_p-1) == '\r'){ 435 if ( *(line_p-1) == '\r'){
452 line_p--; 436 line_p--;
453 } 437 }
454 438
455 /* copy one space up to eliminate the leading space*/ 439 /* copy one space up to eliminate the leading space*/
456 icalmemory_append_string(&line,&line_p,&buf_size, 440 icalmemory_append_string(&line,&line_p,&buf_size,
457 impl->temp+1); 441 parser->temp+1);
458 442
459 } else { 443 } else {
460 icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); 444 icalmemory_append_string(&line,&line_p,&buf_size,parser->temp);
461 } 445 }
462 446
463 impl->temp[0] = '\0' ; 447 parser->temp[0] = '\0' ;
464 } 448 }
465 449
466 impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */ 450 parser->temp[parser->tmp_buf_size-1] = 1; /* Mark end of buffer */
467 451
468 /****** Here is where the routine gets string data ******************/ 452 /****** Here is where the routine gets string data ******************/
469 if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data) 453 if ((*line_gen_func)(parser->temp,parser->tmp_buf_size,parser->line_gen_data)
470 ==0){/* Get more data */ 454 ==0){/* Get more data */
471 455
472 /* If the first position is clear, it means we didn't get 456 /* If the first position is clear, it means we didn't get
473 any more data from the last call to line_ge_func*/ 457 any more data from the last call to line_ge_func*/
474 if (impl->temp[0] == '\0'){ 458 if (parser->temp[0] == '\0'){
475 459
476 if(line[0] != '\0'){ 460 if(line[0] != '\0'){
477 /* There is data in the output, so fall trhough and process it*/ 461 /* There is data in the output, so fall trhough and process it*/
478 break; 462 break;
479 } else { 463 } else {
480 /* No data in output; return and signal that there 464 /* No data in output; return and signal that there
481 is no more input*/ 465 is no more input*/
482 free(line); 466 free(line);
@@ -485,22 +469,21 @@ char* icalparser_get_line(icalparser *parser,
485 } 469 }
486 } 470 }
487 471
488 472
489 /* If the output line ends in a '\n' and the temp buffer 473 /* If the output line ends in a '\n' and the temp buffer
490 begins with a ' ', then the buffer holds a continuation 474 begins with a ' ', then the buffer holds a continuation
491 line, so keep reading. */ 475 line, so keep reading. */
492 476
493 if ( line_p > line+1 && *(line_p-1) == '\n' 477 if ( line_p > line+1 && *(line_p-1) == '\n' && parser->temp[0] == ' ') {
494 && (impl->temp[0] == ' ' || impl->temp[0] == '\t') ) {
495 478
496 impl->continuation_line = 1; 479 parser->continuation_line = 1;
497 480
498 } else if ( impl->buffer_full == 1 ) { 481 } else if ( parser->buffer_full == 1 ) {
499 482
500 /* The buffer was filled on the last read, so read again */ 483 /* The buffer was filled on the last read, so read again */
501 484
502 } else { 485 } else {
503 486
504 /* Looks like the end of this content line, so break */ 487 /* Looks like the end of this content line, so break */
505 break; 488 break;
506 } 489 }
@@ -514,21 +497,27 @@ char* icalparser_get_line(icalparser *parser,
514 if ( *(line_p-2) == '\r'){ 497 if ( *(line_p-2) == '\r'){
515 *(line_p-2) = '\0'; 498 *(line_p-2) = '\0';
516 } 499 }
517 500
518 } else { 501 } else {
519 *(line_p) = '\0'; 502 *(line_p) = '\0';
520 } 503 }
521 504
505 while ( (*line_p == '\0' || iswspace(*line_p)) && line_p > line )
506 {
507 *line_p = '\0';
508 line_p--;
509 }
510
522 return line; 511 return line;
523 512
524} 513}
525 514
526void insert_error(icalcomponent* comp, char* text, 515static void insert_error(icalcomponent* comp, char* text,
527 char* message, icalparameter_xlicerrortype type) 516 char* message, icalparameter_xlicerrortype type)
528{ 517{
529 char temp[1024]; 518 char temp[1024];
530 519
531 if (text == 0){ 520 if (text == 0){
532 snprintf(temp,1024,"%s:",message); 521 snprintf(temp,1024,"%s:",message);
533 } else { 522 } else {
534 snprintf(temp,1024,"%s: %s",message,text); 523 snprintf(temp,1024,"%s: %s",message,text);
@@ -537,17 +526,18 @@ void insert_error(icalcomponent* comp, char* text,
537 icalcomponent_add_property 526 icalcomponent_add_property
538 (comp, 527 (comp,
539 icalproperty_vanew_xlicerror( 528 icalproperty_vanew_xlicerror(
540 temp, 529 temp,
541 icalparameter_new_xlicerrortype(type), 530 icalparameter_new_xlicerrortype(type),
542 0)); 531 0));
543} 532}
544 533
545int line_is_blank(char* line){ 534
535static int line_is_blank(char* line){
546 int i=0; 536 int i=0;
547 537
548 for(i=0; *(line+i)!=0; i++){ 538 for(i=0; *(line+i)!=0; i++){
549 char c = *(line+i); 539 char c = *(line+i);
550 540
551 if(c != ' ' && c != '\n' && c != '\t'){ 541 if(c != ' ' && c != '\n' && c != '\t'){
552 return 0; 542 return 0;
553 } 543 }
@@ -559,34 +549,34 @@ int line_is_blank(char* line){
559icalcomponent* icalparser_parse(icalparser *parser, 549icalcomponent* icalparser_parse(icalparser *parser,
560 char* (*line_gen_func)(char *s, size_t size, 550 char* (*line_gen_func)(char *s, size_t size,
561 void* d)) 551 void* d))
562{ 552{
563 553
564 char* line; 554 char* line;
565 icalcomponent *c=0; 555 icalcomponent *c=0;
566 icalcomponent *root=0; 556 icalcomponent *root=0;
567 struct icalparser_impl *impl = (struct icalparser_impl*)parser;
568 icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); 557 icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR);
558 int cont;
569 559
570 icalerror_check_arg_rz((parser !=0),"parser"); 560 icalerror_check_arg_rz((parser !=0),"parser");
571 561
572 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); 562 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL);
573 563
574 do{ 564 do{
575 line = icalparser_get_line(parser, line_gen_func); 565 line = icalparser_get_line(parser, line_gen_func);
576 566
577 if ((c = icalparser_add_line(parser,line)) != 0){ 567 if ((c = icalparser_add_line(parser,line)) != 0){
578 568
579 if(icalcomponent_get_parent(c) !=0){ 569 if(icalcomponent_get_parent(c) !=0){
580 /* This is bad news... assert? */ 570 /* This is bad news... assert? */
581 } 571 }
582 572
583 assert(impl->root_component == 0); 573 assert(parser->root_component == 0);
584 assert(pvl_count(impl->components) ==0); 574 assert(pvl_count(parser->components) ==0);
585 575
586 if (root == 0){ 576 if (root == 0){
587 /* Just one component */ 577 /* Just one component */
588 root = c; 578 root = c;
589 } else if(icalcomponent_isa(root) != ICAL_XROOT_COMPONENT) { 579 } else if(icalcomponent_isa(root) != ICAL_XROOT_COMPONENT) {
590 /*Got a second component, so move the two components under 580 /*Got a second component, so move the two components under
591 an XROOT container */ 581 an XROOT container */
592 icalcomponent *tempc = icalcomponent_new(ICAL_XROOT_COMPONENT); 582 icalcomponent *tempc = icalcomponent_new(ICAL_XROOT_COMPONENT);
@@ -601,48 +591,48 @@ icalcomponent* icalparser_parse(icalparser *parser,
601 } else { 591 } else {
602 /* Badness */ 592 /* Badness */
603 assert(0); 593 assert(0);
604 } 594 }
605 595
606 c = 0; 596 c = 0;
607 597
608 } 598 }
599 cont = 0;
609 if(line != 0){ 600 if(line != 0){
610 free(line); 601 free(line);
602 cont = 1;
611 } 603 }
612 } while ( line != 0); 604 } while ( cont );
613 605
614 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); 606 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es);
615 607
616 return root; 608 return root;
617 609
618} 610}
619 611
620 612
621icalcomponent* icalparser_add_line(icalparser* parser, 613icalcomponent* icalparser_add_line(icalparser* parser,
622 char* line) 614 char* line)
623{ 615{
624 char *p;
625 char *str; 616 char *str;
626 char *end; 617 char *end;
627 int vcount = 0; 618 int vcount = 0;
628 icalproperty *prop; 619 icalproperty *prop;
629 icalproperty_kind prop_kind; 620 icalproperty_kind prop_kind;
630 icalvalue *value; 621 icalvalue *value;
631 icalvalue_kind value_kind = ICAL_NO_VALUE; 622 icalvalue_kind value_kind = ICAL_NO_VALUE;
632 623
633 624
634 struct icalparser_impl *impl = (struct icalparser_impl*)parser;
635 icalerror_check_arg_rz((parser != 0),"parser"); 625 icalerror_check_arg_rz((parser != 0),"parser");
636 626
637 627
638 if (line == 0) 628 if (line == 0)
639 { 629 {
640 impl->state = ICALPARSER_ERROR; 630 parser->state = ICALPARSER_ERROR;
641 return 0; 631 return 0;
642 } 632 }
643 633
644 if(line_is_blank(line) == 1){ 634 if(line_is_blank(line) == 1){
645 return 0; 635 return 0;
646 } 636 }
647 637
648 /* Begin by getting the property name at the start of the line. The 638 /* Begin by getting the property name at the start of the line. The
@@ -650,110 +640,115 @@ icalcomponent* icalparser_add_line(icalparser* parser,
650 is not really a property, but the marker for the start or end of 640 is not really a property, but the marker for the start or end of
651 a component */ 641 a component */
652 642
653 end = 0; 643 end = 0;
654 str = icalparser_get_prop_name(line, &end); 644 str = icalparser_get_prop_name(line, &end);
655 645
656 if (str == 0 || strlen(str) == 0 ){ 646 if (str == 0 || strlen(str) == 0 ){
657 /* Could not get a property name */ 647 /* Could not get a property name */
658 icalcomponent *tail = pvl_data(pvl_tail(impl->components)); 648 icalcomponent *tail = pvl_data(pvl_tail(parser->components));
659 649
660 if (tail){ 650 if (tail){
661 insert_error(tail,line, 651 insert_error(tail,line,
662 "Got a data line, but could not find a property name or component begin tag", 652 "Got a data line, but could not find a property name or component begin tag",
663 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); 653 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
664 } 654 }
665 tail = 0; 655 tail = 0;
666 impl->state = ICALPARSER_ERROR; 656 parser->state = ICALPARSER_ERROR;
667 return 0; 657 return 0;
668 } 658 }
669 659
670 /********************************************************************** 660 /**********************************************************************
671 * Handle begin and end of components 661 * Handle begin and end of components
672 **********************************************************************/ 662 **********************************************************************/
673 /* If the property name is BEGIN or END, we are actually 663 /* If the property name is BEGIN or END, we are actually
674 starting or ending a new component */ 664 starting or ending a new component */
675 665
666
676 if(strcmp(str,"BEGIN") == 0){ 667 if(strcmp(str,"BEGIN") == 0){
677 icalcomponent *c; 668 icalcomponent *c;
678 icalcomponent_kind comp_kind; 669 icalcomponent_kind comp_kind;
679 670
680 impl->level++; 671
672 parser->level++;
681 str = icalparser_get_next_value(end,&end, value_kind); 673 str = icalparser_get_next_value(end,&end, value_kind);
682 674
683 675
684 comp_kind = icalenum_string_to_component_kind(str); 676 comp_kind = icalenum_string_to_component_kind(str);
685 677
678
686 if (comp_kind == ICAL_NO_COMPONENT){ 679 if (comp_kind == ICAL_NO_COMPONENT){
680
681
687 c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); 682 c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
688 insert_error(c,str,"Parse error in component name", 683 insert_error(c,str,"Parse error in component name",
689 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); 684 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
690 } 685 }
691 686
692 c = icalcomponent_new(comp_kind); 687 c = icalcomponent_new(comp_kind);
693 688
694 if (c == 0){ 689 if (c == 0){
695 c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); 690 c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
696 insert_error(c,str,"Parse error in component name", 691 insert_error(c,str,"Parse error in component name",
697 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); 692 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
698 } 693 }
699 694
700 pvl_push(impl->components,c); 695 pvl_push(parser->components,c);
701 696
702 impl->state = ICALPARSER_BEGIN_COMP; 697 parser->state = ICALPARSER_BEGIN_COMP;
703 return 0; 698 return 0;
704 699
705 } else if (strcmp(str,"END") == 0 ) { 700 } else if (strcmp(str,"END") == 0 ) {
706 icalcomponent* tail; 701 icalcomponent* tail;
707 702
708 impl->level--; 703 parser->level--;
709 str = icalparser_get_next_value(end,&end, value_kind); 704 str = icalparser_get_next_value(end,&end, value_kind);
710 705
711 /* Pop last component off of list and add it to the second-to-last*/ 706 /* Pop last component off of list and add it to the second-to-last*/
712 impl->root_component = pvl_pop(impl->components); 707 parser->root_component = pvl_pop(parser->components);
713 708
714 tail = pvl_data(pvl_tail(impl->components)); 709 tail = pvl_data(pvl_tail(parser->components));
715 710
716 if(tail != 0){ 711 if(tail != 0){
717 icalcomponent_add_component(tail,impl->root_component); 712 icalcomponent_add_component(tail,parser->root_component);
718 } 713 }
719 714
720 tail = 0; 715 tail = 0;
721 716
722 /* Return the component if we are back to the 0th level */ 717 /* Return the component if we are back to the 0th level */
723 if (impl->level == 0){ 718 if (parser->level == 0){
724 icalcomponent *rtrn; 719 icalcomponent *rtrn;
725 720
726 if(pvl_count(impl->components) != 0){ 721 if(pvl_count(parser->components) != 0){
727 /* There are still components on the stack -- this means 722 /* There are still components on the stack -- this means
728 that one of them did not have a proper "END" */ 723 that one of them did not have a proper "END" */
729 pvl_push(impl->components,impl->root_component); 724 pvl_push(parser->components,parser->root_component);
730 icalparser_clean(parser); /* may reset impl->root_component*/ 725 icalparser_clean(parser); /* may reset parser->root_component*/
731 } 726 }
732 727
733 assert(pvl_count(impl->components) == 0); 728 assert(pvl_count(parser->components) == 0);
734 729
735 impl->state = ICALPARSER_SUCCESS; 730 parser->state = ICALPARSER_SUCCESS;
736 rtrn = impl->root_component; 731 rtrn = parser->root_component;
737 impl->root_component = 0; 732 parser->root_component = 0;
738 return rtrn; 733 return rtrn;
739 734
740 } else { 735 } else {
741 impl->state = ICALPARSER_END_COMP; 736 parser->state = ICALPARSER_END_COMP;
742 return 0; 737 return 0;
743 } 738 }
744 } 739 }
745 740
746 741
747 /* There is no point in continuing if we have not seen a 742 /* There is no point in continuing if we have not seen a
748 component yet */ 743 component yet */
749 744
750 if(pvl_data(pvl_tail(impl->components)) == 0){ 745 if(pvl_data(pvl_tail(parser->components)) == 0){
751 impl->state = ICALPARSER_ERROR; 746 parser->state = ICALPARSER_ERROR;
752 return 0; 747 return 0;
753 } 748 }
754 749
755 750
756 /********************************************************************** 751 /**********************************************************************
757 * Handle property names 752 * Handle property names
758 **********************************************************************/ 753 **********************************************************************/
759 754
@@ -762,46 +757,45 @@ icalcomponent* icalparser_add_line(icalparser* parser,
762 the component */ 757 the component */
763 758
764 759
765 prop_kind = icalproperty_string_to_kind(str); 760 prop_kind = icalproperty_string_to_kind(str);
766 761
767 prop = icalproperty_new(prop_kind); 762 prop = icalproperty_new(prop_kind);
768 763
769 if (prop != 0){ 764 if (prop != 0){
770 icalcomponent *tail = pvl_data(pvl_tail(impl->components)); 765 icalcomponent *tail = pvl_data(pvl_tail(parser->components));
771 766
772 if(prop_kind==ICAL_X_PROPERTY){ 767 if(prop_kind==ICAL_X_PROPERTY){
773 icalproperty_set_x_name(prop,str); 768 icalproperty_set_x_name(prop,str);
774 } 769 }
775 770
776 icalcomponent_add_property(tail, prop); 771 icalcomponent_add_property(tail, prop);
777 772
778 /* Set the value kind for the default for this type of 773 /* Set the value kind for the default for this type of
779 property. This may be re-set by a VALUE parameter */ 774 property. This may be re-set by a VALUE parameter */
780 value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop)); 775 value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop));
781 776
782 } else { 777 } else {
783 icalcomponent* tail = pvl_data(pvl_tail(impl->components)); 778 icalcomponent* tail = pvl_data(pvl_tail(parser->components));
784 779
785 insert_error(tail,str,"Parse error in property name", 780 insert_error(tail,str,"Parse error in property name",
786 ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); 781 ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);
787 782
788 tail = 0; 783 tail = 0;
789 impl->state = ICALPARSER_ERROR; 784 parser->state = ICALPARSER_ERROR;
790 return 0; 785 return 0;
791 } 786 }
792 787
793 /********************************************************************** 788 /**********************************************************************
794 * Handle parameter values 789 * Handle parameter values
795 **********************************************************************/ 790 **********************************************************************/
796 791
797 /* Now, add any parameters to the last property */ 792 /* Now, add any parameters to the last property */
798 793
799 p = 0;
800 while(1) { 794 while(1) {
801 795
802 if (*(end-1) == ':'){ 796 if (*(end-1) == ':'){
803 /* if the last seperator was a ":" and the value is a 797 /* if the last seperator was a ":" and the value is a
804 URL, icalparser_get_next_parameter will find the 798 URL, icalparser_get_next_parameter will find the
805 ':' in the URL, so better break now. */ 799 ':' in the URL, so better break now. */
806 break; 800 break;
807 } 801 }
@@ -809,17 +803,17 @@ icalcomponent* icalparser_add_line(icalparser* parser,
809 str = icalparser_get_next_parameter(end,&end); 803 str = icalparser_get_next_parameter(end,&end);
810 804
811 if (str != 0){ 805 if (str != 0){
812 char* name; 806 char* name;
813 char* pvalue; 807 char* pvalue;
814 808
815 icalparameter *param = 0; 809 icalparameter *param = 0;
816 icalparameter_kind kind; 810 icalparameter_kind kind;
817 icalcomponent *tail = pvl_data(pvl_tail(impl->components)); 811 icalcomponent *tail = pvl_data(pvl_tail(parser->components));
818 812
819 name = icalparser_get_param_name(str,&pvalue); 813 name = icalparser_get_param_name(str,&pvalue);
820 814
821 if (name == 0){ 815 if (name == 0){
822 /* 'tail' defined above */ 816 /* 'tail' defined above */
823 insert_error(tail, str, "Cant parse parameter name", 817 insert_error(tail, str, "Cant parse parameter name",
824 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); 818 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
825 tail = 0; 819 tail = 0;
@@ -840,27 +834,27 @@ icalcomponent* icalparser_add_line(icalparser* parser,
840 } else if (kind != ICAL_NO_PARAMETER){ 834 } else if (kind != ICAL_NO_PARAMETER){
841 param = icalparameter_new_from_value_string(kind,pvalue); 835 param = icalparameter_new_from_value_string(kind,pvalue);
842 } else { 836 } else {
843 /* Error. Failed to parse the parameter*/ 837 /* Error. Failed to parse the parameter*/
844 /* 'tail' defined above */ 838 /* 'tail' defined above */
845 insert_error(tail, str, "Cant parse parameter name", 839 insert_error(tail, str, "Cant parse parameter name",
846 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); 840 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
847 tail = 0; 841 tail = 0;
848 impl->state = ICALPARSER_ERROR; 842 parser->state = ICALPARSER_ERROR;
849 return 0; 843 return 0;
850 } 844 }
851 845
852 if (param == 0){ 846 if (param == 0){
853 /* 'tail' defined above */ 847 /* 'tail' defined above */
854 insert_error(tail,str,"Cant parse parameter value", 848 insert_error(tail,str,"Cant parse parameter value",
855 ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); 849 ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
856 850
857 tail = 0; 851 tail = 0;
858 impl->state = ICALPARSER_ERROR; 852 parser->state = ICALPARSER_ERROR;
859 continue; 853 continue;
860 } 854 }
861 855
862 /* If it is a VALUE parameter, set the kind of value*/ 856 /* If it is a VALUE parameter, set the kind of value*/
863 if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ 857 if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){
864 858
865 value_kind = (icalvalue_kind) 859 value_kind = (icalvalue_kind)
866 icalparameter_value_to_value_kind( 860 icalparameter_value_to_value_kind(
@@ -880,17 +874,17 @@ icalcomponent* icalparser_add_line(icalparser* parser,
880 icalparameter_free(param); 874 icalparameter_free(param);
881 875
882 value_kind = 876 value_kind =
883 icalproperty_kind_to_value_kind( 877 icalproperty_kind_to_value_kind(
884 icalproperty_isa(prop)); 878 icalproperty_isa(prop));
885 879
886 icalparameter_free(param); 880 icalparameter_free(param);
887 tail = 0; 881 tail = 0;
888 impl->state = ICALPARSER_ERROR; 882 parser->state = ICALPARSER_ERROR;
889 return 0; 883 return 0;
890 } 884 }
891 } 885 }
892 886
893 /* Everything is OK, so add the parameter */ 887 /* Everything is OK, so add the parameter */
894 icalproperty_add_parameter(prop,param); 888 icalproperty_add_parameter(prop,param);
895 tail = 0; 889 tail = 0;
896 890
@@ -914,144 +908,143 @@ icalcomponent* icalparser_add_line(icalparser* parser,
914 while(1) { 908 while(1) {
915 str = icalparser_get_next_value(end,&end, value_kind); 909 str = icalparser_get_next_value(end,&end, value_kind);
916 910
917 if (str != 0){ 911 if (str != 0){
918 912
919 if (vcount > 0){ 913 if (vcount > 0){
920 /* Actually, only clone after the second value */ 914 /* Actually, only clone after the second value */
921 icalproperty* clone = icalproperty_new_clone(prop); 915 icalproperty* clone = icalproperty_new_clone(prop);
922 icalcomponent* tail = pvl_data(pvl_tail(impl->components)); 916 icalcomponent* tail = pvl_data(pvl_tail(parser->components));
923 917
924 icalcomponent_add_property(tail, clone); 918 icalcomponent_add_property(tail, clone);
925 prop = clone; 919 prop = clone;
926 tail = 0; 920 tail = 0;
927 } 921 }
928 922
929 value = icalvalue_new_from_string(value_kind, str); 923 value = icalvalue_new_from_string(value_kind, str);
930 924
931 /* Don't add properties without value */ 925 /* Don't add properties without value */
932 if (value == 0){ 926 if (value == 0){
933 char temp[200]; /* HACK */ 927 char temp[200]; /* HACK */
934 928
935 icalproperty_kind prop_kind = icalproperty_isa(prop); 929 icalproperty_kind prop_kind = icalproperty_isa(prop);
936 icalcomponent* tail = pvl_data(pvl_tail(impl->components)); 930 icalcomponent* tail = pvl_data(pvl_tail(parser->components));
937 931
938 sprintf(temp,"Cant parse as %s value in %s property. Removing entire property", 932 sprintf(temp,"Cant parse as %s value in %s property. Removing entire property",
939 icalvalue_kind_to_string(value_kind), 933 icalvalue_kind_to_string(value_kind),
940 icalproperty_kind_to_string(prop_kind)); 934 icalproperty_kind_to_string(prop_kind));
941 935
942 insert_error(tail, str, temp, 936 insert_error(tail, str, temp,
943 ICAL_XLICERRORTYPE_VALUEPARSEERROR); 937 ICAL_XLICERRORTYPE_VALUEPARSEERROR);
944 938
945 /* Remove the troublesome property */ 939 /* Remove the troublesome property */
946 icalcomponent_remove_property(tail,prop); 940 icalcomponent_remove_property(tail,prop);
947 icalproperty_free(prop); 941 icalproperty_free(prop);
948 prop = 0; 942 prop = 0;
949 tail = 0; 943 tail = 0;
950 impl->state = ICALPARSER_ERROR; 944 parser->state = ICALPARSER_ERROR;
951 return 0; 945 return 0;
952 946
953 } else { 947 } else {
954 vcount++; 948 vcount++;
955 icalproperty_set_value(prop, value); 949 icalproperty_set_value(prop, value);
956 } 950 }
957 951
958 952
959 } else { 953 } else {
960 if (vcount == 0){ 954 if (vcount == 0){
961 char temp[200]; /* HACK */ 955 char temp[200]; /* HACK */
962 956
963 icalproperty_kind prop_kind = icalproperty_isa(prop); 957 icalproperty_kind prop_kind = icalproperty_isa(prop);
964 icalcomponent *tail = pvl_data(pvl_tail(impl->components)); 958 icalcomponent *tail = pvl_data(pvl_tail(parser->components));
965 959
966 sprintf(temp,"No value for %s property. Removing entire property", 960 sprintf(temp,"No value for %s property. Removing entire property",
967 icalproperty_kind_to_string(prop_kind)); 961 icalproperty_kind_to_string(prop_kind));
968 962
969 insert_error(tail, str, temp, 963 insert_error(tail, str, temp,
970 ICAL_XLICERRORTYPE_VALUEPARSEERROR); 964 ICAL_XLICERRORTYPE_VALUEPARSEERROR);
971 965
972 /* Remove the troublesome property */ 966 /* Remove the troublesome property */
973 icalcomponent_remove_property(tail,prop); 967 icalcomponent_remove_property(tail,prop);
974 icalproperty_free(prop); 968 icalproperty_free(prop);
975 prop = 0; 969 prop = 0;
976 tail = 0; 970 tail = 0;
977 impl->state = ICALPARSER_ERROR; 971 parser->state = ICALPARSER_ERROR;
978 return 0; 972 return 0;
979 } else { 973 } else {
980 974
981 break; 975 break;
982 } 976 }
983 } 977 }
984 } 978 }
985 979
986 /**************************************************************** 980 /****************************************************************
987 * End of component parsing. 981 * End of component parsing.
988 *****************************************************************/ 982 *****************************************************************/
989 983
990 if (pvl_data(pvl_tail(impl->components)) == 0 && 984 if (pvl_data(pvl_tail(parser->components)) == 0 &&
991 impl->level == 0){ 985 parser->level == 0){
992 /* HACK. Does this clause ever get executed? */ 986 /* HACK. Does this clause ever get executed? */
993 impl->state = ICALPARSER_SUCCESS; 987 parser->state = ICALPARSER_SUCCESS;
994 assert(0); 988 assert(0);
995 return impl->root_component; 989 return parser->root_component;
996 } else { 990 } else {
997 impl->state = ICALPARSER_IN_PROGRESS; 991 parser->state = ICALPARSER_IN_PROGRESS;
998 return 0; 992 return 0;
999 } 993 }
1000 994
1001} 995}
1002 996
1003icalparser_state icalparser_get_state(icalparser* parser) 997icalparser_state icalparser_get_state(icalparser* parser)
1004{ 998{
1005 struct icalparser_impl* impl = (struct icalparser_impl*) parser; 999 return parser->state;
1006 return impl->state;
1007 1000
1008} 1001}
1009 1002
1010icalcomponent* icalparser_clean(icalparser* parser) 1003icalcomponent* icalparser_clean(icalparser* parser)
1011{ 1004{
1012 struct icalparser_impl* impl = (struct icalparser_impl*) parser;
1013 icalcomponent *tail; 1005 icalcomponent *tail;
1014 1006
1015 icalerror_check_arg_rz((parser != 0 ),"parser"); 1007 icalerror_check_arg_rz((parser != 0 ),"parser");
1016 1008
1017 /* We won't get a clean exit if some components did not have an 1009 /* We won't get a clean exit if some components did not have an
1018 "END" tag. Clear off any component that may be left in the list */ 1010 "END" tag. Clear off any component that may be left in the list */
1019 1011
1020 while((tail=pvl_data(pvl_tail(impl->components))) != 0){ 1012 while((tail=pvl_data(pvl_tail(parser->components))) != 0){
1021 1013
1022 insert_error(tail," ", 1014 insert_error(tail," ",
1023 "Missing END tag for this component. Closing component at end of input.", 1015 "Missing END tag for this component. Closing component at end of input.",
1024 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); 1016 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
1025 1017
1026 1018
1027 impl->root_component = pvl_pop(impl->components); 1019 parser->root_component = pvl_pop(parser->components);
1028 tail=pvl_data(pvl_tail(impl->components)); 1020 tail=pvl_data(pvl_tail(parser->components));
1029 1021
1030 if(tail != 0){ 1022 if(tail != 0){
1031 if(icalcomponent_get_parent(impl->root_component)!=0){ 1023 if(icalcomponent_get_parent(parser->root_component)!=0){
1032 icalerror_warn("icalparser_clean is trying to attach a component for the second time"); 1024 icalerror_warn("icalparser_clean is trying to attach a component for the second time");
1033 } else { 1025 } else {
1034 icalcomponent_add_component(tail,impl->root_component); 1026 icalcomponent_add_component(tail,parser->root_component);
1035 } 1027 }
1036 } 1028 }
1037 1029
1038 } 1030 }
1039 1031
1040 return impl->root_component; 1032 return parser->root_component;
1041 1033
1042} 1034}
1043 1035
1044struct slg_data { 1036struct slg_data {
1045 const char* pos; 1037 const char* pos;
1046 const char* str; 1038 const char* str;
1047}; 1039};
1048 1040
1049char* string_line_generator(char *out, size_t buf_size, void *d) 1041
1042char* icalparser_string_line_generator(char *out, size_t buf_size, void *d)
1050{ 1043{
1051 char *n; 1044 char *n;
1052 size_t size; 1045 size_t size;
1053 struct slg_data* data = (struct slg_data*)d; 1046 struct slg_data* data = (struct slg_data*)d;
1054 1047
1055 if(data->pos==0){ 1048 if(data->pos==0){
1056 data->pos=data->str; 1049 data->pos=data->str;
1057 } 1050 }
@@ -1095,17 +1088,17 @@ icalcomponent* icalparser_parse_string(const char* str)
1095 d.pos = 0; 1088 d.pos = 0;
1096 d.str = str; 1089 d.str = str;
1097 1090
1098 p = icalparser_new(); 1091 p = icalparser_new();
1099 icalparser_set_gen_data(p,&d); 1092 icalparser_set_gen_data(p,&d);
1100 1093
1101 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); 1094 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL);
1102 1095
1103 c = icalparser_parse(p,string_line_generator); 1096 c = icalparser_parse(p,icalparser_string_line_generator);
1104 1097
1105 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); 1098 icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es);
1106 1099
1107 icalparser_free(p); 1100 icalparser_free(p);
1108 1101
1109 return c; 1102 return c;
1110 1103
1111} 1104}