X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=parse.c;h=2321f7d13a890b4fc085e818ce57ad9cf791654a;hb=a71e8dd777a27b5e9c56e1834f964b385b1157d4;hp=6277a9021aeb93da8ed9eb43d2d22aafbbb46397;hpb=ed45f7cb140a508b6f661f75b2c4803686b0e379;p=ext%2Fsubsurface.git diff --git a/parse.c b/parse.c index 6277a90..2321f7d 100644 --- a/parse.c +++ b/parse.c @@ -1,23 +1,128 @@ #include +#include +#include #include #include -static void show_one_node(int i, xmlNode *node) +/* + * File boundaries are dive boundaries. But sometimes there are + * multiple dives per file, so there can be other events too that + * trigger a "new dive" marker and you may get some nesting due + * to that. Just ignore nesting levels. + */ +static void dive_start(void) { - static const char indent[] = " .."; + printf("---\n"); +} + +static void dive_end(void) +{ +} + +static void sample_start(void) +{ + printf("Sample:\n"); +} + +static void sample_end(void) +{ +} + +static void entry(const char *name, int size, const char *buffer) +{ + printf("%s: %.*s\n", name, size, buffer); +} + +static const char *nodename(xmlNode *node, char *buf, int len) +{ + /* Don't print out the node name if it is "text" */ + if (!strcmp(node->name, "text")) { + node = node->parent; + if (!node || !node->name) + return "root"; + } - if (i >= sizeof(indent)) - i = sizeof(indent)-1; - printf("%.*snode '%s': %s\n", i, indent, node->name, node->content); + buf += len; + *--buf = 0; + len--; + + for(;;) { + const char *name = node->name; + int i = strlen(name); + while (--i >= 0) { + unsigned char c = name[i]; + *--buf = tolower(c); + if (!--len) + return buf; + } + node = node->parent; + if (!node || !node->name) + return buf; + *--buf = '.'; + if (!--len) + return buf; + } +} + +#define MAXNAME 64 + +static void visit_one_node(xmlNode *node) +{ + int len; + const unsigned char *content; + char buffer[MAXNAME]; + const char *name; + + content = node->content; + if (!content) + return; + + /* Trim whitespace at beginning */ + while (isspace(*content)) + content++; + + /* Trim whitespace at end */ + len = strlen(content); + while (len && isspace(content[len-1])) + len--; + + if (!len) + return; + + name = nodename(node, buffer, sizeof(buffer)); + + entry(name, len, content); } -static void show(int indent, xmlNode *node) +static void traverse(xmlNode *node) { xmlNode *n; for (n = node; n; n = n->next) { - show_one_node(indent, n); - show(indent+2, n->children); + /* XML from libdivecomputer: 'dive' per new dive */ + if (!strcmp(n->name, "dive")) { + dive_start(); + traverse(n->children); + dive_end(); + continue; + } + + /* + * At least both libdivecomputer and Suunto + * agree on "sample". + * + * Well - almost. Ignore case. + */ + if (!strcasecmp(n->name, "sample")) { + sample_start(); + traverse(n->children); + sample_end(); + continue; + } + + /* Anything else - just visit it and recurse */ + visit_one_node(n); + traverse(n->children); } } @@ -31,7 +136,9 @@ static void parse(const char *filename) return; } - show(0, xmlDocGetRootElement(doc)); + dive_start(); + traverse(xmlDocGetRootElement(doc)); + dive_end(); xmlFreeDoc(doc); xmlCleanupParser(); }