aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libical/icalparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src/libical/icalparser.c')
-rw-r--r--libical/src/libical/icalparser.c963
1 files changed, 526 insertions, 437 deletions
diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c
index b4c1822a68..8541ae4fab 100644
--- a/libical/src/libical/icalparser.c
+++ b/libical/src/libical/icalparser.c
@@ -16,25 +16,30 @@
the License for the specific language governing rights and
limitations under the License.
- The Original Code is eric. The Initial Developer of the Original
- Code is
+ The Initial Developer of the Original Code is Eric Busboom
(C) COPYRIGHT 1999 The Software Studio.
http://www.softwarestudio.org
======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
#include "ical.h"
#include "pvl.h"
#include "icalparser.h"
#include "icalmemory.h"
-#include <string.h> /* For strncpy */
+#include <string.h> /* For strncpy & size_t */
#include <stdio.h> /* For FILE and fgets and sprintf */
#include <stdlib.h> /* for free */
extern icalvalue* icalparser_yy_value;
void set_parser_value_state(icalvalue_kind kind);
-int icalparser_yyparse(void);
+int ical_yy_parse(void);
char* icalparser_get_next_char(char c, char *str);
char* icalparser_get_next_parameter(char* line,char** end);
@@ -42,7 +47,77 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind);
char* icalparser_get_prop_name(char* line, char** end);
char* icalparser_get_param_name(char* line, char **end);
-icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind, char* str, icalproperty **error);
+#define TMP_BUF_SIZE 80
+
+struct icalparser_impl
+{
+ int buffer_full;
+ size_t tmp_buf_size;
+ char temp[TMP_BUF_SIZE];
+ icalcomponent *root_component;
+ icalcomponent *tail;
+ int version;
+ int level;
+ int lineno;
+ icalparser_state state;
+ pvl_list components;
+
+ void *line_gen_data;
+
+};
+
+
+icalparser* icalparser_new()
+{
+ struct icalparser_impl* impl = 0;
+
+ if ( ( impl = (struct icalparser_impl*)
+ malloc(sizeof(struct icalparser_impl))) == 0) {
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+
+ impl->root_component = 0;
+ impl->components = pvl_newlist();
+ impl->level = 0;
+ impl->state = ICALPARSER_SUCCESS;
+
+ impl->tmp_buf_size = TMP_BUF_SIZE;
+ impl->buffer_full = 0;
+ impl->lineno = 0;
+
+ memset(impl->temp,0, TMP_BUF_SIZE);
+
+ return (icalparser*)impl;
+}
+
+void icalparser_free(icalparser* parser)
+{
+ struct icalparser_impl* impl = (struct icalparser_impl*)parser;
+ icalcomponent *c;
+
+ if (impl->root_component != 0){
+ icalcomponent_free(impl->root_component);
+ }
+
+ while( (c=pvl_pop(impl->components)) != 0){
+ icalcomponent_free(c);
+ }
+
+ pvl_free(impl->components);
+}
+
+void icalparser_set_gen_data(icalparser* parser, void* data)
+{
+ struct icalparser_impl* impl = (struct icalparser_impl*)parser;
+
+ impl->line_gen_data = data;
+}
+
+
+icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,
+ char* str,
+ icalproperty **error);
@@ -114,7 +189,7 @@ void icalparser_clear_flex_input()
/* Cal the flex parser to parse a complex value */
icalvalue* icalparser_parse_value(icalvalue_kind kind,
- char* str, icalproperty** error)
+ char* str, icalproperty** error)
{
int r;
input_buffer_p = input_buffer = str;
@@ -122,7 +197,7 @@ icalvalue* icalparser_parse_value(icalvalue_kind kind,
set_parser_value_state(kind);
icalparser_yy_value = 0;
- r = icalparser_yyparse();
+ r = ical_yy_parse();
/* Error. Parse failed */
if( icalparser_yy_value == 0 || r != 0){
@@ -176,7 +251,7 @@ char* icalparser_get_param_name(char* line, char **end)
next = icalparser_get_next_char('=',line);
if (next == 0) {
- return 0;
+ return 0;
}
str = make_segment(line,next);
@@ -223,50 +298,50 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind)
p = line;
while(1){
- next = icalparser_get_next_char(',',p);
+ next = icalparser_get_next_char(',',p);
- /* Unforunately, RFC2445 says that for the RECUR value, COMMA
- can both seperate digits in a list, and it can seperate
- multiple recurrence specifications. This is not a friendly
- part of the spec. This weirdness tries to
- distinguish the two uses. it is probably a HACK*/
+ /* Unforunately, RFC2445 says that for the RECUR value, COMMA
+ can both seperate digits in a list, and it can seperate
+ multiple recurrence specifications. This is not a friendly
+ part of the spec. This weirdness tries to
+ distinguish the two uses. it is probably a HACK*/
- if( kind == ICAL_RECUR_VALUE ) {
- if ( next != 0 &&
- (*end+length) > next+5 &&
- strncmp(next,"FREQ",4) == 0
- ) {
- /* The COMMA was followed by 'FREQ', is it a real seperator*/
- /* Fall through */
- printf("%s\n",next);
- } else if (next != 0){
- /* Not real, get the next COMMA */
- p = next+1;
- next = 0;
- continue;
- }
- }
-
- /* If the comma is preceeded by a '\', then it is a literal and
- not a value seperator*/
+ if( kind == ICAL_RECUR_VALUE ) {
+ if ( next != 0 &&
+ (*end+length) > next+5 &&
+ strncmp(next,"FREQ",4) == 0
+ ) {
+ /* The COMMA was followed by 'FREQ', is it a real seperator*/
+ /* Fall through */
+ printf("%s\n",next);
+ } else if (next != 0){
+ /* Not real, get the next COMMA */
+ p = next+1;
+ next = 0;
+ continue;
+ }
+ }
+
+ /* If the comma is preceeded by a '\', then it is a literal and
+ not a value seperator*/
- if ( (next!=0 && *(next-1) == '\\') ||
- (next!=0 && *(next-3) == '\\')
- )
- /*second clause for '/' is on prev line. HACK may be out of bounds */
- {
- p = next+1;
- } else {
- break;
- }
+ if ( (next!=0 && *(next-1) == '\\') ||
+ (next!=0 && *(next-3) == '\\')
+ )
+ /*second clause for '/' is on prev line. HACK may be out of bounds */
+ {
+ p = next+1;
+ } else {
+ break;
+ }
}
if (next == 0){
next = (char*)(size_t)line+length;
- *end = next;
+ *end = next;
} else {
- *end = next+1;
+ *end = next+1;
}
if (next == line){
@@ -305,22 +380,18 @@ char* icalparser_get_next_parameter(char* line,char** end)
}
}
-/* HACK. This is not threadsafe */
-int buffer_full=0;
-size_t tmp_buf_size = 80;
-char temp[80];
-
-
/* Get a single property line, from the property name through the
final new line, and include any continuation lines */
-char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno)
+char* icalparser_get_line(icalparser *parser,
+ char* (*line_gen_func)(char *s, size_t size, void *d))
{
char *line;
char *line_p;
- size_t buf_size = tmp_buf_size;
-
+ struct icalparser_impl* impl = (struct icalparser_impl*)parser;
+ size_t buf_size = impl->tmp_buf_size;
+
line_p = line = icalmemory_new_buffer(buf_size);
line[0] = '\0';
@@ -328,43 +399,63 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d),
/* The buffer is not clear, so transfer the data in it to the
output. This may be left over from a previous call */
- if (temp[0] != '\0' ) {
- if (temp[tmp_buf_size-1] == 0){
- buffer_full = 1;
+ if (impl->temp[0] != '\0' ) {
+
+ /* If the last position in the temp buffer is occupied,
+ mark the buffer as full. The means we will do another
+ read later, because the line is not finished */
+ if (impl->temp[impl->tmp_buf_size-1] == 0){
+ impl->buffer_full = 1;
} else {
- buffer_full = 0;
+ impl->buffer_full = 0;
}
- icalmemory_append_string(&line,&line_p,&buf_size,temp);
- temp[0] = '\0' ;
+
+ /* Copy the temp to the output and clear the temp buffer. */
+ icalmemory_append_string(&line,&line_p,&buf_size,impl->temp);
+ impl->temp[0] = '\0' ;
}
- temp[tmp_buf_size-1] = 1; /* Mark end of buffer */
+ impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */
+
+ if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data)
+ ==0){/* Get more data */
+
+ /* If the first position is clear, it means we didn't get
+ any more data from the last call to line_ge_func*/
+ if (impl->temp[0] == '\0'){
- if ((*line_gen_func)(temp,tmp_buf_size,0)==0){/* Get more data */
- if (temp[0] == '\0'){
if(line[0] != '\0'){
+ /* There is data in the output, so fall trhough and process it*/
break;
} else {
+ /* No data in output; return and signal that there
+ is no more input*/
free(line);
return 0;
}
}
}
+
+
+ /* If the output line ends in a '\n' and the temp buffer
+ begins with a ' ', then the buffer holds a continuation
+ line, so keep reading. */
- if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') {
-
- /* If the output line ends in a '\n' and the temp buffer
- begins with a ' ', then the buffer holds a continuation
- line, so keep reading. */
+ if ( line_p > line+1 && *(line_p-1) == '\n' && impl->temp[0] == ' ') {
/* back up the pointer to erase the continuation characters */
line_p--;
+ if ( *(line_p-1) == '\r'){
+ line_p--;
+ }
+
/* shift the temp buffer down to eliminate the leading space*/
- memmove(&(temp[0]),&(temp[1]),tmp_buf_size);
- temp[tmp_buf_size-1] = temp[tmp_buf_size-2];
+ memmove(&(impl->temp[0]),&(impl->temp[1]),impl->tmp_buf_size);
+
+ impl->temp[impl->tmp_buf_size-1] = impl->temp[impl->tmp_buf_size-2];
- } else if ( buffer_full == 1 ) {
+ } else if ( impl->buffer_full == 1 ) {
/* The buffer was filled on the last read, so read again */
@@ -377,10 +468,13 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d),
}
- /* Erase the final newline */
- if ( line_p > line+1 && *(line_p-1) == '\n') {
-
+ /* Erase the final newline and/or carriage return*/
+ if ( line_p > line+1 && *(line_p-1) == '\n') {
*(line_p-1) = '\0';
+ if ( *(line_p-2) == '\r'){
+ *(line_p-2) = '\0';
+ }
+
} else {
*(line_p) = '\0';
}
@@ -389,111 +483,6 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d),
}
-#if 0
-char* icalparser_old_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno)
-{
- char *line, *output_line;
- char *line_p;
- char last_line = 0;
- size_t buf_size = tmp_buf_size;
- int break_flag = 0;
-
- line_p = line = icalmemory_new_buffer(buf_size);
-
- /* If the hold buffer is empty, read a line. Otherwise, use the data that
- is still in 'temp'*/
- if (hold == 1){
- /* Do nothing */
- } else {
- temp[tmp_buf_size-1] = 1; /* Mark end of buffer */
- (*line_gen_func)(temp,tmp_buf_size,0);
- }
-
- /* Append the hold buffer or new line into the output */
- icalmemory_append_string(&line,&line_p,&buf_size,temp);
-
- if ( temp[tmp_buf_size-1] == 0 ) { /* Check if mark was overwritten */
- buffer_full = 1;
- } else {
- buffer_full = 0;
- }
-
- /* Try to suck up any continuation lines */
- while(last_line == 0){
-
- temp[tmp_buf_size-1] = 1; /* Mark end of buffer */
- if ((*line_gen_func)(temp,tmp_buf_size,0) == 0){
- /* No more lines -- we are finished */
- if (hold == 1) {
- hold = 0;
- break_flag = 1;
- } else {
- icalmemory_free_buffer(line);
- return 0;
- }
- } else {
- if ( temp[tmp_buf_size-1] == 0 ) {
- buffer_full = 1;
- } else {
- buffer_full = 0;
- }
- }
-
- /* keep track of line numbers */
- if (lineno != 0){
- (*lineno)++;
- }
-
-
- /* Determine wether to copy the line to the output, or
- save it in the hold buffer */
-
- if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') {
-
- /* If the last line ( in the 'line' string ) ends in a '\n'
- and the current line begins with a ' ', then the current line
- is a continuation line, so append it. */
-
- /* back up the pointer to erase the continuation characters */
- line_p--;
- icalmemory_append_string(&line,&line_p,&buf_size,&(temp[1]));
-
- hold = 0;
- buffer_full= 0;
-
- } else if (buffer_full == 1) {
-
- /* The last line that was read filled up the read
- buffer. Append it and read again */
-
- icalmemory_append_string(&line,&line_p,&buf_size,temp);
-
- hold = 0;
-
- } else if (break_flag != 1 ){
- /* Nope -- the line was not a continuation line.
- Save the line for the next call */
-
- hold =1;
- break;
- } else {
- break;
- }
- }
-
- /* Erase the final newline */
- if ( line_p > line+1 && *(line_p-1) == '\n') {
-
- *(line_p-1) = '\0';
- }
-
- output_line = icalmemory_tmp_copy(line);
- icalmemory_free_buffer(line);
-
- return output_line;
-}
-#endif
-
void insert_error(icalcomponent* comp, char* text,
char* message, icalparameter_xlicerrortype type)
{
@@ -513,389 +502,489 @@ void insert_error(icalcomponent* comp, char* text,
0));
}
-icalcomponent* icalparser_parse(char* (*line_gen_func)(char *s, size_t size, void* d))
+icalcomponent* icalparser_parse(icalparser *parser,
+ char* (*line_gen_func)(char *s, size_t size,
+ void* d))
{
- char *line = 0;
+ char* line;
+ icalcomponent *c=0;
+ icalcomponent *root_component=0;
+
+ icalerror_check_arg_rz((parser !=0),"parser");
+
+ do{
+ line = icalparser_get_line(parser, line_gen_func);
+
+ if ((c = icalparser_add_line(parser,line)) != 0){
+ if (root_component == 0){
+ /* Just one component */
+ icalparser_claim(parser);
+ root_component = c;
+ } else if(icalcomponent_isa(root_component)
+ != ICAL_XROOT_COMPONENT) {
+ /*Got a second component, so move the two components under
+ an XROOT container */
+ icalcomponent *tempc;
+ tempc = icalcomponent_new(ICAL_XROOT_COMPONENT);
+ icalcomponent_add_component(tempc, root_component);
+ icalparser_claim(parser);
+ icalcomponent_add_component(tempc, c);
+ root_component = tempc;
+ } else {
+ /* Already have an XROOT container, so add the component
+ to it*/
+ icalcomponent_add_component(root_component, c);
+ icalparser_claim(parser);
+ }
+ }
+ } while ( line != 0);
+
+ return root_component;
+
+}
+
+icalcomponent* icalparser_add_line(icalparser* parser,
+ char* line)
+{
char *p;
char *str;
char *end;
- int lineno = 0;
-
int vcount = 0;
-
- icalcomponent *root_component = 0;
- icalcomponent *tail = 0;
icalproperty *prop;
icalvalue *value;
+ icalvalue_kind value_kind = ICAL_NO_VALUE;
- icalvalue_kind value_kind;
-
- pvl_list components = pvl_newlist();
-
- do {
- value_kind = ICAL_NO_VALUE;
+ struct icalparser_impl *impl = (struct icalparser_impl*)parser;
+ icalerror_check_arg_rz((parser != 0),"parser");
- /* Get a single property line, from a property name through a
- newline */
- if (line!=0){
- free(line);
- }
-
- line = icalparser_get_line(line_gen_func,&lineno);
- if (line == 0){
- continue;
- }
+ if (line == 0)
+ {
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
- end = 0;
+ /* Begin by getting the property name at the start of the line. The
+ property name may end up being "BEGIN" or "END" in which case it
+ is not really a property, but the market for the start or end of
+ a component */
- str = icalparser_get_prop_name(line, &end);
+ end = 0;
+ str = icalparser_get_prop_name(line, &end);
- if (str == 0){
- tail = pvl_data(pvl_tail(components));
+ if (str == 0){
+ /* Could not get a property name */
+ icalcomponent *tail = pvl_data(pvl_tail(impl->components));
- if (tail){
- insert_error(tail,line,
- "Got a data line, but could not find a property name or component begin tag",
- ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
- }
- tail = 0;
- continue;
+ if (tail){
+ insert_error(tail,line,
+ "Got a data line, but could not find a property name or component begin tag",
+ ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
}
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
-/**********************************************************************
- * Handle begin and end of components
- **********************************************************************/
+ /**********************************************************************
+ * Handle begin and end of components
+ **********************************************************************/
- /* If the property name is BEGIN or END, we are actually
- starting or ending a new component */
+ /* If the property name is BEGIN or END, we are actually
+ starting or ending a new component */
- if(strcmp(str,"BEGIN") == 0){
- icalcomponent *c; ;
+ if(strcmp(str,"BEGIN") == 0){
+ icalcomponent *c;
- str = icalparser_get_next_value(end,&end, value_kind);
+ impl->level++;
+ str = icalparser_get_next_value(end,&end, value_kind);
- c = icalcomponent_new_from_string(str);
+ c = icalcomponent_new_from_string(str);
- if (c == 0){
- c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
- insert_error(c,str,"Parse error in component name",
- ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
- }
+ if (c == 0){
+ c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
+ insert_error(c,str,"Parse error in component name",
+ ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
+ }
- pvl_push(components,c);
+ pvl_push(impl->components,c);
- continue;
- } else if (strcmp(str,"END") == 0 ) {
+ impl->state = ICALPARSER_BEGIN_COMP;
+ return 0;
- str = icalparser_get_next_value(end,&end, value_kind);
+ } else if (strcmp(str,"END") == 0 ) {
+ icalcomponent* tail;
- root_component = pvl_pop(components);
+ impl->level--;
+ str = icalparser_get_next_value(end,&end, value_kind);
- tail = pvl_data(pvl_tail(components));
+ impl->root_component = pvl_pop(impl->components);
- if(tail != 0){
- icalcomponent_add_component(tail,root_component);
- }
+ tail = pvl_data(pvl_tail(impl->components));
- tail = 0;
- continue;
+ if(tail != 0){
+ icalcomponent_add_component(tail,impl->root_component);
}
+ tail = 0;
- /* There is no point in continuing if we have not seen a
- component yet */
-
- if(pvl_data(pvl_tail(components)) == 0){
- continue;
+ /* Return the component if we are back to the 0th level */
+ if (impl->level == 0){
+ impl->state = ICALPARSER_SUCCESS;
+ return impl->root_component;
+ } else {
+ impl->state = ICALPARSER_END_COMP;
+ return 0;
}
+ }
+
+
+ /* There is no point in continuing if we have not seen a
+ component yet */
+ if(pvl_data(pvl_tail(impl->components)) == 0){
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
-/**********************************************************************
- * Handle property names
- **********************************************************************/
- /* At this point, the property name really is a property name,
- (Not a component name) so make a new property and add it to
- the component */
- prop = icalproperty_new_from_string(str);
+ /**********************************************************************
+ * Handle property names
+ **********************************************************************/
+ /* At this point, the property name really is a property name,
+ (Not a component name) so make a new property and add it to
+ the component */
- if (prop != 0){
- tail = pvl_data(pvl_tail(components));
+ prop = icalproperty_new_from_string(str);
- icalcomponent_add_property(tail, prop);
+ if (prop != 0){
+ icalcomponent *tail = pvl_data(pvl_tail(impl->components));
- /* Set the value kind for the default for this type of
- property. This may be re-set by a VALUE parameter */
- value_kind =
- icalenum_property_kind_to_value_kind(
- icalproperty_isa(prop));
- } else {
- icalcomponent* tail = pvl_data(pvl_tail(components));
+ icalcomponent_add_property(tail, prop);
+
+ /* Set the value kind for the default for this type of
+ property. This may be re-set by a VALUE parameter */
+ value_kind =
+ icalenum_property_kind_to_value_kind(
+ icalproperty_isa(prop));
- insert_error(tail,str,"Parse error in property name",
- ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);
+ } else {
+ icalcomponent* tail = pvl_data(pvl_tail(impl->components));
+
+ insert_error(tail,str,"Parse error in property name",
+ ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);
- tail = 0;
- continue;
- }
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
-/**********************************************************************
- * Handle parameter values
- **********************************************************************/
+ /**********************************************************************
+ * Handle parameter values
+ **********************************************************************/
- /* Now, add any parameters to the last property */
+ /* Now, add any parameters to the last property */
- p = 0;
- while(1) {
+ p = 0;
+ while(1) {
- if (*(end-1) == ':'){
- /* if the last seperator was a ":" and the value is a
- URL, icalparser_get_next_parameter will find the
- ':' in the URL, so better break now. */
- break;
- }
+ if (*(end-1) == ':'){
+ /* if the last seperator was a ":" and the value is a
+ URL, icalparser_get_next_parameter will find the
+ ':' in the URL, so better break now. */
+ break;
+ }
- str = icalparser_get_next_parameter(end,&end);
+ str = icalparser_get_next_parameter(end,&end);
- if (str != 0){
- char* name;
- char* pvalue;
- icalparameter *param = 0;
- icalparameter_kind kind;
-
- tail = pvl_data(pvl_tail(components));
+ if (str != 0){
+ char* name;
+ char* pvalue;
+
+ icalparameter *param = 0;
+ icalparameter_kind kind;
+ icalcomponent *tail = pvl_data(pvl_tail(impl->components));
- name = icalparser_get_param_name(str,&pvalue);
+ name = icalparser_get_param_name(str,&pvalue);
- if (name == 0){
- insert_error(tail, str, "Can't parse parameter name",
- ICAL_XLICERRORTYPE_PARAMETERPARSEERROR);
- tail = 0;
- break;
- }
+ if (name == 0){
+ /* 'tail' defined above */
+ insert_error(tail, str, "Can't parse parameter name",
+ ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
+ tail = 0;
+ break;
+ }
- kind = icalenum_string_to_parameter_kind(name);
- if (kind != ICAL_NO_PARAMETER){
- param = icalparameter_new_from_string(kind,pvalue);
- } else {
+ kind = icalenum_string_to_parameter_kind(name);
- /* Error. Failed to parse the parameter*/
- insert_error(tail, str, "Can't parse parameter name",
- ICAL_XLICERRORTYPE_PARAMETERPARSEERROR);
- tail = 0;
- continue;
- }
+ if (kind != ICAL_NO_PARAMETER){
+ param = icalparameter_new_from_string(kind,pvalue);
+ } else {
+ /* Error. Failed to parse the parameter*/
+ /* 'tail' defined above */
+ insert_error(tail, str, "Can't parse parameter name",
+ ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
- if (param == 0){
- insert_error(tail,str,"Can't parse parameter value",
- ICAL_XLICERRORTYPE_PARAMETERPARSEERROR);
+ if (param == 0){
+ /* 'tail' defined above */
+ insert_error(tail,str,"Can't parse parameter value",
+ ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
- tail = 0;
- continue;
- }
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ continue;
+ }
- /* If it is a VALUE parameter, set the kind of value*/
- if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){
+ /* If it is a VALUE parameter, set the kind of value*/
+ if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){
- value_kind = (icalvalue_kind)
- icalparameter_get_value(param);
+ value_kind = (icalvalue_kind)
+ icalparameter_get_value(param);
- if (value_kind == ICAL_NO_VALUE){
+ if (value_kind == ICAL_NO_VALUE){
- /* Ooops, could not parse the value of the
- parameter ( it was not one of the defined
- values ), so reset the value_kind */
+ /* Ooops, could not parse the value of the
+ parameter ( it was not one of the defined
+ values ), so reset the value_kind */
- icalcomponent* tail
- = pvl_data(pvl_tail(components));
+ insert_error(
+ tail, str,
+ "Got a VALUE parameter with an unknown type",
+ ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
+ icalparameter_free(param);
- insert_error(
- tail, str,
- "Got a VALUE parameter with an unknown type",
- ICAL_XLICERRORTYPE_PARAMETERPARSEERROR);
- icalparameter_free(param);
+ value_kind =
+ icalenum_property_kind_to_value_kind(
+ icalproperty_isa(prop));
- value_kind =
- icalenum_property_kind_to_value_kind(
- icalproperty_isa(prop));
-
- icalparameter_free(param);
- tail = 0;
- continue;
- }
- }
+ icalparameter_free(param);
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ }
+ }
- /* Everything is OK, so add the parameter */
- icalproperty_add_parameter(prop,param);
- tail = 0;
+ /* Everything is OK, so add the parameter */
+ icalproperty_add_parameter(prop,param);
+ tail = 0;
- } else {
- /* If we did not get a param string, go on to looking
- for a value */
- break;
- }
- }
+ } else { /* if ( str != 0) */
+ /* If we did not get a param string, go on to looking
+ for a value */
+ break;
+ } /* if ( str != 0) */
+
+ } /* while(1) */
-/**********************************************************************
- * Handle values
- **********************************************************************/
+ /**********************************************************************
+ * Handle values
+ **********************************************************************/
- /* Look for values. If there are ',' characters in the values,
- then there are multiple values, so clone the current
- parameter and add one part of the value to each clone */
+ /* Look for values. If there are ',' characters in the values,
+ then there are multiple values, so clone the current
+ parameter and add one part of the value to each clone */
- vcount=0;
- while(1) {
- str = icalparser_get_next_value(end,&end, value_kind);
+ vcount=0;
+ while(1) {
+ str = icalparser_get_next_value(end,&end, value_kind);
- if (str != 0){
+ if (str != 0){
- if (vcount > 0){
- /* Actually, only clone after the second value */
- icalproperty* clone = icalproperty_new_clone(prop);
- tail = pvl_data(pvl_tail(components));
+ if (vcount > 0){
+ /* Actually, only clone after the second value */
+ icalproperty* clone = icalproperty_new_clone(prop);
+ icalcomponent* tail = pvl_data(pvl_tail(impl->components));
- icalcomponent_add_property(tail, clone);
- prop = clone;
- tail = 0;
- }
+ icalcomponent_add_property(tail, clone);
+ prop = clone;
+ tail = 0;
+ }
- value = icalvalue_new_from_string(value_kind, str);
+ value = icalvalue_new_from_string(value_kind, str);
- /* Don't add properties without value */
- if (value == 0){
- char temp[1024];
+ /* Don't add properties without value */
+ if (value == 0){
+ char temp[200]; /* HACK */
- icalproperty_kind prop_kind = icalproperty_isa(prop);
- tail = pvl_data(pvl_tail(components));
+ icalproperty_kind prop_kind = icalproperty_isa(prop);
+ icalcomponent* tail = pvl_data(pvl_tail(impl->components));
- sprintf(temp,"Can't parse as %s value in %s property. Removing entire property",
- icalenum_value_kind_to_string(value_kind),
- icalenum_property_kind_to_string(prop_kind));
+ sprintf(temp,"Can't parse as %s value in %s property. Removing entire property",
+ icalenum_value_kind_to_string(value_kind),
+ icalenum_property_kind_to_string(prop_kind));
- insert_error(tail, str, temp,
- ICAL_XLICERRORTYPE_VALUEPARSEERROR);
+ insert_error(tail, str, temp,
+ ICAL_XLICERRORTYPE_VALUEPARSEERROR);
- /* Remove the troublesome property */
- icalcomponent_remove_property(tail,prop);
- icalproperty_free(prop);
- prop = 0;
- tail = 0;
- break;
+ /* Remove the troublesome property */
+ icalcomponent_remove_property(tail,prop);
+ icalproperty_free(prop);
+ prop = 0;
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
- } else {
- vcount++;
- icalproperty_set_value(prop, value);
- }
+ } else {
+ vcount++;
+ icalproperty_set_value(prop, value);
+ }
- } else {
+ } else {
+ if (vcount == 0){
+ char temp[200]; /* HACK */
+ icalproperty_kind prop_kind = icalproperty_isa(prop);
+ icalcomponent *tail = pvl_data(pvl_tail(impl->components));
+
+ sprintf(temp,"No value for %s property. Removing entire property",
+ icalenum_property_kind_to_string(prop_kind));
+
+ insert_error(tail, str, temp,
+ ICAL_XLICERRORTYPE_VALUEPARSEERROR);
+
+ /* Remove the troublesome property */
+ icalcomponent_remove_property(tail,prop);
+ icalproperty_free(prop);
+ prop = 0;
+ tail = 0;
+ impl->state = ICALPARSER_ERROR;
+ return 0;
+ } else {
+
break;
}
}
+ }
- } while( !feof(stdin) && line !=0 );
+ /****************************************************************
+ * End of component parsing.
+ *****************************************************************/
-
- if (pvl_data(pvl_tail(components)) == 0){
- /* A nice, clean exit */
- pvl_free(components);
- free(line);
- return root_component;
+ if (pvl_data(pvl_tail(impl->components)) == 0 &&
+ impl->level == 0){
+ impl->state = ICALPARSER_SUCCESS;
+ return impl->root_component;
+ } else {
+ impl->state = ICALPARSER_IN_PROGRESS;
+ return 0;
}
- /* Clear off any component that may be left in the list */
- /* This will happen if some components did not have an "END" tag*/
+}
+
+icalparser_state icalparser_get_state(icalparser* parser)
+{
+ struct icalparser_impl* impl = (struct icalparser_impl*) parser;
+ return impl->state;
+
+}
+
+icalcomponent* icalparser_claim(icalparser* parser)
+{
+ struct icalparser_impl* impl = (struct icalparser_impl*) parser;
+ icalcomponent *c = impl->root_component;
+
+ impl->root_component = 0;
+
+ return c;
+
+}
+
+
+icalcomponent* icalparser_clean(icalparser* parser)
+{
+ struct icalparser_impl* impl = (struct icalparser_impl*) parser;
+ icalcomponent *tail = pvl_data(pvl_tail(impl->components));
- while((tail=pvl_data(pvl_tail(components))) != 0){
+ icalerror_check_arg_rz((parser != 0 ),"parser");
+
+ /* We won't get a clean exit if some components did not have an
+ "END" tag. Clear off any component that may be left in the list */
+
+
+ while((tail=pvl_data(pvl_tail(impl->components))) != 0){
insert_error(tail," ",
"Missing END tag for this component. Closing component at end of input.",
ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
- root_component = pvl_pop(components);
- tail=pvl_data(pvl_tail(components));
+ impl->root_component = pvl_pop(impl->components);
+ tail=pvl_data(pvl_tail(impl->components));
if(tail != 0){
- icalcomponent_add_component(tail,root_component);
+ icalcomponent_add_component(tail,impl->root_component);
}
}
- free(line);
- return root_component;
+ return impl->root_component;
+
}
-char* string_line_generator_pos=0;
-char* string_line_generator_str;
+struct slg_data {
+ char* pos;
+ char* str;
+};
+
char* string_line_generator(char *out, size_t buf_size, void *d)
{
char *n;
-
- if(string_line_generator_pos==0){
- string_line_generator_pos=string_line_generator_str;
+ size_t size;
+ struct slg_data* data = (struct slg_data*)d;
+
+ if(data->pos==0){
+ data->pos=data->str;
}
/* If the pointer is at the end of the string, we are done */
- if (*string_line_generator_pos ==0){
+ if (*(data->pos)==0){
return 0;
}
- n = strchr(string_line_generator_pos,'\n');
+ n = strchr(data->pos,'\n');
- /* If no newline, take the rest of the string, and leave the
- pointer at the \0 */
-
- if (n == 0) {
- n = string_line_generator_pos + strlen(string_line_generator_pos);
+ if (n == 0){
+ size = strlen(data->pos);
} else {
- n++;
+ n++; /* include newline in output */
+ size = (n-data->pos);
}
- strncpy(out,string_line_generator_pos,(n-string_line_generator_pos));
-
- *(out+(n-string_line_generator_pos)) = '\0';
-
- string_line_generator_pos = n;
-
- return out;
+ if (size > buf_size-1){
+ size = buf_size-1;
+ }
-}
-void _test_string_line_generator(char* str)
-{
- char *line;
- int lineno=0;
- string_line_generator_str = str;
- string_line_generator_pos = 0;
-
- while((line = icalparser_get_line(string_line_generator,&lineno))){
- printf("#%d: %s\n",lineno,line);
- }
+ strncpy(out,data->pos,size);
+ *(out+size) = '\0';
- string_line_generator_pos = 0;
- string_line_generator_str = 0;
-}
-
+ data->pos += size;
+ return out;
+}
icalcomponent* icalparser_parse_string(char* str)
{
-
icalcomponent *c;
-
- string_line_generator_str = str;
- string_line_generator_pos = 0;
- c = icalparser_parse(string_line_generator);
- string_line_generator_pos = 0;
- string_line_generator_str = 0;
-
+ struct slg_data d;
+ icalparser *p;
+
+ d.pos = 0;
+ d.str = str;
+
+ p = icalparser_new();
+ icalparser_set_gen_data(p,&d);
+ c = icalparser_parse(p,string_line_generator);
+ icalparser_free(p);
+
return c;
}