Document a lot of setCellProperties.
[pspp] / parse-xml.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <libxml/parser.h>
4 #include <libxml/tree.h>
5
6 static void
7 print_parents(xmlNode *node)
8 {
9   for (; node; node = node->next)
10     {
11       if (node->type == XML_ELEMENT_NODE)
12         {
13           for (xmlNode *child = node->children; child; child = child->next)
14             {
15               if (child->type == XML_ELEMENT_NODE)
16                   printf ("%s %s\n", node->name, child->name);
17               else if (child->type == XML_TEXT_NODE)
18                 printf ("%s <text>\n", node->name);
19               else if (child->type == XML_CDATA_SECTION_NODE)
20                 printf ("%s <cdata>\n", node->name);
21               else if (child->type == XML_COMMENT_NODE)
22                 printf ("%s <comment>\n", node->name);
23               else
24                 printf ("%s <%d>\n", node->name, child->type);
25             }
26         }
27
28       print_parents (node->children);
29     }
30 }
31
32 static void
33 print_containment (xmlNode *node)
34 {
35   for (; node; node = node->next)
36     {
37       if (node->type == XML_ELEMENT_NODE)
38         {
39           const char *child_names[512];
40           int child_name_cnt[512];
41           int n_names = 0;
42           for (xmlNode *child = node->children; child; child = child->next)
43             {
44               const char *name;
45
46               if (child->type == XML_ELEMENT_NODE)
47                 name = (char *) child->name;
48               else if (child->type == XML_TEXT_NODE)
49                 name = "<text>";
50               else if (child->type == XML_CDATA_SECTION_NODE)
51                 name = "<cdata>";
52               else if (child->type == XML_COMMENT_NODE)
53                 {
54                   name = "<comment>";
55                   //printf ("comment %s\n", (char *) child->content);
56                   continue;
57                 }
58               else
59                 name = "<other>";
60
61               for (int i = 0; i < n_names; i++)
62                 if (!strcmp(name, child_names[i]))
63                   {
64                     child_name_cnt[i]++;
65                     goto next;
66                   }
67               child_names[n_names] = name;
68               child_name_cnt[n_names] = 1;
69               n_names++;
70
71             next:;
72             }
73
74           printf ("%s", node->name);
75           for (int i = 0; i < n_names; i++)
76             {
77               printf (" %s", child_names[i]);
78               if (child_name_cnt[i] > 1)
79                 printf ("+");
80             }
81           printf ("\n");
82         }
83
84       print_containment (node->children);
85     }
86 }
87
88 static void
89 print_labels (xmlNode *node)
90 {
91   for (; node; node = node->next)
92     {
93       if (node->type == XML_ELEMENT_NODE
94           && !strcmp((char *) node->name, "label")
95           && node->parent->type == XML_ELEMENT_NODE
96           && !strcmp((char *) node->parent->name, "container"))
97         {
98           for (xmlNode *child = node->children; child; child = child->next)
99             if (child->type == XML_TEXT_NODE)
100               puts ((char *) child->content);
101         }
102
103       print_labels (node->children);
104     }
105 }
106
107 static void
108 print_attributes (xmlNode * a_node)
109 {
110   for (xmlNode *node = a_node; node; node = node->next)
111     {
112       if (node->type == XML_ELEMENT_NODE)
113         {
114           printf ("%s", node->name);
115           for (xmlAttr *attr = node->properties; attr; attr = attr->next)
116             printf (" %s", attr->name);
117           putchar ('\n');
118         }
119
120       print_attributes (node->children);
121     }
122 }
123
124 static void
125 print_string(xmlChar *s)
126 {
127   for (char *p = (char *) s; *p; p++)
128     if (*p == '\n')
129       printf ("\\n");
130     else
131       putchar (*p);
132 }
133
134 static void
135 print_cdata (xmlNode * a_node)
136 {
137   for (xmlNode *node = a_node; node; node = node->next)
138     {
139       if (node->type == XML_CDATA_SECTION_NODE)
140         {
141           print_string (node->content);
142           putchar ('\n');
143         }
144
145       print_cdata (node->children);
146     }
147 }
148
149 static void
150 print_attribute (xmlNode *node, const char *attr)
151 {
152   for (; node; node = node->next)
153     {
154       const char *s = (char *) xmlGetProp (node, (xmlChar *) attr);
155       if (s)
156         printf ("%s %s=%s\n", node->name, attr, s);
157
158       print_attribute (node->children, attr);
159     }
160 }
161
162 static void
163 print_xml (xmlDoc *doc, xmlNode *node)
164 {
165   xmlBuffer *buf = xmlBufferCreate();
166   xmlNodeDump (buf, doc, node, 0, 1);
167   xmlBufferDump (stdout, buf);
168   xmlBufferFree (buf);
169   putchar ('\n');
170 }
171
172 static void
173 print_element (xmlDoc *doc, xmlNode *node, const char *element)
174 {
175   for (; node; node = node->next)
176     {
177       if (node->name && !strcmp(element, (char *) node->name))
178         print_xml (doc, node);
179
180       print_element (doc, node->children, element);
181     }
182 }
183
184 static void
185 print_id (xmlDoc *doc, xmlNode *node, const char *id)
186 {
187   for (; node; node = node->next)
188     {
189       if (node->type == XML_ELEMENT_NODE)
190         {
191           const char *node_id = (char *) xmlGetProp (node, (xmlChar *) "id");
192           if (node_id && !strcmp (node_id, id))
193             {
194               print_xml (doc, node);
195               break;
196             }
197         }
198
199       print_id (doc, node->children, id);
200     }
201 }
202
203 static __attribute__((unused)) xmlNode *
204 find_page_setup (xmlNode *node)
205 {
206   for (; node; node = node->next)
207     {
208       if (node->name && !strcmp ((char *) node->name, "pageSetup"))
209         return node;
210
211       xmlNode *ps = find_page_setup (node->children);
212       if (ps)
213         return ps;
214     }
215   return NULL;
216 }
217
218 static void
219 print_text (xmlNode *node)
220 {
221   for (; node; node = node->next)
222     {
223       if (node->type == XML_ELEMENT_NODE)
224         {
225           printf ("%s", node->name);
226           for (xmlNode *child = node->children; child; child = child->next)
227             if (child->type == XML_TEXT_NODE)
228               {
229                 putchar (' ');
230                 print_string (child->content);
231               }
232           putchar ('\n');
233         }
234
235       print_text (node->children);
236     }
237 }
238
239 static void
240 usage (void)
241 {
242   fprintf (stderr, "usage: parse-xml FILE.xml containment|attributes\n");
243   exit (1);
244 }
245
246 int
247 main (int argc, char **argv)
248 {
249   if (argc != 3)
250     usage ();
251
252   LIBXML_TEST_VERSION;
253
254   xmlDoc *doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS);
255   if (doc == NULL)
256     {
257       fprintf (stderr, "error: could not parse file %s\n", argv[1]);
258       exit (1);
259     }
260
261   xmlNode *root = xmlDocGetRootElement(doc);
262
263 #if 0
264   /* Limit what we look at to pageSetup node and below. */
265   root = find_page_setup(root);
266   if (!root)
267     return 0;
268   root->next = NULL;
269 #endif
270
271   if (!strcmp(argv[2], "parents"))
272     print_parents (root);
273   else if (!strcmp(argv[2], "containment"))
274     print_containment (root);
275   else if (!strcmp(argv[2], "attributes"))
276     print_attributes (root);
277   else if (!strcmp(argv[2], "cdata"))
278     print_cdata (root);
279   else if (!strcmp(argv[2], "text"))
280     print_text (root);
281   else if (!strncmp(argv[2], "element:", 8))
282     print_element (doc, root, argv[2] + 8);
283   else if (!strncmp(argv[2], "attr:", 5))
284     print_attribute (root, argv[2] + 5);
285   else if (!strncmp(argv[2], "id:", 3))
286     print_id (doc, root, argv[2] + 3);
287   else if (!strcmp(argv[2], "labels"))
288     print_labels (root);
289   else
290     usage ();
291
292   xmlFreeDoc(doc);
293   xmlCleanupParser();
294
295   return 0;
296 }