📄 helpgen.cpp
字号:
op.m_RetType.c_str(), funcname.c_str()); m_textFunc += func;}void HelpGenVisitor::VisitParameter( spParameter& param ){ if ( m_funcName.empty() ) return; if ( m_isFirstParam ) { m_isFirstParam = false; } else { m_textFunc << ", "; } m_textFunc << "\\param{" << param.m_Type << " }{" << param.GetName(); wxString defvalue = param.m_InitVal; if ( !defvalue.empty() ) { m_textFunc << " = " << defvalue; } m_textFunc << '}';}// ---------------------------------------------------------------------------// DocManager// ---------------------------------------------------------------------------DocManager::DocManager(bool checkParamNames){ m_checkParamNames = checkParamNames;}size_t DocManager::TryMatch(const char *str, const char *match){ size_t lenMatch = 0; while ( str[lenMatch] == match[lenMatch] ) { lenMatch++; if ( match[lenMatch] == '\0' ) return lenMatch; } return 0;}bool DocManager::SkipUntil(const char **pp, char c){ const char *p = *pp; while ( *p != c ) { if ( *p == '\0' ) break; if ( *p == '\n' ) m_line++; p++; } *pp = p; return *p == c;}bool DocManager::SkipSpaceUntil(const char **pp, char c){ const char *p = *pp; while ( *p != c ) { if ( !isspace(*p) || *p == '\0' ) break; if ( *p == '\n' ) m_line++; p++; } *pp = p; return *p == c;}wxString DocManager::ExtractStringBetweenBraces(const char **pp){ wxString result; if ( !SkipSpaceUntil(pp, '{') ) { wxLogWarning("file %s(%d): '{' expected after '\\param'", m_filename.c_str(), (int)m_line); } else { const char *startParam = ++*pp; // skip '{' if ( !SkipUntil(pp, '}') ) { wxLogWarning("file %s(%d): '}' expected after '\\param'", m_filename.c_str(), (int)m_line); } else { result = wxString(startParam, (*pp)++ - startParam); } } return result;}bool DocManager::ParseTeXFile(const wxString& filename){ m_filename = filename; wxFile file(m_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; } // reinit everything m_line = 1; wxLogVerbose("%s: starting to parse doc file '%s'.", GetCurrentTimeFormatted("%H:%M:%S"), m_filename.c_str()); // the name of the class from the last "\membersection" command: we assume // that the following "\func" or "\constfunc" always documents a method of // this class (and it should always be like that in wxWidgets documentation) wxString classname; for ( const char *current = buf; current - buf < len; current++ ) { // FIXME parsing is awfully inefficient if ( *current == '%' ) { // comment, skip until the end of line current++; SkipUntil(¤t, '\n'); continue; } // all the command we're interested in start with '\\' while ( *current != '\\' && *current != '\0' ) { if ( *current++ == '\n' ) m_line++; } if ( *current == '\0' ) { // no more TeX commands left break; } current++; // skip '\\' enum { Nothing, Func, ConstFunc, MemberSect } foundCommand = Nothing; size_t lenMatch = TryMatch(current, "func"); if ( lenMatch ) { foundCommand = Func; } else { lenMatch = TryMatch(current, "constfunc"); if ( lenMatch ) foundCommand = ConstFunc; else { lenMatch = TryMatch(current, "membersection"); if ( lenMatch ) foundCommand = MemberSect; } } if ( foundCommand == Nothing ) continue; current += lenMatch; if ( !SkipSpaceUntil(¤t, '{') ) { wxLogWarning("file %s(%d): '{' expected after \\func, " "\\constfunc or \\membersection.", m_filename.c_str(), (int)m_line); continue; } current++; if ( foundCommand == MemberSect ) { // what follows has the form <classname>::<funcname> const char *startClass = current; if ( !SkipUntil(¤t, ':') || *(current + 1) != ':' ) { wxLogWarning("file %s(%d): '::' expected after " "\\membersection.", m_filename.c_str(), (int)m_line); } else { classname = wxString(startClass, current - startClass); TeXUnfilter(&classname); } continue; } // extract the return type const char *startRetType = current; if ( !SkipUntil(¤t, '}') ) { wxLogWarning("file %s(%d): '}' expected after return type", m_filename.c_str(), (int)m_line); continue; } wxString returnType = wxString(startRetType, current - startRetType); TeXUnfilter(&returnType); current++; if ( !SkipSpaceUntil(¤t, '{') ) { wxLogWarning("file %s(%d): '{' expected after return type", m_filename.c_str(), (int)m_line); continue; } current++; const char *funcEnd = current; if ( !SkipUntil(&funcEnd, '}') ) { wxLogWarning("file %s(%d): '}' expected after function name", m_filename.c_str(), (int)m_line); continue; } wxString funcName = wxString(current, funcEnd - current); current = funcEnd + 1; // trim spaces from both sides funcName.Trim(false); funcName.Trim(true); // special cases: '$...$' may be used for LaTeX inline math, remove the // '$'s if ( funcName.Find('$') != wxNOT_FOUND ) { wxString name; for ( const char *p = funcName.c_str(); *p != '\0'; p++ ) { if ( *p != '$' && !isspace(*p) ) name += *p; } funcName = name; } // \destruct{foo} is really ~foo if ( funcName[0u] == '\\' ) { size_t len = strlen("\\destruct{"); if ( funcName(0, len) != "\\destruct{" ) { wxLogWarning("file %s(%d): \\destruct expected", m_filename.c_str(), (int)m_line); continue; } funcName.erase(0, len); funcName.Prepend('~'); if ( !SkipSpaceUntil(¤t, '}') ) { wxLogWarning("file %s(%d): '}' expected after destructor", m_filename.c_str(), (int)m_line); continue; } funcEnd++; // there is an extra '}' to count } TeXUnfilter(&funcName); // extract params current = funcEnd + 1; // skip '}' if ( !SkipSpaceUntil(¤t, '{') || (current++, !SkipSpaceUntil(¤t, '\\')) ) { wxLogWarning("file %s(%d): '\\param' or '\\void' expected", m_filename.c_str(), (int)m_line); continue; } wxArrayString paramNames, paramTypes, paramValues; bool isVararg = false; current++; // skip '\\' lenMatch = TryMatch(current, "void"); if ( !lenMatch ) { lenMatch = TryMatch(current, "param"); while ( lenMatch && (current - buf < len) ) { current += lenMatch; // now come {paramtype}{paramname} wxString paramType = ExtractStringBetweenBraces(¤t); if ( !paramType.empty() ) { wxString paramText = ExtractStringBetweenBraces(¤t); if ( !paramText.empty() ) { // the param declaration may contain default value wxString paramName = paramText.BeforeFirst('='), paramValue = paramText.AfterFirst('='); // sanitize all strings TeXUnfilter(¶mValue); TeXUnfilter(¶mName); TeXUnfilter(¶mType); paramValues.Add(paramValue); paramNames.Add(paramName); paramTypes.Add(paramType); } } else { // vararg function? wxString paramText = ExtractStringBetweenBraces(¤t); if ( paramText == "..." ) { isVararg = true; } else { wxLogWarning("Parameters of '%s::%s' are in " "incorrect form.", classname.c_str(), funcName.c_str()); } } // what's next? current = SkipSpaces(current); if ( *current == ',' || *current == '}' ) { current = SkipSpaces(++current); lenMatch = TryMatch(current, "\\param"); } else { wxLogWarning("file %s(%d): ',' or '}' expected after " "'\\param'", m_filename.c_str(), (int)m_line); continue; } } // if we got here there was no '\\void', so must have some params if ( paramNames.IsEmpty() ) { wxLogWarning("file %s(%d): '\\param' or '\\void' expected", m_filename.c_str(), (int)m_line); continue; } } // verbose diagnostic output wxString paramsAll; size_t param, paramCount = paramNames.GetCount(); for ( param = 0; param < paramCount; param++ ) { if ( param != 0 ) { paramsAll << ", "; } paramsAll << paramTypes[param] << ' ' << paramNames[param]; } wxString constStr; if (foundCommand == ConstFunc) constStr = _T(" const"); wxLogVerbose("file %s(%d): found '%s %s::%s(%s)%s'", m_filename.c_str(), (int)m_line, returnType.c_str(), classname.c_str(), funcName.c_str(), paramsAll.c_str(), constStr.c_str()); // store the info about the just found function ArrayMethodInfo *methods; int index = m_classes.Index(classname); if ( index == wxNOT_FOUND ) { m_classes.Add(classname); methods = new ArrayMethodInfo; m_methods.Add(methods); } else { methods = m_methods[(size_t)index]; } ArrayParamInfo params; for ( param = 0; param < paramCount; param++ ) { params.Add(new ParamInfo(paramTypes[param], paramNames[param], paramValues[param])); } MethodInfo *method = new MethodInfo(returnType, funcName, params); if ( foundCommand == ConstFunc ) method->SetFlag(MethodInfo::Const); if ( isVararg ) method->SetFlag(MethodInfo::Vararg); methods->Add(method); } delete [] buf; wxLogVerbose("%s: finished parsing doc file '%s'.\n", GetCurrentTimeFormatted("%H:%M:%S"), m_filename.c_str()); return true;}bool DocManager::DumpDifferences(spContext *ctxTop) const{ typedef MMemberListT::const_iterator MemberIndex; bool foundDiff = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -