Ticket #3931: mythtv_xml_include_v1.diff

File mythtv_xml_include_v1.diff, 5.5 KB (added by Roo <roo.watt@…>, 14 years ago)

v1 of patch, search path for parent and inluded files

  • mythtv/libs/libmyth/xmlparse.h

     
    5555    void parseKey(LayerSet *, QDomElement &);
    5656 
    5757  private:
    58     bool doLoadTheme(QDomElement &, QString, QString);
     58    bool doLoadTheme(QDomElement &, QString, QString, QStringList);
    5959    QMap<QString, fontProp> fontMap;
    6060    QMap<QString, LayerSet*> layerMap;
    6161    vector<LayerSet *> *allTypes;
     
    6464    double hmult;
    6565
    6666    int usetrans;
    67    
     67
     68    enum {INCLUDE_RECURSION_LIMIT = 10};
     69
    6870    QString fontSizeType;
    6971};
    7072
  • mythtv/libs/libmyth/xmlparse.cpp

     
    3434    fontSizeType = gContext->GetSetting("ThemeFontSizeType", "default");
    3535
    3636    QValueList<QString> searchpath = gContext->GetThemeSearchPath();
    37     for (QValueList<QString>::const_iterator ii = searchpath.begin();
    38         ii != searchpath.end(); ii++)
     37
     38    QString themefile = specialfile + "ui.xml";
     39
     40    if (doLoadTheme(ele, winName, themefile, searchpath))
    3941    {
    40         QString themefile = *ii + specialfile + "ui.xml";
    41         if (doLoadTheme(ele, winName, themefile))
    42         {
    43             VERBOSE(VB_GENERAL, "XMLParse::LoadTheme using " << themefile);
    44             return true;
    45         }
     42        VERBOSE(VB_GENERAL, "XMLParse::LoadTheme using " << themefile);
     43        return true;
    4644    }
    47    
     45
    4846    return false;
    4947}
    5048
    51 bool XMLParse::doLoadTheme(QDomElement &ele, QString winName, QString themeFile)
     49bool XMLParse::doLoadTheme(QDomElement &ele, QString winName,
     50        QString themeFile, QStringList searchpath)
    5251{
    53     QDomDocument doc;
    54     QFile f(themeFile);
     52    QFile f;
     53    bool fileSuccess = false;
     54    for (QValueList<QString>::const_iterator ii = searchpath.begin();
     55            ii != searchpath.end(); ii++)
     56    {
     57        f.setName( *ii + themeFile );
     58        if (f.open(IO_ReadOnly))
     59        {
     60            fileSuccess = true;
     61            break;
     62        }
     63    }
    5564
    56     if (!f.open(IO_ReadOnly))
    57     {   
    58         //cerr << "XMLParse::LoadTheme(): Can't open: " << themeFile << endl;
     65    if (!fileSuccess)
     66    {
     67        cerr << "XMLParse::LoadTheme(): Can't open: " << themeFile << endl;
    5968        return false;
    6069    }
    61      
     70
     71    QDomDocument doc;
    6272    QString errorMsg;
    6373    int errorLine = 0;
    6474    int errorColumn = 0;
    6575
     76    // Create xml document, report erros
    6677    if (!doc.setContent(&f, false, &errorMsg, &errorLine, &errorColumn))
    6778    {
    6879        cerr << "Error parsing: " << themeFile << endl;
     
    7182        f.close();
    7283        return false;
    7384    }
    74 
    7585    f.close();
     86    QDomElement docElem = doc.documentElement();
    7687
    77     QDomElement docElem = doc.documentElement();
     88    QDomDocument incDoc;
     89    uint includeRecursionCount = 0;
     90
     91    // Find include elements
     92    QDomNodeList includeFileList = docElem.elementsByTagName("include_file");
     93    while ( includeFileList.count() )
     94    {
     95        // Node to be replaced in original document
     96        QDomNode replacementNode = includeFileList.item(0);
     97
     98        // Get include file name
     99        QString includeFile = replacementNode.toElement().attribute("src","");
     100        if (includeFile.isEmpty())
     101        {
     102            cerr << "Expecting <include_file src=\"filename.xml\"/>" << endl;
     103            return false;
     104        }
     105
     106        QFile g;
     107        fileSuccess = false;
     108        for (QValueList<QString>::const_iterator ii = searchpath.begin();
     109                ii != searchpath.end(); ii++)
     110        {
     111            g.setName( *ii + includeFile );
     112            if (g.open(IO_ReadOnly))
     113            {
     114                fileSuccess = true;
     115                break;
     116            }
     117        }
     118
     119        if (!fileSuccess)
     120        {
     121            cerr << "XMLParse::LoadTheme(): Can't open include_file: "
     122                << includeFile << endl;
     123            return false;
     124        }
     125
     126        // Import doc reporting on errors
     127        if (!incDoc.setContent(&g, false, &errorMsg, &errorLine, &errorColumn))
     128        {
     129            cerr << "Error parsing: " << includeFile << endl;
     130            cerr << "at line: " << errorLine
     131                 << "  column: " << errorColumn << endl;
     132            cerr << errorMsg << endl;
     133            cerr << "Includes MUST be valid XML documents"
     134                    " with a single root element!" << endl;
     135            g.close();
     136            return false;
     137        }
     138        g.close();
     139
     140        // Insert all children from the include file root
     141        QDomNodeList includeNodeList = incDoc.documentElement().childNodes();
     142        while( includeNodeList.count() )
     143            replacementNode.parentNode()
     144                .insertBefore( includeNodeList.item(0), replacementNode );
     145
     146        if ( docElem.isNull() )
     147        {
     148            cerr << "*** Error detected whilst including \""
     149                 << includeFile << "\"!" << endl;
     150            return false;
     151        }
     152
     153        // Error out if include recursion limit met
     154        if ( ++includeRecursionCount >= INCLUDE_RECURSION_LIMIT )
     155        {
     156            cerr << "Error recursion limit reached: " << INCLUDE_RECURSION_LIMIT << endl;
     157            return false;
     158        }
     159
     160        // Delete <include_file>s
     161        replacementNode.parentNode().removeChild( replacementNode );
     162    }
     163
    78164    QDomNode n = docElem.firstChild();
    79165    while (!n.isNull())
    80166    {