📄 helpgen.cpp
字号:
m_classname = op.GetClass().GetName();
wxString funcname = op.GetName();
if ( m_ignoreNames.IgnoreMethod(m_classname, funcname) ) {
wxLogVerbose("Skipping ignored '%s::%s'.",
m_classname.c_str(), funcname.c_str());
return;
}
InsertMethodsHeader();
// save state info
m_funcName = funcname;
m_isFirstParam = true;
m_textStoredFunctionComment = GetAllComments(op);
// start function documentation
wxString totalText;
// check for the special case of dtor
wxString dtor;
if ( (funcname[0u] == '~') && (m_classname == funcname.c_str() + 1) ) {
dtor.Printf("\\destruct{%s}", m_classname.c_str());
funcname = dtor;
}
m_textFunc.Printf("\n"
"\\membersection{%s::%s}\\label{%s}\n",
m_classname.c_str(), funcname.c_str(),
MakeLabel(m_classname, funcname).c_str());
wxString constStr;
if(op.mIsConstant) constStr = _T("const");
wxString virtualStr;
if(op.mIsVirtual) virtualStr = _T("virtual ");
wxString func;
func.Printf(_T("\n")
_T("\\%sfunc{%s%s}{%s}{"),
constStr.c_str(),
virtualStr.c_str(),
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 << ", ";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -