]> mj.ucw.cz Git - leo.git/commitdiff
More clean OSM XML parsing
authorMartin Mares <mj@ucw.cz>
Thu, 12 Feb 2015 19:04:55 +0000 (20:04 +0100)
committerMartin Mares <mj@ucw.cz>
Thu, 12 Feb 2015 19:04:55 +0000 (20:04 +0100)
xml.c

diff --git a/xml.c b/xml.c
index 6ba94275ea8eaf692b2b07879f049dc0ff58eba7..69e739d06915121f8f34e95a73368e62dd219912 100644 (file)
--- a/xml.c
+++ b/xml.c
@@ -1,9 +1,11 @@
 /*
  *     Hic Est Leo -- OSM XML Parser
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
+#undef LOCAL_DEBUG
+
 #include <ucw/lib.h>
 #include <ucw/fastbuf.h>
 #include <ucw-xml/xml.h>
@@ -159,30 +161,36 @@ static void parse_element(struct xml_context *ctx, struct xml_node *e)
 
 void osm_xml_parse(const char *name)
 {
-  struct xml_context ctx;
-  xml_init(&ctx);
-  ctx.h_warn = ctx.h_error = ctx.h_fatal = h_error;
-  xml_push_fastbuf(&ctx, bopen_file(name, O_RDONLY, NULL));
+  struct xml_context xml_ctx, *ctx = &xml_ctx;
+  xml_init(ctx);
+  ctx->h_warn = ctx->h_error = ctx->h_fatal = h_error;
+  xml_push_fastbuf(ctx, bopen_file(name, O_RDONLY, NULL));
 
   uint state;
-  while (state = xml_next_state(&ctx, XML_PULL_STAG))
-    switch (state)
+  while (state = xml_next_state(ctx, XML_PULL_STAG))
+    if (state == XML_STATE_STAG)
       {
-      case XML_STATE_STAG:
-       // printf("STAG %s\n", ctx.node->name);
-       if (strcmp(ctx.node->name, "osm"))
+       DBG("Level 1 tag <%s>", ctx->node->name);
+       if (!strcmp(ctx->node->name, "osm"))
          {
-           ctx.flags |= XML_ALLOC_CHARS | XML_ALLOC_TAGS;
-           if (xml_skip_element(&ctx) == XML_STATE_ETAG)
+           DBG("Switched to level 2");
+           while ((state = xml_next_state(ctx, XML_PULL_STAG | XML_PULL_ETAG)) == XML_STATE_STAG)
              {
-               // printf("ETAG %s\n", ctx.node->name);
-               parse_element(&ctx, ctx.node);
+               ctx->flags |= XML_ALLOC_CHARS | XML_ALLOC_TAGS;
+               if (xml_skip_element(ctx) == XML_STATE_ETAG)
+                 {
+                   DBG("Level 2 tag <%s>", ctx->node->name);
+                   parse_element(ctx, ctx->node);
+                 }
              }
+           DBG("Exited level 2 in state %u", state);
          }
+       else
+         xml_skip_element(ctx);
       }
 
-  if (ctx.err_code)
+  if (ctx->err_code)
     die("Fatal error in XML parser");
 
-  xml_cleanup(&ctx);
+  xml_cleanup(ctx);
 }