Blame example/gjobread.c

Packit 423ecb
/*
Packit 423ecb
 * gjobread.c : a small test program for gnome jobs XML format
Packit 423ecb
 *
Packit 423ecb
 * See Copyright for the status of this software.
Packit 423ecb
 *
Packit 423ecb
 * Daniel.Veillard@w3.org
Packit 423ecb
 */
Packit 423ecb
Packit 423ecb
#include <stdio.h>
Packit 423ecb
#include <string.h>
Packit 423ecb
#include <stdlib.h>
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * This example should compile and run indifferently with libxml-1.8.8 +
Packit 423ecb
 * and libxml2-2.1.0 +
Packit 423ecb
 * Check the COMPAT comments below
Packit 423ecb
 */
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * COMPAT using xml-config --cflags to get the include path this will
Packit 423ecb
 * work with both 
Packit 423ecb
 */
Packit 423ecb
#include <libxml/xmlmemory.h>
Packit 423ecb
#include <libxml/parser.h>
Packit 423ecb
Packit 423ecb
#define DEBUG(x) printf(x)
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * A person record
Packit 423ecb
 * an xmlChar * is really an UTF8 encoded char string (0 terminated)
Packit 423ecb
 */
Packit 423ecb
typedef struct person {
Packit 423ecb
    xmlChar *name;
Packit 423ecb
    xmlChar *email;
Packit 423ecb
    xmlChar *company;
Packit 423ecb
    xmlChar *organisation;
Packit 423ecb
    xmlChar *smail;
Packit 423ecb
    xmlChar *webPage;
Packit 423ecb
    xmlChar *phone;
Packit 423ecb
} person, *personPtr;
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * And the code needed to parse it
Packit 423ecb
 */
Packit 423ecb
static personPtr
Packit 423ecb
parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
Packit 423ecb
    personPtr ret = NULL;
Packit 423ecb
Packit 423ecb
DEBUG("parsePerson\n");
Packit 423ecb
    /*
Packit 423ecb
     * allocate the struct
Packit 423ecb
     */
Packit 423ecb
    ret = (personPtr) malloc(sizeof(person));
Packit 423ecb
    if (ret == NULL) {
Packit 423ecb
        fprintf(stderr,"out of memory\n");
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
    memset(ret, 0, sizeof(person));
Packit 423ecb
Packit 423ecb
    /* We don't care what the top level element name is */
Packit 423ecb
    /* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
Packit 423ecb
    cur = cur->xmlChildrenNode;
Packit 423ecb
    while (cur != NULL) {
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *)"Person")) &&
Packit 423ecb
	    (cur->ns == ns))
Packit 423ecb
	    ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *)"Email")) &&
Packit 423ecb
	    (cur->ns == ns))
Packit 423ecb
	    ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Packit 423ecb
	cur = cur->next;
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    return(ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * and to print it
Packit 423ecb
 */
Packit 423ecb
static void
Packit 423ecb
printPerson(personPtr cur) {
Packit 423ecb
    if (cur == NULL) return;
Packit 423ecb
    printf("------ Person\n");
Packit 423ecb
    if (cur->name) printf("	name: %s\n", cur->name);
Packit 423ecb
    if (cur->email) printf("	email: %s\n", cur->email);
Packit 423ecb
    if (cur->company) printf("	company: %s\n", cur->company);
Packit 423ecb
    if (cur->organisation) printf("	organisation: %s\n", cur->organisation);
Packit 423ecb
    if (cur->smail) printf("	smail: %s\n", cur->smail);
Packit 423ecb
    if (cur->webPage) printf("	Web: %s\n", cur->webPage);
Packit 423ecb
    if (cur->phone) printf("	phone: %s\n", cur->phone);
Packit 423ecb
    printf("------\n");
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * a Description for a Job
Packit 423ecb
 */
Packit 423ecb
typedef struct job {
Packit 423ecb
    xmlChar *projectID;
Packit 423ecb
    xmlChar *application;
Packit 423ecb
    xmlChar *category;
Packit 423ecb
    personPtr contact;
Packit 423ecb
    int nbDevelopers;
Packit 423ecb
    personPtr developers[100]; /* using dynamic alloc is left as an exercise */
Packit 423ecb
} job, *jobPtr;
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * And the code needed to parse it
Packit 423ecb
 */
Packit 423ecb
static jobPtr
Packit 423ecb
parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
Packit 423ecb
    jobPtr ret = NULL;
Packit 423ecb
Packit 423ecb
DEBUG("parseJob\n");
Packit 423ecb
    /*
Packit 423ecb
     * allocate the struct
Packit 423ecb
     */
Packit 423ecb
    ret = (jobPtr) malloc(sizeof(job));
Packit 423ecb
    if (ret == NULL) {
Packit 423ecb
        fprintf(stderr,"out of memory\n");
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
    memset(ret, 0, sizeof(job));
Packit 423ecb
Packit 423ecb
    /* We don't care what the top level element name is */
Packit 423ecb
    cur = cur->xmlChildrenNode;
Packit 423ecb
    while (cur != NULL) {
Packit 423ecb
        
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Project")) &&
Packit 423ecb
	    (cur->ns == ns)) {
Packit 423ecb
	    ret->projectID = xmlGetProp(cur, (const xmlChar *) "ID");
Packit 423ecb
	    if (ret->projectID == NULL) {
Packit 423ecb
		fprintf(stderr, "Project has no ID\n");
Packit 423ecb
	    }
Packit 423ecb
	}
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Application")) &&
Packit 423ecb
            (cur->ns == ns))
Packit 423ecb
	    ret->application = 
Packit 423ecb
		xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Category")) &&
Packit 423ecb
	    (cur->ns == ns))
Packit 423ecb
	    ret->category =
Packit 423ecb
		xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Contact")) &&
Packit 423ecb
	    (cur->ns == ns))
Packit 423ecb
	    ret->contact = parsePerson(doc, ns, cur);
Packit 423ecb
	cur = cur->next;
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    return(ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * and to print it
Packit 423ecb
 */
Packit 423ecb
static void
Packit 423ecb
printJob(jobPtr cur) {
Packit 423ecb
    int i;
Packit 423ecb
Packit 423ecb
    if (cur == NULL) return;
Packit 423ecb
    printf("=======  Job\n");
Packit 423ecb
    if (cur->projectID != NULL) printf("projectID: %s\n", cur->projectID);
Packit 423ecb
    if (cur->application != NULL) printf("application: %s\n", cur->application);
Packit 423ecb
    if (cur->category != NULL) printf("category: %s\n", cur->category);
Packit 423ecb
    if (cur->contact != NULL) printPerson(cur->contact);
Packit 423ecb
    printf("%d developers\n", cur->nbDevelopers);
Packit 423ecb
Packit 423ecb
    for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
Packit 423ecb
    printf("======= \n");
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
/*
Packit 423ecb
 * A pool of Gnome Jobs
Packit 423ecb
 */
Packit 423ecb
typedef struct gjob {
Packit 423ecb
    int nbJobs;
Packit 423ecb
    jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */
Packit 423ecb
} gJob, *gJobPtr;
Packit 423ecb
Packit 423ecb
Packit 423ecb
static gJobPtr
Packit 423ecb
parseGjobFile(char *filename ATTRIBUTE_UNUSED) {
Packit 423ecb
    xmlDocPtr doc;
Packit 423ecb
    gJobPtr ret;
Packit 423ecb
    jobPtr curjob;
Packit 423ecb
    xmlNsPtr ns;
Packit 423ecb
    xmlNodePtr cur;
Packit 423ecb
Packit 423ecb
#ifdef LIBXML_SAX1_ENABLED
Packit 423ecb
    /*
Packit 423ecb
     * build an XML tree from a the file;
Packit 423ecb
     */
Packit 423ecb
    doc = xmlParseFile(filename);
Packit 423ecb
    if (doc == NULL) return(NULL);
Packit 423ecb
#else
Packit 423ecb
    /*
Packit 423ecb
     * the library has been compiled without some of the old interfaces
Packit 423ecb
     */
Packit 423ecb
    return(NULL);
Packit 423ecb
#endif /* LIBXML_SAX1_ENABLED */
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Check the document is of the right kind
Packit 423ecb
     */
Packit 423ecb
    
Packit 423ecb
    cur = xmlDocGetRootElement(doc);
Packit 423ecb
    if (cur == NULL) {
Packit 423ecb
        fprintf(stderr,"empty document\n");
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
    ns = xmlSearchNsByHref(doc, cur,
Packit 423ecb
	    (const xmlChar *) "http://www.gnome.org/some-location");
Packit 423ecb
    if (ns == NULL) {
Packit 423ecb
        fprintf(stderr,
Packit 423ecb
	        "document of the wrong type, GJob Namespace not found\n");
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
    if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {
Packit 423ecb
        fprintf(stderr,"document of the wrong type, root node != Helping");
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Allocate the structure to be returned.
Packit 423ecb
     */
Packit 423ecb
    ret = (gJobPtr) malloc(sizeof(gJob));
Packit 423ecb
    if (ret == NULL) {
Packit 423ecb
        fprintf(stderr,"out of memory\n");
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
    memset(ret, 0, sizeof(gJob));
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Now, walk the tree.
Packit 423ecb
     */
Packit 423ecb
    /* First level we expect just Jobs */
Packit 423ecb
    cur = cur->xmlChildrenNode;
Packit 423ecb
    while ( cur && xmlIsBlankNode ( cur ) ) {
Packit 423ecb
	cur = cur -> next;
Packit 423ecb
    }
Packit 423ecb
    if ( cur == 0 ) {
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	free(ret);
Packit 423ecb
	return ( NULL );
Packit 423ecb
    }
Packit 423ecb
    if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
Packit 423ecb
        fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
Packit 423ecb
		cur->name);
Packit 423ecb
	fprintf(stderr,"xmlDocDump follows\n");
Packit 423ecb
#ifdef LIBXML_OUTPUT_ENABLED
Packit 423ecb
	xmlDocDump ( stderr, doc );
Packit 423ecb
	fprintf(stderr,"xmlDocDump finished\n");
Packit 423ecb
#endif /* LIBXML_OUTPUT_ENABLED */
Packit 423ecb
	xmlFreeDoc(doc);
Packit 423ecb
	free(ret);
Packit 423ecb
	return(NULL);
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /* Second level is a list of Job, but be laxist */
Packit 423ecb
    cur = cur->xmlChildrenNode;
Packit 423ecb
    while (cur != NULL) {
Packit 423ecb
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
Packit 423ecb
	    (cur->ns == ns)) {
Packit 423ecb
	    curjob = parseJob(doc, ns, cur);
Packit 423ecb
	    if (curjob != NULL)
Packit 423ecb
	        ret->jobs[ret->nbJobs++] = curjob;
Packit 423ecb
            if (ret->nbJobs >= 500) break;
Packit 423ecb
	}
Packit 423ecb
	cur = cur->next;
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    return(ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
static void
Packit 423ecb
handleGjob(gJobPtr cur) {
Packit 423ecb
    int i;
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Do whatever you want and free the structure.
Packit 423ecb
     */
Packit 423ecb
    printf("%d Jobs registered\n", cur->nbJobs);
Packit 423ecb
    for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
int main(int argc, char **argv) {
Packit 423ecb
    int i;
Packit 423ecb
    gJobPtr cur;
Packit 423ecb
Packit 423ecb
    /* COMPAT: Do not genrate nodes for formatting spaces */
Packit 423ecb
    LIBXML_TEST_VERSION
Packit 423ecb
    xmlKeepBlanksDefault(0);
Packit 423ecb
Packit 423ecb
    for (i = 1; i < argc ; i++) {
Packit 423ecb
	cur = parseGjobFile(argv[i]);
Packit 423ecb
	if ( cur )
Packit 423ecb
	  handleGjob(cur);
Packit 423ecb
	else
Packit 423ecb
	  fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
Packit 423ecb
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /* Clean up everything else before quitting. */
Packit 423ecb
    xmlCleanupParser();
Packit 423ecb
Packit 423ecb
    return(0);
Packit 423ecb
}