]> Pileus Git - lackey/commitdiff
Use expat for EWS calendar parsing
authorAndy Spencer <andy753421@gmail.com>
Sat, 3 Dec 2016 09:10:58 +0000 (09:10 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 12 Jun 2017 05:26:46 +0000 (05:26 +0000)
cals/ews.c
makefile

index 63580457e5d06999b6f6948fb5b8a6acb5f8ffaa..62776d2471058095503f8d239d71dc8039f87d40 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdio.h>
 
 #include <curl/curl.h>
+#include <expat.h>
 
 #include "util.h"
 #include "conf.h"
@@ -37,6 +38,7 @@ typedef struct ews_t {
 
        // Parsing
        CURL         *curl;
+       XML_Parser    expat;
        buf_t         buf;
 
        // Debugging
@@ -80,33 +82,52 @@ static char *req_calendar =
 ;
 
 /* Local functions */
-static void dump_xml(const char *buf, int len)
+static void on_start(void *_cal, const char *tag, const char **attrs)
 {
-       int indent = 0;
-       for (int i = 0; i < len; i++) {
-               const char prev = i>0 ? buf[i-1] : '\0';
-               const char this = buf[i];
-               const char next = i<len ? buf[i+1] : '\0';
-               if (this == '<' && next == '/')
-                       indent--;
-               if (this == '<' && prev == '>') {
-                       putchar('\n');
-                       for (int j = 0; j < indent*4; j++)
-                               putchar(' ');
+       ews_t *cal = _cal;
+
+       /* Debug print */
+       if (cal->debug) {
+               printf("%*s%s\n",
+                       cal->indent*4, "", tag);
+               for (int i = 0; attrs[i]; i += 2) {
+                       printf("%*s %s=\"%s\"\n",
+                               cal->indent*4+6, "--",
+                               attrs[i+0], attrs[i+1]);
+                       attrs+=2;
                }
-               if (this == '>' && prev == '/')
-                       indent--;
-               if (this == '<' && next != '/' && next != '?')
-                       indent++;
-               putchar(buf[i]);
+               cal->indent++;
        }
-       putchar('\n');
+}
+
+static void on_end(void *_cal, const char *tag)
+{
+       ews_t *cal = _cal;
+
+       /* Debug print */
+       if (cal->debug) {
+               if (cal->buf.len)
+                       printf("%*s \"%s\"\n",
+                               cal->indent*4+2, "--",
+                               (char*)cal->buf.data);
+               cal->indent--;
+       }
+
+       /* Parse items */
+       cal->buf.len = 0;
+}
+
+static void on_data(void *_cal, const char *data, int len)
+{
+       ews_t *cal = _cal;
+       if (cal->debug)
+               append(&cal->buf, data, len);
 }
 
 static size_t on_write(void *buf, size_t size, size_t n, ews_t *cal)
 {
        int len = size * n;
-       append(&cal->buf, buf, len);
+       XML_Parse(cal->expat, buf, len, 0);
        return len;
 }
 
@@ -126,6 +147,14 @@ static void sync_ews(ews_t *cal)
        debug("  location = %s", cal->location);
        debug("  domain   = %s", cal->domain);
 
+       /* Setup Expat */
+       if (!(cal->expat = XML_ParserCreate(NULL)))
+               error("XML Parser Create");
+       XML_SetUserData(cal->expat, cal);
+       XML_SetStartElementHandler(cal->expat, on_start);
+       XML_SetEndElementHandler(cal->expat, on_end);
+       XML_SetCharacterDataHandler(cal->expat, on_data);
+
        /* Setup HTTP request */
        if (!(cal->curl = curl_easy_init()))
                error("Curl easy init failed");
@@ -171,12 +200,10 @@ static void sync_ews(ews_t *cal)
                printf("EWS -- HTTP Status %ld\n", status);
        if (cal->debug && !cal->buf.data)
                printf("EWS -- No Response Data\n");
-       if (cal->debug)
-               dump_xml(cal->buf.data, cal->buf.len);
 
        /* Cleanup */
        curl_easy_cleanup(cal->curl);
-       release(&cal->buf);
+       XML_ParserFree(cal->expat);
 }
 
 /* Config parser */
index 552b59bf510a3055c1ff5ecd9462fa91f26d796f..70ebe5f82e80ff0088c54afad791a5b5512e034e 100644 (file)
--- a/makefile
+++ b/makefile
@@ -11,7 +11,7 @@ MANPREFIX ?= $(PREFIX)/share/man
 # Compiler
 GCC       ?= gcc
 CFLAGS    ?= -Wall --std=c99
-LDFLAGS   ?= -lncursesw -lical -lcurl
+LDFLAGS   ?= -lncursesw -lical -lcurl -lexpat
 
 # Sources
 PROG      ?= lackey