1. more C++ parser fixes - now it almost parses wx/string.h

a) #if/#ifdef/#else (very) limited support
 b) param type fix - now indirection chars are correctly handled
 c) class/struct/union distinction
 d) public/private fixes
 e) Dump() function added - very useful for debugging

2. option to ignore parameter names during 'diff' (in fact, they're ignored
   by default, and this option switches it on)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1744 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-02-21 22:32:46 +00:00
parent c4c794e1d0
commit d12e353663
6 changed files with 2617 additions and 2197 deletions

View File

@@ -7,7 +7,7 @@
// Created: 22/09/98 // Created: 22/09/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas // Copyright: (c) Aleskandars Gluchovas
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef __CJPARSESR_G__ #ifndef __CJPARSESR_G__
@@ -22,72 +22,72 @@
// class parses given "memory-resident" Java or C++ source code // class parses given "memory-resident" Java or C++ source code
// and captures information about classes/attrubutes/methods/ // and captures information about classes/attrubutes/methods/
// arguments/etc into structures. Conforms with SourceParserBase // arguments/etc into structures. Conforms with SourceParserBase
// interface requirements. // interface requirements.
class CJSourceParser : public SourceParserBase class CJSourceParser : public SourceParserBase
{ {
protected: protected:
// begining of the full-text area of the source file // begining of the full-text area of the source file
char* mpStart; char* mpStart;
// points to first character after the end // points to first character after the end
// of teh full-text area // of teh full-text area
char* mpEnd; char* mpEnd;
// current "privacy level" // current "privacy level"
int mCurVis; int mCurVis;
// current parsing position int full-text area // current parsing position int full-text area
char* cur; char* cur;
// about the current class // about the current class
bool mIsVirtual; bool mIsVirtual;
bool mIsTemplate; bool mIsTemplate;
size_t mNestingLevel; size_t mNestingLevel;
// context data for which is currently being collected // context data for which is currently being collected
spContext* mpCurCtx; spContext* mpCurCtx;
int mCurCtxType; // type of the current context int mCurCtxType; // type of the current context
bool mCommentsOn; bool mCommentsOn;
bool mMacrosOn; bool mMacrosOn;
protected: protected:
void AttachComments( spContext& ctx, char* cur ); void AttachComments( spContext& ctx, char* cur );
void ParseKeyword( char*& cur ); void ParseKeyword( char*& cur );
bool ParseNameAndRetVal( char*& cur, bool& isAMacro ); bool ParseNameAndRetVal( char*& cur, bool& isAMacro );
bool ParseArguments( char*& cur ); bool ParseArguments( char*& cur );
void ParseMemberVar( char*& cur ); void ParseMemberVar( char*& cur );
void SkipFunction( char*& cur ); void SkipFunction( char*& cur );
void SkipFunctionBody( char*& cur ); void SkipFunctionBody( char*& cur );
bool CheckVisibilty( char*& cur ); bool CheckVisibilty( char*& cur );
void AddClassNode( char*& cur ); void AddClassNode( char*& cur );
void AddMacroNode( char*& cur ); void AddMacroNode( char*& cur );
void AddEnumNode( char*& cur ); void AddEnumNode( char*& cur );
void AddTypeDefNode( char*& cur ); void AddTypeDefNode( char*& cur );
void DumpOperationInfo( spOperation& info, const string& tab, ostream& os ); void DumpOperationInfo( spOperation& info, const string& tab, ostream& os );
void DumpClassHeader( spClass& info, ostream& os ); void DumpClassHeader( spClass& info, ostream& os );
void DumpClassBody( spClass& info, ostream& os ); void DumpClassBody( spClass& info, ostream& os );
public: public:
// NOTE:: discarding of macros or comments improves performance and // NOTE:: discarding of macros or comments improves performance and
// decreases memory usage // decreases memory usage
CJSourceParser(bool collectCommnets = 1, CJSourceParser(bool collectCommnets = 1,
bool collectMacros = 1); bool collectMacros = 1);
// returns the root-node of the created context tree // returns the root-node of the created context tree
// (user is responsible for releasing it from the heep) // (user is responsible for releasing it from the heep)
// "end" should point to the last (character + 1) of the // "end" should point to the last (character + 1) of the
// source text // source text
virtual spFile* Parse( char* start, char* end ); virtual spFile* Parse( char* start, char* end );
}; };
// inline'ed helpers used (just info): // inline'ed helpers used (just info):

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,7 @@
(ii) plans for version 2 (ii) plans for version 2
1. Use wxTextFile for direct file access to avoid one scan method problems 1. Use wxTextFile for direct file access to avoid one scan method problems
2. Use command line parser class for the options 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 (iii) plans for version 3
1. Merging with existing files 1. Merging with existing files
@@ -120,15 +121,70 @@ private:
wxTeXFile& operator=(const wxTeXFile&); wxTeXFile& operator=(const wxTeXFile&);
}; };
// 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, "");
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
WX_DEFINE_SORTED_ARRAY(IgnoreListEntry *, ArrayNamesToIgnore);
ArrayNamesToIgnore m_ignore;
private:
IgnoreNamesHandler(const IgnoreNamesHandler&);
IgnoreNamesHandler& operator=(const IgnoreNamesHandler&);
};
// visitor implementation which writes all collected data to a .tex file // visitor implementation which writes all collected data to a .tex file
class HelpGenVisitor : public spVisitor class HelpGenVisitor : public spVisitor
{ {
public: public:
// ctor // ctor
HelpGenVisitor(const wxString& directoryOut) : m_directoryOut(directoryOut) HelpGenVisitor(const wxString& directoryOut, bool overwrite);
{
Reset();
}
virtual void VisitFile( spFile& fl ); virtual void VisitFile( spFile& fl );
virtual void VisitClass( spClass& cl ); virtual void VisitClass( spClass& cl );
@@ -141,6 +197,9 @@ public:
void EndVisit(); void EndVisit();
// get our `ignore' object
IgnoreNamesHandler& GetIgnoreHandler() { return m_ignoreNames; }
// shut up g++ warning (ain't it stupid?) // shut up g++ warning (ain't it stupid?)
virtual ~HelpGenVisitor() { } virtual ~HelpGenVisitor() { }
@@ -160,7 +219,9 @@ protected:
// terminate the function documentation if it was started // terminate the function documentation if it was started
void CloseFunction(); void CloseFunction();
wxString m_directoryOut; // directory for the output 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 wxTeXFile m_file; // file we're writing to now
// state variables // state variables
@@ -178,6 +239,10 @@ protected:
// headers included by this file // headers included by this file
wxArrayString m_headers; wxArrayString m_headers;
// ignore handler: tells us which classes to ignore for doc generation
// purposes
IgnoreNamesHandler m_ignoreNames;
private: private:
HelpGenVisitor(const HelpGenVisitor&); HelpGenVisitor(const HelpGenVisitor&);
HelpGenVisitor& operator=(const HelpGenVisitor&); HelpGenVisitor& operator=(const HelpGenVisitor&);
@@ -189,18 +254,18 @@ private:
class DocManager class DocManager
{ {
public: public:
DocManager() : m_ignore(CompareIgnoreListEntries) { } DocManager(bool checkParamNames);
~DocManager(); ~DocManager();
// load file with class names and function names to ignore during diff
bool LoadIgnoreFile(const wxString& filename);
// returns FALSE on failure // returns FALSE on failure
bool ParseTeXFile(const wxString& filename); bool ParseTeXFile(const wxString& filename);
// returns FALSE if there were any differences // returns FALSE if there were any differences
bool DumpDifferences(spContext *ctxTop) const; bool DumpDifferences(spContext *ctxTop) const;
// get our `ignore' object
IgnoreNamesHandler& GetIgnoreHandler() { return m_ignoreNames; }
protected: protected:
// parsing TeX files // parsing TeX files
// ----------------- // -----------------
@@ -242,40 +307,8 @@ protected:
// functions and classes to ignore during diff // functions and classes to ignore during diff
// ------------------------------------------- // -------------------------------------------
struct IgnoreListEntry
{
IgnoreListEntry(const wxString& classname,
const wxString& funcname)
: m_classname(classname), m_funcname(funcname)
{
}
wxString m_classname; IgnoreNamesHandler m_ignoreNames;
wxString m_funcname; // if empty, ignore class entirely
};
static int CompareIgnoreListEntries(IgnoreListEntry *first,
IgnoreListEntry *second);
// for efficiency, let's sort it
WX_DEFINE_SORTED_ARRAY(IgnoreListEntry *, ArrayNamesToIgnore);
ArrayNamesToIgnore m_ignore;
// return TRUE if we ignore this function
bool IgnoreMethod(const wxString& classname,
const wxString& funcname) const
{
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
{
return IgnoreMethod(classname, "");
}
// information about all functions documented in the TeX file(s) // information about all functions documented in the TeX file(s)
// ------------------------------------------------------------- // -------------------------------------------------------------
@@ -367,6 +400,13 @@ protected:
// the class name appears in m_classes // the class name appears in m_classes
wxArrayString m_classes; wxArrayString m_classes;
ArrayMethodInfos m_methods; ArrayMethodInfos m_methods;
// are we checking parameter names?
bool m_checkParamNames;
private:
DocManager(const DocManager&);
DocManager& operator=(const DocManager&);
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -397,18 +437,20 @@ static void usage()
" -v be verbose\n" " -v be verbose\n"
" -H give this usage message\n" " -H give this usage message\n"
" -V print the version info\n" " -V print the version info\n"
" -i file file with classes/function to ignore\n"
"\n" "\n"
" where mode is one of: dump, diff\n" " where mode is one of: dump, diff\n"
"\n" "\n"
" dump means generate .tex files for TeX2RTF converter from specified\n" " dump means generate .tex files for TeX2RTF converter from specified\n"
" headers files, mode options are:\n" " headers files, mode options are:\n"
" -f overwrite existing files\n"
" -o outdir directory for generated files\n" " -o outdir directory for generated files\n"
"\n" "\n"
" diff means compare the set of methods documented .tex file with the\n" " diff means compare the set of methods documented .tex file with the\n"
" methods declared in the header:\n" " methods declared in the header:\n"
" %s diff <file.h> <files.tex...>.\n" " %s diff <file.h> <files.tex...>.\n"
" options are:\n" " mode specific options are:\n"
" -i file file with classes/function to ignore during diff\n" " -p do check parameter names (not done by default)\n"
"\n", basename.c_str(), basename.c_str()); "\n", basename.c_str(), basename.c_str());
exit(1); exit(1);
@@ -430,7 +472,10 @@ int main(int argc, char **argv)
} }
wxArrayString filesH, filesTeX; wxArrayString filesH, filesTeX;
wxString directoryOut, ignoreFile; 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++ ) { for ( int current = 1; current < argc ; current++ ) {
// all options have one letter // all options have one letter
@@ -452,12 +497,6 @@ int main(int argc, char **argv)
usage(); usage();
case 'i': case 'i':
if ( mode != Mode_Diff ) {
wxLogError("-i is only valid with diff.");
break;
}
current++; current++;
if ( current >= argc ) { if ( current >= argc ) {
wxLogError("-i option requires an argument."); wxLogError("-i option requires an argument.");
@@ -468,6 +507,26 @@ int main(int argc, char **argv)
ignoreFile = argv[current]; ignoreFile = argv[current];
continue; 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': case 'o':
if ( mode != Mode_Dump ) { if ( mode != Mode_Dump ) {
wxLogError("-o is only valid with dump."); wxLogError("-o is only valid with dump.");
@@ -501,12 +560,16 @@ int main(int argc, char **argv)
continue; continue;
default: default:
wxLogError("unknown option '%s'", argv[current]);
break; 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 // only get here after a break from switch or from else branch of if
wxLogError("unknown option '%s'", argv[current]);
usage(); usage();
} }
@@ -517,7 +580,7 @@ int main(int argc, char **argv)
else if ( strcmp(argv[current], "dump") == 0 ) else if ( strcmp(argv[current], "dump") == 0 )
mode = Mode_Dump; mode = Mode_Dump;
else { else {
wxLogError("unknown mode '%s'."); wxLogError("unknown mode '%s'.", argv[current]);
usage(); usage();
} }
@@ -538,7 +601,10 @@ int main(int argc, char **argv)
// create a parser object and a visitor derivation // create a parser object and a visitor derivation
CJSourceParser parser; CJSourceParser parser;
HelpGenVisitor visitor(directoryOut); HelpGenVisitor visitor(directoryOut, overwrite);
if ( !!ignoreFile && mode == Mode_Dump )
visitor.GetIgnoreHandler().AddNamesFromFile(ignoreFile);
spContext *ctxTop = NULL; spContext *ctxTop = NULL;
// parse all header files // parse all header files
@@ -555,6 +621,11 @@ int main(int argc, char **argv)
visitor.VisitAll(*ctxTop); visitor.VisitAll(*ctxTop);
visitor.EndVisit(); visitor.EndVisit();
} }
#ifdef __WXDEBUG__
if ( 0 && ctxTop )
ctxTop->Dump("");
#endif // __WXDEBUG__
} }
// parse all TeX files // parse all TeX files
@@ -566,7 +637,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
DocManager docman; DocManager docman(paramNames);
size_t nFiles = filesTeX.GetCount(); size_t nFiles = filesTeX.GetCount();
for ( size_t n = 0; n < nFiles; n++ ) { for ( size_t n = 0; n < nFiles; n++ ) {
@@ -578,7 +649,7 @@ int main(int argc, char **argv)
} }
if ( !!ignoreFile ) if ( !!ignoreFile )
docman.LoadIgnoreFile(ignoreFile); docman.GetIgnoreHandler().AddNamesFromFile(ignoreFile);
docman.DumpDifferences(ctxTop); docman.DumpDifferences(ctxTop);
} }
@@ -590,6 +661,15 @@ int main(int argc, char **argv)
// HelpGenVisitor implementation // HelpGenVisitor implementation
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
HelpGenVisitor::HelpGenVisitor(const wxString& directoryOut,
bool overwrite)
: m_directoryOut(directoryOut)
{
m_overwrite = overwrite;
Reset();
}
void HelpGenVisitor::Reset() void HelpGenVisitor::Reset()
{ {
m_inClass = m_inClass =
@@ -657,20 +737,31 @@ void HelpGenVisitor::EndVisit()
{ {
CloseFunction(); CloseFunction();
m_fileHeader.Empty();
wxLogVerbose("%s: finished generating for the current file.", wxLogVerbose("%s: finished generating for the current file.",
GetCurrentTime("%H:%M:%S")); GetCurrentTime("%H:%M:%S"));
} }
void HelpGenVisitor::VisitFile( spFile& file ) void HelpGenVisitor::VisitFile( spFile& file )
{ {
m_fileHeader = file.mFileName;
wxLogVerbose("%s: started generating docs for classes from file '%s'...", wxLogVerbose("%s: started generating docs for classes from file '%s'...",
GetCurrentTime("%H:%M:%S"), file.mFileName.c_str()); GetCurrentTime("%H:%M:%S"), m_fileHeader.c_str());
} }
void HelpGenVisitor::VisitClass( spClass& cl ) void HelpGenVisitor::VisitClass( spClass& cl )
{ {
m_inClass = FALSE; // will be left FALSE on error
wxString name = cl.GetName(); 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" // the file name is built from the class name by removing the leading "wx"
// if any and converting it to the lower case // if any and converting it to the lower case
wxString filename = m_directoryOut; wxString filename = m_directoryOut;
@@ -684,12 +775,10 @@ void HelpGenVisitor::VisitClass( spClass& cl )
filename.MakeLower(); filename.MakeLower();
filename += ".tex"; filename += ".tex";
if ( wxFile::Exists(filename) ) { if ( !m_overwrite && wxFile::Exists(filename) ) {
wxLogError("Won't overwrite existing file '%s' - please use '-o'.", wxLogError("Won't overwrite existing file '%s' - please use '-f'.",
filename.c_str()); filename.c_str());
m_inClass = FALSE;
return; return;
} }
@@ -720,7 +809,7 @@ void HelpGenVisitor::VisitClass( spClass& cl )
"\n" "\n"
"\n" "\n"
"\\section{\\class{%s}}\\label{%s}\n", "\\section{\\class{%s}}\\label{%s}\n",
filename.c_str(), GetCurrentTime("%d/%b/%y %H:%M:%S"), m_fileHeader.c_str(), GetCurrentTime("%d/%b/%y %H:%M:%S"),
name.c_str(), wxString(name).MakeLower().c_str()); name.c_str(), wxString(name).MakeLower().c_str());
totalText << header << '\n'; totalText << header << '\n';
@@ -931,8 +1020,14 @@ void HelpGenVisitor::VisitOperation( spOperation& op )
{ {
CloseFunction(); CloseFunction();
if ( !m_inClass || !op.IsInClass() ) { if ( !m_inClass ) {
// FIXME that's a bug too // 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()); wxLogWarning("skipped global function '%s'.", op.GetName().c_str());
return; return;
@@ -943,6 +1038,15 @@ void HelpGenVisitor::VisitOperation( spOperation& op )
return; return;
} }
wxString funcname = op.GetName(),
classname = op.GetClass().GetName();
if ( m_ignoreNames.IgnoreMethod(classname, funcname) ) {
wxLogVerbose("Skipping ignored '%s::%s'.",
classname.c_str(), funcname.c_str());
return;
}
InsertMethodsHeader(); InsertMethodsHeader();
// save state info // save state info
@@ -953,13 +1057,11 @@ void HelpGenVisitor::VisitOperation( spOperation& op )
// start function documentation // start function documentation
wxString totalText; wxString totalText;
const char *funcname = op.GetName().c_str();
const char *classname = op.GetClass().GetName().c_str();
// check for the special case of dtor // check for the special case of dtor
wxString dtor; wxString dtor;
if ( (funcname[0] == '~') && (strcmp(funcname + 1, classname) == 0) ) { if ( (funcname[0] == '~') && (classname == funcname.c_str() + 1) ) {
dtor.Printf("\\destruct{%s}", classname); dtor.Printf("\\destruct{%s}", classname.c_str());
funcname = dtor; funcname = dtor;
} }
@@ -967,12 +1069,12 @@ void HelpGenVisitor::VisitOperation( spOperation& op )
"\\membersection{%s::%s}\\label{%s}\n" "\\membersection{%s::%s}\\label{%s}\n"
"\n" "\n"
"\\%sfunc{%s%s}{%s}{", "\\%sfunc{%s%s}{%s}{",
classname, funcname, classname.c_str(), funcname.c_str(),
MakeLabel(classname, funcname).c_str(), MakeLabel(classname, funcname).c_str(),
op.mIsConstant ? "const" : "", op.mIsConstant ? "const" : "",
op.mIsVirtual ? "virtual " : "", op.mIsVirtual ? "virtual " : "",
op.mRetType.c_str(), op.mRetType.c_str(),
funcname); funcname.c_str());
m_file.WriteTeX(totalText); m_file.WriteTeX(totalText);
} }
@@ -1005,6 +1107,11 @@ void HelpGenVisitor::VisitParameter( spParameter& param )
// DocManager // DocManager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
DocManager::DocManager(bool checkParamNames)
{
m_checkParamNames = checkParamNames;
}
size_t DocManager::TryMatch(const char *str, const char *match) size_t DocManager::TryMatch(const char *str, const char *match)
{ {
size_t lenMatch = 0; size_t lenMatch = 0;
@@ -1280,7 +1387,7 @@ bool DocManager::ParseTeXFile(const wxString& filename)
lenMatch = TryMatch(current, "void"); lenMatch = TryMatch(current, "void");
if ( !lenMatch ) { if ( !lenMatch ) {
lenMatch = TryMatch(current, "param"); lenMatch = TryMatch(current, "param");
while ( lenMatch ) { while ( lenMatch && (current - buf < len) ) {
current += lenMatch; current += lenMatch;
// now come {paramtype}{paramname} // now come {paramtype}{paramname}
@@ -1423,7 +1530,7 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
const wxString& nameClass = ctxClass->mName; const wxString& nameClass = ctxClass->mName;
int index = m_classes.Index(nameClass); int index = m_classes.Index(nameClass);
if ( index == wxNOT_FOUND ) { if ( index == wxNOT_FOUND ) {
if ( !IgnoreClass(nameClass) ) { if ( !m_ignoreNames.IgnoreClass(nameClass) ) {
foundDiff = TRUE; foundDiff = TRUE;
wxLogError("Class '%s' is not documented at all.", wxLogError("Class '%s' is not documented at all.",
@@ -1466,7 +1573,7 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
} }
if ( aMethodsWithSameName.IsEmpty() && ctxMethod->IsPublic() ) { if ( aMethodsWithSameName.IsEmpty() && ctxMethod->IsPublic() ) {
if ( !IgnoreMethod(nameClass, nameMethod) ) { if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) {
foundDiff = TRUE; foundDiff = TRUE;
wxLogError("'%s::%s' is not documented.", wxLogError("'%s::%s' is not documented.",
@@ -1481,7 +1588,7 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
index = (size_t)aMethodsWithSameName[0u]; index = (size_t)aMethodsWithSameName[0u];
methodExists[index] = TRUE; methodExists[index] = TRUE;
if ( IgnoreMethod(nameClass, nameMethod) ) if ( m_ignoreNames.IgnoreMethod(nameClass, nameMethod) )
continue; continue;
if ( !ctxMethod->IsPublic() ) { if ( !ctxMethod->IsPublic() ) {
@@ -1533,7 +1640,8 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
spParameter *ctxParam = (spParameter *)ctx; spParameter *ctxParam = (spParameter *)ctx;
const ParamInfo& param = method.GetParam(nParam); const ParamInfo& param = method.GetParam(nParam);
if ( param.GetName() != ctxParam->mName ) { if ( m_checkParamNames &&
(param.GetName() != ctxParam->mName) ) {
foundDiff = TRUE; foundDiff = TRUE;
wxLogError("Parameter #%d of '%s::%s' should be " wxLogError("Parameter #%d of '%s::%s' should be "
@@ -1575,9 +1683,9 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
} }
} }
else { else {
// TODO add real support for overloaded methods // TODO OVER add real support for overloaded methods
if ( IgnoreMethod(nameClass, nameMethod) ) if ( m_ignoreNames.IgnoreMethod(nameClass, nameMethod) )
continue; continue;
if ( aOverloadedMethods.Index(nameMethod) == wxNOT_FOUND ) { if ( aOverloadedMethods.Index(nameMethod) == wxNOT_FOUND ) {
@@ -1602,7 +1710,7 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
for ( nMethod = 0; nMethod < countMethods; nMethod++ ) { for ( nMethod = 0; nMethod < countMethods; nMethod++ ) {
if ( !methodExists[nMethod] ) { if ( !methodExists[nMethod] ) {
const wxString& nameMethod = methods[nMethod]->GetName(); const wxString& nameMethod = methods[nMethod]->GetName();
if ( !IgnoreMethod(nameClass, nameMethod) ) { if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) {
foundDiff = TRUE; foundDiff = TRUE;
wxLogError("'%s::%s' is documented but doesn't exist.", wxLogError("'%s::%s' is documented but doesn't exist.",
@@ -1633,11 +1741,14 @@ bool DocManager::DumpDifferences(spContext *ctxTop) const
DocManager::~DocManager() DocManager::~DocManager()
{ {
WX_CLEAR_ARRAY(m_methods); WX_CLEAR_ARRAY(m_methods);
WX_CLEAR_ARRAY(m_ignore);
} }
int DocManager::CompareIgnoreListEntries(IgnoreListEntry *first, // ---------------------------------------------------------------------------
IgnoreListEntry *second) // IgnoreNamesHandler implementation
// ---------------------------------------------------------------------------
int IgnoreNamesHandler::CompareIgnoreListEntries(IgnoreListEntry *first,
IgnoreListEntry *second)
{ {
// first compare the classes // first compare the classes
int rc = first->m_classname.Cmp(second->m_classname); int rc = first->m_classname.Cmp(second->m_classname);
@@ -1647,7 +1758,7 @@ int DocManager::CompareIgnoreListEntries(IgnoreListEntry *first,
return rc; return rc;
} }
bool DocManager::LoadIgnoreFile(const wxString& filename) bool IgnoreNamesHandler::AddNamesFromFile(const wxString& filename)
{ {
wxFile file(filename, wxFile::read); wxFile file(filename, wxFile::read);
if ( !file.IsOpened() ) if ( !file.IsOpened() )
@@ -1803,11 +1914,52 @@ static const char *GetCurrentTime(const char *timeFormat)
/* /*
$Log$ $Log$
Revision 1.7 1999/02/21 22:32:32 VZ
1. more C++ parser fixes - now it almost parses wx/string.h
a) #if/#ifdef/#else (very) limited support
b) param type fix - now indirection chars are correctly handled
c) class/struct/union distinction
d) public/private fixes
e) Dump() function added - very useful for debugging
2. option to ignore parameter names during 'diff' (in fact, they're ignored
by default, and this option switches it on)
Revision 1.6 1999/02/20 23:00:26 VZ Revision 1.6 1999/02/20 23:00:26 VZ
1. new 'diff' mode which seems to work 1. new 'diff' mode which seems to work
2. output files are not overwritten in 'dmup' mode 2. output files are not overwritten in 'dmup' mode
3. fixes for better handling of const functions and operators 3. fixes for better handling of const functions and operators
----------------------------
revision 1.5
date: 1999/02/15 23:07:25; author: VZ; state: Exp; lines: +106 -45
1. Parser improvements
a) const and virtual methods are parsed correctly (not static yet)
b) "const" which is part of the return type is not swallowed
2. HelpGen improvements: -o outputdir parameter added to the cmd line,
"//---------" kind comments discarded now.
----------------------------
revision 1.4
date: 1999/01/13 14:23:31; author: JS; state: Exp; lines: +4 -4
some tweaks to HelpGen
----------------------------
revision 1.3
date: 1999/01/09 20:18:03; author: JS; state: Exp; lines: +7 -2
HelpGen starting to compile with VC++
----------------------------
revision 1.2
date: 1999/01/08 19:46:22; author: VZ; state: Exp; lines: +208 -35
supports typedefs, generates "See also:" and adds "virtual " for virtual
functions
----------------------------
revision 1.1
date: 1999/01/08 17:45:55; author: VZ; state: Exp;
HelpGen is a prototype of the tool for automatic generation of the .tex files
for wxWindows documentation from C++ headers
*/ */
/* vi: set tw=80 et ts=4 sw=4: */ /* vi: set tw=80 et ts=4 sw=4: */

File diff suppressed because it is too large Load Diff

View File

@@ -238,7 +238,7 @@ inline void ScriptTemplate::PrintVar( TVarInfo* pInfo,
if ( !sz ) if ( !sz )
{ {
// DBG:: // DBG::
int u; int u = 0;
++u; ++u;
break; break;
} }

View File

@@ -6,7 +6,7 @@
// Created: 22/09/98 // Created: 22/09/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas // Copyright: (c) Aleskandars Gluchovas
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
@@ -33,387 +33,387 @@
/***** Implementation for class spVisitor *****/ /***** Implementation for class spVisitor *****/
void spVisitor::VisitAll( spContext& atContext, void spVisitor::VisitAll( spContext& atContext,
bool sortContent bool sortContent
) )
{ {
mSiblingSkipped = FALSE; mSiblingSkipped = FALSE;
mChildSkipped = FALSE; mChildSkipped = FALSE;
mContextMask = SP_CTX_ANY; // FIXME:: should be an arg. mContextMask = SP_CTX_ANY; // FIXME:: should be an arg.
if ( sortContent && !atContext.IsSorted() ) if ( sortContent && !atContext.IsSorted() )
atContext.SortMembers(); atContext.SortMembers();
mpCurCxt = &atContext; // FIXME:: this is dirty, restoring it each time mpCurCxt = &atContext; // FIXME:: this is dirty, restoring it each time
if ( atContext.GetContextType() & mContextMask ) if ( atContext.GetContextType() & mContextMask )
atContext.AcceptVisitor( *this ); atContext.AcceptVisitor( *this );
MMemberListT& members = atContext.GetMembers(); MMemberListT& members = atContext.GetMembers();
for( size_t i = 0; i != members.size(); ++i ) for( size_t i = 0; i != members.size(); ++i )
{ {
if ( mSiblingSkipped ) if ( mSiblingSkipped )
return; return;
if ( !mChildSkipped ) if ( !mChildSkipped )
{ {
size_t prevSz = members.size(); size_t prevSz = members.size();
// visit members of the context recursivelly // visit members of the context recursivelly
VisitAll( *members[i], sortContent ); VisitAll( *members[i], sortContent );
if ( members.size() != prevSz ) if ( members.size() != prevSz )
--i; // current member was removed! --i; // current member was removed!
mChildSkipped = 0; mChildSkipped = 0;
} }
} }
} }
void spVisitor::RemoveCurrentContext() void spVisitor::RemoveCurrentContext()
{ {
if ( mpCurCxt->GetParent() ) if ( mpCurCxt->GetParent() )
mpCurCxt->GetParent()->RemoveChild( mpCurCxt ); mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
} }
void spVisitor::SkipSiblings() void spVisitor::SkipSiblings()
{ {
mSiblingSkipped = TRUE; mSiblingSkipped = TRUE;
} }
void spVisitor::SkipChildren() void spVisitor::SkipChildren()
{ {
mChildSkipped = TRUE; mChildSkipped = TRUE;
} }
void spVisitor::SetFilter( int contextMask ) void spVisitor::SetFilter( int contextMask )
{ {
mContextMask = contextMask; mContextMask = contextMask;
} }
/***** Implementation for class spComment *****/ /***** Implementation for class spComment *****/
bool spComment::IsMultiline() const bool spComment::IsMultiline() const
{ {
return mIsMultiline; return mIsMultiline;
} }
bool spComment::StartsParagraph() const bool spComment::StartsParagraph() const
{ {
return mStartsPar; return mStartsPar;
} }
string& spComment::GetText() string& spComment::GetText()
{ {
return mText; return mText;
} }
string spComment::GetText() const string spComment::GetText() const
{ {
return mText; return mText;
} }
/***** Implementation for class spContext *****/ /***** Implementation for class spContext *****/
spContext::spContext() spContext::spContext()
: mpParent ( NULL ), : mpParent ( NULL ),
mpFirstOccurence( NULL ), mpFirstOccurence( NULL ),
mAlreadySorted ( FALSE ), mAlreadySorted ( FALSE ),
mSrcLineNo (-1), mSrcLineNo (-1),
mSrcOffset (-1), mSrcOffset (-1),
mContextLength(-1), mContextLength(-1),
mLastScrLineNo(-1), mLastScrLineNo(-1),
mHeaderLength (-1), mHeaderLength (-1),
mFooterLength (-1), mFooterLength (-1),
mFirstCharPos (-1), mFirstCharPos (-1),
mLastCharPos (-1), mLastCharPos (-1),
mVisibility( SP_VIS_PRIVATE ), mVisibility( SP_VIS_PRIVATE ),
mIsVirtualContext ( FALSE ), mIsVirtualContext ( FALSE ),
mVirtualContextHasChildren( FALSE ), mVirtualContextHasChildren( FALSE ),
mpUserData( NULL ) mpUserData( NULL )
{} {}
void spContext::RemoveChildren() void spContext::RemoveChildren()
{ {
for( size_t i = 0; i != mMembers.size(); ++i ) for( size_t i = 0; i != mMembers.size(); ++i )
delete mMembers[i]; delete mMembers[i];
mMembers.erase( mMembers.begin(), mMembers.end() ); mMembers.erase( mMembers.begin(), mMembers.end() );
} }
spContext::~spContext() spContext::~spContext()
{ {
RemoveChildren(); RemoveChildren();
for( size_t i = 0; i != mComments.size(); ++i ) for( size_t i = 0; i != mComments.size(); ++i )
delete mComments[i]; delete mComments[i];
} }
bool spContext::IsSorted() bool spContext::IsSorted()
{ {
return mAlreadySorted; return mAlreadySorted;
} }
void spContext::GetContextList( MMemberListT& lst, int contextMask ) void spContext::GetContextList( MMemberListT& lst, int contextMask )
{ {
for( size_t i = 0; i != mMembers.size(); ++i ) for( size_t i = 0; i != mMembers.size(); ++i )
{ {
spContext& member = *mMembers[i]; spContext& member = *mMembers[i];
if ( member.GetContextType() & contextMask ) if ( member.GetContextType() & contextMask )
lst.push_back( &member ); lst.push_back( &member );
// collect required contexts recursively // collect required contexts recursively
member.GetContextList( lst, contextMask ); member.GetContextList( lst, contextMask );
} }
} }
bool spContext::HasComments() bool spContext::HasComments()
{ {
return ( mComments.size() != 0 ); return ( mComments.size() != 0 );
} }
void spContext::RemoveChild( spContext* pChild ) void spContext::RemoveChild( spContext* pChild )
{ {
for( size_t i = 0; i != mMembers.size(); ++i ) for( size_t i = 0; i != mMembers.size(); ++i )
if ( mMembers[i] == pChild ) if ( mMembers[i] == pChild )
{ {
mMembers.erase( &mMembers[i] ); mMembers.erase( &mMembers[i] );
delete pChild; delete pChild;
return; return;
} }
// the given child should exist on the parent's list // the given child should exist on the parent's list
wxASSERT( 0 ); wxASSERT( 0 );
} }
spContext* spContext::GetEnclosingContext( int mask ) spContext* spContext::GetEnclosingContext( int mask )
{ {
spContext* cur = this->GetParent(); spContext* cur = this->GetParent();
while ( cur && !(cur->GetContextType() & mask) ) while ( cur && !(cur->GetContextType() & mask) )
cur = cur->GetParent(); cur = cur->GetParent();
return cur; return cur;
} }
bool spContext::PositionIsKnown() bool spContext::PositionIsKnown()
{ {
return ( mSrcOffset != (-1) && mContextLength != (-1) ); return ( mSrcOffset != (-1) && mContextLength != (-1) );
} }
bool spContext::IsVirtualContext() bool spContext::IsVirtualContext()
{ {
return mIsVirtualContext; return mIsVirtualContext;
} }
bool spContext::VitualContextHasChildren() bool spContext::VitualContextHasChildren()
{ {
return mVirtualContextHasChildren; return mVirtualContextHasChildren;
} }
string spContext::GetVirtualContextBody() string spContext::GetVirtualContextBody()
{ {
wxASSERT( mIsVirtualContext ); wxASSERT( mIsVirtualContext );
return mVirtualContextBody; return mVirtualContextBody;
} }
string spContext::GetFooterOfVirtualContextBody() string spContext::GetFooterOfVirtualContextBody()
{ {
wxASSERT( mIsVirtualContext ); wxASSERT( mIsVirtualContext );
return mVittualContextFooter; return mVittualContextFooter;
} }
void spContext::SetVirtualContextBody( const string& body, void spContext::SetVirtualContextBody( const string& body,
bool hasChildren, bool hasChildren,
const string& footer ) const string& footer )
{ {
mVirtualContextHasChildren = hasChildren; mVirtualContextHasChildren = hasChildren;
mVirtualContextBody = body; mVirtualContextBody = body;
mVittualContextFooter = footer; mVittualContextFooter = footer;
// atuomaticllay becomes virtual context // atuomaticllay becomes virtual context
mIsVirtualContext = TRUE; mIsVirtualContext = TRUE;
} }
string spContext::GetBody( spContext* pCtx ) string spContext::GetBody( spContext* pCtx )
{ {
if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext ) if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
return mVirtualContextBody; return mVirtualContextBody;
if ( GetParent() ) if ( GetParent() )
return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this ); return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
else else
return ""; // source-fragment cannot be found return ""; // source-fragment cannot be found
} }
string spContext::GetHeader( spContext* pCtx ) string spContext::GetHeader( spContext* pCtx )
{ {
if ( GetParent() ) if ( GetParent() )
return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this ); return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
else else
return ""; // source-fragment cannot be found return ""; // source-fragment cannot be found
} }
bool spContext::IsFirstOccurence() bool spContext::IsFirstOccurence()
{ {
return ( mpFirstOccurence != 0 ); return ( mpFirstOccurence != 0 );
} }
spContext* spContext::GetFirstOccurence() spContext* spContext::GetFirstOccurence()
{ {
// this object should not itself be // this object should not itself be
// the first occurence of the context // the first occurence of the context
wxASSERT( mpFirstOccurence != 0 ); wxASSERT( mpFirstOccurence != 0 );
return mpFirstOccurence; return mpFirstOccurence;
} }
void spContext::AddMember( spContext* pMember ) void spContext::AddMember( spContext* pMember )
{ {
mMembers.push_back( pMember ); mMembers.push_back( pMember );
pMember->mpParent = this; pMember->mpParent = this;
} }
void spContext::AddComment( spComment* pComment ) void spContext::AddComment( spComment* pComment )
{ {
mComments.push_back( pComment ); mComments.push_back( pComment );
} }
MMemberListT& spContext::GetMembers() MMemberListT& spContext::GetMembers()
{ {
return mMembers; return mMembers;
} }
spContext* spContext::FindContext( const string& identifier, spContext* spContext::FindContext( const string& identifier,
int contextType, int contextType,
bool searchSubMembers bool searchSubMembers
) )
{ {
for( size_t i = 0; i != mMembers.size(); ++i ) for( size_t i = 0; i != mMembers.size(); ++i )
{ {
spContext& member = *mMembers[i]; spContext& member = *mMembers[i];
if ( member.GetName() == identifier && if ( member.GetName() == identifier &&
( contextType & member.GetContextType() ) ( contextType & member.GetContextType() )
) )
return &member; return &member;
if ( searchSubMembers ) if ( searchSubMembers )
{ {
spContext* result = spContext* result =
member.FindContext( identifier, contextType, 1 ); member.FindContext( identifier, contextType, 1 );
if ( result ) return result; if ( result ) return result;
} }
} }
return 0; return 0;
} }
void spContext::RemoveThisContext() void spContext::RemoveThisContext()
{ {
if ( mpParent ) if ( mpParent )
mpParent->RemoveChild( this ); mpParent->RemoveChild( this );
else else
// context should have a parent // context should have a parent
wxASSERT(0); wxASSERT(0);
} }
spContext* spContext::GetOutterContext() spContext* spContext::GetOutterContext()
{ {
return mpParent; return mpParent;
} }
bool spContext::HasOutterContext() bool spContext::HasOutterContext()
{ {
return ( mpParent != 0 ); return ( mpParent != 0 );
} }
bool spContext::IsInFile() bool spContext::IsInFile()
{ {
return ( GetOutterContext()->GetContextType() == SP_CTX_FILE ); return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
} }
bool spContext::IsInNameSpace() bool spContext::IsInNameSpace()
{ {
return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE ); return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
} }
bool spContext::IsInClass() bool spContext::IsInClass()
{ {
return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS ); return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
} }
bool spContext::IsInOperation() bool spContext::IsInOperation()
{ {
return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION ); return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
} }
spClass& spContext::GetClass() spClass& spContext::GetClass()
{ {
wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS ); wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
return *((spClass*)mpParent ); return *((spClass*)mpParent );
} }
spFile& spContext::GetFile() spFile& spContext::GetFile()
{ {
wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE ); wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
return *((spFile*)mpParent ); return *((spFile*)mpParent );
} }
spNameSpace& spContext::GetNameSpace() spNameSpace& spContext::GetNameSpace()
{ {
wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE ); wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
return *((spNameSpace*)mpParent ); return *((spNameSpace*)mpParent );
} }
spOperation& spContext::GetOperation() spOperation& spContext::GetOperation()
{ {
wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION ); wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
return *((spOperation*)mpParent ); return *((spOperation*)mpParent );
} }
/***** Implementation for class spClass *****/ /***** Implementation for class spClass *****/
void spClass::SortMembers() void spClass::SortMembers()
{ {
// TBD:: // TBD::
} }
/***** Implementation for class spOperation *****/ /***** Implementation for class spOperation *****/
spOperation::spOperation() spOperation::spOperation()
: mHasDefinition( FALSE ) : mHasDefinition( FALSE )
{ {
mIsConstant = mIsConstant =
mIsVirtual = mIsVirtual =
@@ -422,83 +422,83 @@ spOperation::spOperation()
string spOperation::GetFullName(MarkupTagsT tags) string spOperation::GetFullName(MarkupTagsT tags)
{ {
string txt = tags[TAG_BOLD].start + mRetType; string txt = tags[TAG_BOLD].start + mRetType;
txt += " "; txt += " ";
txt += mName; txt += mName;
txt += "( "; txt += "( ";
txt += tags[TAG_BOLD].end; txt += tags[TAG_BOLD].end;
for( size_t i = 0; i != mMembers.size(); ++i ) for( size_t i = 0; i != mMembers.size(); ++i )
{ {
// DBG:: // DBG::
wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER ); wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER );
spParameter& param = *((spParameter*)mMembers[i]); spParameter& param = *((spParameter*)mMembers[i]);
if ( i != 0 ) if ( i != 0 )
txt += ", "; txt += ", ";
txt += tags[TAG_BOLD].start; txt += tags[TAG_BOLD].start;
txt += param.mType; txt += param.mType;
txt += tags[TAG_BOLD].end; txt += tags[TAG_BOLD].end;
txt += tags[TAG_ITALIC].start; txt += tags[TAG_ITALIC].start;
txt += " "; txt += " ";
txt += param.mName; txt += param.mName;
if ( param.mInitVal != "" ) if ( param.mInitVal != "" )
{ {
txt += " = "; txt += " = ";
txt += tags[TAG_BOLD].start; txt += tags[TAG_BOLD].start;
txt += param.mInitVal; txt += param.mInitVal;
txt += tags[TAG_BOLD].end; txt += tags[TAG_BOLD].end;
} }
txt += tags[TAG_ITALIC].end;; txt += tags[TAG_ITALIC].end;;
} }
txt += tags[TAG_BOLD].start; txt += tags[TAG_BOLD].start;
txt += " )"; txt += " )";
txt += tags[TAG_BOLD].end; txt += tags[TAG_BOLD].end;
// TBD:: constantness of method // TBD:: constantness of method
return txt; return txt;
} }
/***** Implemenentation for class spPreprocessorLine *****/ /***** Implemenentation for class spPreprocessorLine *****/
string spPreprocessorLine::CPP_GetIncludedFileNeme() string spPreprocessorLine::CPP_GetIncludedFileNeme() const
{ {
wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE ); wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE );
size_t i = 0; size_t i = 0;
while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '<' ) while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '<' )
++i; ++i;
++i; ++i;
size_t start = i; size_t start = i;
while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '>' ) while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '>' )
++i; ++i;
if ( start < mLine.length() ) if ( start < mLine.length() )
{ {
string fname; string fname;
fname.append( mLine, start, ( i - start ) ); fname.append( mLine, start, ( i - start ) );
return fname; return fname;
} }
else else
return ""; // syntax error probably return ""; // syntax error probably
} }
@@ -507,41 +507,202 @@ string spPreprocessorLine::CPP_GetIncludedFileNeme()
SourceParserBase::SourceParserBase() SourceParserBase::SourceParserBase()
: mpFileBuf( NULL ), : mpFileBuf( NULL ),
mFileBufSz( 0 ), mFileBufSz( 0 ),
mpPlugin( NULL ) mpPlugin( NULL )
{} {}
SourceParserBase::~SourceParserBase() SourceParserBase::~SourceParserBase()
{ {
if ( mpFileBuf ) free( mpFileBuf ); if ( mpFileBuf ) free( mpFileBuf );
if ( mpPlugin ) delete mpPlugin; if ( mpPlugin ) delete mpPlugin;
} }
spFile* SourceParserBase::ParseFile( const char* fname ) spFile* SourceParserBase::ParseFile( const char* fname )
{ {
// FIXME:: the below should not be fixed! // FIXME:: the below should not be fixed!
const size_t MAX_BUF_SIZE = 1024*256; const size_t MAX_BUF_SIZE = 1024*256;
if ( !mpFileBuf ) mpFileBuf = (char*)malloc( MAX_BUF_SIZE ); if ( !mpFileBuf ) mpFileBuf = (char*)malloc( MAX_BUF_SIZE );
mFileBufSz = MAX_BUF_SIZE; mFileBufSz = MAX_BUF_SIZE;
FILE* fp = fopen( fname, "rt" ); FILE* fp = fopen( fname, "rt" );
if ( (int)fp == -1 || !fp ) return NULL; if ( (int)fp == -1 || !fp ) return NULL;
int sz = fread( mpFileBuf, 1, mFileBufSz, fp ); int sz = fread( mpFileBuf, 1, mFileBufSz, fp );
return Parse( mpFileBuf, mpFileBuf + sz ); return Parse( mpFileBuf, mpFileBuf + sz );
} }
void SourceParserBase::SetPlugin( SourceParserPlugin* pPlugin ) void SourceParserBase::SetPlugin( SourceParserPlugin* pPlugin )
{ {
if ( mpPlugin ) delete mpPlugin; if ( mpPlugin ) delete mpPlugin;
mpPlugin = pPlugin; mpPlugin = pPlugin;
} }
// ===========================================================================
// debug methods
// ===========================================================================
#ifdef __WXDEBUG__
void spContext::Dump(const wxString& indent) const
{
DumpThis(indent);
// increase it for the children
wxString indentChild = indent + " ";
for ( MMemberListT::const_iterator i = mMembers.begin();
i != mMembers.end();
i++ ) {
(*i)->Dump(indentChild);
}
}
void spContext::DumpThis(const wxString& indent) const
{
wxFAIL_MSG("abstract base class can't be found in parser tree!");
}
void spParameter::DumpThis(const wxString& indent) const
{
wxLogDebug("%sparam named '%s' of type '%s'",
indent.c_str(), mName.c_str(), mType.c_str());
}
void spAttribute::DumpThis(const wxString& indent) const
{
wxLogDebug("%svariable named '%s' of type '%s'",
indent.c_str(), mName.c_str(), mType.c_str());
}
void spOperation::DumpThis(const wxString& indent) const
{
wxString protection;
if ( !!mScope ) {
switch ( mVisibility ) {
case SP_VIS_PUBLIC:
protection = "public";
break;
case SP_VIS_PROTECTED:
protection = "protected";
break;
case SP_VIS_PRIVATE:
protection = "private";
break;
default:
wxFAIL_MSG("unknown protection type");
}
}
else {
protection = "global";
}
wxLogDebug("%s%s%s%s function named '%s::%s' of type '%s'",
indent.c_str(),
mIsConstant ? "const " : "",
mIsVirtual ? "virtual " : "",
protection.c_str(),
mScope.c_str(), mName.c_str(), mRetType.c_str());
}
void spPreprocessorLine::DumpThis(const wxString& indent) const
{
wxString kind;
switch ( mDefType ) {
case SP_PREP_DEF_DEFINE_SYMBOL:
kind = "define";
break;
case SP_PREP_DEF_REDEFINE_SYMBOL:
kind = "redefine";
break;
case SP_PREP_DEF_INCLUDE_FILE:
kind.Printf("include (%s)", CPP_GetIncludedFileNeme().c_str());
break;
case SP_PREP_DEF_OTHER:
kind = "other";
break;
}
wxLogDebug("%spreprocessor statement: %s",
indent.c_str(), kind.c_str());
}
void spClass::DumpThis(const wxString& indent) const
{
wxString base;
for ( StrListT::const_iterator i = mSuperClassNames.begin();
i != mSuperClassNames.end();
i++ ) {
if ( !!base )
base += ", ";
base += *i;
}
if ( !base )
base = "none";
wxString kind;
switch ( mClassSubType ) {
case SP_CLTYPE_CLASS:
kind = "class";
break;
case SP_CLTYPE_TEMPLATE_CLASS:
kind = "template class";
break;
case SP_CLTYPE_STRUCTURE:
kind = "struc";
break;
case SP_CLTYPE_UNION:
kind = "union";
break;
case SP_CLTYPE_INTERFACE:
kind = "interface";
break;
default:
wxFAIL_MSG("unknown class subtype");
}
wxLogDebug("%s%s named '%s' (base classes: %s)",
indent.c_str(), kind.c_str(),
mName.c_str(), base.c_str());
}
void spEnumeration::DumpThis(const wxString& indent) const
{
wxLogDebug("%senum named '%s'",
indent.c_str(), mName.c_str());
}
void spTypeDef::DumpThis(const wxString& indent) const
{
wxLogDebug("%stypedef %s = %s",
indent.c_str(), mName.c_str(), mOriginalType.c_str());
}
void spFile::DumpThis(const wxString& indent) const
{
wxLogDebug("%sfile '%s'",
indent.c_str(), mFileName.c_str());
}
#endif // __WXDEBUG__