void config::get_element_attribute(const std::string& e, const std::string& a, std::string& t) { QDomNode domNode = m_node.firstChild(); while(!domNode.isNull()) { if(domNode.isElement()) { QDomElement domElement = domNode.toElement(); if(!domElement.isNull()) { if(domElement.tagName() == e.c_str()) { if(domElement.tagName() == a.c_str()) { QString tt = domElement.text(); globals::qstring_to_string(tt, t); } } } } m_node = domNode; get_element_attribute(e, a, t) ; domNode = domNode.nextSibling(); } }
bool Traces::parse(const char *filename, int verbose) { xmlDocPtr doc = xmlParseFile(filename); if (doc == NULL) { cout << "Error parsing the "<< filename << " !" << endl; goto err; } xmlNodePtr node; node = doc->children; XMLASSERT(node->type == XML_ELEMENT_NODE && !strcmp((const char*)node->name, "gltrace")); { // parse tracelist xmlNodePtr xmllist = get_child_element(node, "tracelist"); XMLASSERT(xmllist); for(xmlNodePtr tracenode = xmllist->children; tracenode; tracenode = tracenode->next) { if(tracenode->type == XML_TEXT_NODE) continue; XMLASSERT(tracenode->type == XML_ELEMENT_NODE && !strcmp((const char*)tracenode->name, "trace")); const char *object = get_element_attribute(tracenode, "object"); const char *name = get_element_attribute(tracenode, "name"); XMLASSERT(object && name); xmlNodePtr shot = get_child_element(tracenode, "shot"); XMLASSERT(shot); const char *id_str = get_element_attribute(shot, "id"); XMLASSERT(id_str); int id; XMLASSERT(sscanf(id_str, "%d", &id) == 1); while((int)tracelist.size() <= id) { tracelist.push_back(TracedEvent()); } tracelist[id].name = name; tracelist[id].obj = object; } if(verbose) printf("loaded %ld traces\n", tracelist.size()); } { // load links xmlNodePtr linklist = get_child_element(node, "linklist"); XMLASSERT(linklist); for(xmlNodePtr linknode = linklist->children; linknode; linknode = linknode->next) { if(linknode->type == XML_TEXT_NODE) continue; Link link; XMLASSERT(linknode->type == XML_ELEMENT_NODE && !strcmp((const char*)linknode->name, "link")); xmlNodePtr source = get_child_element(linknode, "source"); xmlNodePtr destination = get_child_element(linknode, "destination"); XMLASSERT(source && destination); string sourcecol = get_element_attribute(source, "name"); string destcol = get_element_attribute(destination, "name"); XMLASSERT(sourcecol.size() && destcol.size()); link.source = sourcecol.substr(0, sourcecol.find(':')); link.sourceport = sourcecol.substr(sourcecol.find(':') + 1); link.dest = destcol.substr(0, destcol.find(':')); link.destport = destcol.substr(destcol.find(':') + 1); // printf("size %d %p\n", links.size(), &links[0]); links.push_back(link); // printf("osize %d %s\n", links.size(), links[0].source.c_str()); } if(verbose) printf("%ld links\n", links.size()); } { // fill in nextEvents for(int i = 0; i < tracelist.size(); i++) { TracedEvent &ev = tracelist[i]; Link *waitBeginLink = NULL; bool recorded = false; for(int l = 0; l < links.size(); l++) { Link & link = links[l]; if(link.source == ev.obj && link.sourceport == ev.name) { int dest_ev = find_event(link.dest, link.destport); ev.links.push_back(&link); if(dest_ev >= 0) { ev.nextEvents.push_back(dest_ev); recorded = true; } } if(link.source == ev.obj && link.sourceport == "waitBegin") waitBeginLink = &link; if(link.dest == ev.obj && link.destport == ev.name && link.destport != "waitEnd") { ev.links.push_back(&link); recorded = true; } } if(!recorded) { // probably a user event if(waitBeginLink) { ev.links.push_back(waitBeginLink); } else { printf("could not find waitBegin/waitEnd where trace %d %s:%s fits\n", i, ev.obj.c_str(), ev.name.c_str()); } } if(verbose) { printf("tev %d %s:%s, nextEvents = [", i, ev.obj.c_str(), ev.name.c_str()); for(int j = 0; j < ev.nextEvents.size(); j++) printf("%d ", ev.nextEvents[j]); printf("] links = ["); for(int j = 0; j < ev.links.size(); j++) { Link & link = *ev.links[j]; printf("%s:%s->%s:%s ", link.source.c_str(), link.sourceport.c_str(), link.dest.c_str(), link.destport.c_str()); } printf("]\n"); } } } { // load actual trace data xmlNodePtr xmlfiles = get_child_element(node, "filelist"); XMLASSERT(xmlfiles); vector<Chunk> chunks; for(xmlNodePtr filenode = xmlfiles->children; filenode; filenode = filenode->next) { if(filenode->type == XML_TEXT_NODE || (filenode->type == XML_ELEMENT_NODE && !strcmp((const char*)filenode->name, "pingresults"))) continue; XMLASSERT(filenode->type == XML_ELEMENT_NODE && !strcmp((const char*)filenode->name, "tracefile")); const char *chunkfilename = get_element_attribute(filenode, "file"); XMLASSERT(chunkfilename); { FILE *chunkfile = fopen(chunkfilename, "r"); XMLASSERT(chunkfile); size_t file_size; { struct stat sbuf; fstat(fileno(chunkfile), &sbuf); file_size = sbuf.st_size; } XMLASSERT(file_size % sizeof(Chunk) == 0); size_t nelt = file_size / sizeof(Chunk); size_t n0 = chunks.size(); chunks.resize(n0 + nelt); fread(&chunks[n0], nelt, sizeof(Chunk), chunkfile); fclose(chunkfile); } } if(verbose) printf("loaded %ld chunks\n", chunks.size()); chunks_to_evlists(chunks, tracelist, t0, t1); {// also record all timestamps double t_prev = -10; for(int i = 0; i < chunks.size(); i++) { double t = chunks[i].tv_sec + chunks[i].tv_usec * 1e-6; if(t > t_prev) timestamps.push_back(t); t_prev = t; } } } xmlFreeDoc(doc); return true; err: xmlFreeDoc(doc); return false; }