-/*
- * icalparse.y -- icalendar (RFC 5545) parser
+/* icalparse.y -- icalendar (RFC 5545) parser
*
* This code is Copyright (c) 2014, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
*/
#include "h/mh.h"
+#include "sbr/error.h"
#include "h/icalendar.h"
#include "h/utils.h"
static char *append (contentline *, const char *, const size_t);
-static void new_input_line (contentline **);
+static void new_content_line (contentline **);
static void new_vevent (vevent *);
static void free_param_names (param_list *);
static void free_param_values (value_list *);
/* contentline = name *(";" param ) ":" value CRLF */
contentline
: ICAL_NAME {
- new_input_line (&vevents.last->contentlines);
+ new_content_line (&vevents.last->contentlines);
append (vevents.last->contentlines->last, $1, strlen ($1));
vevents.last->contentlines->last->name = $1;
} ICAL_COLON {
}
}
| ICAL_NAME {
- new_input_line (&vevents.last->contentlines);
+ new_content_line (&vevents.last->contentlines);
append (vevents.last->contentlines->last, $1, strlen ($1));
vevents.last->contentlines->last->name = $1;
} param_list ICAL_COLON {
* Remove the contentline node (by setting its name to NULL).
*/
void
-remove_contentline (contentline *node) {
+remove_contentline (contentline *node)
+{
free (node->name);
node->name = NULL;
}
contentline *
-add_contentline (contentline *node, const char *name) {
+add_contentline (contentline *node, const char *name)
+{
contentline *new_node;
NEW0(new_node);
* Remove the value from a value_list.
*/
void
-remove_value (value_list *node) {
+remove_value (value_list *node)
+{
free (node->value);
node->value = NULL;
}
*/
contentline *
find_contentline (contentline *contentlines, const char *name,
- const char *val) {
+ const char *val)
+{
contentline *node;
for (node = contentlines; node; node = node->next) {
/* node->name will be NULL if the line was "deleted". */
if (node->name && ! strcasecmp (name, node->name)) {
- if (val && node->value) {
- if (! strcasecmp (val, node->value)) {
- return node;
- }
- } else {
+ if (!val || !node->value || !strcasecmp(val, node->value))
return node;
- }
}
}
}
static char *
-append (contentline *cline, const char *src, const size_t src_len) {
+append (contentline *cline, const char *src, const size_t src_len)
+{
if (src_len > 0) {
const size_t len = cline->input_line_len + src_len;
while (len >= cline->input_line_size) {
cline->input_line_size = cline->input_line_size == 0
- ? (BUFSIZ>=8192 ? BUFSIZ : 8192)
+ ? NMH_BUFSIZ
: 2 * cline->input_line_size;
cline->input_line =
mh_xrealloc (cline->input_line, cline->input_line_size);
}
static void
-new_input_line (contentline **cline) {
+new_content_line (contentline **cline)
+{
contentline *new_node;
NEW0(new_node);
}
static void
-new_vevent (vevent *event) {
+new_vevent (vevent *event)
+{
vevent *new_node, *node;
NEW0(new_node);
}
void
-add_param_name (contentline *cline, char *name) {
+add_param_name (contentline *cline, char *name)
+{
param_list *new_node;
param_list *p;
* Add a value to the last parameter seen.
*/
void
-add_param_value (contentline *cline, char *value) {
+add_param_value (contentline *cline, char *value)
+{
value_list *new_node;
param_list *p;
value_list *v;
}
void
-free_contentlines (contentline *root) {
+free_contentlines (contentline *root)
+{
contentline *i, *next;
for (i = root; i; i = next) {
}
free (i->value);
free (i->input_line);
+ charstring_free (i->unexpected);
next = i->next;
free (i);
}
}
static void
-free_param_names (param_list *p) {
+free_param_names (param_list *p)
+{
param_list *next;
for ( ; p; p = next) {
}
static void
-free_param_values (value_list *v) {
+free_param_values (value_list *v)
+{
value_list *next;
for ( ; v; v = next) {
}
static int
-icalerror (const char *error) {
+icalerror (const char *error)
+{
+ contentline *c;
+ charstring_t context = NULL;
+
+ /* Find last chunk of unexpected text. */
+ for (c = vevents.last->contentlines; c; c = c->next) {
+ if (c->unexpected) {
+ context = c->unexpected;
+ }
+ }
+
if (! strcmp ("syntax error, unexpected $end, expecting ICAL_NAME",
error)) {
/* Empty input: produce no output. */
} else {
- adios (NULL, "%s", error);
+ if (context) {
+ inform ("%s after \"%s\"", error, charstring_buffer (context));
+ } else {
+ inform ("%s", error);
+ }
+ parser_status = -1;
+ return -1;
}
return 0; /* The return value isn't used anyway. */