diff --git a/utils/wxrc/wxrc.cpp b/utils/wxrc/wxrc.cpp index f7a5d9a14f..fc522790b2 100644 --- a/utils/wxrc/wxrc.cpp +++ b/utils/wxrc/wxrc.cpp @@ -242,8 +242,10 @@ private: ExtractedStrings FindStrings(); ExtractedStrings FindStrings(const wxString& filename, wxXmlNode *node); - bool flagVerbose, flagCPP, flagPython, flagGettext; - wxString parOutput, parFuncname, parOutputPath; + bool Validate(); + + bool flagVerbose, flagCPP, flagPython, flagGettext, flagValidate, flagValidateOnly; + wxString parOutput, parFuncname, parOutputPath, parSchemaFile; wxArrayString parFiles; int retCode; @@ -266,6 +268,9 @@ int XmlResApp::OnRun() { wxCMD_LINE_SWITCH, "g", "gettext", "output list of translatable strings (to stdout or file if -o used)" }, { wxCMD_LINE_OPTION, "n", "function", "C++/Python function name (with -c or -p) [InitXmlResource]" }, { wxCMD_LINE_OPTION, "o", "output", "output file [resource.xrs/cpp]" }, + { wxCMD_LINE_SWITCH, "", "validate", "check XRC correctness (in addition to other processing)" }, + { wxCMD_LINE_SWITCH, "", "validate-only", "check XRC correctness and do nothing else" }, + { wxCMD_LINE_OPTION, "", "xrc-schema", "RELAX NG schema file to validate against (optional)" }, #if 0 // not yet implemented { wxCMD_LINE_OPTION, "l", "list-of-handlers", "output list of necessary handlers to this file" }, #endif @@ -286,6 +291,15 @@ int XmlResApp::OnRun() case 0: retCode = 0; ParseParams(parser); + + if (flagValidate) + { + if ( !Validate() ) + return 2; + if ( flagValidateOnly ) + return 0; + } + if (flagGettext) OutputGettext(); else @@ -305,7 +319,10 @@ void XmlResApp::ParseParams(const wxCmdLineParser& cmdline) flagCPP = cmdline.Found("c"); flagPython = cmdline.Found("p"); flagH = flagCPP && cmdline.Found("e"); + flagValidateOnly = cmdline.Found("validate-only"); + flagValidate = flagValidateOnly || cmdline.Found("validate"); + cmdline.Found("xrc-schema", &parSchemaFile); if (!cmdline.Found("o", &parOutput)) { @@ -990,3 +1007,56 @@ XmlResApp::FindStrings(const wxString& filename, wxXmlNode *node) } return arr; } + + +bool XmlResApp::Validate() +{ + if ( flagVerbose ) + wxPuts("validating XRC files..."); + + wxString schemaURI; + + if ( !parSchemaFile.empty() ) + { + schemaURI = parSchemaFile; + } + else + { + schemaURI = "http://www.wxwidgets.org/wxxrc"; + + // Normally, we'd use an OASIS XML catalog to map the URI to a local copy, + // but Jing's catalog support (-C catalogFile) requires additional + // dependency, resolver.jar, that is not commonly installed alongside Jing + // by systems that package Jing. So do the (trivial) mapping manually here: + wxString wxWinRoot; + if ( wxGetEnv("WXWIN", &wxWinRoot) ) + { + wxString schemaFile(wxWinRoot + "/misc/schema/xrc_schema.rnc"); + if ( wxFileExists(schemaFile) ) + schemaURI = schemaFile; + } + } + + wxString cmdline = wxString::Format("jing -c \"%s\"", schemaURI); + for ( size_t i = 0; i < parFiles.GetCount(); i++ ) + cmdline << wxString::Format(" \"%s\"", parFiles[i]); + + int res = wxExecute(cmdline, wxEXEC_BLOCK); + if (res == -1) + { + wxLogError("Running RELAX NG validator failed."); + wxLogError("Please install Jing (http://www.thaiopensource.com/relaxng/jing.html)."); + wxLogError("See http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk/misc/schema/README for more information."); + return false; + } + + if ( flagVerbose ) + { + if ( res == 0 ) + wxPuts("XRC validation passed without errors."); + else + wxPuts("XRC validation failed, there are errors."); + } + + return res == 0; +}