📄 helpgen.cpp
字号:
bool operator==(const wxString& type) const { return m_type == type; } bool operator!=(const wxString& type) const { return m_type != type; } const wxString& GetName() const { return m_type; } private: wxString m_type; }; friend class ParamInfo; // for access to TypeInfo // info abotu a function parameter class ParamInfo { public: ParamInfo(const wxString& type, const wxString& name, const wxString& value) : m_type(type), m_name(name), m_value(value) { } const TypeInfo& GetType() const { return m_type; } const wxString& GetName() const { return m_name; } const wxString& GetDefValue() const { return m_value; } private: TypeInfo m_type; // type of parameter wxString m_name; // name wxString m_value; // default value };public: // FIXME: macro requires it WX_DEFINE_ARRAY_PTR(ParamInfo *, ArrayParamInfo); // info about a function struct MethodInfo { public: enum MethodFlags { Const = 0x0001, Virtual = 0x0002, Pure = 0x0004, Static = 0x0008, Vararg = 0x0010 }; MethodInfo(const wxString& type, const wxString& name, const ArrayParamInfo& params) : m_typeRet(type), m_name(name), m_params(params) { m_flags = 0; } void SetFlag(MethodFlags flag) { m_flags |= flag; } const TypeInfo& GetType() const { return m_typeRet; } const wxString& GetName() const { return m_name; } const ParamInfo& GetParam(size_t n) const { return *(m_params[n]); } size_t GetParamCount() const { return m_params.GetCount(); } bool HasFlag(MethodFlags flag) const { return (m_flags & flag) != 0; } ~MethodInfo() { WX_CLEAR_ARRAY(m_params); } private: TypeInfo m_typeRet; // return type wxString m_name; int m_flags; // bit mask of the value from the enum above ArrayParamInfo m_params; }; WX_DEFINE_ARRAY_PTR(MethodInfo *, ArrayMethodInfo); WX_DEFINE_ARRAY_PTR(ArrayMethodInfo *, ArrayMethodInfos);private: // first array contains the names of all classes we found, the second has a // pointer to the array of methods of the given class at the same index as // the class name appears in m_classes wxArrayString m_classes; ArrayMethodInfos m_methods; // are we checking parameter names? bool m_checkParamNames;private: DocManager(const DocManager&); DocManager& operator=(const DocManager&);};// =============================================================================// implementation// =============================================================================static char **g_argv = NULL;// this function never returnsstatic void usage(){ wxString prog = g_argv[0]; wxString basename = prog.AfterLast('/');#ifdef __WXMSW__ if ( !basename ) basename = prog.AfterLast('\\');#endif if ( !basename ) basename = prog; wxLogMessage("usage: %s [global options] <mode> [mode options] <files...>\n""\n"" where global options are:\n"" -q be quiet\n"" -v be verbose\n"" -H give this usage message\n"" -V print the version info\n"" -i file file with classes/function to ignore\n""\n"" where mode is one of: dump, diff\n""\n"" dump means generate .tex files for TeX2RTF converter from specified\n"" headers files, mode options are:\n"" -f overwrite existing files\n"" -o outdir directory for generated files\n""\n"" diff means compare the set of methods documented .tex file with the\n"" methods declared in the header:\n"" %s diff <file.h> <files.tex...>.\n"" mode specific options are:\n"" -p do check parameter names (not done by default)\n""\n", basename.c_str(), basename.c_str()); exit(1);}int main(int argc, char **argv){ g_argv = argv; wxInitializer initializer; if ( !initializer ) { fprintf(stderr, "Failed to initialize the wxWidgets library, aborting."); return -1; } enum { Mode_None, Mode_Dump, Mode_Diff } mode = Mode_None; if ( argc < 2 ) { usage(); } wxArrayString filesH, filesTeX; wxString directoryOut, // directory for 'dmup' output ignoreFile; // file with classes/functions to ignore bool overwrite = false, // overwrite existing files during 'dump'? paramNames = false; // check param names during 'diff'? for ( int current = 1; current < argc ; current++ ) { // all options have one letter if ( argv[current][0] == '-' ) { if ( argv[current][2] == '\0' ) { switch ( argv[current][1] ) { case 'v': // be verbose wxLog::GetActiveTarget()->SetVerbose(); continue; case 'q': // be quiet wxLog::GetActiveTarget()->SetVerbose(false); continue; case 'H': // help requested usage(); // doesn't return case 'V': // version requested wxLogMessage("HelpGen version %s\n" "(c) 1999-2001 Vadim Zeitlin\n", GetVersionString().c_str()); return 0; case 'i': current++; if ( current >= argc ) { wxLogError("-i option requires an argument."); break; } ignoreFile = argv[current]; continue; case 'p': if ( mode != Mode_Diff ) { wxLogError("-p is only valid with diff."); break; } paramNames = true; continue; case 'f': if ( mode != Mode_Dump ) { wxLogError("-f is only valid with dump."); break; } overwrite = true; continue; case 'o': if ( mode != Mode_Dump ) { wxLogError("-o is only valid with dump."); break; } current++; if ( current >= argc ) { wxLogError("-o option requires an argument."); break; } directoryOut = argv[current]; if ( !directoryOut.empty() ) { // terminate with a '/' if it doesn't have it switch ( directoryOut.Last() ) { case '/':#ifdef __WXMSW__ case '\\':#endif break; default: directoryOut += '/'; } } //else: it's empty, do nothing continue; default: wxLogError("unknown option '%s'", argv[current]); break; } } else { wxLogError("only one letter options are allowed, not '%s'.", argv[current]); } // only get here after a break from switch or from else branch of if usage(); } else { if ( mode == Mode_None ) { if ( strcmp(argv[current], "diff") == 0 ) mode = Mode_Diff; else if ( strcmp(argv[current], "dump") == 0 ) mode = Mode_Dump; else { wxLogError("unknown mode '%s'.", argv[current]); usage(); } } else { if ( mode == Mode_Dump || filesH.IsEmpty() ) { filesH.Add(argv[current]); } else { // 2nd files and further are TeX files in diff mode wxASSERT( mode == Mode_Diff ); filesTeX.Add(argv[current]); } } } } // create a parser object and a visitor derivation CJSourceParser parser; HelpGenVisitor visitor(directoryOut, overwrite); if ( !ignoreFile.empty() && mode == Mode_Dump ) visitor.GetIgnoreHandler().AddNamesFromFile(ignoreFile); spContext *ctxTop = NULL; // parse all header files size_t nFiles = filesH.GetCount(); for ( size_t n = 0; n < nFiles; n++ ) { wxString header = filesH[n]; ctxTop = parser.ParseFile(header); if ( !ctxTop ) { wxLogWarning("Header file '%s' couldn't be processed.", header.c_str()); } else if ( mode == Mode_Dump ) { ((spFile *)ctxTop)->m_FileName = header; visitor.VisitAll(*ctxTop); visitor.EndVisit(); }#ifdef __WXDEBUG__ if ( 0 && ctxTop ) ctxTop->Dump(wxEmptyString);#endif // __WXDEBUG__ } // parse all TeX files if ( mode == Mode_Diff ) { if ( !ctxTop ) { wxLogError("Can't complete diff."); // failure return false; } DocManager docman(paramNames); size_t nFiles = filesTeX.GetCount(); for ( size_t n = 0; n < nFiles; n++ ) { wxString file = filesTeX[n]; if ( !docman.ParseTeXFile(file) ) { wxLogWarning("TeX file '%s' couldn't be processed.", file.c_str()); } } if ( !ignoreFile.empty() ) docman.GetIgnoreHandler().AddNamesFromFile(ignoreFile); docman.DumpDifferences(ctxTop); } return 0;}// -----------------------------------------------------------------------------// HelpGenVisitor implementation// -----------------------------------------------------------------------------HelpGenVisitor::HelpGenVisitor(const wxString& directoryOut, bool overwrite) : m_directoryOut(directoryOut){ m_overwrite = overwrite; Reset();}void HelpGenVisitor::Reset(){ m_inClass = m_inTypesSection = m_inMethodSection = false; m_classname = m_funcName = m_textFunc = m_textStoredTypedefs = m_textStoredFunctionComment = wxEmptyString; m_arrayFuncDocs.Empty(); m_storedEnums.Empty(); m_storedEnumsVerb.Empty(); m_headers.Empty();}void HelpGenVisitor::InsertTypedefDocs(){ m_file.WriteTeX(m_textStoredTypedefs); m_textStoredTypedefs.Empty();}void HelpGenVisitor::InsertEnumDocs(){ size_t count = m_storedEnums.GetCount(); for ( size_t n = 0; n < count; n++ ) { m_file.WriteTeX(m_storedEnums[n]); m_file.WriteVerbatim(m_storedEnumsVerb[n] + '\n'); } m_storedEnums.Empty(); m_storedEnumsVerb.Empty();}void HelpGenVisitor::InsertDataStructuresHeader(){ if ( !m_inTypesSection ) { m_inTypesSection = true; m_file.WriteVerbatim("\\wxheading{Data structures}\n\n"); }}void HelpGenVisitor::InsertMethodsHeader(){ if ( !m_inMethodSection ) { m_inMethodSection = true; m_file.WriteVerbatim( "\\latexignore{\\rtfignore{\\wxheading{Members}}}\n\n"); }}void HelpGenVisitor::CloseFunction(){ if ( !m_funcName.empty() ) { if ( m_isFirstParam ) { // no params found m_textFunc << "\\void"; } m_textFunc << "}\n\n"; if ( !m_textStoredFunctionComment.empty() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -