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

📄 helpgen.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        HelpGen.cpp
// Purpose:     Main program file for HelpGen
// Author:      Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Modified by:
// Created:     06/01/99
// RCS-ID:      $Id: HelpGen.cpp,v 1.44 2005/05/31 17:47:45 ABX Exp $
// Copyright:   (c) 1999 VZ
// Licence:     wxWindows Licence
/////////////////////////////////////////////////////////////////////////////

/*
   BUGS

    1. wx/string.h confuses C++ parser terribly
    2. C++ parser doesn't know about virtual functions, nor static ones
    3. param checking is not done for vararg functions
    4. type comparison is dumb: it doesn't know that "char *" is the same
       that "char []" nor that "const char *" is the same as "char const *"

   TODO (+ means fixed), see also the change log at the end of the file.

   (i) small fixes in the current version

   +1. Quote special TeX characters like '&' and '_' (=> derive from wxFile)
    2. Document typedefs
    3. Document global variables
    4. Document #defines
   +5. Program options
    6. Include file name/line number in the "diff" messages?
   +7. Support for vararg functions

   (ii) plans for version 2
    1. Use wxTextFile for direct file access to avoid one scan method problems
    2. Use command line parser class for the options
    3. support for overloaded functions in diff mode (search for OVER)

   (iii) plans for version 3
    1. Merging with existing files
    2. GUI
*/

// =============================================================================
// declarations
// =============================================================================

// -----------------------------------------------------------------------------
// headers
// -----------------------------------------------------------------------------

// wxWidgets
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#if wxUSE_UNICODE
    #error "HelpGen doesn't build in Unicode mode"
#endif

#ifndef WX_PRECOMP
    #include "wx/string.h"
    #include "wx/log.h"
    #include "wx/dynarray.h"
    #include "wx/app.h"
#endif // WX_PRECOMP

#include "wx/file.h"
#include "wx/regex.h"
#include "wx/hash.h"

// C++ parsing classes
#include "cjparser.h"

// standard headers
#include <stdio.h>
#include <time.h>

// -----------------------------------------------------------------------------
// private functions
// -----------------------------------------------------------------------------

// return the label for the given function name (i.e. argument of \label)
static wxString MakeLabel(const wxChar *classname, const wxChar *funcname = NULL);

// return the whole \helpref{arg}{arg_label} string
static wxString MakeHelpref(const wxChar *argument);

// [un]quote special TeX characters (in place)
static void TeXFilter(wxString* str);
static void TeXUnfilter(wxString* str); // also trims spaces

// get all comments associated with this context
static wxString GetAllComments(const spContext& ctx);

// get the string with current time (returns pointer to static buffer)
// timeFormat is used for the call of strftime(3)
static const char *GetCurrentTimeFormatted(const char *timeFormat);

// get the string containing the program version
static const wxString GetVersionString();

// -----------------------------------------------------------------------------
// private classes
// -----------------------------------------------------------------------------

// a function documentation entry
struct FunctionDocEntry
{
    FunctionDocEntry(const wxString& name_, const wxString& text_)
        : name(name_), text(text_) { }

    // the function name
    wxString name;

    // the function doc text
    wxString text;

    // sorting stuff
    static int Compare(FunctionDocEntry **pp1, FunctionDocEntry **pp2)
    {
        // the methods should appear in the following order: ctors, dtor, all
        // the rest in the alphabetical order
        bool isCtor1 = (*pp1)->name == classname;
        bool isCtor2 = (*pp2)->name == classname;

        if ( isCtor1 ) {
            if ( isCtor2 ) {
                // we don't order the ctors because we don't know how to do it
                return 0;
            }

            // ctor comes before non-ctor
            return -1;
        }
        else {
            if ( isCtor2 ) {
                // non-ctor must come after ctor
                return 1;
            }

            wxString dtorname = wxString(_T("~")) + classname;

            // there is only one dtor, so the logic here is simpler
            if ( (*pp1)->name == dtorname ) {
                return -1;
            }
            else if ( (*pp2)->name == dtorname ) {
                return 1;
            }

            // two normal methods
            return wxStrcmp((*pp1)->name, (*pp2)->name);
        }
    }

    static wxString classname;
};

wxString FunctionDocEntry::classname;

WX_DECLARE_OBJARRAY(FunctionDocEntry, FunctionDocEntries);

#include "wx/arrimpl.cpp"

WX_DEFINE_OBJARRAY(FunctionDocEntries);

// add a function which sanitazes the string before writing it to the file and
// also capable of delaying output and sorting it before really writing it to
// the file (done from FlushAll())
class wxTeXFile : public wxFile
{
public:
    wxTeXFile() { }

    // write a string to file verbatim (should only be used for the strings
    // inside verbatim environment)
    void WriteVerbatim(const wxString& s)
    {
        m_text += s;
    }

    // write a string quoting TeX specials in it
    void WriteTeX(const wxString& s)
    {
        wxString t(s);
        TeXFilter(&t);

        m_text += t;
    }

    // do write everything to file
    bool FlushAll()
    {
        if ( m_text.empty() )
            return true;

        if ( !Write(m_text) ) {
            wxLogError(_T("Failed to output generated documentation."));

            return false;
        }

        m_text.clear();

        return true;
    }

private:
    wxTeXFile(const wxTeXFile&);
    wxTeXFile& operator=(const wxTeXFile&);

    wxString m_text;
};

// helper class which manages the classes and function names to ignore for
// the documentation purposes (used by both HelpGenVisitor and DocManager)
class IgnoreNamesHandler
{
public:
    IgnoreNamesHandler() : m_ignore(CompareIgnoreListEntries) { }
    ~IgnoreNamesHandler() { WX_CLEAR_ARRAY(m_ignore); }

    // load file with classes/functions to ignore (add them to the names we
    // already have)
    bool AddNamesFromFile(const wxString& filename);

    // return true if we ignore this function
    bool IgnoreMethod(const wxString& classname,
                      const wxString& funcname) const
    {
        if ( IgnoreClass(classname) )
            return true;

        IgnoreListEntry ignore(classname, funcname);

        return m_ignore.Index(&ignore) != wxNOT_FOUND;
    }

    // return true if we ignore this class entirely
    bool IgnoreClass(const wxString& classname) const
    {
        IgnoreListEntry ignore(classname, wxEmptyString);

        return m_ignore.Index(&ignore) != wxNOT_FOUND;
    }

protected:
    struct IgnoreListEntry
    {
        IgnoreListEntry(const wxString& classname,
                        const wxString& funcname)
            : m_classname(classname), m_funcname(funcname)
        {
        }

        wxString m_classname;
        wxString m_funcname;    // if empty, ignore class entirely
    };

    static int CompareIgnoreListEntries(IgnoreListEntry *first,
                                        IgnoreListEntry *second);

    // for efficiency, let's sort it
public: // FIXME: macro requires it
    WX_DEFINE_SORTED_ARRAY(IgnoreListEntry *, ArrayNamesToIgnore);

protected:
    ArrayNamesToIgnore m_ignore;

private:
    IgnoreNamesHandler(const IgnoreNamesHandler&);
    IgnoreNamesHandler& operator=(const IgnoreNamesHandler&);
};

// visitor implementation which writes all collected data to a .tex file
class HelpGenVisitor : public spVisitor
{
public:
    // ctor
    HelpGenVisitor(const wxString& directoryOut, bool overwrite);

    virtual void VisitFile( spFile& fl );
    virtual void VisitClass( spClass& cl );
    virtual void VisitEnumeration( spEnumeration& en );
    virtual void VisitTypeDef( spTypeDef& td );
    virtual void VisitPreprocessorLine( spPreprocessorLine& pd );
    virtual void VisitAttribute( spAttribute& attr );
    virtual void VisitOperation( spOperation& op );
    virtual void VisitParameter( spParameter& param );

    void EndVisit();

    // get our `ignore' object
    IgnoreNamesHandler& GetIgnoreHandler() { return m_ignoreNames; }

    // shut up g++ warning (ain't it stupid?)
    virtual ~HelpGenVisitor() { }

protected:
    // (re)initialize the state
    void Reset();

    // insert documentation for enums/typedefs coming immediately before the
    // class declaration into the class documentation
    void InsertTypedefDocs();
    void InsertEnumDocs();

    // write the headers for corresponding sections (only once)
    void InsertDataStructuresHeader();
    void InsertMethodsHeader();

    // terminate the function documentation if it was started
    void CloseFunction();

    // write out all function docs when there are no more left in this class
    // after sorting them in alphabetical order
    void CloseClass();

    wxString  m_directoryOut,   // directory for the output
              m_fileHeader;     // name of the .h file we parse
    bool      m_overwrite;      // overwrite existing files?
    wxTeXFile m_file;           // file we're writing to now

    // state variables
    bool m_inClass,         // true after file successfully opened
         m_inTypesSection,  // enums & typedefs go there
         m_inMethodSection, // functions go here
         m_isFirstParam;    // first parameter of current function?

    // non empty while parsing a class
    wxString m_classname;

    // these are only non-empty while parsing a method:
    wxString m_funcName,    // the function name
             m_textFunc;    // the function doc text

    // the array containing the documentation entries for the functions in the
    // class currently being parsed
    FunctionDocEntries m_arrayFuncDocs;

    // holders for "saved" documentation
    wxString m_textStoredTypedefs,
             m_textStoredFunctionComment;

    // for enums we have to use an array as we can't intermix the normal text
    // and the text inside verbatim environment
    wxArrayString m_storedEnums,
                  m_storedEnumsVerb;

    // headers included by this file
    wxArrayString m_headers;

    // ignore handler: tells us which classes to ignore for doc generation
    // purposes
    IgnoreNamesHandler m_ignoreNames;

private:
    HelpGenVisitor(const HelpGenVisitor&);
    HelpGenVisitor& operator=(const HelpGenVisitor&);
};

// documentation manager - a class which parses TeX files and remembers the
// functions documented in them and can later compare them with all functions
// found under ctxTop by C++ parser
class DocManager
{
public:
    DocManager(bool checkParamNames);
    ~DocManager();

    // returns false on failure
    bool ParseTeXFile(const wxString& filename);

    // returns false if there were any differences
    bool DumpDifferences(spContext *ctxTop) const;

    // get our `ignore' object
    IgnoreNamesHandler& GetIgnoreHandler() { return m_ignoreNames; }

protected:
    // parsing TeX files
    // -----------------

    // returns the length of 'match' if the string 'str' starts with it or 0
    // otherwise
    static size_t TryMatch(const wxChar *str, const wxChar *match);

    // skip spaces: returns pointer to first non space character (also
    // updates the value of m_line)
    const char *SkipSpaces(const char *p)
    {
        while ( isspace(*p) ) {
            if ( *p++ == '\n' )
                m_line++;
        }

        return p;
    }

    // skips characters until the next 'c' in '*pp' unless it ends before in
    // which case false is returned and pp points to '\0', otherwise true is
    // returned and pp points to 'c'
    bool SkipUntil(const char **pp, char c);

    // the same as SkipUntil() but only spaces are skipped: on first non space
    // character different from 'c' the function stops and returns false
    bool SkipSpaceUntil(const char **pp, char c);

    // extract the string between {} and modify '*pp' to point at the
    // character immediately after the closing '}'. The returned string is empty
    // on error.
    wxString ExtractStringBetweenBraces(const char **pp);

    // the current file and line while we're in ParseTeXFile (for error
    // messages)
    wxString m_filename;
    size_t   m_line;

    // functions and classes to ignore during diff

⌨️ 快捷键说明

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