/*************************************************************************** * Copyright (C) 2006 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef PROG_XML_TO_DATA_H #define PROG_XML_TO_DATA_H #include #include #include #include "xml_to_data.h" #include "devices/list/device_list.h" //---------------------------------------------------------------------------- template class ExtXmlToData : public ::XmlToData { public: ExtXmlToData(const TQString &basename, const TQString &namespac) : _basename(basename), _namespace(namespac) {} protected: TQString _basename, _namespace; virtual bool hasFamilies() const { return true; } const TQStringList &families() const { return _families; } virtual uint familyIndex(const TQString &family) const { return _families.findIndex(family); } virtual void parseData(TQDomElement, Data &) = 0; virtual void includes(TQTextStream &) const {} virtual void outputData(const Data &, TQTextStream &) const {} virtual void outputFunctions(TQTextStream &) const {} virtual TQString currentDevice() const { return _current; } virtual void parseDevice(TQDomElement element); ::Group::Support extractSupport(const TQString &s) const; bool hasDevice(const TQString &device) const { return _map.contains(device); } virtual void parse(); protected: TQString _current; class PData { public: uint family; ::Group::Support support; Data data; }; TQMap _map; TQStringList _families; virtual void output(); }; template Group::Support ExtXmlToData::extractSupport(const TQString &s) const { if ( s.isEmpty() ) return Group::Support::Untested; Group::Support support = Group::Support::fromKey(s); if ( support==Group::Support::None ) qFatal("Cannot be \"not supported\""); if ( support==Group::Support::Nb_Types ) qFatal("Unknown support type"); return support; } template void ExtXmlToData::parseDevice(TQDomElement element) { if ( element.nodeName()!="device" ) qFatal("Root node child should be named \"device\""); _current = element.attribute("name").upper(); if ( Device::lister().data(_current)==0 ) qFatal(TQString("Device name \"%1\" unknown").tqarg(_current)); if ( _map.contains(_current) ) qFatal(TQString("Device \"%1\" already parsed").tqarg(_current)); PData data; if ( hasFamilies() ) { TQString family = element.attribute("family"); if ( family.isEmpty() ) qFatal(TQString("Family is empty").tqarg(family)); if ( _families.find(family)==_families.end() ) _families.append(family); data.family = familyIndex(family); } data.support = extractSupport(element.attribute("support_type")); parseData(element, data.data); _map[_current] = data; } template void ExtXmlToData::parse() { TQDomDocument doc = parseFile(_basename + ".xml"); TQDomElement root = doc.documentElement(); if ( root.nodeName()!="type" ) qFatal("Root node should be \"type\""); if ( root.attribute("name")!=_basename ) qFatal(TQString("Root node name is not \"%1\"").tqarg(_basename)); TQDomNode child = root.firstChild(); while ( !child.isNull() ) { if ( child.isComment() ) qDebug("comment: %s", child.toComment().data().latin1()); else { if ( !child.isElement() ) qFatal("Root node child should be an element"); parseDevice(child.toElement()); } child = child.nextSibling(); } } template void ExtXmlToData::output() { // write .cpp file TQFile file(_basename + "_data.cpp"); if ( !file.open(IO_WriteOnly) ) qFatal(TQString("Cannot open output file \"%1\"").tqarg(file.name())); TQTextStream s(&file); s << "// #### Do not edit: this file is autogenerated !!!" << endl << endl; s << "#include \"devices/list/device_list.h\"" << endl; s << "#include \"" + _basename + ".h\"" << endl; s << "#include \"" + _basename + "_data.h\"" << endl; includes(s); s << endl; s << "namespace " << _namespace << endl; s << "{" << endl; s << "struct CData {" << endl; s << " const char *name;" << endl; if ( hasFamilies() ) s << " uint family;" << endl; s << " uint support;" << endl; s << " Data data;" << endl; s << "};" << endl; s << endl; // data list typename TQMap::const_iterator it = _map.begin(); for (; it!=_map.end(); ++it) { s << "const CData PIC" << it.key() << "_DATA = {"; s << " \"" << it.key() << "\", "; if ( hasFamilies() ) s << it.data().family << ", "; s << it.data().support.type() << ", "; s << "{ "; outputData(it.data().data, s); s << " }"; s << " };" << endl; } s << endl; s << "const CData *DATA_LIST[] = {" << endl; uint i = 0; it = _map.begin(); for (; it!=_map.end(); ++it) { s << "&PIC" << it.key() << "_DATA,"; i++; if ( (i%10)==0 ) s << endl; } s << "0 " << endl; s << "};" << endl; // functions s << endl; s << "const CData *cdata(const TQString &device)" << endl; s << "{" << endl; s << " for(uint i=0; DATA_LIST[i]; i++)" << endl; s << " if ( device==DATA_LIST[i]->name ) return DATA_LIST[i];" << endl; s << " return 0;" << endl; s << "}" << endl; s << "bool isSupported(const TQString &device)" << endl; s << "{" << endl; s << " return cdata(device);" << endl; s << "}" << endl; if ( hasFamilies() ) { s << "uint family(const TQString &device)" << endl; s << "{" << endl; s << " return cdata(device)->family;" << endl; s << "}" << endl; } s << "::Group::Support support(const TQString &device)" << endl; s << "{" << endl; s << " return ::Group::Support::Type(cdata(device)->support);" << endl; s << "}" << endl; s << "const Data &data(const TQString &device)" << endl; s << "{" << endl; s << " return cdata(device)->data;" << endl; s << "}" << endl; s << endl; outputFunctions(s); s << endl; s << "}" << endl; } //---------------------------------------------------------------------------- namespace Programmer { template class XmlToData : public ExtXmlToData { public: XmlToData(const TQString &basename, const TQString &namespac) : ExtXmlToData(basename, namespac) {} protected: virtual void outputFunctions(TQTextStream &s) const; virtual void includes(TQTextStream &) const; }; template void Programmer::XmlToData::outputFunctions(TQTextStream &s) const { s << "void Group::initSupported()" << endl; s << "{" << endl; s << " for (uint i=0; DATA_LIST[i]; i++) {" << endl; s << " const Device::Data *data = Device::lister().data(DATA_LIST[i]->name);" << endl; s << " addDevice(data->name(), data, ::Group::Support::Type(DATA_LIST[i]->support));" << endl; s << " }" << endl; s << "}" << endl; s << endl; } template void Programmer::XmlToData::includes(TQTextStream &s) const { s << "#include \"" << ExtXmlToData::_basename << "_prog.h\"" << endl; } } // namespace #endif