#include #include #include #include #include using namespace std; #include #include #include #include "DClassDef.h" string XML_FILENAME = "/home/davidl/work/latest/sim-recon/src/libraries/HDDM/event.xml"; string HDDM_CLASS = "x"; string CXXFLAGS = ""; // first and last character should be space (or empty string) //string CXXFLAGS = " -pg -g "; map CLASSES; unsigned int MAX_DEPTH=0; unsigned int TARGET_DEPTH=1; void startElement(void *data, const char *el, const char **attr); void endElement(void *data, const char *el); void CreateCopyRoutines(void); void CreateHDDM2ROOT_tool(void); string NameToHDDMname(string name); string HDDMPlural(string name_hddm); void Usage(void); void ParseCommandLineArguments(int narg, char *argv[]); //-------------- // main //-------------- int main(int narg, char *argv[]) { // Parse Command line args ParseCommandLineArguments(narg, argv); // Parse XML file to get class definitions stack ancestory; XML_Parser parser = XML_ParserCreate(NULL); XML_SetUserData(parser, &ancestory); XML_SetElementHandler(parser, startElement, endElement); ifstream ifs(XML_FILENAME.c_str()); // get length of file: ifs.seekg (0, ios::end); int length = ifs.tellg(); ifs.seekg (0, ios::beg); if(length > 102400)length = 102400; // limit size to 100kB in case this is hddm file char *buff = new char[length]; ifs.read (buff,length); ifs.close(); int done = 0; XML_Parse(parser, buff, length, done); delete[] buff; // Create a header file for each class. This is needed to make // the ROOT dictionaries (cint doesn't seem to like it when they // are all in the same file). // Put all headers in sub-directory just to keep things a little cleaner mkdir("hddm_root_generated", S_IRWXU | S_IRWXG | S_IRWXO); // Print class definitions // Here we must print them in reverse-depth order so the classes // that show up as members of others are defined first. map::iterator iter; for(iter=CLASSES.begin(); iter!=CLASSES.end(); iter++){ string name = iter->first; string type = iter->second.name; map &members = iter->second.members; //if(iter->second.depth != depth)continue; // printing in reverse-depth order if(name == "HDDM_t")continue; // Skip outer HDDM tags // Open output file string fname = string("hddm_root_generated/") + name + ".h"; cout<<"writing "<" << endl; ofs << "using namespace std;" << endl; ofs << endl; ofs << "#include" << endl; ofs << "#include" << endl; ofs << endl; ofs << "#ifndef _" << name << "_"< &include_types = iter->second.include_types; set::iterator iter_inc; for(iter_inc=include_types.begin(); iter_inc!=include_types.end(); iter_inc++){ ofs << "#include \"" << *iter_inc << "_t.h\""<::iterator iter2; for(iter2=members.begin(); iter2!=members.end(); iter2++){ ofs << " " << iter2->second << " " << iter2->first << ";" << endl; } ofs<first; if(name == "HDDM_t")continue; // Skip outer HDDM tags string cmd = " rootcint -f " + name + "_Dict.cc -c " + name + ".h"; ofs << cmd << endl; } for(iter=CLASSES.begin(); iter!=CLASSES.end(); iter++){ string name = iter->first; if(name == "HDDM_t")continue; // Skip outer HDDM tags string cmd = " c++ `root-config --cflags` -c " + name + "_Dict.cc" + CXXFLAGS; ofs << cmd << endl; } ofs << " ar -r libhddm_root.a *_t_Dict.o" << endl; ofs << endl; ofs << endl; ofs << "copy_routines: hddm_root_CopyRoutines.cc hddm_root_CopyRoutines.h" << endl; string cmd = " c++ `root-config --cflags` -c -I${HALLD_HOME}/include -I. hddm_root_CopyRoutines.cc" + CXXFLAGS; ofs << cmd << endl; ofs << " ar -r libhddm_root.a hddm_root_CopyRoutines.o" << endl; ofs << endl; ofs << "tool: hddm2root_*.cc" << endl; cmd = " c++ `root-config --cflags --libs` -I${HALLD_HOME}/include -I. hddm2root_" + HDDM_CLASS + ".cc -o hddm2root_" + HDDM_CLASS + CXXFLAGS + " ./libhddm_root.a -lbz2 -lz -L${HALLD_HOME}/lib/${BMS_OSNAME} -lHDDM -lxstream"; ofs << cmd << endl; ofs << endl; ofs << endl; ofs.close(); // Create Copy Routines CreateCopyRoutines(); // Create main tool file CreateHDDM2ROOT_tool(); // Notify user of final step cout< &ancestory = *(stack*)data; // Convert element tag to string string name(el); // Loop over attributes, temporarily storing them into map map members; bool is_unbounded = false; for (int i = 0; attr[i]; i += 2) { string name(attr[i]); string type(attr[i+1]); // Some attributes are HDDM-specific if(name == "class") HDDM_CLASS = type; if(name == "minOccurs")continue; if(name == "version")continue; if(name == "maxOccurs"){ if(type == "unbounded"){ is_unbounded = true; continue; } if(atoi(type.c_str())>1){ is_unbounded = true; continue; } continue; } if(type.find("GeV")== 0 )continue; // skip Eunit and punit stuff if(type == "ns")continue; if(type == "cm")continue; if(type=="boolean") type = "bool"; // (sigh...) // Add member to list members[name] = type; } // If there is a parent, add this element as a member if(!ancestory.empty()){ if(is_unbounded){ CLASSES[ancestory.top()].members[name+"s"] = string("vector<") + name + "_t>"; }else{ CLASSES[ancestory.top()].members[name] = name + "_t"; } CLASSES[ancestory.top()].include_types.insert(name); } // Get reference to class definition, creating it if necessary DClassDef &class_def = CLASSES[name + "_t"]; class_def.members.insert(members.begin(), members.end()); class_def.depth = ancestory.size(); if(class_def.depth > MAX_DEPTH) MAX_DEPTH = class_def.depth; ancestory.push(name + "_t"); } //-------------- // endElement //-------------- void endElement(void *data, const char *el) { stack &ancestory = *(stack*)data; ancestory.pop(); } //-------------- // CreateCopyRoutines //-------------- void CreateCopyRoutines(void) { // Open header file to write into cout << "Writing hddm_root_generated/hddm_root_CopyRoutines.h" << endl; ofstream ofs("hddm_root_generated/hddm_root_CopyRoutines.h"); // Add file header time_t t = time(NULL); ofs << "//" << endl; ofs << "// Auto-generated HDDM to ROOT copy routines DO NOT EDIT" << endl; ofs << "//" << endl; ofs << "// "<::iterator iter; for(unsigned int depth=0; depthsecond.depth != depth) continue; if(iter->first == "HDDM_t")continue; ofs << "#include \"" << iter->first << ".h\"" << endl; } } ofs << "#undef Particle_t" << endl; ofs << endl; ofs << endl; ofs << "#include "<first; string varname = name.substr(0, name.length()-2); string name_hddm = NameToHDDMname(varname); if(varname == "HDDM")continue; ofs << "void Copy"<first; string varname = name.substr(0, name.length()-2); string name_hddm = NameToHDDMname(varname); if(varname == "HDDM")continue; ofs << "void Clear"<first; string varname = name.substr(0, name.length()-2); string name_hddm = NameToHDDMname(varname); string name_hddm_plural = HDDMPlural(name_hddm); map &members = iter->second.members; if(varname == "HDDM")continue; ofs << "void Copy"<::iterator iter_members; for(iter_members=members.begin(); iter_members!=members.end(); iter_members++){ string myname = iter_members->first; string mytype = iter_members->second; string myvarname = myname; string myname_hddm = NameToHDDMname(myvarname); if( mytype == "int" || mytype == "float" || mytype == "bool" || mytype == "Particle_t" || mytype == "string"){ // Atomic type uses equals ofs << " " << varname<<"."<first; string varname = name.substr(0, name.length()-2); string name_hddm = NameToHDDMname(varname); string name_hddm_plural = HDDMPlural(name_hddm); map &members = iter->second.members; if(varname == "HDDM")continue; ofs << "void Clear"<::iterator iter_members; for(iter_members=members.begin(); iter_members!=members.end(); iter_members++){ string myname = iter_members->first; string mytype = iter_members->second; string myvarname = myname; string myname_hddm = NameToHDDMname(myvarname); if(mytype == "int" || mytype == "Particle_t"){ ofs << " " << varname<<"."<" << endl; ofs << "#include " << endl; ofs << "#include " << endl; ofs << "#include " << endl; ofs << "#include " << endl; ofs << "using namespace std;" << endl; ofs << endl; ofs << "#include \"hddm_root_CopyRoutines.h\"" << endl; ofs << endl; ofs << endl; // Add main ofs << "int main(int narg, char *argv[])" << endl; ofs << "{" << endl; ofs << endl; ofs << " string usage = \"Usage:\\n\\n hddm2root_"<::iterator iter; for(iter=CLASSES.begin(); iter!=CLASSES.end(); iter++){ if(iter->second.depth!=TARGET_DEPTH)continue; string name = iter->first; string varname = name.substr(0, name.length()-2); ofs << " " << name << " *"<Branch(\""<> xrec;"<second.depth!=TARGET_DEPTH)continue; string name = iter->first; string varname = name.substr(0, name.length()-2); string name_hddm = NameToHDDMname(varname); ofs << " Clear" << name_hddm << "(*"<Fill();" << endl; ofs << " if(++N%10 == 0){cout<<\" \"<0 && N>=MAX_EVENTS)break;"<Write();" << endl; ofs << " f->Close();" << endl; ofs << " delete f;" << endl; ofs << endl; ofs << " cout< hddm2root $HALLD_HOME/src/libraries/HDDM/rest.xml"< hddm2root_r file.hddm"<= narg){ cerr<