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

📄 helpgen.cpp

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

    IgnoreNamesHandler m_ignoreNames;

    // information about all functions documented in the TeX file(s)
    // -------------------------------------------------------------

public: // Note: Sun C++ 5.5 requires TypeInfo and ParamInfo to be public

    // info about a type: for now stored as text string, but must be parsed
    // further later (to know that "char *" == "char []" - TODO)
    class TypeInfo
    {
    public:
        TypeInfo(const wxString& type) : m_type(type) { }

        bool operator==(const wxString& type) const { return m_type == type; }
        bool operator!=(const wxString& type) const { return m_type != type; }

        const wxString& GetName() const { return m_type; }

    private:
        wxString m_type;
    };

    friend class ParamInfo; // for access to TypeInfo

    // info abotu a function parameter
    class ParamInfo
    {
    public:
        ParamInfo(const wxString& type,
                  const wxString& name,
                  const wxString& value)
            : m_type(type), m_name(name), m_value(value)
        {
        }

        const TypeInfo& GetType() const { return m_type; }
        const wxString& GetName() const { return m_name; }
        const wxString& GetDefValue() const { return m_value; }

    private:
        TypeInfo m_type;      // type of parameter
        wxString m_name;      // name
        wxString m_value;     // default value
    };

public: // FIXME: macro requires it
    WX_DEFINE_ARRAY_PTR(ParamInfo *, ArrayParamInfo);

    // info about a function
    struct MethodInfo
    {
    public:
        enum MethodFlags
        {
            Const   = 0x0001,
            Virtual = 0x0002,
            Pure    = 0x0004,
            Static  = 0x0008,
            Vararg  = 0x0010
        };

        MethodInfo(const wxString& type,
                   const wxString& name,
                   const ArrayParamInfo& params)
            : m_typeRet(type), m_name(name), m_params(params)
        {
            m_flags = 0;
        }

        void SetFlag(MethodFlags flag) { m_flags |= flag; }

        const TypeInfo& GetType() const { return m_typeRet; }
        const wxString& GetName() const { return m_name; }
        const ParamInfo& GetParam(size_t n) const { return *(m_params[n]); }
        size_t GetParamCount() const { return m_params.GetCount(); }

        bool HasFlag(MethodFlags flag) const { return (m_flags & flag) != 0; }

        ~MethodInfo() { WX_CLEAR_ARRAY(m_params); }

    private:
        TypeInfo m_typeRet;     // return type
        wxString m_name;
        int      m_flags;       // bit mask of the value from the enum above

        ArrayParamInfo m_params;
    };

    WX_DEFINE_ARRAY_PTR(MethodInfo *, ArrayMethodInfo);
    WX_DEFINE_ARRAY_PTR(ArrayMethodInfo *, ArrayMethodInfos);

private:
    // first array contains the names of all classes we found, the second has a
    // pointer to the array of methods of the given class at the same index as
    // the class name appears in m_classes
    wxArrayString    m_classes;
    ArrayMethodInfos m_methods;

    // are we checking parameter names?
    bool m_checkParamNames;

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

// =============================================================================
// implementation
// =============================================================================

static char **g_argv = NULL;

// this function never returns
static void usage()
{
    wxString prog = g_argv[0];
    wxString basename = prog.AfterLast('/');
#ifdef __WXMSW__
    if ( !basename )
        basename = prog.AfterLast('\\');
#endif
    if ( !basename )
        basename = prog;

    wxLogMessage(
"usage: %s [global options] <mode> [mode options] <files...>\n"
"\n"
"   where global options are:\n"
"       -q          be quiet\n"
"       -v          be verbose\n"
"       -H          give this usage message\n"
"       -V          print the version info\n"
"       -i file     file with classes/function to ignore\n"
"\n"
"   where mode is one of: dump, diff\n"
"\n"
"   dump means generate .tex files for TeX2RTF converter from specified\n"
"   headers files, mode options are:\n"
"       -f          overwrite existing files\n"
"       -o outdir   directory for generated files\n"
"\n"
"   diff means compare the set of methods documented .tex file with the\n"
"   methods declared in the header:\n"
"           %s diff <file.h> <files.tex...>.\n"
"   mode specific options are:\n"
"       -p          do check parameter names (not done by default)\n"
"\n", basename.c_str(), basename.c_str());

    exit(1);
}

