📄 helpgen.cpp
字号:
// -------------------------------------------
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 + -