bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename) { wxTextFile tf; if (!tf.Open(filename)) { wxLogError("can't open the '%s' preprocessor output file.", filename); return false; } size_t useful = 0; #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ for (unsigned int i=0; i < tf.GetLineCount(); i++) { const wxString& line = tf.GetLine(i); wxString defnameval = line.Mid(8); // what follows the "#define " string // the format of this line should be: // #define DEFNAME DEFVALUE if (!line.StartsWith("#define ")) { wxLogError("unexpected content in '%s' at line %d.", filename, i+1); return false; } if (defnameval.Contains(" ")) { // get DEFNAME wxString defname = defnameval.BeforeFirst(' '); if (defname.Contains("(")) continue; // this is a macro, skip it! // get DEFVAL wxString defval = defnameval.AfterFirst(' ').Strip(wxString::both); if (defval.StartsWith("(") && defval.EndsWith(")")) defval = defval.Mid(1, defval.Len()-2); // store this pair in the doxygen interface, where it can be useful m_doxyInterface.AddPreprocessorValue(defname, defval); useful++; } else { // it looks like the format of this line is: // #define DEFNAME // we are not interested to symbols #defined to nothing, // so we just ignore this line. } } wxLogMessage("Parsed %d preprocessor #defines from '%s' which will be used later...", useful, filename); return true; }
int IfaceCheckApp::OnRun() { long startTime = wxGetLocalTime(); // for timing purpose wxCmdLineParser parser(g_cmdLineDesc, argc, argv); parser.SetLogo( wxString::Format("wxWidgets Interface checker utility (built %s against %s)", __DATE__, wxVERSION_STRING)); // make the output more readable: wxLog::SetActiveTarget(new IfaceCheckLog); wxLog::DisableTimestamp(); // parse the command line... bool ok = true; wxString preprocFile; switch (parser.Parse()) { case 0: if (parser.Found(VERBOSE_SWITCH)) g_verbose = true; // IMPORTANT: parsing #define values must be done _before_ actually // parsing the GCC/doxygen XML files if (parser.Found(USE_PREPROCESSOR_OPTION, &preprocFile)) { if (!ParsePreprocessorOutput(preprocFile)) return 1; } // in any case set basic std preprocessor #defines: m_doxyInterface.AddPreprocessorValue("NULL", "0"); // parse the two XML files which contain the real and the doxygen interfaces // for wxWidgets API: if (!m_gccInterface.Parse(parser.GetParam(0)) || !m_doxyInterface.Parse(parser.GetParam(1))) return 1; if (parser.Found(DUMP_SWITCH)) { wxLogMessage("Dumping real API to '%s'...", API_DUMP_FILE); m_gccInterface.Dump(API_DUMP_FILE); wxLogMessage("Dumping interface API to '%s'...", INTERFACE_DUMP_FILE); m_doxyInterface.Dump(INTERFACE_DUMP_FILE); } else { if (parser.Found(MODIFY_SWITCH)) m_modify = true; if (parser.Found(PROCESS_ONLY_OPTION, &m_strToMatch)) { size_t len = m_strToMatch.Len(); if (m_strToMatch.StartsWith("\"") && m_strToMatch.EndsWith("\"") && len > 2) m_strToMatch = m_strToMatch.Mid(1, len-2); } ok = Compare(); } PrintStatistics(wxGetLocalTime() - startTime); return ok ? 0 : 1; default: wxPrintf("\nThis utility checks that the interface XML files created by Doxygen are in\n"); wxPrintf("synch with the real headers (whose contents are extracted by the gcc XML file).\n\n"); wxPrintf("The 'gccXML' parameter should be the wxapi.xml file created by the 'rungccxml.sh'\n"); wxPrintf("script which resides in 'utils/ifacecheck'.\n"); wxPrintf("The 'doxygenXML' parameter should be the index.xml file created by Doxygen\n"); wxPrintf("for the wxWidgets 'interface' folder.\n\n"); wxPrintf("Since the gcc XML file does not contain info about #defines, if you use\n"); wxPrintf("the -%s option, you'll get a smaller number of false warnings.\n", USE_PREPROCESSOR_OPTION); // HELP_SWITCH was passed or a syntax error occurred return 0; } }