X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=parse-xml.c;h=95625d12f550cf34854c9949ca2496af08b39ea9;hb=14d7601cdf8b5ba05c7889f6272fdad3fee03c80;hp=58d446db099c46f408a3c27d35bdfec99e249d40;hpb=4350a75b9455387c0da36b9b52349a858d8fca9c;p=ext%2Fsubsurface.git diff --git a/parse-xml.c b/parse-xml.c index 58d446d..95625d1 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -33,26 +33,30 @@ static void record_dive(struct dive *dive) dive_table.nr = nr+1; } -static void nonmatch(const char *type, const char *fullname, const char *name, char *buffer) +static void start_match(const char *type, const char *name, char *buffer) { - if (verbose > 1) - printf("Unable to match %s '(%.*s)%s' (%s)\n", type, - (int) (name - fullname), fullname, name, - buffer); - free(buffer); + if (verbose > 2) + printf("Matching %s '%s' (%s)\n", + type, name, buffer); } -static const char *last_part(const char *name) +static void nonmatch(const char *type, const char *name, char *buffer) { - const char *p = strrchr(name, '.'); - return p ? p+1 : name; + if (verbose > 1) + printf("Unable to match %s '%s' (%s)\n", + type, name, buffer); + free(buffer); } typedef void (*matchfn_t)(char *buffer, void *); -static int match(const char *pattern, const char *name, matchfn_t fn, char *buf, void *data) +static int match(const char *pattern, int plen, + const char *name, int nlen, + matchfn_t fn, char *buf, void *data) { - if (strcasecmp(pattern, name)) + if (plen > nlen) + return 0; + if (memcmp(pattern, name + nlen - plen, plen)) return 0; fn(buf, data); return 1; @@ -296,71 +300,62 @@ static void duration(char *buffer, void *_time) sampletime(buffer, _time); } -static void ignore(char *buffer, void *_time) -{ -} +#define MATCH(pattern, fn, dest) \ + match(pattern, strlen(pattern), name, len, fn, buf, dest) /* We're in samples - try to convert the random xml value to something useful */ static void try_to_fill_sample(struct sample *sample, const char *name, char *buf) { - const char *last = last_part(name); + int len = strlen(name); - if (match("pressure", last, pressure, buf, &sample->tankpressure)) + start_match("sample", name, buf); + if (MATCH(".sample.pressure", pressure, &sample->tankpressure)) return; - if (match("cylpress", last, pressure, buf, &sample->tankpressure)) + if (MATCH(".sample.cylpress", pressure, &sample->tankpressure)) return; - if (match("depth", last, depth, buf, &sample->depth)) + if (MATCH(".sample.depth", depth, &sample->depth)) return; - if (match("temperature", last, temperature, buf, &sample->temperature)) + if (MATCH(".sample.temperature", temperature, &sample->temperature)) return; - if (match("sampletime", last, sampletime, buf, &sample->time)) + if (MATCH(".sample.sampletime", sampletime, &sample->time)) return; - if (match("time", last, sampletime, buf, &sample->time)) + if (MATCH(".sample.time", sampletime, &sample->time)) return; - nonmatch("sample", name, last, buf); + nonmatch("sample", name, buf); } /* We're in the top-level dive xml. Try to convert whatever value to a dive value */ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf) { - const char *last = last_part(name); + int len = strlen(name); - if (match("date", last, divedate, buf, &dive->when)) - return; - if (match("time", last, divetime, buf, &dive->when)) - return; - if (match("datetime", last, divedatetime, buf, &dive->when)) - return; - if (match("maxdepth", last, depth, buf, &dive->maxdepth)) + start_match("dive", name, buf); + if (MATCH(".date", divedate, &dive->when)) return; - if (match("meandepth", last, depth, buf, &dive->meandepth)) + if (MATCH(".time", divetime, &dive->when)) return; - if (match("divetime", last, duration, buf, &dive->duration)) + if (MATCH(".datetime", divedatetime, &dive->when)) return; - if (match("divetimesec", last, duration, buf, &dive->duration)) + if (MATCH(".maxdepth", depth, &dive->maxdepth)) return; - if (match("surfacetime", last, duration, buf, &dive->surfacetime)) + if (MATCH(".meandepth", depth, &dive->meandepth)) return; - if (match("airtemp", last, temperature, buf, &dive->airtemp)) + if (MATCH(".divetime", duration, &dive->duration)) return; - if (match("watertemp", last, temperature, buf, &dive->watertemp)) + if (MATCH(".divetimesec", duration, &dive->duration)) return; - if (match("cylinderstartpressure", last, pressure, buf, &dive->beginning_pressure)) + if (MATCH(".surfacetime", duration, &dive->surfacetime)) return; - if (match("cylinderendpressure", last, pressure, buf, &dive->end_pressure)) + if (MATCH(".airtemp", temperature, &dive->airtemp)) return; - if (match("divenumber", last, ignore, buf, NULL)) + if (MATCH(".watertemp", temperature, &dive->watertemp)) return; - if (match("diveseries", last, ignore, buf, NULL)) + if (MATCH(".cylinderstartpressure", pressure, &dive->beginning_pressure)) return; - if (match("number", last, ignore, buf, NULL)) + if (MATCH(".cylinderendpressure", pressure, &dive->end_pressure)) return; - if (match("size", last, ignore, buf, NULL)) - return; - if (match("fingerprint", last, ignore, buf, NULL)) - return; - nonmatch("dive", name, last, buf); + nonmatch("dive", name, buf); } static unsigned int dive_size(int samples) @@ -538,15 +533,32 @@ static void visit_one_node(xmlNode *node) entry(name, len, content); } -static void traverse(xmlNode *node) +static void traverse(xmlNode *root); + +static void traverse_properties(xmlNode *node) +{ + xmlAttr *p; + + for (p = node->properties; p; p = p->next) + traverse(p->children); +} + +static void visit(xmlNode *n) +{ + visit_one_node(n); + traverse_properties(n); + traverse(n->children); +} + +static void traverse(xmlNode *root) { xmlNode *n; - for (n = node; n; n = n->next) { + for (n = root; n; n = n->next) { /* XML from libdivecomputer: 'dive' per new dive */ if (!strcmp(n->name, "dive")) { dive_start(); - traverse(n->children); + visit(n); dive_end(); continue; } @@ -559,14 +571,13 @@ static void traverse(xmlNode *node) */ if (!strcasecmp(n->name, "sample")) { sample_start(); - traverse(n->children); + visit(n); sample_end(); continue; } /* Anything else - just visit it and recurse */ - visit_one_node(n); - traverse(n->children); + visit(n); } }