int main(int argc, char **argv)
{
    g_argv = argv;

    wxInitializer initializer;
    if ( !initializer )
    {
        fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.");

        return -1;
    }

    enum
    {
        Mode_None,
        Mode_Dump,
        Mode_Diff
    } mode = Mode_None;

    if ( argc < 2 ) {
        usage();
    }

    wxArrayString filesH, filesTeX;
    wxString directoryOut,      // directory for 'dmup' output
             ignoreFile;        // file with classes/functions to ignore
    bool overwrite = false,     // overwrite existing files during 'dump'?
         paramNames = false;    // check param names during 'diff'?

    for ( int current = 1; current < argc ; current++ ) {
        // all options have one letter
        if ( argv[current][0] == '-' ) {
            if ( argv[current][2] == '\0' ) {
                switch ( argv[current][1] ) {
                    case 'v':
                        // be verbose
                        wxLog::GetActiveTarget()->SetVerbose();
                        continue;

                    case 'q':
                        // be quiet
                        wxLog::GetActiveTarget()->SetVerbose(false);
                        continue;

                    case 'H':
                        // help requested
                        usage();
                        // doesn't return

                    case 'V':
                        // version requested
                        wxLogMessage("HelpGen version %s\n"
                                     "(c) 1999-2001 Vadim Zeitlin\n",
                                     GetVersionString().c_str());
                        return 0;

                    case 'i':
                        current++;
                        if ( current >= argc ) {
                            wxLogError("-i option requires an argument.");

                            break;
                        }

                        ignoreFile = argv[current];
                        continue;

                    case 'p':
                        if ( mode != Mode_Diff ) {
                            wxLogError("-p is only valid with diff.");

                            break;
                        }

                        paramNames = true;
                        continue;

                    case 'f':
                        if ( mode != Mode_Dump ) {
                            wxLogError("-f is only valid with dump.");

                            break;
                        }

                        overwrite = true;
                        continue;

                    case 'o':
                        if ( mode != Mode_Dump ) {
                            wxLogError("-o is only valid with dump.");

                            break;
                        }

                        current++;
                        if ( current >= argc ) {
                            wxLogError("-o option requires an argument.");

                            break;
                        }

                        directoryOut = argv[current];
                        if ( !directoryOut.empty() ) {
                            // terminate with a '/' if it doesn't have it
                            switch ( directoryOut.Last() ) {
                                case '/':
#ifdef __WXMSW__
                                case '\\':
#endif
                                    break;

                                default:
                                    directoryOut += '/';
                            }
                        }
                        //else: it's empty, do nothing

                        continue;

                    default:
                        wxLogError("unknown option '%s'", argv[current]);
                        break;
                }
            }
            else {
                wxLogError("only one letter options are allowed, not '%s'.",
                           argv[current]);
            }

            // only get here after a break from switch or from else branch of if

            usage();
        }
        else {
            if ( mode == Mode_None ) {
                if ( strcmp(argv[current], "diff") == 0 )
                    mode = Mode_Diff;
                else if ( strcmp(argv[current], "dump") == 0 )
                    mode = Mode_Dump;
                else {
                    wxLogError("unknown mode '%s'.", argv[current]);

                    usage();
                }
            }
            else {
                if ( mode == Mode_Dump || filesH.IsEmpty() ) {
                    filesH.Add(argv[current]);
                }
                else {
                    // 2nd files and further are TeX files in diff mode
                    wxASSERT( mode == Mode_Diff );

                    filesTeX.Add(argv[current]);
                }
            }
        }
    }

    // create a parser object and a visitor derivation
    CJSourceParser parser;
    HelpGenVisitor visitor(directoryOut, overwrite);
    if ( !ignoreFile.empty() && mode == Mode_Dump )
        visitor.GetIgnoreHandler().AddNamesFromFile(ignoreFile);

    spContext *ctxTop = NULL;

    // parse all header files
    size_t nFiles = filesH.GetCount();
    for ( size_t n = 0; n < nFiles; n++ ) {
        wxString header = filesH[n];
        ctxTop = parser.ParseFile(header);
        if ( !ctxTop ) {
            wxLogWarning("Header file '%s' couldn't be processed.",
                         header.c_str());
        }
        else if ( mode == Mode_Dump ) {
            ((spFile *)ctxTop)->m_FileName = header;
            visitor.VisitAll(*ctxTop);
            visitor.EndVisit();
        }

#ifdef __WXDEBUG__
        if ( 0 && ctxTop )
            ctxTop->Dump(wxEmptyString);
#endif // __WXDEBUG__
    }

    // parse all TeX files
    if ( mode == Mode_Diff ) {
        if ( !ctxTop ) {
            wxLogError("Can't complete diff.");

            // failure
            return false;
        }

        DocManager docman(paramNames);

        size_t nFiles = filesTeX.GetCount();
        for ( size_t n = 0; n < nFiles; n++ ) {
            wxString file = filesTeX[n];
            if ( !docman.ParseTeXFile(file) ) {
                wxLogWarning("TeX file '%s' couldn't be processed.",
                             file.c_str());
            }
        }

        if ( !ignoreFile.empty() )
            docman.GetIgnoreHandler().AddNamesFromFile(ignoreFile);

        docman.DumpDifferences(ctxTop);
    }

    return 0;
}

// -----------------------------------------------------------------------------
// HelpGenVisitor implementation
// -----------------------------------------------------------------------------

HelpGenVisitor::HelpGenVisitor(const wxString& directoryOut,
                               bool overwrite)
              : m_directoryOut(directoryOut)
{
    m_overwrite = overwrite;

    Reset();
}

void HelpGenVisitor::Reset()
{
    m_inClass =
    m_inTypesSection =
    m_inMethodSection = false;

    m_classname =
    m_funcName =
    m_textFunc =
    m_textStoredTypedefs =
    m_textStoredFunctionComment = wxEmptyString;

    m_arrayFuncDocs.Empty();

    m_storedEnums.Empty();
    m_storedEnumsVerb.Empty();
    m_headers.Empty();
}

void HelpGenVisitor::InsertTypedefDocs()
{
    m_file.WriteTeX(m_textStoredTypedefs);
    m_textStoredTypedefs.Empty();
}

void HelpGenVisitor::InsertEnumDocs()
{
    size_t count = m_storedEnums.GetCount();
    for ( size_t n = 0; n < count; n++ )
    {
        m_file.WriteTeX(m_storedEnums[n]);
        m_file.WriteVerbatim(m_storedEnumsVerb[n] + '\n');
    }

    m_storedEnums.Empty();
    m_storedEnumsVerb.Empty();
}

⌨️ 快捷键说明

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