📄 helpgen.cpp
字号:
// flag telling us whether the given class was found at all in the header size_t nClass, countClassesInDocs = m_classes.GetCount(); bool *classExists = new bool[countClassesInDocs]; for ( nClass = 0; nClass < countClassesInDocs; nClass++ ) { classExists[nClass] = false; } // ctxTop is normally an spFile wxASSERT( ctxTop->GetContextType() == SP_CTX_FILE ); const MMemberListT& classes = ctxTop->GetMembers(); for ( MemberIndex i = classes.begin(); i != classes.end(); i++ ) { spContext *ctx = *i; if ( ctx->GetContextType() != SP_CTX_CLASS ) { // TODO process also global functions, macros, ... continue; } spClass *ctxClass = (spClass *)ctx; const wxString& nameClass = ctxClass->m_Name; int index = m_classes.Index(nameClass); if ( index == wxNOT_FOUND ) { if ( !m_ignoreNames.IgnoreClass(nameClass) ) { foundDiff = true; wxLogError("Class '%s' is not documented at all.", nameClass.c_str()); } // it makes no sense to check for its functions continue; } else { classExists[index] = true; } // array of method descriptions for this class const ArrayMethodInfo& methods = *(m_methods[index]); size_t nMethod, countMethods = methods.GetCount(); // flags telling if we already processed given function bool *methodExists = new bool[countMethods]; for ( nMethod = 0; nMethod < countMethods; nMethod++ ) { methodExists[nMethod] = false; } wxArrayString aOverloadedMethods; const MMemberListT& functions = ctxClass->GetMembers(); for ( MemberIndex j = functions.begin(); j != functions.end(); j++ ) { ctx = *j; if ( ctx->GetContextType() != SP_CTX_OPERATION ) continue; spOperation *ctxMethod = (spOperation *)ctx; const wxString& nameMethod = ctxMethod->m_Name; // find all functions with the same name wxArrayInt aMethodsWithSameName; for ( nMethod = 0; nMethod < countMethods; nMethod++ ) { if ( methods[nMethod]->GetName() == nameMethod ) aMethodsWithSameName.Add(nMethod); } if ( aMethodsWithSameName.IsEmpty() && ctxMethod->IsPublic() ) { if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) { foundDiff = true; wxLogError("'%s::%s' is not documented.", nameClass.c_str(), nameMethod.c_str()); } // don't check params continue; } else if ( aMethodsWithSameName.GetCount() == 1 ) { index = (size_t)aMethodsWithSameName[0u]; methodExists[index] = true; if ( m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) continue; if ( !ctxMethod->IsPublic() ) { wxLogWarning("'%s::%s' is documented but not public.", nameClass.c_str(), nameMethod.c_str()); } // check that the flags match const MethodInfo& method = *(methods[index]); bool isVirtual = ctxMethod->mIsVirtual; if ( isVirtual != method.HasFlag(MethodInfo::Virtual) ) { wxString virtualStr; if(isVirtual)virtualStr = _T("not "); wxLogWarning("'%s::%s' is incorrectly documented as %s" "virtual.", nameClass.c_str(), nameMethod.c_str(), virtualStr.c_str()); } bool isConst = ctxMethod->mIsConstant; if ( isConst != method.HasFlag(MethodInfo::Const) ) { wxString constStr; if(isConst)constStr = _T("not "); wxLogWarning("'%s::%s' is incorrectly documented as %s" "constant.", nameClass.c_str(), nameMethod.c_str(), constStr.c_str()); } // check that the params match const MMemberListT& params = ctxMethod->GetMembers(); if ( params.size() != method.GetParamCount() ) { wxLogError("Incorrect number of parameters for '%s::%s' " "in the docs: should be %d instead of %d.", nameClass.c_str(), nameMethod.c_str(), (int)params.size(), (int)method.GetParamCount()); } else { size_t nParam = 0; for ( MemberIndex k = params.begin(); k != params.end(); k++, nParam++ ) { ctx = *k; // what else can a function have? wxASSERT( ctx->GetContextType() == SP_CTX_PARAMETER ); spParameter *ctxParam = (spParameter *)ctx; const ParamInfo& param = method.GetParam(nParam); if ( m_checkParamNames && (param.GetName() != ctxParam->m_Name.c_str()) ) { foundDiff = true; wxLogError("Parameter #%d of '%s::%s' should be " "'%s' and not '%s'.", (int)(nParam + 1), nameClass.c_str(), nameMethod.c_str(), ctxParam->m_Name.c_str(), param.GetName().c_str()); continue; } if ( param.GetType() != ctxParam->m_Type ) { foundDiff = true; wxLogError("Type of parameter '%s' of '%s::%s' " "should be '%s' and not '%s'.", ctxParam->m_Name.c_str(), nameClass.c_str(), nameMethod.c_str(), ctxParam->m_Type.c_str(), param.GetType().GetName().c_str()); continue; } if ( param.GetDefValue() != ctxParam->m_InitVal.c_str() ) { wxLogWarning("Default value of parameter '%s' of " "'%s::%s' should be '%s' and not " "'%s'.", ctxParam->m_Name.c_str(), nameClass.c_str(), nameMethod.c_str(), ctxParam->m_InitVal.c_str(), param.GetDefValue().c_str()); } } } } else { // TODO OVER add real support for overloaded methods if ( m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) continue; if ( aOverloadedMethods.Index(nameMethod) == wxNOT_FOUND ) { // mark all methods with this name as existing for ( nMethod = 0; nMethod < countMethods; nMethod++ ) { if ( methods[nMethod]->GetName() == nameMethod ) methodExists[nMethod] = true; } aOverloadedMethods.Add(nameMethod); wxLogVerbose("'%s::%s' is overloaded and I'm too " "stupid to find the right match - skipping " "the param and flags checks.", nameClass.c_str(), nameMethod.c_str()); } //else: warning already given } } for ( nMethod = 0; nMethod < countMethods; nMethod++ ) { if ( !methodExists[nMethod] ) { const wxString& nameMethod = methods[nMethod]->GetName(); if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) { foundDiff = true; wxLogError("'%s::%s' is documented but doesn't exist.", nameClass.c_str(), nameMethod.c_str()); } } } delete [] methodExists; } // check that all classes we found in the docs really exist for ( nClass = 0; nClass < countClassesInDocs; nClass++ ) { if ( !classExists[nClass] ) { foundDiff = true; wxLogError("Class '%s' is documented but doesn't exist.", m_classes[nClass].c_str()); } } delete [] classExists; return !foundDiff;}DocManager::~DocManager(){ WX_CLEAR_ARRAY(m_methods);}// ---------------------------------------------------------------------------// IgnoreNamesHandler implementation// ---------------------------------------------------------------------------int IgnoreNamesHandler::CompareIgnoreListEntries(IgnoreListEntry *first, IgnoreListEntry *second){ // first compare the classes int rc = first->m_classname.Cmp(second->m_classname); if ( rc == 0 ) rc = first->m_funcname.Cmp(second->m_funcname); return rc;}bool IgnoreNamesHandler::AddNamesFromFile(const wxString& filename){ wxFile file(filename, wxFile::read); if ( !file.IsOpened() ) return false; off_t len = file.Length(); if ( len == wxInvalidOffset ) return false; char *buf = new char[len + 1]; buf[len] = '\0'; if ( file.Read(buf, len) == wxInvalidOffset ) { delete [] buf; return false; } wxString line; for ( const char *current = buf; ; current++ ) {#ifdef __WXMSW__ // skip DOS line separator if ( *current == '\r' ) current++;#endif // wxMSW if ( *current == '\n' || *current == '\0' ) { if ( line[0u] != '#' ) { if ( line.Find(':') != wxNOT_FOUND ) { wxString classname = line.BeforeFirst(':'), funcname = line.AfterLast(':'); m_ignore.Add(new IgnoreListEntry(classname, funcname)); } else { // entire class m_ignore.Add(new IgnoreListEntry(line, wxEmptyString)); } } //else: comment if ( *current == '\0' ) break; line.Empty(); } else { line += *current; } } delete [] buf; return true;}// -----------------------------------------------------------------------------// global function implementation// -----------------------------------------------------------------------------static wxString MakeLabel(const char *classname, const char *funcname){ wxString label(classname); if ( funcname && funcname[0] == '\\' ) { // we may have some special TeX macro - so far only \destruct exists, // but may be later others will be added static const char *macros[] = { "destruct" }; static const char *replacement[] = { "dtor" }; size_t n; for ( n = 0; n < WXSIZEOF(macros); n++ ) { if ( strncmp(funcname + 1, macros[n], strlen(macros[n])) == 0 ) { // found break; } } if ( n == WXSIZEOF(macros) ) { wxLogWarning("unknown function name '%s' - leaving as is.", funcname); } else { funcname = replacement[n]; } } if ( funcname ) { // special treatment for operatorXXX() stuff because the C operators // are not valid in LaTeX labels wxString oper; if ( wxString(funcname).StartsWith("operator", &oper) ) { label << "operator"; static const struct { const char *oper; const char *name; } operatorNames[] = { { "=", "assign" }, { "==", "equal" }, }; size_t n; for ( n = 0; n < WXSIZEOF(operatorNames); n++ ) { if ( oper == operatorNames[n].oper ) { label << operatorNames[n].name; break; } } if ( n == WXSIZEOF(operatorNames) ) { wxLogWarning("unknown operator '%s' - making dummy label.", oper.c_str()); label << "unknown"; } } else // simply use the func name { label << funcname; } } label.MakeLower(); return label;}static wxString MakeHelpref(const char *argument){ wxString helpref; helpref << "\\helpref{" << argument << "}{" << MakeLabel(argument) << '}'; return helpref;}static void TeXFilter(wxString* str){ // TeX special which can be quoted (don't include backslash nor braces as // we generate them static wxRegEx reNonSpecialSpecials("[#$%&_]"), reAccents("[~^]"); // just quote reNonSpecialSpecials.ReplaceAll(str, "\\\\\\0"); // can't quote these ones as they produce accents when preceded by // backslash, so put them inside verb reAccents.ReplaceAll(str, "\\\\verb|\\0|");}static void TeXUnfilter(wxString* str){ // FIXME may be done much more quickly str->Trim(true); str->Trim(false); // undo TeXFilter static wxRegEx reNonSpecialSpecials("\\\\([#$%&_{}])"), reAccents("\\\\verb\\|([~^])\\|"); reNonSpecialSpecials.ReplaceAll(str, "\\1"); reAccents.ReplaceAll(str, "\\1");}static wxString GetAllComments(const spContext& ctx){ wxString comments; const MCommentListT& commentsList = ctx.GetCommentList(); for ( MCommentListT::const_iterator i = commentsList.begin(); i != commentsList.end(); i++ ) { wxString comment = (*i)->GetText(); // don't take comments like "// ----------" &c comment.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -