1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker * gjobread.c : a small test program for gnome jobs XML format
3*7c568831SAndroid Build Coastguard Worker *
4*7c568831SAndroid Build Coastguard Worker * See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker *
6*7c568831SAndroid Build Coastguard Worker * [email protected]
7*7c568831SAndroid Build Coastguard Worker */
8*7c568831SAndroid Build Coastguard Worker
9*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
10*7c568831SAndroid Build Coastguard Worker #include <string.h>
11*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
12*7c568831SAndroid Build Coastguard Worker
13*7c568831SAndroid Build Coastguard Worker /*
14*7c568831SAndroid Build Coastguard Worker * This example should compile and run indifferently with libxml-1.8.8 +
15*7c568831SAndroid Build Coastguard Worker * and libxml2-2.1.0 +
16*7c568831SAndroid Build Coastguard Worker * Check the COMPAT comments below
17*7c568831SAndroid Build Coastguard Worker */
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Worker /*
20*7c568831SAndroid Build Coastguard Worker * COMPAT using xml-config --cflags to get the include path this will
21*7c568831SAndroid Build Coastguard Worker * work with both
22*7c568831SAndroid Build Coastguard Worker */
23*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
24*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
25*7c568831SAndroid Build Coastguard Worker
26*7c568831SAndroid Build Coastguard Worker #define DEBUG(x) printf(x)
27*7c568831SAndroid Build Coastguard Worker
28*7c568831SAndroid Build Coastguard Worker /*
29*7c568831SAndroid Build Coastguard Worker * A person record
30*7c568831SAndroid Build Coastguard Worker * an xmlChar * is really an UTF8 encoded char string (0 terminated)
31*7c568831SAndroid Build Coastguard Worker */
32*7c568831SAndroid Build Coastguard Worker typedef struct person {
33*7c568831SAndroid Build Coastguard Worker xmlChar *name;
34*7c568831SAndroid Build Coastguard Worker xmlChar *email;
35*7c568831SAndroid Build Coastguard Worker xmlChar *company;
36*7c568831SAndroid Build Coastguard Worker xmlChar *organisation;
37*7c568831SAndroid Build Coastguard Worker xmlChar *smail;
38*7c568831SAndroid Build Coastguard Worker xmlChar *webPage;
39*7c568831SAndroid Build Coastguard Worker xmlChar *phone;
40*7c568831SAndroid Build Coastguard Worker } person, *personPtr;
41*7c568831SAndroid Build Coastguard Worker
42*7c568831SAndroid Build Coastguard Worker /*
43*7c568831SAndroid Build Coastguard Worker * And the code needed to parse it
44*7c568831SAndroid Build Coastguard Worker */
45*7c568831SAndroid Build Coastguard Worker static personPtr
parsePerson(xmlDocPtr doc,xmlNsPtr ns,xmlNodePtr cur)46*7c568831SAndroid Build Coastguard Worker parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
47*7c568831SAndroid Build Coastguard Worker personPtr ret = NULL;
48*7c568831SAndroid Build Coastguard Worker
49*7c568831SAndroid Build Coastguard Worker DEBUG("parsePerson\n");
50*7c568831SAndroid Build Coastguard Worker /*
51*7c568831SAndroid Build Coastguard Worker * allocate the struct
52*7c568831SAndroid Build Coastguard Worker */
53*7c568831SAndroid Build Coastguard Worker ret = (personPtr) malloc(sizeof(person));
54*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
55*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"out of memory\n");
56*7c568831SAndroid Build Coastguard Worker return(NULL);
57*7c568831SAndroid Build Coastguard Worker }
58*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(person));
59*7c568831SAndroid Build Coastguard Worker
60*7c568831SAndroid Build Coastguard Worker /* We don't care what the top level element name is */
61*7c568831SAndroid Build Coastguard Worker /* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
62*7c568831SAndroid Build Coastguard Worker cur = cur->xmlChildrenNode;
63*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
64*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *)"Person")) &&
65*7c568831SAndroid Build Coastguard Worker (cur->ns == ns))
66*7c568831SAndroid Build Coastguard Worker ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
67*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *)"Email")) &&
68*7c568831SAndroid Build Coastguard Worker (cur->ns == ns))
69*7c568831SAndroid Build Coastguard Worker ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
70*7c568831SAndroid Build Coastguard Worker cur = cur->next;
71*7c568831SAndroid Build Coastguard Worker }
72*7c568831SAndroid Build Coastguard Worker
73*7c568831SAndroid Build Coastguard Worker return(ret);
74*7c568831SAndroid Build Coastguard Worker }
75*7c568831SAndroid Build Coastguard Worker
76*7c568831SAndroid Build Coastguard Worker /*
77*7c568831SAndroid Build Coastguard Worker * and to print it
78*7c568831SAndroid Build Coastguard Worker */
79*7c568831SAndroid Build Coastguard Worker static void
printPerson(personPtr cur)80*7c568831SAndroid Build Coastguard Worker printPerson(personPtr cur) {
81*7c568831SAndroid Build Coastguard Worker if (cur == NULL) return;
82*7c568831SAndroid Build Coastguard Worker printf("------ Person\n");
83*7c568831SAndroid Build Coastguard Worker if (cur->name) printf(" name: %s\n", cur->name);
84*7c568831SAndroid Build Coastguard Worker if (cur->email) printf(" email: %s\n", cur->email);
85*7c568831SAndroid Build Coastguard Worker if (cur->company) printf(" company: %s\n", cur->company);
86*7c568831SAndroid Build Coastguard Worker if (cur->organisation) printf(" organisation: %s\n", cur->organisation);
87*7c568831SAndroid Build Coastguard Worker if (cur->smail) printf(" smail: %s\n", cur->smail);
88*7c568831SAndroid Build Coastguard Worker if (cur->webPage) printf(" Web: %s\n", cur->webPage);
89*7c568831SAndroid Build Coastguard Worker if (cur->phone) printf(" phone: %s\n", cur->phone);
90*7c568831SAndroid Build Coastguard Worker printf("------\n");
91*7c568831SAndroid Build Coastguard Worker }
92*7c568831SAndroid Build Coastguard Worker
93*7c568831SAndroid Build Coastguard Worker /*
94*7c568831SAndroid Build Coastguard Worker * a Description for a Job
95*7c568831SAndroid Build Coastguard Worker */
96*7c568831SAndroid Build Coastguard Worker typedef struct job {
97*7c568831SAndroid Build Coastguard Worker xmlChar *projectID;
98*7c568831SAndroid Build Coastguard Worker xmlChar *application;
99*7c568831SAndroid Build Coastguard Worker xmlChar *category;
100*7c568831SAndroid Build Coastguard Worker personPtr contact;
101*7c568831SAndroid Build Coastguard Worker int nbDevelopers;
102*7c568831SAndroid Build Coastguard Worker personPtr developers[100]; /* using dynamic alloc is left as an exercise */
103*7c568831SAndroid Build Coastguard Worker } job, *jobPtr;
104*7c568831SAndroid Build Coastguard Worker
105*7c568831SAndroid Build Coastguard Worker /*
106*7c568831SAndroid Build Coastguard Worker * And the code needed to parse it
107*7c568831SAndroid Build Coastguard Worker */
108*7c568831SAndroid Build Coastguard Worker static jobPtr
parseJob(xmlDocPtr doc,xmlNsPtr ns,xmlNodePtr cur)109*7c568831SAndroid Build Coastguard Worker parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
110*7c568831SAndroid Build Coastguard Worker jobPtr ret = NULL;
111*7c568831SAndroid Build Coastguard Worker
112*7c568831SAndroid Build Coastguard Worker DEBUG("parseJob\n");
113*7c568831SAndroid Build Coastguard Worker /*
114*7c568831SAndroid Build Coastguard Worker * allocate the struct
115*7c568831SAndroid Build Coastguard Worker */
116*7c568831SAndroid Build Coastguard Worker ret = (jobPtr) malloc(sizeof(job));
117*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
118*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"out of memory\n");
119*7c568831SAndroid Build Coastguard Worker return(NULL);
120*7c568831SAndroid Build Coastguard Worker }
121*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(job));
122*7c568831SAndroid Build Coastguard Worker
123*7c568831SAndroid Build Coastguard Worker /* We don't care what the top level element name is */
124*7c568831SAndroid Build Coastguard Worker cur = cur->xmlChildrenNode;
125*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
126*7c568831SAndroid Build Coastguard Worker
127*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *) "Project")) &&
128*7c568831SAndroid Build Coastguard Worker (cur->ns == ns)) {
129*7c568831SAndroid Build Coastguard Worker ret->projectID = xmlGetProp(cur, (const xmlChar *) "ID");
130*7c568831SAndroid Build Coastguard Worker if (ret->projectID == NULL) {
131*7c568831SAndroid Build Coastguard Worker fprintf(stderr, "Project has no ID\n");
132*7c568831SAndroid Build Coastguard Worker }
133*7c568831SAndroid Build Coastguard Worker }
134*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *) "Application")) &&
135*7c568831SAndroid Build Coastguard Worker (cur->ns == ns))
136*7c568831SAndroid Build Coastguard Worker ret->application =
137*7c568831SAndroid Build Coastguard Worker xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
138*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *) "Category")) &&
139*7c568831SAndroid Build Coastguard Worker (cur->ns == ns))
140*7c568831SAndroid Build Coastguard Worker ret->category =
141*7c568831SAndroid Build Coastguard Worker xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
142*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *) "Contact")) &&
143*7c568831SAndroid Build Coastguard Worker (cur->ns == ns))
144*7c568831SAndroid Build Coastguard Worker ret->contact = parsePerson(doc, ns, cur);
145*7c568831SAndroid Build Coastguard Worker cur = cur->next;
146*7c568831SAndroid Build Coastguard Worker }
147*7c568831SAndroid Build Coastguard Worker
148*7c568831SAndroid Build Coastguard Worker return(ret);
149*7c568831SAndroid Build Coastguard Worker }
150*7c568831SAndroid Build Coastguard Worker
151*7c568831SAndroid Build Coastguard Worker /*
152*7c568831SAndroid Build Coastguard Worker * and to print it
153*7c568831SAndroid Build Coastguard Worker */
154*7c568831SAndroid Build Coastguard Worker static void
printJob(jobPtr cur)155*7c568831SAndroid Build Coastguard Worker printJob(jobPtr cur) {
156*7c568831SAndroid Build Coastguard Worker int i;
157*7c568831SAndroid Build Coastguard Worker
158*7c568831SAndroid Build Coastguard Worker if (cur == NULL) return;
159*7c568831SAndroid Build Coastguard Worker printf("======= Job\n");
160*7c568831SAndroid Build Coastguard Worker if (cur->projectID != NULL) printf("projectID: %s\n", cur->projectID);
161*7c568831SAndroid Build Coastguard Worker if (cur->application != NULL) printf("application: %s\n", cur->application);
162*7c568831SAndroid Build Coastguard Worker if (cur->category != NULL) printf("category: %s\n", cur->category);
163*7c568831SAndroid Build Coastguard Worker if (cur->contact != NULL) printPerson(cur->contact);
164*7c568831SAndroid Build Coastguard Worker printf("%d developers\n", cur->nbDevelopers);
165*7c568831SAndroid Build Coastguard Worker
166*7c568831SAndroid Build Coastguard Worker for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
167*7c568831SAndroid Build Coastguard Worker printf("======= \n");
168*7c568831SAndroid Build Coastguard Worker }
169*7c568831SAndroid Build Coastguard Worker
170*7c568831SAndroid Build Coastguard Worker /*
171*7c568831SAndroid Build Coastguard Worker * A pool of Gnome Jobs
172*7c568831SAndroid Build Coastguard Worker */
173*7c568831SAndroid Build Coastguard Worker typedef struct gjob {
174*7c568831SAndroid Build Coastguard Worker int nbJobs;
175*7c568831SAndroid Build Coastguard Worker jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */
176*7c568831SAndroid Build Coastguard Worker } gJob, *gJobPtr;
177*7c568831SAndroid Build Coastguard Worker
178*7c568831SAndroid Build Coastguard Worker
179*7c568831SAndroid Build Coastguard Worker static gJobPtr
parseGjobFile(char * filename)180*7c568831SAndroid Build Coastguard Worker parseGjobFile(char *filename) {
181*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
182*7c568831SAndroid Build Coastguard Worker gJobPtr ret;
183*7c568831SAndroid Build Coastguard Worker jobPtr curjob;
184*7c568831SAndroid Build Coastguard Worker xmlNsPtr ns;
185*7c568831SAndroid Build Coastguard Worker xmlNodePtr cur;
186*7c568831SAndroid Build Coastguard Worker
187*7c568831SAndroid Build Coastguard Worker /*
188*7c568831SAndroid Build Coastguard Worker * build an XML tree from a the file;
189*7c568831SAndroid Build Coastguard Worker */
190*7c568831SAndroid Build Coastguard Worker doc = xmlReadFile(filename, NULL, XML_PARSE_NOBLANKS);
191*7c568831SAndroid Build Coastguard Worker if (doc == NULL) return(NULL);
192*7c568831SAndroid Build Coastguard Worker
193*7c568831SAndroid Build Coastguard Worker /*
194*7c568831SAndroid Build Coastguard Worker * Check the document is of the right kind
195*7c568831SAndroid Build Coastguard Worker */
196*7c568831SAndroid Build Coastguard Worker
197*7c568831SAndroid Build Coastguard Worker cur = xmlDocGetRootElement(doc);
198*7c568831SAndroid Build Coastguard Worker if (cur == NULL) {
199*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"empty document\n");
200*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
201*7c568831SAndroid Build Coastguard Worker return(NULL);
202*7c568831SAndroid Build Coastguard Worker }
203*7c568831SAndroid Build Coastguard Worker ns = xmlSearchNsByHref(doc, cur,
204*7c568831SAndroid Build Coastguard Worker (const xmlChar *) "http://www.gnome.org/some-location");
205*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
206*7c568831SAndroid Build Coastguard Worker fprintf(stderr,
207*7c568831SAndroid Build Coastguard Worker "document of the wrong type, GJob Namespace not found\n");
208*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
209*7c568831SAndroid Build Coastguard Worker return(NULL);
210*7c568831SAndroid Build Coastguard Worker }
211*7c568831SAndroid Build Coastguard Worker if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {
212*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"document of the wrong type, root node != Helping");
213*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
214*7c568831SAndroid Build Coastguard Worker return(NULL);
215*7c568831SAndroid Build Coastguard Worker }
216*7c568831SAndroid Build Coastguard Worker
217*7c568831SAndroid Build Coastguard Worker /*
218*7c568831SAndroid Build Coastguard Worker * Allocate the structure to be returned.
219*7c568831SAndroid Build Coastguard Worker */
220*7c568831SAndroid Build Coastguard Worker ret = (gJobPtr) malloc(sizeof(gJob));
221*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
222*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"out of memory\n");
223*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
224*7c568831SAndroid Build Coastguard Worker return(NULL);
225*7c568831SAndroid Build Coastguard Worker }
226*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(gJob));
227*7c568831SAndroid Build Coastguard Worker
228*7c568831SAndroid Build Coastguard Worker /*
229*7c568831SAndroid Build Coastguard Worker * Now, walk the tree.
230*7c568831SAndroid Build Coastguard Worker */
231*7c568831SAndroid Build Coastguard Worker /* First level we expect just Jobs */
232*7c568831SAndroid Build Coastguard Worker cur = cur->xmlChildrenNode;
233*7c568831SAndroid Build Coastguard Worker while ( cur && xmlIsBlankNode ( cur ) ) {
234*7c568831SAndroid Build Coastguard Worker cur = cur -> next;
235*7c568831SAndroid Build Coastguard Worker }
236*7c568831SAndroid Build Coastguard Worker if ( cur == 0 ) {
237*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
238*7c568831SAndroid Build Coastguard Worker free(ret);
239*7c568831SAndroid Build Coastguard Worker return ( NULL );
240*7c568831SAndroid Build Coastguard Worker }
241*7c568831SAndroid Build Coastguard Worker if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
242*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
243*7c568831SAndroid Build Coastguard Worker cur->name);
244*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"xmlDocDump follows\n");
245*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
246*7c568831SAndroid Build Coastguard Worker xmlDocDump ( stderr, doc );
247*7c568831SAndroid Build Coastguard Worker fprintf(stderr,"xmlDocDump finished\n");
248*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
249*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
250*7c568831SAndroid Build Coastguard Worker free(ret);
251*7c568831SAndroid Build Coastguard Worker return(NULL);
252*7c568831SAndroid Build Coastguard Worker }
253*7c568831SAndroid Build Coastguard Worker
254*7c568831SAndroid Build Coastguard Worker /* Second level is a list of Job, but be laxist */
255*7c568831SAndroid Build Coastguard Worker cur = cur->xmlChildrenNode;
256*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
257*7c568831SAndroid Build Coastguard Worker if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
258*7c568831SAndroid Build Coastguard Worker (cur->ns == ns)) {
259*7c568831SAndroid Build Coastguard Worker curjob = parseJob(doc, ns, cur);
260*7c568831SAndroid Build Coastguard Worker if (curjob != NULL)
261*7c568831SAndroid Build Coastguard Worker ret->jobs[ret->nbJobs++] = curjob;
262*7c568831SAndroid Build Coastguard Worker if (ret->nbJobs >= 500) break;
263*7c568831SAndroid Build Coastguard Worker }
264*7c568831SAndroid Build Coastguard Worker cur = cur->next;
265*7c568831SAndroid Build Coastguard Worker }
266*7c568831SAndroid Build Coastguard Worker
267*7c568831SAndroid Build Coastguard Worker return(ret);
268*7c568831SAndroid Build Coastguard Worker }
269*7c568831SAndroid Build Coastguard Worker
270*7c568831SAndroid Build Coastguard Worker static void
handleGjob(gJobPtr cur)271*7c568831SAndroid Build Coastguard Worker handleGjob(gJobPtr cur) {
272*7c568831SAndroid Build Coastguard Worker int i;
273*7c568831SAndroid Build Coastguard Worker
274*7c568831SAndroid Build Coastguard Worker /*
275*7c568831SAndroid Build Coastguard Worker * Do whatever you want and free the structure.
276*7c568831SAndroid Build Coastguard Worker */
277*7c568831SAndroid Build Coastguard Worker printf("%d Jobs registered\n", cur->nbJobs);
278*7c568831SAndroid Build Coastguard Worker for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
279*7c568831SAndroid Build Coastguard Worker }
280*7c568831SAndroid Build Coastguard Worker
main(int argc,char ** argv)281*7c568831SAndroid Build Coastguard Worker int main(int argc, char **argv) {
282*7c568831SAndroid Build Coastguard Worker int i;
283*7c568831SAndroid Build Coastguard Worker gJobPtr cur;
284*7c568831SAndroid Build Coastguard Worker
285*7c568831SAndroid Build Coastguard Worker /* COMPAT: Do not generate nodes for formatting spaces */
286*7c568831SAndroid Build Coastguard Worker LIBXML_TEST_VERSION
287*7c568831SAndroid Build Coastguard Worker
288*7c568831SAndroid Build Coastguard Worker for (i = 1; i < argc ; i++) {
289*7c568831SAndroid Build Coastguard Worker cur = parseGjobFile(argv[i]);
290*7c568831SAndroid Build Coastguard Worker if ( cur )
291*7c568831SAndroid Build Coastguard Worker handleGjob(cur);
292*7c568831SAndroid Build Coastguard Worker else
293*7c568831SAndroid Build Coastguard Worker fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
294*7c568831SAndroid Build Coastguard Worker
295*7c568831SAndroid Build Coastguard Worker }
296*7c568831SAndroid Build Coastguard Worker
297*7c568831SAndroid Build Coastguard Worker /* Clean up everything else before quitting. */
298*7c568831SAndroid Build Coastguard Worker xmlCleanupParser();
299*7c568831SAndroid Build Coastguard Worker
300*7c568831SAndroid Build Coastguard Worker return(0);
301*7c568831SAndroid Build Coastguard Worker }
302