⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helpgen.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:

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() ) {
            m_textFunc << m_textStoredFunctionComment << '\n';
        }

        m_arrayFuncDocs.Add(new FunctionDocEntry(m_funcName, m_textFunc));

        m_funcName.clear();
    }
}

void HelpGenVisitor::CloseClass()
{
    CloseFunction();

    if ( m_inClass )
    {
        size_t count = m_arrayFuncDocs.GetCount();
        if ( count )
        {
            size_t n;
            FunctionDocEntry::classname = m_classname;

            m_arrayFuncDocs.Sort(FunctionDocEntry::Compare);

            // Now examine each first line and if it's been seen, cut it
            // off (it's a duplicate \membersection)
            wxHashTable membersections(wxKEY_STRING);

            for ( n = 0; n < count; n++ )
            {
                wxString section(m_arrayFuncDocs[n].text);

                // Strip leading whitespace
                int pos = section.Find(_T("\\membersection"));
                if (pos > -1)
                {
                    section = section.Mid(pos);
                }

                wxString ms(section.BeforeFirst(wxT('\n')));
                if (membersections.Get(ms))
                {
                    m_arrayFuncDocs[n].text = section.AfterFirst(wxT('\n'));
                }
                else
                {
                    membersections.Put(ms.c_str(), & membersections);
                }
            }

            for ( n = 0; n < count; n++ ) {
                m_file.WriteTeX(m_arrayFuncDocs[n].text);
            }

            m_arrayFuncDocs.Empty();
        }

        m_inClass = false;
        m_classname.clear();
    }
    m_file.FlushAll();
}

void HelpGenVisitor::EndVisit()
{
    CloseFunction();

    CloseClass();

    m_fileHeader.Empty();

    m_file.FlushAll();
    if (m_file.IsOpened())
    {
        m_file.Flush();
        m_file.Close();
    }

    wxLogVerbose("%s: finished generating for the current file.",
                 GetCurrentTimeFormatted("%H:%M:%S"));
}

void HelpGenVisitor::VisitFile( spFile& file )
{
    m_fileHeader = file.m_FileName;
    wxLogVerbose("%s: started generating docs for classes from file '%s'...",
                 GetCurrentTimeFormatted("%H:%M:%S"), m_fileHeader.c_str());
}

void HelpGenVisitor::VisitClass( spClass& cl )
{
    CloseClass();

    if (m_file.IsOpened())
    {
        m_file.Flush();
        m_file.Close();
    }

    wxString name = cl.GetName();

    if ( m_ignoreNames.IgnoreClass(name) ) {
        wxLogVerbose("Skipping ignored class '%s'.", name.c_str());

        return;
    }

    // the file name is built from the class name by removing the leading "wx"
    // if any and converting it to the lower case
    wxString filename;
    if ( name(0, 2) == "wx" ) {
        filename << name.c_str() + 2;
    }
    else {
        filename << name;
    }

    filename.MakeLower();
    filename += ".tex";
    filename.Prepend(m_directoryOut);

    if ( !m_overwrite && wxFile::Exists(filename) ) {
        wxLogError("Won't overwrite existing file '%s' - please use '-f'.",
                   filename.c_str());

        return;
    }

    m_inClass = m_file.Open(filename, wxFile::write);
    if ( !m_inClass ) {
        wxLogError("Can't generate documentation for the class '%s'.",
                   name.c_str());

        return;
    }

    m_inMethodSection =
    m_inTypesSection = false;

    wxLogInfo("Created new file '%s' for class '%s'.",
              filename.c_str(), name.c_str());

    // write out the header
    wxString header;
    header.Printf("%%\n"
                  "%% automatically generated by HelpGen %s from\n"
                  "%% %s at %s\n"
                  "%%\n"
                  "\n"
                  "\n"
                  "\\section{\\class{%s}}\\label{%s}\n\n",
                  GetVersionString().c_str(),
                  m_fileHeader.c_str(),
                  GetCurrentTimeFormatted("%d/%b/%y %H:%M:%S"),
                  name.c_str(),
                  wxString(name).MakeLower().c_str());

    m_file.WriteVerbatim(header);

    // the entire text we're writing to file
    wxString totalText;

    // if the header includes other headers they must be related to it... try to
    // automatically generate the "See also" clause
    if ( !m_headers.IsEmpty() ) {
        // correspondence between wxWidgets headers and class names
        static const char *headers[] = {
            "object",
            "defs",
            "string",
            "dynarray",
            "file",
            "time",
        };

        // NULL here means not to insert anything in "See also" for the
        // corresponding header
        static const char *classes[] = {
            NULL,
            NULL,
            NULL,
            NULL,
            "wxFile",
            "wxTime",
        };

        wxASSERT_MSG( WXSIZEOF(headers) == WXSIZEOF(classes),
                      "arrays must be in sync!" );

        wxArrayInt interestingClasses;

        size_t count = m_headers.Count(), index;
        for ( size_t n = 0; n < count; n++ ) {
            wxString baseHeaderName = m_headers[n].Before('.');
            if ( baseHeaderName(0, 3) != "wx/" )
                continue;

            baseHeaderName.erase(0, 3);
            for ( index = 0; index < WXSIZEOF(headers); index++ ) {
                if ( Stricmp(baseHeaderName, headers[index]) == 0 )
                    break;
            }

            if ( (index < WXSIZEOF(headers)) && classes[index] ) {
                // interesting header
                interestingClasses.Add(index);
            }
        }

        if ( !interestingClasses.IsEmpty() ) {
            // do generate "See also" clause
            totalText << "\\wxheading{See also:}\n\n";

            count = interestingClasses.Count();
            for ( index = 0; index < count; index++ ) {
                if ( index > 0 )
                    totalText << ", ";

                totalText << MakeHelpref(classes[interestingClasses[index]]);
            }

            totalText << "\n\n";
        }
    }

    // the comment before the class generally explains what is it for so put it
    // in place of the class description
    if ( cl.HasComments() ) {
        wxString comment = GetAllComments(cl);

        totalText << '\n' << comment << '\n';
    }

    // derived from section
    wxString derived = "\\wxheading{Derived from}\n\n";

    const StrListT& baseClasses = cl.m_SuperClassNames;
    if ( baseClasses.size() == 0 ) {
        derived << "No base class";
    }
    else {
        bool first = true;
        for ( StrListT::const_iterator i = baseClasses.begin();
              i != baseClasses.end();
              i++ ) {
            if ( !first ) {
                // separate from the previous one
                derived << "\\\\\n";
            }
            else {
                first = false;
            }

            wxString baseclass = *i;
            derived << "\\helpref{" << baseclass << "}";
            derived << "{" << baseclass.MakeLower()  << "}";
        }
    }
    totalText << derived << "\n\n";

    // include file section
    wxString includeFile = "\\wxheading{Include files}\n\n";
    includeFile << "<" << m_fileHeader << ">";

    totalText << includeFile << "\n\n";

    // write all this to file
    m_file.WriteTeX(totalText);

    // if there were any enums/typedefs before, insert their documentation now
    InsertDataStructuresHeader();
    InsertTypedefDocs();
    InsertEnumDocs();

    //m_file.Flush();
}

