start moving beyond PMModelItemInfo
[pspp] / parse-xml.c
index 0c00abd908a57678cfae6f47db31b45df5cd1f66..15c4ba2e9bc1c21cb4eb4935304d8c894add1581 100644 (file)
@@ -36,26 +36,15 @@ print_containment (xmlNode *node)
     {
       if (node->type == XML_ELEMENT_NODE)
         {
-          const char *child_names[5000];
-          int child_name_cnt[5000];
+          const char *child_names[512];
+          int child_name_cnt[512];
           int n_names = 0;
           for (xmlNode *child = node->children; child; child = child->next)
             {
               const char *name;
 
               if (child->type == XML_ELEMENT_NODE)
-                {
-                  name = (char *) child->name;
-                  if (!strcmp((char *) node->name, "derivedVariable")
-                      && !strcmp((char *) name, "extension"))
-                    {
-                      char *p;
-                      asprintf(&p, "%s/%s", 
-                               (char *) xmlGetProp (child, (xmlChar *) "from"),
-                               (char *) xmlGetProp (child, (xmlChar *) "helpId"));
-                      name = p;
-                    }
-                }
+                name = (char *) child->name;
               else if (child->type == XML_TEXT_NODE)
                 name = "<text>";
               else if (child->type == XML_CDATA_SECTION_NODE)
@@ -69,19 +58,17 @@ print_containment (xmlNode *node)
               else
                 name = "<other>";
 
-#if 0
               for (int i = 0; i < n_names; i++)
                 if (!strcmp(name, child_names[i]))
                   {
                     child_name_cnt[i]++;
                     goto next;
                   }
-#endif
               child_names[n_names] = name;
               child_name_cnt[n_names] = 1;
               n_names++;
 
-              //next:;
+            next:;
             }
 
           printf ("%s", node->name);
@@ -117,14 +104,6 @@ print_labels (xmlNode *node)
     }
 }
 
-static int
-compare_strings(const void *a_, const void *b_)
-{
-  const void *const *ap = a_;
-  const void *const *bp = b_;
-  return strcmp (*ap, *bp);
-}
-
 static void
 print_attributes (xmlNode * a_node)
 {
@@ -132,19 +111,13 @@ print_attributes (xmlNode * a_node)
     {
       if (node->type == XML_ELEMENT_NODE)
         {
-          printf ("%s<-%s", node->name, node->parent->name);
-
-          char *attrs[500];
-          int n_attrs = 0;
+          printf ("%s", node->name);
           for (xmlAttr *attr = node->properties; attr; attr = attr->next)
-            if (!strcmp((char *) attr->name, "baseFormat"))
-              printf(" baseFormat=%s", attr->children->content);
-            else
-              attrs[n_attrs++] = (char *) attr->name;
-          qsort(attrs, n_attrs, sizeof *attrs, compare_strings);
-
-          for (int i = 0; i < n_attrs; i++)
-            printf (" %s", attrs[i]);
+            {
+              printf (" %s", attr->name);
+              if (!strcmp ((char *) attr->name, "baseFormat"))
+                printf ("=%s", (char *) xmlGetProp (node, attr->name));
+            }
           putchar ('\n');
         }
 
@@ -190,33 +163,56 @@ print_attribute (xmlNode *node, const char *attr)
     }
 }
 
+static void
+print_xml (xmlDoc *doc, xmlNode *node)
+{
+  xmlBuffer *buf = xmlBufferCreate();
+  xmlNodeDump (buf, doc, node, 0, 0);
+  xmlBufferDump (stdout, buf);
+  xmlBufferFree (buf);
+  putchar ('\n');
+}
+
 static void
 print_element (xmlDoc *doc, xmlNode *node, const char *element)
 {
   for (; node; node = node->next)
     {
-      if (!strcmp(element, (char *) node->name))
+      if (node->name && !strcmp(element, (char *) node->name))
+        print_xml (doc, node);
+
+      print_element (doc, node->children, element);
+    }
+}
+
+static void
+print_id (xmlDoc *doc, xmlNode *node, const char *id)
+{
+  for (; node; node = node->next)
+    {
+      if (node->type == XML_ELEMENT_NODE)
         {
-          xmlBuffer *buf = xmlBufferCreate();
-          xmlNodeDump (buf, doc, node, 0, 1);
-          xmlBufferDump (stdout, buf);
-          xmlBufferFree (buf);
-          putchar ('\n');
+          const char *node_id = (char *) xmlGetProp (node, (xmlChar *) "id");
+          if (node_id && !strcmp (node_id, id))
+            {
+              print_xml (doc, node);
+              break;
+            }
         }
 
-      print_element (doc, node->children, element);
+      print_id (doc, node->children, id);
     }
 }
 
 static __attribute__((unused)) xmlNode *
-find_page_setup (xmlNode *node)
+find_node (xmlNode *node, const char *name)
 {
   for (; node; node = node->next)
     {
-      if (node->name && !strcmp ((char *) node->name, "pageSetup"))
+      if (node->name && !strcmp ((char *) node->name, name))
         return node;
 
-      xmlNode *ps = find_page_setup (node->children);
+      xmlNode *ps = find_node (node->children, name);
       if (ps)
         return ps;
     }
@@ -244,6 +240,21 @@ print_text (xmlNode *node)
     }
 }
 
+static void
+check_version (xmlNode *root, const char *version)
+{
+  const char *s = (char *) xmlGetProp (root, (xmlChar *) "version");
+  if (!s)
+    {
+      fprintf (stderr, "missing version\n");
+      exit (1);
+    }
+  else if (strcmp(version, s))
+    {
+      exit (0);
+    }
+}
+
 static void
 usage (void)
 {
@@ -254,7 +265,7 @@ usage (void)
 int
 main (int argc, char **argv)
 {
-  if (argc != 3)
+  if (argc < 3)
     usage ();
 
   LIBXML_TEST_VERSION;
@@ -268,32 +279,44 @@ main (int argc, char **argv)
 
   xmlNode *root = xmlDocGetRootElement(doc);
 
-#if 0
-  /* Limit what we look at to pageSetup node and below. */
-  root = find_page_setup(root);
-  if (!root)
-    return 0;
-  root->next = NULL;
-#endif
-
-  if (!strcmp(argv[2], "parents"))
-    print_parents (root);
-  else if (!strcmp(argv[2], "containment"))
-    print_containment (root);
-  else if (!strcmp(argv[2], "attributes"))
-    print_attributes (root);
-  else if (!strcmp(argv[2], "cdata"))
-    print_cdata (root);
-  else if (!strcmp(argv[2], "text"))
-    print_text (root);
-  else if (!strncmp(argv[2], "element:", 8))
-    print_element (doc, root, argv[2] + 8);
-  else if (!strncmp(argv[2], "attr:", 5))
-    print_attribute (root, argv[2] + 5);
-  else if (!strcmp(argv[2], "labels"))
-    print_labels (root);
-  else
-    usage ();
+  for (int i = 2; i < argc; i++)
+    {
+      if (!strcmp(argv[i], "parents"))
+        print_parents (root);
+      else if (!strcmp(argv[i], "containment"))
+        print_containment (root);
+      else if (!strcmp(argv[i], "attributes"))
+        print_attributes (root);
+      else if (!strcmp(argv[i], "cdata"))
+        print_cdata (root);
+      else if (!strcmp(argv[i], "text"))
+        print_text (root);
+      else if (!strncmp(argv[i], "element:", 8))
+        print_element (doc, root, argv[i] + 8);
+      else if (!strncmp(argv[i], "attr:", 5))
+        print_attribute (root, argv[i] + 5);
+      else if (!strncmp(argv[i], "id:", 3))
+        print_id (doc, root, argv[i] + 3);
+      else if (!strncmp(argv[i], "root:", 5))
+        {
+          /* Limit content to descendants of the given node. */
+          root = find_node (root, argv[i] + 5);
+          if (!root)
+            return 0;
+          root->next = NULL;
+        }
+      else if (!strncmp(argv[i], "musthave:", 9))
+        {
+          if (!find_node (root, argv[i] + 9))
+            return 0;
+        }
+      else if (!strcmp(argv[i], "labels"))
+        print_labels (root);
+      else if (!strncmp(argv[i], "version=", 8))
+        check_version (root, argv[i] + 8);
+      else
+        usage ();
+    }
 
   xmlFreeDoc(doc);
   xmlCleanupParser();