rendered paste body#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <ctype.h>#include <xml.h>#include <tt.h>#define isblank(c) __isctype((c), _ISblank)voidXmlDebug(XmlPtr xml){ QstPtr qst = NULL; AnsPtr ans = NULL; NodePtr node = NULL; NodePtr inode = NULL; int i, j; i=j=0; printf("\n\n\n\n"); printf("Test Filename:\t\t\"%s\"\n", xml->filename); printf("Test ID:\t\t\"%s\"\n", xml->id); printf("Test Class:\t\t\"%s\"\n", xml->class); printf("Test Level:\t\t\"%s\"\n", xml->level); printf("Test's Author:\t\t\"%s\"\n", xml->author); printf("Author's Contact:\t\"%s\"\n", xml->contact); printf("Test Date:\t\t\"%s\"\n", xml->date); if (xml->question) { for (node = (xml->question)->head; node != NULL; node = node->next) { qst = node->data; printf("%d %s\"%s\"%s\n", i, Qcolor, qst->title, ColorOut); i++; if (qst->answers) { for (inode = (qst->answers)->head; inode != NULL; inode = inode->next) { ans = inode->data; printf ("\t%d %s\"%s\"%s\n", j, Ocolor, ans->answer, ColorOut); j++; } if (qst->image) printf("\ti %s\"%s\"%s\n", Icolor, qst->image, ColorOut); putchar('\n'); } } }}voidFreeAnswersList(void *data){ if (data == NULL) return; char **s = data; free(*s); free(data); return;}voidFreeQuestionsList(void *data){ QstPtr tmp = data; if(data == NULL) return; if(tmp->title) free(tmp->title); if(tmp->image) free(tmp->image); if(tmp->answers) { ListFree(&tmp->answers); } free(tmp); return;}voidXmlValidateDTD (XmlPtr xml){ xmlParserCtxtPtr ctxt; /* the parser context */ xmlDocPtr doc; /* the resulting document tree */ /* create a parser context */ ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { fprintf(stderr, _("Failed to allocate parser context. ")); stt.mask = MallocError; ProcStat(); } /* parse the file, activating the DTD validation option */ doc = xmlCtxtReadFile(ctxt, xml->filename, "ISO-8859-1", XML_PARSE_DTDVALID | XML_PARSE_PEDANTIC); /* check if parsing suceeded */ if (doc == NULL) { fprintf(stderr, _("Failed to parse %s\n"), xml->filename); xmlFreeParserCtxt(ctxt); stt.mask = Exit; ProcStat(); } else { /* check if validation suceeded */ if (ctxt->valid == 0) { fprintf(stderr, _("Failed to validate `%s\'\n"), xml->filename); xmlFreeDoc(doc); xmlFreeParserCtxt(ctxt); stt.mask = Exit; ProcStat(); } xmlFreeDoc(doc); } /* free up the parser context */ xmlFreeParserCtxt(ctxt);} /* XmlValidateDTD */voidXmlInit (XmlPtr *tmp) { XmlPtr xml = NULL; *tmp = malloc(sizeof(Xml)); check (*tmp); xml = *tmp; xml->poolcache = NULL; xml->filename = NULL; xml->id = NULL; xml->class = NULL; xml->level = NULL; xml->author = NULL; xml->contact = NULL; xml->date = NULL; xml->comment = NULL; xml->question = NULL; Call( CtxInitPool(xml) ); /* We should have at least a file on qeue to be processed or else * we wound't have reached this function, so let's validate it */ Call( XmlValidateDTD (xml) ); /* It's ok, so we can procceed to parse it */ Call( XmlParseDocument(xml) ); Ok;} /* XmlInit */voidXmlProcessXIncludes(XmlPtr xml, xmlDocPtr doc){ int ret = 0; /* Process xi:includes */ ret = xmlXIncludeProcess(doc); if(ret == 0 || ret == -1) { printf(_("Unable to perform requested xinclude sustitutions\n")); stt.mask = Exit; ProcStat(); } Ok;} /* XmlProcessXIncludes */voidXmlGetMetaData (XmlPtr xml, xmlDocPtr doc, xmlNodePtr cur){ xmlChar *key; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"ID"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->id = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Class"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->class = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Level"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->level = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Author"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->author = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Contact"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->contact = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Date"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->date = XmlNormalizeString(&key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Comment"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xml->comment = XmlNormalizeString(&key); } cur = cur->next; } Ok;} /* XmlGetMetaData */voidXmlParseDocument (XmlPtr xml){ xmlNodePtr cur = NULL; xmlDocPtr doc = xmlParseFile(xml->filename); check(doc); cur = xmlDocGetRootElement(doc); cur = cur->xmlChildrenNode; /* Apply any xincludes if neccesary */ XmlProcessXIncludes(xml, doc); while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Data"))) Call ( XmlGetMetaData (xml, doc, cur) ); if ((!xmlStrcmp(cur->name, (const xmlChar *)"Set"))) Call ( XmlGetSet (xml, doc, cur) ); cur = cur->next; } xmlFreeDoc(doc); xmlFree(cur); return;} /* XmlParseDocument */voidXmlGetSet (XmlPtr xml, xmlDocPtr doc, xmlNodePtr cur){ cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Question"))) Call ( XmlGetQuestion (xml, doc, cur) ); cur = cur->next; } Ok;} /* XmlGetSet */voidXmlGetQuestion (XmlPtr xml, xmlDocPtr doc, xmlNodePtr cur){ xmlChar *key; NodePtr node = NULL; QstPtr qst = malloc(sizeof(Qst)); check(qst); qst->ganswer = 0; qst->canswer = 0; qst->title = NULL; qst->image = NULL; qst->answers = NULL; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Title"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); qst->title = XmlNormalizeString(&key); ListAllocNode(&node); node->data = qst; /* Init the list if we already haven't */ if (!xml->question) ListAlloc(&xml->question, FreeQuestionsList); ListAttachNode(xml->question, node); XmlGetQuestionData (xml, doc, cur, node); } cur = cur->next; } Ok;} /* XmlGetQuestion */voidXmlGetQuestionData (XmlPtr xml, xmlDocPtr doc, xmlNodePtr cur, NodePtr node){ int count = 0; xmlChar *key; NodePtr inode = NULL; AnsPtr ans = NULL; QstPtr qst = node->data; xmlKeepBlanksDefault(0); while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Answer"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); ans = malloc(sizeof(Ans)); check(ans); ans->answer = XmlNormalizeString(&key); ListAllocNode(&inode); inode->data = ans; if (!qst->answers) ListAlloc(&qst->answers, FreeAnswersList); ListAttachNode(qst->answers, inode); count++; } if ((!xmlStrcmp(cur->name, (const xmlChar *)"CorrectAnswer"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); ans = malloc(sizeof(Ans)); ans->answer = XmlNormalizeString(&key); ListAllocNode(&node); node->data = ans; Call ( ListAttachNode(qst->answers, node) ); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"Image"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); qst->image = XmlNormalizeString(&key); } cur = cur->next; } Ok;} /* XmlGetQuestionData */char*XmlNormalizeString(unsigned char **utf){ unsigned char *utfp, *iso; const char *start, *end, *pointer; char *tmpin = NULL, *tmp = NULL; int tlen, size, out_size, temp, ret; int dblspace = 0; start = end = pointer = NULL; utfp = *utf; size = (int)strlen((char*)utfp)+1; out_size = size*2-1; iso = malloc(out_size); check(iso); memset(iso, 0, out_size); temp=size; ret = UTF8Toisolat1(iso, &out_size, utfp, &temp); if (ret < 0) { if (ret == -1) { printf(_("unknown transcoding error\n")); }else if (ret == -2) { printf(_("UTF8Toisolat1 transcoding error\n")); }else printf(_("UTF8Toisolat1 transcoding failed\n")); } xmlFree(utfp); tmpin = malloc((int)strlen((char*)iso)+1); check(tmpin); memset(tmpin, 0, strlen((char*)iso)+1); memcpy(tmpin, iso, strlen((char*)iso)); free(iso); start = end = tmpin; while (*start != 0 && isspace(*start)) start++; while (*end != 0) end++; end--; while (end > start && isspace(*end)) end--; end++; /* check for double-spaces existence, and if so, count them up */ pointer = start; while (pointer < end) { if (isspace(*pointer)) { pointer++; if (isspace(*pointer)) { while(isspace(*pointer)) { dblspace++; pointer++; } } } pointer++; } if (start == tmpin) { /* not leading white-spaces */ if (end == (start + strlen(tmpin))) { /* nor trailing either */ if (dblspace==0) { return tmpin; } } } tlen = ((end - start) - dblspace) + 1; tmp = malloc(tlen); check(tmp); memset(tmp, 0, tlen); pointer = tmp; while(start < end) { if (isspace(*start)) { memcpy((char*)pointer, " ", 1); pointer++; start++; if (isspace(*start)) while(isspace(*start)) start++; }else{ if((!isspace(*start)) || (!isblank(*start))) { memcpy((char*)pointer, start, 1); pointer++; } start++; } } free(tmpin); return tmp;} /* XmlNormalizeString */