void HelpGenVisitor::VisitEnumeration( spEnumeration& en )
{
    CloseFunction();

    if ( m_inMethodSection ) {
        // FIXME that's a bug, but tell the user aboit it nevertheless... we
        // should be smart enough to process even the enums which come after the
        // functions
        wxLogWarning("enum '%s' ignored, please put it before the class "
                     "methods.", en.GetName().c_str());
        return;
    }

    // simply copy the enum text in the docs
    wxString enumeration = GetAllComments(en),
             enumerationVerb;

    enumerationVerb << _T("\\begin{verbatim}\n")
                    << en.m_EnumContent
                    << _T("\n\\end{verbatim}\n");

    // remember for later use if we're not inside a class yet
    if ( !m_inClass ) {
        m_storedEnums.Add(enumeration);
        m_storedEnumsVerb.Add(enumerationVerb);
    }
    else {
        // write the header for this section if not done yet
        InsertDataStructuresHeader();

        m_file.WriteTeX(enumeration);
        m_file.WriteVerbatim(enumerationVerb);
        m_file.WriteVerbatim('\n');
    }
}

void HelpGenVisitor::VisitTypeDef( spTypeDef& td )
{
    CloseFunction();

    if ( m_inMethodSection ) {
        // FIXME that's a bug, but tell the user aboit it nevertheless...
        wxLogWarning("typedef '%s' ignored, please put it before the class "
                     "methods.", td.GetName().c_str());
        return;
    }

    wxString typedefdoc;
    typedefdoc << _T("{\\small \\begin{verbatim}\n")
               << _T("typedef ") << td.m_OriginalType << _T(' ') << td.GetName()
               << _T("\n\\end{verbatim}}\n")
               << GetAllComments(td);

    // remember for later use if we're not inside a class yet
    if ( !m_inClass ) {
        if ( !m_textStoredTypedefs.empty() ) {
            m_textStoredTypedefs << '\n';
        }

        m_textStoredTypedefs << typedefdoc;
    }
    else {
        // write the header for this section if not done yet
        InsertDataStructuresHeader();

        typedefdoc << '\n';
        m_file.WriteTeX(typedefdoc);
    }
}

void HelpGenVisitor::VisitPreprocessorLine( spPreprocessorLine& pd )
{
    switch ( pd.GetStatementType() ) {
        case SP_PREP_DEF_INCLUDE_FILE:
            m_headers.Add(pd.CPP_GetIncludedFileNeme());
            break;

        case SP_PREP_DEF_DEFINE_SYMBOL:
            // TODO decide if it's a constant and document it if it is
            break;
    }
}

void HelpGenVisitor::VisitAttribute( spAttribute& attr )
{
    CloseFunction();

    // only document the public member variables
    if ( !m_inClass || !attr.IsPublic() )
        return;

    wxLogWarning("Ignoring member variable '%s'.", attr.GetName().c_str());
}

void HelpGenVisitor::VisitOperation( spOperation& op )
{
    CloseFunction();

    if ( !m_inClass ) {
        // we don't generate docs right now - either we ignore this class
        // entirely or we couldn't open the file
        return;
    }

    if ( !op.IsInClass() ) {
        // TODO document global functions
        wxLogWarning("skipped global function '%s'.", op.GetName().c_str());

        return;
    }

    if ( op.mVisibility == SP_VIS_PRIVATE ) {
        // FIXME should we document protected functions?
        return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -