// Created: 22/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef __CJPARSESR_G__
// class parses given "memory-resident" Java or C++ source code
// and captures information about classes/attrubutes/methods/
-// arguments/etc into structures. Conforms with SourceParserBase
+// arguments/etc into structures. Conforms with SourceParserBase
// interface requirements.
class CJSourceParser : public SourceParserBase
{
protected:
- // begining of the full-text area of the source file
- char* mpStart;
+ // begining of the full-text area of the source file
+ char* mpStart;
- // points to first character after the end
- // of teh full-text area
- char* mpEnd;
+ // points to first character after the end
+ // of teh full-text area
+ char* mpEnd;
- // current "privacy level"
- int mCurVis;
+ // current "privacy level"
+ int mCurVis;
- // current parsing position int full-text area
- char* cur;
+ // current parsing position int full-text area
+ char* cur;
- // about the current class
- bool mIsVirtual;
- bool mIsTemplate;
- size_t mNestingLevel;
+ // about the current class
+ bool mIsVirtual;
+ bool mIsTemplate;
+ size_t mNestingLevel;
- // context data for which is currently being collected
- spContext* mpCurCtx;
+ // context data for which is currently being collected
+ spContext* mpCurCtx;
- int mCurCtxType; // type of the current context
+ int mCurCtxType; // type of the current context
- bool mCommentsOn;
- bool mMacrosOn;
+ bool mCommentsOn;
+ bool mMacrosOn;
protected:
- void AttachComments( spContext& ctx, char* cur );
- void ParseKeyword( char*& cur );
- bool ParseNameAndRetVal( char*& cur, bool& isAMacro );
- bool ParseArguments( char*& cur );
- void ParseMemberVar( char*& cur );
- void SkipFunction( char*& cur );
- void SkipFunctionBody( char*& cur );
- bool CheckVisibilty( char*& cur );
+ void AttachComments( spContext& ctx, char* cur );
+ void ParseKeyword( char*& cur );
+ bool ParseNameAndRetVal( char*& cur, bool& isAMacro );
+ bool ParseArguments( char*& cur );
+ void ParseMemberVar( char*& cur );
+ void SkipFunction( char*& cur );
+ void SkipFunctionBody( char*& cur );
+ bool CheckVisibilty( char*& cur );
- void AddClassNode( char*& cur );
- void AddMacroNode( char*& cur );
- void AddEnumNode( char*& cur );
- void AddTypeDefNode( char*& cur );
+ void AddClassNode( char*& cur );
+ void AddMacroNode( char*& cur );
+ void AddEnumNode( char*& cur );
+ void AddTypeDefNode( char*& cur );
- void DumpOperationInfo( spOperation& info, const string& tab, ostream& os );
- void DumpClassHeader( spClass& info, ostream& os );
- void DumpClassBody( spClass& info, ostream& os );
+ void DumpOperationInfo( spOperation& info, const string& tab, ostream& os );
+ void DumpClassHeader( spClass& info, ostream& os );
+ void DumpClassBody( spClass& info, ostream& os );
public:
- // NOTE:: discarding of macros or comments improves performance and
- // decreases memory usage
+ // NOTE:: discarding of macros or comments improves performance and
+ // decreases memory usage
- CJSourceParser(bool collectCommnets = 1,
- bool collectMacros = 1);
+ CJSourceParser(bool collectCommnets = 1,
+ bool collectMacros = 1);
- // returns the root-node of the created context tree
- // (user is responsible for releasing it from the heep)
- // "end" should point to the last (character + 1) of the
- // source text
+ // returns the root-node of the created context tree
+ // (user is responsible for releasing it from the heep)
+ // "end" should point to the last (character + 1) of the
+ // source text
- virtual spFile* Parse( char* start, char* end );
+ virtual spFile* Parse( char* start, char* end );
};
// inline'ed helpers used (just info):
// Created: 22/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef __SRCPARSER_G__
#define __SRCPARSER_G__
#if defined( wxUSE_TEMPLATE_STL )
- #include <vector>
+ #include <vector>
- #ifdef WIN32
- #include <bstring.h>
- #else
+ #ifdef WIN32
+ #include <bstring.h>
+ #else
- #include <strclass.h>
- #include <string.h>
+ #include <strclass.h>
+ #include <string.h>
- #endif
+ #endif
#else
- #include "wx/string.h"
- #include "wxstlvec.h"
+ #include "wx/string.h"
+ #include "wxstlvec.h"
- // FOR NOW:: quick n' dirty:
+ // FOR NOW:: quick n' dirty:
- #define string wxString
+ #define string wxString
#endif
#include "markup.h" // markup tags used in spOperator::GetFullName()
+// these methods are used for debugging only and disappear in the release build
+#ifdef __WXDEBUG__
+ #define DECLARE_DUMP virtual void DumpThis(const wxString& indent) const;
+#else
+ #define DECLARE_DUMP
+#endif
+
// context class list in "inside-out" order :
class spContext;
// source context visibilities
enum SRC_VISIBLITY_TYPES
{
- SP_VIS_PUBLIC,
- SP_VIS_PROTECTED,
- SP_VIS_PRIVATE
+ SP_VIS_PUBLIC,
+ SP_VIS_PROTECTED,
+ SP_VIS_PRIVATE
};
// class types
enum SP_CLASS_TYPES
{
- SP_CLTYPE_CLASS,
- SP_CLTYPE_TEMPLATE_CLASS,
- SP_CLTYPE_STRUCTURE,
- SP_CLTYPE_UNION,
- SP_CLTYPE_INTERFACE
+ SP_CLTYPE_INVALID,
+ SP_CLTYPE_CLASS,
+ SP_CLTYPE_TEMPLATE_CLASS,
+ SP_CLTYPE_STRUCTURE,
+ SP_CLTYPE_UNION,
+ SP_CLTYPE_INTERFACE
};
// inheritance types
enum SP_INHERITANCE_TYPES
{
- SP_INHERIT_VIRTUAL,
- SP_INHERIT_PUBLIC,
- SP_INHERIT_PRIVATE
+ SP_INHERIT_VIRTUAL,
+ SP_INHERIT_PUBLIC,
+ SP_INHERIT_PRIVATE
};
// proprocessor definitions types (specific to C++ code)
enum SP_PREP_DEFINITION_TYPES
{
- SP_PREP_DEF_DEFINE_SYMBOL,
- SP_PREP_DEF_REDEFINE_SYMBOL,
- SP_PREP_DEF_INCLUDE_FILE,
- SP_PREP_DEF_OTHER
+ SP_PREP_DEF_DEFINE_SYMBOL,
+ SP_PREP_DEF_REDEFINE_SYMBOL,
+ SP_PREP_DEF_INCLUDE_FILE,
+ SP_PREP_DEF_OTHER
};
// common context types
#define SP_CTX_UNKNOWN 0x000
-#define SP_CTX_FILE 0x001
-#define SP_CTX_NAMESPACE 0x002
-#define SP_CTX_CLASS 0x004
+#define SP_CTX_FILE 0x001
+#define SP_CTX_NAMESPACE 0x002
+#define SP_CTX_CLASS 0x004
#define SP_CTX_TYPEDEF 0x008
#define SP_CTX_PREPROCESSOR 0x010
#define SP_CTX_ENUMERATION 0x020
-#define SP_CTX_ATTRIBUTE 0x040
-#define SP_CTX_OPERATION 0x080
-#define SP_CTX_PARAMETER 0x100
+#define SP_CTX_ATTRIBUTE 0x040
+#define SP_CTX_OPERATION 0x080
+#define SP_CTX_PARAMETER 0x100
// other (custom) context codes may be defined elsewere, however they should
// not clash with above codes for common type and also should not
-// exceed 16-bits of in value
+// exceed 16-bits of in value
// masks all context types (up to 16 custom context can be defined)
#if defined( wxUSE_TEMPLATE_STL )
- // context members
- typedef vector<spContext*> MMemberListT;
- // comments list
- typedef vector<spComment*> MCommentListT;
- // list of parameters
- typedef vector<spParameter*> MParamListT;
- // string list
- typedef vector<string> StrListT;
+ // context members
+ typedef vector<spContext*> MMemberListT;
+ // comments list
+ typedef vector<spComment*> MCommentListT;
+ // list of parameters
+ typedef vector<spParameter*> MParamListT;
+ // string list
+ typedef vector<string> StrListT;
#else
- typedef spContext* spContextPtrT;
- typedef spComment* spCommentPtrT;
- typedef spParameter* spParameterPtrT;
- typedef WXSTL_VECTOR_SHALLOW_COPY(spContextPtrT) MMemberListT;
- typedef WXSTL_VECTOR_SHALLOW_COPY(spCommentPtrT) MCommentListT;
- typedef WXSTL_VECTOR_SHALLOW_COPY(spParameterPtrT) MParamListT;
- typedef WXSTL_VECTOR_SHALLOW_COPY(string) StrListT;
+ typedef spContext* spContextPtrT;
+ typedef spComment* spCommentPtrT;
+ typedef spParameter* spParameterPtrT;
+ typedef WXSTL_VECTOR_SHALLOW_COPY(spContextPtrT) MMemberListT;
+ typedef WXSTL_VECTOR_SHALLOW_COPY(spCommentPtrT) MCommentListT;
+ typedef WXSTL_VECTOR_SHALLOW_COPY(spParameterPtrT) MParamListT;
+ typedef WXSTL_VECTOR_SHALLOW_COPY(string) StrListT;
#endif;
// base class for all visitors of source code contents
-class spVisitor
+class spVisitor
{
protected:
- bool mSiblingSkipped;
- bool mChildSkipped;
- int mContextMask;
+ bool mSiblingSkipped;
+ bool mChildSkipped;
+ int mContextMask;
- spContext* mpCurCxt;
+ spContext* mpCurCxt;
public:
- // methods invoked by context
+ // methods invoked by context
- // method invoked from user's controling code
- // to visit all nodes staring at the given context.
- // Content is sorted if requrired, see comments
- // spClass on sorting the class members
+ // method invoked from user's controling code
+ // to visit all nodes staring at the given context.
+ // Content is sorted if requrired, see comments
+ // spClass on sorting the class members
- void VisitAll( spContext& atContext,
- bool sortContent = TRUE
- );
+ void VisitAll( spContext& atContext,
+ bool sortContent = TRUE
+ );
- // methods invoked by visitor
+ // methods invoked by visitor
- // goes to the next context in the outter scope
- // NOTE:: should not be invoked more than once while
- // visiting certain context
+ // goes to the next context in the outter scope
+ // NOTE:: should not be invoked more than once while
+ // visiting certain context
- void SkipSiblings();
+ void SkipSiblings();
- // prevents going down into the contexts contained by
- // the current context
- // NOTE:: the same as above
+ // prevents going down into the contexts contained by
+ // the current context
+ // NOTE:: the same as above
- void SkipChildren();
+ void SkipChildren();
- // can be called only in from visiting procedure
- void RemoveCurrentContext();
+ // can be called only in from visiting procedure
+ void RemoveCurrentContext();
- // method enables fast filtered traversal
- // of source content, e.g. collecting only classes,
- // or only global functions
+ // method enables fast filtered traversal
+ // of source content, e.g. collecting only classes,
+ // or only global functions
- // arg. context - can contain combination of contexts concatinated
- // with bitwise OR, e.g. SP_CTX_CLASS | SP_CTX_NAMESPACE
- //
- // method can be invoked from the user's controling as well as
- // from within the visting procedure
+ // arg. context - can contain combination of contexts concatinated
+ // with bitwise OR, e.g. SP_CTX_CLASS | SP_CTX_NAMESPACE
+ //
+ // method can be invoked from the user's controling as well as
+ // from within the visting procedure
- void SetFilter( int contextMask );
+ void SetFilter( int contextMask );
- // methods should be implemneted by specific visitor:
+ // methods should be implemneted by specific visitor:
- // NOTE:: Do not confuse visiting with parsing, first
- // the source is parsed, and than can be visited
- // multiple times by variouse visitors (there can
- // be more the one visitor visiting content at a time)
+ // NOTE:: Do not confuse visiting with parsing, first
+ // the source is parsed, and than can be visited
+ // multiple times by variouse visitors (there can
+ // be more the one visitor visiting content at a time)
- virtual void VisitFile( spFile& fl ) {}
+ virtual void VisitFile( spFile& fl ) {}
- virtual void VisitNameSpace( spNameSpace& ns ) {}
+ virtual void VisitNameSpace( spNameSpace& ns ) {}
- virtual void VisitClass( spClass& cl ) {}
+ virtual void VisitClass( spClass& cl ) {}
- virtual void VisitEnumeration( spEnumeration& en ) {}
+ virtual void VisitEnumeration( spEnumeration& en ) {}
- virtual void VisitTypeDef( spTypeDef& td ) {}
+ virtual void VisitTypeDef( spTypeDef& td ) {}
- virtual void VisitPreprocessorLine( spPreprocessorLine& pd ) {}
+ virtual void VisitPreprocessorLine( spPreprocessorLine& pd ) {}
- virtual void VisitAttribute( spAttribute& attr ) {}
+ virtual void VisitAttribute( spAttribute& attr ) {}
- virtual void VisitOperation( spOperation& op ) {}
+ virtual void VisitOperation( spOperation& op ) {}
- virtual void VisitParameter( spParameter& param ) {}
+ virtual void VisitParameter( spParameter& param ) {}
- virtual void VisitCustomContext( spContext& ctx ) {}
+ virtual void VisitCustomContext( spContext& ctx ) {}
};
// stores one section of comments,
class spComment
{
public:
- string mText;
- bool mIsMultiline; // multiline comments ar those with /**/'s
+ string mText;
+ bool mIsMultiline; // multiline comments ar those with /**/'s
- // TRUE, if these was an empty empty
- // line above single line comment
+ // TRUE, if these was an empty empty
+ // line above single line comment
+
+ bool mStartsPar;
- bool mStartsPar;
-
public:
- bool IsMultiline() const;
- bool StartsParagraph() const;
+ bool IsMultiline() const;
+ bool StartsParagraph() const;
- string& GetText();
+ string& GetText();
- // contstant version of GetText()
- string GetText() const;
+ // contstant version of GetText()
+ string GetText() const;
};
-// abstract base class for common (to most languages) code
-// contexts (constructs), e.g file, namespace, class, operation,
+// abstract base class for common (to most languages) code
+// contexts (constructs), e.g file, namespace, class, operation,
// etc
class spContext
{
protected:
- // "linked" list of comments belonging to this context
- MCommentListT mComments;
-
- // NULL, if this is file context
- MMemberListT mMembers;
+ // "linked" list of comments belonging to this context
+ MCommentListT mComments;
+
+ // NULL, if this is file context
+ MMemberListT mMembers;
- // NULL, if this is top-most context
- spContext* mpParent;
+ // NULL, if this is top-most context
+ spContext* mpParent;
- // points to context object, where the this context
- // was originally declared, meaning that this object
- // is redeclaration (or if in the case of operation
- // this context object most probably referres to the
- // implemnetation in .cpp file for example)
+ // points to context object, where the this context
+ // was originally declared, meaning that this object
+ // is redeclaration (or if in the case of operation
+ // this context object most probably referres to the
+ // implemnetation in .cpp file for example)
- // is NULL, if this object referres to the first occurence
- // of the context
+ // is NULL, if this object referres to the first occurence
+ // of the context
- spContext* mpFirstOccurence;
+ spContext* mpFirstOccurence;
- // used, to avoid excessive sorting of context's agreggates
- bool mAlreadySorted;
+ // used, to avoid excessive sorting of context's agreggates
+ bool mAlreadySorted;
public:
- // source line number, (-1) if unknown
- int mSrcLineNo;
+ // source line number, (-1) if unknown
+ int mSrcLineNo;
+
+ // offset of context in the source file, (-1) if unknown
+ int mSrcOffset;
- // offset of context in the source file, (-1) if unknown
- int mSrcOffset;
+ // lentgh of the context in characters, (-1) if unknown
+ int mContextLength;
- // lentgh of the context in characters, (-1) if unknown
- int mContextLength;
+ // source line number, in which this cotext ends, (-1) if unknown
+ int mLastScrLineNo;
- // source line number, in which this cotext ends, (-1) if unknown
- int mLastScrLineNo;
+ // fields are valid, if the may contain other contexts nested inside
+ int mHeaderLength;
+ int mFooterLength;
- // fields are valid, if the may contain other contexts nested inside
- int mHeaderLength;
- int mFooterLength;
+ // zero-based index of the first character of
+ // this context in the source line, (-1) if unknown
+ int mFirstCharPos;
- // zero-based index of the first character of
- // this context in the source line, (-1) if unknown
- int mFirstCharPos;
-
- // zero-based index of the first character of
- // this context in the last source line of this context, (-1) if unknown
- int mLastCharPos;
+ // zero-based index of the first character of
+ // this context in the last source line of this context, (-1) if unknown
+ int mLastCharPos;
- // see SRC_VISIBLITY_TYPES enumeration
- int mVisibility;
+ // see SRC_VISIBLITY_TYPES enumeration
+ int mVisibility;
- // TRUE, if context does not really exist in the source
- // but was created by external tools (e.g. forward engineering)
+ // TRUE, if context does not really exist in the source
+ // but was created by external tools (e.g. forward engineering)
- bool mIsVirtualContext;
- bool mVirtualContextHasChildren;
-
- // body of the context in case (mIsVirtual == TRUE)
- string mVirtualContextBody;
- string mVittualContextFooter;
+ bool mIsVirtualContext;
+ bool mVirtualContextHasChildren;
- // e.g. can be used by documentation generator to store
- // reference to section object
- void* mpUserData;
+ // body of the context in case (mIsVirtual == TRUE)
+ string mVirtualContextBody;
+ string mVittualContextFooter;
+
+ // e.g. can be used by documentation generator to store
+ // reference to section object
+ void* mpUserData;
public:
- // universal identifier of the context (e.g. class name)
- string mName;
+ // universal identifier of the context (e.g. class name)
+ string mName;
public:
- // default constructor
- spContext();
+ // default constructor
+ spContext();
+
+ // automatically destorys all aggregated contexts
+ // (thus, it's enought to call destructor of root-context)
+ virtual ~spContext();
- // automatically destorys all aggregated contexts
- // (thus, it's enought to call destructor of root-context)
- virtual ~spContext();
+ // see mUererData member;
+ void* GetUserData() { return mpUserData; }
- // see mUererData member;
- void* GetUserData() { return mpUserData; }
+ // sets untyped pointer to user data
+ void SetUserData( void* pUserData )
+ { mpUserData = pUserData; }
- // sets untyped pointer to user data
- void SetUserData( void* pUserData )
- { mpUserData = pUserData; }
+ // searches the whole context tree for the cotnexts
+ // which match given masks, pust results into lst array
+ void GetContextList( MMemberListT& lst, int contextMask );
- // searches the whole context tree for the cotnexts
- // which match given masks, pust results into lst array
- void GetContextList( MMemberListT& lst, int contextMask );
+ // used by default visitor's implementation
+ bool IsSorted();
- // used by default visitor's implementation
- bool IsSorted();
+ /*** forward/reverse ingineering fecilities ***/
- /*** forward/reverse ingineering fecilities ***/
+ bool PositionIsKnown();
- bool PositionIsKnown();
+ bool IsVirtualContext();
- bool IsVirtualContext();
-
- bool VitualContextHasChildren();
+ bool VitualContextHasChildren();
- void SetVirtualContextBody( const string& body,
- bool hasChildren = FALSE,
- const string& footer = "" );
+ void SetVirtualContextBody( const string& body,
+ bool hasChildren = FALSE,
+ const string& footer = "" );
- string GetVirtualContextBody();
- string GetFooterOfVirtualContextBody();
+ string GetVirtualContextBody();
+ string GetFooterOfVirtualContextBody();
- // can be overriden by top-level context classes
- // to find-out ot the source-fragment of this
- // context using it's position information
- virtual string GetBody( spContext* pCtx = NULL );
+ // can be overriden by top-level context classes
+ // to find-out ot the source-fragment of this
+ // context using it's position information
+ virtual string GetBody( spContext* pCtx = NULL );
- virtual string GetHeader( spContext* pCtx = NULL );
+ virtual string GetHeader( spContext* pCtx = NULL );
- // TRUE, if there is at least one entry
- // in the comment list of this context
- bool HasComments();
- MCommentListT& GetCommentList() { return mComments; }
- const MCommentListT& GetCommentList() const { return mComments; }
+ // TRUE, if there is at least one entry
+ // in the comment list of this context
+ bool HasComments();
+ MCommentListT& GetCommentList() { return mComments; }
+ const MCommentListT& GetCommentList() const { return mComments; }
- // should be overriden, if the context supports sorting
- // of it's members
- virtual void SortMembers() {}
+ // should be overriden, if the context supports sorting
+ // of it's members
+ virtual void SortMembers() {}
- // returns identifier of this context
- inline string& GetName() { return mName; }
+ // returns identifier of this context
+ inline string& GetName() { return mName; }
- // returns -1, if souce line # is unknow
- inline int GetSourceLineNo() { return mSrcLineNo; }
+ // returns -1, if souce line # is unknow
+ inline int GetSourceLineNo() { return mSrcLineNo; }
- // see comments on mpFirstOccurence member variable
- bool IsFirstOccurence();
- spContext* GetFirstOccurence();
+ // see comments on mpFirstOccurence member variable
+ bool IsFirstOccurence();
+ spContext* GetFirstOccurence();
- // returns not-NULL value if this context
- // is aggregated by another cotnext
- spContext* GetOutterContext();
+ // returns not-NULL value if this context
+ // is aggregated by another cotnext
+ spContext* GetOutterContext();
- // perhaps more intuitive alias for `GetOutterContext()'
- inline spContext* GetParent() { return mpParent; }
+ // perhaps more intuitive alias for `GetOutterContext()'
+ inline spContext* GetParent() { return mpParent; }
- bool HasOutterContext();
+ bool HasOutterContext();
- // add one aggregate (or child) into this context
- void AddMember ( spContext* pMember );
- MMemberListT& GetMembers();
+ // add one aggregate (or child) into this context
+ void AddMember ( spContext* pMember );
+ MMemberListT& GetMembers();
- // append comment to the comment list decribing
- // this context
- void AddComment( spComment* pComment );
+ // append comment to the comment list decribing
+ // this context
+ void AddComment( spComment* pComment );
- // returns NULL, if the context with the given
- // name and type is not contained by this context
- // and it's children. Children's children are not
- // searched recursivelly if searchSubMembers is FALSE
+ // returns NULL, if the context with the given
+ // name and type is not contained by this context
+ // and it's children. Children's children are not
+ // searched recursivelly if searchSubMembers is FALSE
- spContext* FindContext( const string& identifier,
- int contextType = SP_CTX_ANY,
- bool searchSubMembers = TRUE
- );
+ spContext* FindContext( const string& identifier,
+ int contextType = SP_CTX_ANY,
+ bool searchSubMembers = TRUE
+ );
- // removes this context from it's parent
- // (NOTE:: context should have an outter cotnext
- // to when this method is called, otherwise removal
- // will result assertion failure)
- void RemoveThisContext();
+ // removes this context from it's parent
+ // (NOTE:: context should have an outter cotnext
+ // to when this method is called, otherwise removal
+ // will result assertion failure)
+ void RemoveThisContext();
- // returns TRUE, if this object is aggregated in the file
- bool IsInFile();
+ // returns TRUE, if this object is aggregated in the file
+ bool IsInFile();
- // TRUE, if outter context is a namespace
- bool IsInNameSpace();
+ // TRUE, if outter context is a namespace
+ bool IsInNameSpace();
- // TRUE, if outter context is a class
- bool IsInClass();
+ // TRUE, if outter context is a class
+ bool IsInClass();
- // TRUE, if outter cotext is an operation (TRUE for "spParameter"s)
- bool IsInOperation();
+ // TRUE, if outter cotext is an operation (TRUE for "spParameter"s)
+ bool IsInOperation();
// TRUE if the context is public
bool IsPublic() const { return mVisibility == SP_VIS_PUBLIC; }
- // NOTE:: method returns not the type of this object
- // but the file/namespace/class/operation or file in which this
- // attribute is contained. First, check for the type of
- // context using the above method.
-
- // Requiering container which does not exist, will result
- // in assertion failure
+ // NOTE:: method returns not the type of this object
+ // but the file/namespace/class/operation or file in which this
+ // attribute is contained. First, check for the type of
+ // context using the above method.
+
+ // Requiering container which does not exist, will result
+ // in assertion failure
+
+ spClass& GetClass();
+ spFile& GetFile();
+ spNameSpace& GetNameSpace();
+ spOperation& GetOperation();
+
+ // each new context should override this method
+ // to return it's specific type
+ virtual int GetContextType() const { return SP_CTX_UNKNOWN; }
- spClass& GetClass();
- spFile& GetFile();
- spNameSpace& GetNameSpace();
- spOperation& GetOperation();
+ // perhaps more intuitive short-cut
+ inline int GetType() { return GetContextType(); }
- // each new context should override this method
- // to return it's specific type
- virtual int GetContextType() { return SP_CTX_UNKNOWN; }
+ // cast this context to the desired type - returns NULL if type is wrong
+ spAttribute *CastToAttribute()
+ {
+ return GetContextType() == SP_CTX_ATTRIBUTE ? (spAttribute *)this
+ : NULL;
+ }
- // perhaps more intuitive short-cut
- inline int GetType() { return GetContextType(); }
+ // derived classes override this to invoke VisitXXX method
+ // which corresponds to the class of specific context,
+ // - this is what the "Visitor" pattern told us ^)
- // derived classes override this to invoke VisitXXX method
- // which corresponds to the class of specific context,
- // - this is what the "Visitor" pattern told us ^)
+ // if method is not overriden, then it's probably user-defined
+ // custom context
- // if method is not overriden, then it's probably user-defined
- // custom context
+ virtual void AcceptVisitor( spVisitor& visitor )
- virtual void AcceptVisitor( spVisitor& visitor )
-
- { visitor.VisitCustomContext( *this ); };
+ { visitor.VisitCustomContext( *this ); };
- // called by visitors, to remove given subcontext
- // of this context object
- void RemoveChild( spContext* pChild );
+ // called by visitors, to remove given subcontext
+ // of this context object
+ void RemoveChild( spContext* pChild );
- void RemoveChildren();
+ void RemoveChildren();
- spContext* GetEnclosingContext( int mask = SP_CTX_ANY );
+ spContext* GetEnclosingContext( int mask = SP_CTX_ANY );
+
+#ifdef __WXDEBUG__
+ virtual void Dump(const wxString& indent) const;
+#endif // __WXDEBUG__
+
+ DECLARE_DUMP
};
// stores information about single argument of operation
class spParameter : public spContext
{
public:
- // type of argument (parameter)
- string mType;
+ // type of argument (parameter)
+ string mType;
- // "stringified" initial value
- string mInitVal;
+ // "stringified" initial value
+ string mInitVal;
public:
- virtual int GetContextType() { return SP_CTX_PARAMETER; }
+ virtual int GetContextType() const { return SP_CTX_PARAMETER; }
+
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitParameter( *this ); }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitParameter( *this ); }
+ DECLARE_DUMP
};
class spAttribute : public spContext
{
public:
- // type of the attribute
- string mType;
+ // type of the attribute
+ string mType;
- // it's initial value
- string mInitVal;
+ // it's initial value
+ string mInitVal;
- // constantness
- bool mIsConstant;
+ // constantness
+ bool mIsConstant;
public:
- virtual int GetContextType() { return SP_CTX_ATTRIBUTE; }
+ virtual int GetContextType() const { return SP_CTX_ATTRIBUTE; }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitAttribute( *this ); }
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitAttribute( *this ); }
+
+ DECLARE_DUMP
};
class spOperation : public spContext
{
public:
- // type of return value
- string mRetType;
+ // type of return value
+ string mRetType;
- // argument list
- //MParamListT mParams;
+ // argument list
+ //MParamListT mParams;
- // TRUE, if operation does not modify
- // the content of the object
- bool mIsConstant;
+ // TRUE, if operation does not modify
+ // the content of the object
+ bool mIsConstant;
- // flag, specific to C++
- bool mIsVirtual;
+ // flag, specific to C++
+ bool mIsVirtual;
- // TRUE, if definition follows the declaration immediatelly
- bool mHasDefinition;
+ // TRUE, if definition follows the declaration immediatelly
+ bool mHasDefinition;
- // scope if any (e.g. MyClass::MyFunction(), scope stirng is "MyClass" )
- // usually found along with implementation of the method, which is now skipped
+ // scope if any (e.g. MyClass::MyFunction(), scope stirng is "MyClass" )
+ // usually found along with implementation of the method, which is now skipped
- string mScope;
+ string mScope;
public:
- spOperation();
+ spOperation();
- // returns full declaration of the operations
- // (ret val., identifier, arg. list),
+ // returns full declaration of the operations
+ // (ret val., identifier, arg. list),
- // arguments are marked up with italic,
- // default values marked up with bold-italic,
- // all the rest is marked as bold
+ // arguments are marked up with italic,
+ // default values marked up with bold-italic,
+ // all the rest is marked as bold
- // NOTE:: this method may be overriden by class
- // specific to concrete parser, to provide
- // language-dependent reperesnetation of
- // operation and it's argumetn list
- //
- // the default implementation outputs name in
- // C++/Java syntax
+ // NOTE:: this method may be overriden by class
+ // specific to concrete parser, to provide
+ // language-dependent reperesnetation of
+ // operation and it's argumetn list
+ //
+ // the default implementation outputs name in
+ // C++/Java syntax
- virtual string GetFullName(MarkupTagsT tags);
+ virtual string GetFullName(MarkupTagsT tags);
- virtual int GetContextType() { return SP_CTX_OPERATION; }
+ virtual int GetContextType() const { return SP_CTX_OPERATION; }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitOperation( *this ); }
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitOperation( *this ); }
+ DECLARE_DUMP
};
// stores infromation about preprocessor directive
-class spPreprocessorLine : public spContext
+class spPreprocessorLine : public spContext
{
public:
- // prepocessor statement including '#' and
- // attached multiple lines with '\' character
- string mLine;
+ // prepocessor statement including '#' and
+ // attached multiple lines with '\' character
+ string mLine;
- int mDefType; // see SP_PREP_DEFINITION_TYPES enumeration
+ int mDefType; // see SP_PREP_DEFINITION_TYPES enumeration
public:
- virtual int GetContextType() { return SP_CTX_PREPROCESSOR; }
+ virtual int GetContextType() const { return SP_CTX_PREPROCESSOR; }
+
+ virtual int GetStatementType() const { return mDefType; }
- virtual int GetStatementType() { return mDefType; }
+ string CPP_GetIncludedFileNeme() const;
- string CPP_GetIncludedFileNeme();
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitPreprocessorLine( *this ); }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitPreprocessorLine( *this ); }
+ DECLARE_DUMP
};
-// stores information about the class
+// stores information about the class
class spClass : public spContext
{
public:
- // list of superclasses/interfaces
- StrListT mSuperClassNames;
+ // list of superclasses/interfaces
+ StrListT mSuperClassNames;
- // see SP_CLASS_TYPES enumeration
- int mClassSubType;
+ // see SP_CLASS_TYPES enumeration
+ int mClassSubType;
- // see SP_INHERITANCE_TYPES enumeration
- int mInheritanceType;
+ // see SP_INHERITANCE_TYPES enumeration
+ int mInheritanceType;
- // valid if mClassSubType is SP_CLTYPE_TEMPLATE_CLASS
- string mTemplateTypes;
+ // valid if mClassSubType is SP_CLTYPE_TEMPLATE_CLASS
+ string mTemplateTypes;
- // TRUE, if it's and interface of abstract base class
- bool mIsAbstract;
+ // TRUE, if it's and interface of abstract base class
+ bool mIsAbstract;
public:
-
- // sorts class members in the following order:
- //
- // (by "privacy level" - first private, than protected, public)
- //
- // within above set
- //
- // (by member type - attributes first, than methods, nested classes)
- //
- // within above set
- //
- // (by identifier of the member)
-
- virtual void SortMembers();
-
- virtual int GetContextType() { return SP_CTX_CLASS; }
-
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitClass( *this ); }
+ // sorts class members in the following order:
+ //
+ // (by "privacy level" - first private, than protected, public)
+ //
+ // within above set
+ //
+ // (by member type - attributes first, than methods, nested classes)
+ //
+ // within above set
+ //
+ // (by identifier of the member)
+
+ virtual void SortMembers();
+
+ virtual int GetContextType() const { return SP_CTX_CLASS; }
+
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitClass( *this ); }
+
+ DECLARE_DUMP
};
// stores information about enum statement
class spEnumeration : public spContext
{
public:
- string mEnumContent; // full-text content of enumeration
+ string mEnumContent; // full-text content of enumeration
public:
- virtual int GetContextType() { return SP_CTX_ENUMERATION; }
+ virtual int GetContextType() const { return SP_CTX_ENUMERATION; }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitEnumeration( *this ); }
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitEnumeration( *this ); }
+
+ DECLARE_DUMP
};
class spTypeDef : public spContext
{
public:
- // the original type which is redefined
- // by this type definition
- string mOriginalType;
+ // the original type which is redefined
+ // by this type definition
+ string mOriginalType;
public:
- virtual int GetContextType() { return SP_CTX_TYPEDEF; }
+ virtual int GetContextType() const { return SP_CTX_TYPEDEF; }
+
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitTypeDef( *this ); }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitTypeDef( *this ); }
+ DECLARE_DUMP
};
// NOTE:: files context may be put to other
class spFile : public spContext
{
public:
- // since file name cannot be determined from
- // source code, filling in this field is optional
- string mFileName;
+ // since file name cannot be determined from
+ // source code, filling in this field is optional
+ string mFileName;
public:
- virtual int GetContextType() { return SP_CTX_FILE; }
+ virtual int GetContextType() const { return SP_CTX_FILE; }
+
+ virtual void AcceptVisitor( spVisitor& visitor )
+ { visitor.VisitFile( *this ); }
- virtual void AcceptVisitor( spVisitor& visitor )
- { visitor.VisitFile( *this ); }
+ DECLARE_DUMP
};
//TODO:: comments.
class SourceParserPlugin
{
public:
- virtual bool CanUnderstandContext( char* cur, char* end, spContext* pOuttterCtx ) = 0;
- virtual void ParseContext( char* start, char*& cur, char* end, spContext* pOuttterCtx ) = 0;
+ virtual bool CanUnderstandContext( char* cur, char* end, spContext* pOuttterCtx ) = 0;
+ virtual void ParseContext( char* start, char*& cur, char* end, spContext* pOuttterCtx ) = 0;
};
// abstract interface for source parsers
// should be derivative of spContext, (see
// above classes)
-class SourceParserBase
+class SourceParserBase
{
private:
- // auto-resizing file buffer, created in ParseFile()
- // to reuse large heap block for multiple parsings
-
- char* mpFileBuf;
- int mFileBufSz;
+ // auto-resizing file buffer, created in ParseFile()
+ // to reuse large heap block for multiple parsings
+
+ char* mpFileBuf;
+ int mFileBufSz;
protected:
- SourceParserPlugin* mpPlugin;
-
+ SourceParserPlugin* mpPlugin;
+
protected:
- // value is set in the derived parser classes
- int mParserStatus;
+ // value is set in the derived parser classes
+ int mParserStatus;
public:
- SourceParserBase();
- virtual ~SourceParserBase();
+ SourceParserBase();
+ virtual ~SourceParserBase();
- // loads entier source file(as text) into memory,
- // and passes it's contents to ParseAll() method,
- // memory occupied by source text is released after
- // parsing is done
- //
- // (NOTE:: this is the default implementation),
+ // loads entier source file(as text) into memory,
+ // and passes it's contents to ParseAll() method,
+ // memory occupied by source text is released after
+ // parsing is done
+ //
+ // (NOTE:: this is the default implementation),
- virtual spFile* ParseFile( const char* fname );
+ virtual spFile* ParseFile( const char* fname );
- // should returns the root-node of the created context tree
- // (user is responsible for releasing it from the heep)
- // "end" should point to the (last character + 1) of the
- // source text area
+ // should returns the root-node of the created context tree
+ // (user is responsible for releasing it from the heep)
+ // "end" should point to the (last character + 1) of the
+ // source text area
- virtual spFile* Parse( char* start, char* end ) = 0;
+ virtual spFile* Parse( char* start, char* end ) = 0;
- // returns parser "status word" (specific to concrete parser)
- int GetParserStatus() { return mParserStatus; }
+ // returns parser "status word" (specific to concrete parser)
+ int GetParserStatus() { return mParserStatus; }
- void SetPlugin( SourceParserPlugin* pPlugin );
+ void SetPlugin( SourceParserPlugin* pPlugin );
};
#endif
(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
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
class HelpGenVisitor : public spVisitor
{
public:
// ctor
- HelpGenVisitor(const wxString& directoryOut) : m_directoryOut(directoryOut)
- {
- Reset();
- }
+ HelpGenVisitor(const wxString& directoryOut, bool overwrite);
virtual void VisitFile( spFile& fl );
virtual void VisitClass( spClass& cl );
void EndVisit();
+ // get our `ignore' object
+ IgnoreNamesHandler& GetIgnoreHandler() { return m_ignoreNames; }
+
// shut up g++ warning (ain't it stupid?)
virtual ~HelpGenVisitor() { }
// terminate the function documentation if it was started
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
// state variables
// 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&);
class DocManager
{
public:
- DocManager() : m_ignore(CompareIgnoreListEntries) { }
+ DocManager(bool checkParamNames);
~DocManager();
- // load file with class names and function names to ignore during diff
- bool LoadIgnoreFile(const wxString& filename);
-
// 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
// -----------------
// 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;
- 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, "");
- }
+ IgnoreNamesHandler m_ignoreNames;
// information about all functions documented in the TeX file(s)
// -------------------------------------------------------------
// 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&);
};
// -----------------------------------------------------------------------------
" -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"
-" options are:\n"
-" -i file file with classes/function to ignore during diff\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);
}
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++ ) {
// all options have one letter
usage();
case 'i':
+ current++;
+ if ( current >= argc ) {
+ wxLogError("-i option requires an argument.");
+
+ break;
+ }
+
+ ignoreFile = argv[current];
+ continue;
+
+ case 'p':
if ( mode != Mode_Diff ) {
- wxLogError("-i is only valid with diff.");
+ wxLogError("-p is only valid with diff.");
break;
}
- current++;
- if ( current >= argc ) {
- wxLogError("-i option requires an argument.");
+ paramNames = TRUE;
+ continue;
+
+ case 'f':
+ if ( mode != Mode_Dump ) {
+ wxLogError("-f is only valid with dump.");
break;
}
- ignoreFile = argv[current];
+ overwrite = TRUE;
continue;
case 'o':
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
- wxLogError("unknown option '%s'", argv[current]);
usage();
}
else if ( strcmp(argv[current], "dump") == 0 )
mode = Mode_Dump;
else {
- wxLogError("unknown mode '%s'.");
+ wxLogError("unknown mode '%s'.", argv[current]);
usage();
}
// create a parser object and a visitor derivation
CJSourceParser parser;
- HelpGenVisitor visitor(directoryOut);
+ HelpGenVisitor visitor(directoryOut, overwrite);
+ if ( !!ignoreFile && mode == Mode_Dump )
+ visitor.GetIgnoreHandler().AddNamesFromFile(ignoreFile);
+
spContext *ctxTop = NULL;
// parse all header files
visitor.VisitAll(*ctxTop);
visitor.EndVisit();
}
+
+#ifdef __WXDEBUG__
+ if ( 0 && ctxTop )
+ ctxTop->Dump("");
+#endif // __WXDEBUG__
}
// parse all TeX files
return 1;
}
- DocManager docman;
+ DocManager docman(paramNames);
size_t nFiles = filesTeX.GetCount();
for ( size_t n = 0; n < nFiles; n++ ) {
}
if ( !!ignoreFile )
- docman.LoadIgnoreFile(ignoreFile);
+ docman.GetIgnoreHandler().AddNamesFromFile(ignoreFile);
docman.DumpDifferences(ctxTop);
}
// HelpGenVisitor implementation
// -----------------------------------------------------------------------------
+HelpGenVisitor::HelpGenVisitor(const wxString& directoryOut,
+ bool overwrite)
+ : m_directoryOut(directoryOut)
+{
+ m_overwrite = overwrite;
+
+ Reset();
+}
+
void HelpGenVisitor::Reset()
{
m_inClass =
{
CloseFunction();
+ m_fileHeader.Empty();
+
wxLogVerbose("%s: finished generating for the current file.",
GetCurrentTime("%H:%M:%S"));
}
void HelpGenVisitor::VisitFile( spFile& file )
{
+ m_fileHeader = file.mFileName;
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 )
{
+ m_inClass = FALSE; // will be left FALSE on error
+
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 = m_directoryOut;
filename.MakeLower();
filename += ".tex";
- if ( wxFile::Exists(filename) ) {
- wxLogError("Won't overwrite existing file '%s' - please use '-o'.",
+ if ( !m_overwrite && wxFile::Exists(filename) ) {
+ wxLogError("Won't overwrite existing file '%s' - please use '-f'.",
filename.c_str());
- m_inClass = FALSE;
-
return;
}
"\n"
"\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());
totalText << header << '\n';
{
CloseFunction();
- if ( !m_inClass || !op.IsInClass() ) {
- // FIXME that's a bug too
+ 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;
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();
// save state info
// start function documentation
wxString totalText;
- const char *funcname = op.GetName().c_str();
- const char *classname = op.GetClass().GetName().c_str();
// check for the special case of dtor
wxString dtor;
- if ( (funcname[0] == '~') && (strcmp(funcname + 1, classname) == 0) ) {
- dtor.Printf("\\destruct{%s}", classname);
+ if ( (funcname[0] == '~') && (classname == funcname.c_str() + 1) ) {
+ dtor.Printf("\\destruct{%s}", classname.c_str());
funcname = dtor;
}
"\\membersection{%s::%s}\\label{%s}\n"
"\n"
"\\%sfunc{%s%s}{%s}{",
- classname, funcname,
+ classname.c_str(), funcname.c_str(),
MakeLabel(classname, funcname).c_str(),
op.mIsConstant ? "const" : "",
op.mIsVirtual ? "virtual " : "",
op.mRetType.c_str(),
- funcname);
+ funcname.c_str());
m_file.WriteTeX(totalText);
}
// DocManager
// ---------------------------------------------------------------------------
+DocManager::DocManager(bool checkParamNames)
+{
+ m_checkParamNames = checkParamNames;
+}
+
size_t DocManager::TryMatch(const char *str, const char *match)
{
size_t lenMatch = 0;
lenMatch = TryMatch(current, "void");
if ( !lenMatch ) {
lenMatch = TryMatch(current, "param");
- while ( lenMatch ) {
+ while ( lenMatch && (current - buf < len) ) {
current += lenMatch;
// now come {paramtype}{paramname}
const wxString& nameClass = ctxClass->mName;
int index = m_classes.Index(nameClass);
if ( index == wxNOT_FOUND ) {
- if ( !IgnoreClass(nameClass) ) {
+ if ( !m_ignoreNames.IgnoreClass(nameClass) ) {
foundDiff = TRUE;
wxLogError("Class '%s' is not documented at all.",
}
if ( aMethodsWithSameName.IsEmpty() && ctxMethod->IsPublic() ) {
- if ( !IgnoreMethod(nameClass, nameMethod) ) {
+ if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) {
foundDiff = TRUE;
wxLogError("'%s::%s' is not documented.",
index = (size_t)aMethodsWithSameName[0u];
methodExists[index] = TRUE;
- if ( IgnoreMethod(nameClass, nameMethod) )
+ if ( m_ignoreNames.IgnoreMethod(nameClass, nameMethod) )
continue;
if ( !ctxMethod->IsPublic() ) {
spParameter *ctxParam = (spParameter *)ctx;
const ParamInfo& param = method.GetParam(nParam);
- if ( param.GetName() != ctxParam->mName ) {
+ if ( m_checkParamNames &&
+ (param.GetName() != ctxParam->mName) ) {
foundDiff = TRUE;
wxLogError("Parameter #%d of '%s::%s' should be "
}
}
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;
if ( aOverloadedMethods.Index(nameMethod) == wxNOT_FOUND ) {
for ( nMethod = 0; nMethod < countMethods; nMethod++ ) {
if ( !methodExists[nMethod] ) {
const wxString& nameMethod = methods[nMethod]->GetName();
- if ( !IgnoreMethod(nameClass, nameMethod) ) {
+ if ( !m_ignoreNames.IgnoreMethod(nameClass, nameMethod) ) {
foundDiff = TRUE;
wxLogError("'%s::%s' is documented but doesn't exist.",
DocManager::~DocManager()
{
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
int rc = first->m_classname.Cmp(second->m_classname);
return rc;
}
-bool DocManager::LoadIgnoreFile(const wxString& filename)
+bool IgnoreNamesHandler::AddNamesFromFile(const wxString& filename)
{
wxFile file(filename, wxFile::read);
if ( !file.IsOpened() )
/*
$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
1. new 'diff' mode which seems to work
2. output files are not overwritten in 'dmup' mode
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: */
// Created: 22/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#if defined( wxUSE_TEMPLATE_STL )
- #include <map>
+ #include <map>
#else
- #include "wxstlac.h"
+ #include "wxstlac.h"
#endif
/***** keyword map related structures *****/
-struct less_c_str
+struct less_c_str
{
- inline bool operator()( char* x, char* y) const
- { return ( strcmp( x,y ) < 0 );
- }
+ inline bool operator()( char* x, char* y) const
+ { return ( strcmp( x,y ) < 0 );
+ }
};
//WXSTL_MAP(CharPtrT,CharPtrT, LESS_THEN_FUNCTOR(CharPtrT));
#if defined( wxUSE_TEMPLATE_STL )
- typedef map< char*, char*, less_c_str > KeywordMapT;
+ typedef map< char*, char*, less_c_str > KeywordMapT;
#else
- typedef char* CharPtrT;
- typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
+ typedef char* CharPtrT;
+ typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
#endif
static char* __gKeyWords[] =
{
- "public",
- "protected",
- "private",
-
- "class",
- "struct",
- "union",
- "enum",
- "interface",
-
- "package",
- "import",
-
- "typedef",
- "template",
- "friend",
- "const",
- "volatile",
- "mutable",
- "virtual",
- "inline",
- "static",
- "register",
-
- "final",
- "abstract",
- "native",
-
- "__stdcall",
- "extern",
-
- 0
+ "public",
+ "protected",
+ "private",
+
+ "class",
+ "struct",
+ "union",
+ "enum",
+ "interface",
+
+ "package",
+ "import",
+
+ "typedef",
+ "template",
+ "friend",
+ "const",
+ "volatile",
+ "mutable",
+ "virtual",
+ "inline",
+ "static",
+ "register",
+
+ "final",
+ "abstract",
+ "native",
+
+ "__stdcall",
+ "extern",
+
+ 0
};
static void check_keyword_map()
{
- if ( !__gMapReady )
- {
- __gMapReady = 1;
+ if ( !__gMapReady )
+ {
+ __gMapReady = 1;
- // "make sure" the address of the first member of non-polimorphic class
- // coinsides with the address of the instance
+ // "make sure" the address of the first member of non-polimorphic class
+ // coinsides with the address of the instance
- char** keyword = __gKeyWords;
+ char** keyword = __gKeyWords;
- while ( (*keyword) != 0 )
- {
- __gMultiLangMap.insert(
- KeywordMapT::value_type( *keyword, *keyword )
- );
+ while ( (*keyword) != 0 )
+ {
+ __gMultiLangMap.insert(
+ KeywordMapT::value_type( *keyword, *keyword )
+ );
- ++keyword;
- }
- }
+ ++keyword;
+ }
+ }
}
/***** helper functions *****/
static inline void skip_to_eol( char*& cur )
{
- while( *(cur) != 10 && *cur != 13 && cur < _gSrcEnd) ++cur;
+ while( *(cur) != 10 && *cur != 13 && cur < _gSrcEnd) ++cur;
}
static inline void skip_eol( char*& cur )
{
- if ( *cur == 13 )
+ if ( *cur == 13 )
- cur += 2;
- else
- cur += 1;
+ cur += 2;
+ else
+ cur += 1;
- ++_gLineNo;
+ ++_gLineNo;
}
static inline bool skip_to_next_comment_in_the_line( char*& cur )
{
- do
- {
- while( cur < _gSrcEnd &&
- *cur != 10 &&
- *cur != 13 &&
- *cur != '/'
- ) ++cur;
-
- if ( cur == _gSrcEnd ) return FALSE;
-
- if ( *cur == '/' )
- {
- if ( (*(cur+1) == '*') ||
- (*(cur+1) == '/') ) return TRUE;
- else
- {
- ++cur;
- continue;
- }
- }
-
- return FALSE;
-
- } while(1);
+ do
+ {
+ while( cur < _gSrcEnd &&
+ *cur != 10 &&
+ *cur != 13 &&
+ *cur != '/'
+ ) ++cur;
+
+ if ( cur == _gSrcEnd ) return FALSE;
+
+ if ( *cur == '/' )
+ {
+ if ( (*(cur+1) == '*') ||
+ (*(cur+1) == '/') ) return TRUE;
+ else
+ {
+ ++cur;
+ continue;
+ }
+ }
+
+ return FALSE;
+
+ } while(1);
}
inline static void store_line_no( int& toVar )
{
- toVar = _gLineNo;
+ toVar = _gLineNo;
}
inline static void restore_line_no( int storedLineNo )
{
- _gLineNo = storedLineNo;
+ _gLineNo = storedLineNo;
}
inline static int get_line_no()
{
- return _gLineNo;
+ return _gLineNo;
}
static void skip_to_prev_line( char*& cur )
{
- while( cur >= _gSrcStart &&
- *cur != 10 &&
- *cur != 13
- ) --cur;
+ while( cur >= _gSrcStart &&
+ *cur != 10 &&
+ *cur != 13
+ ) --cur;
- // NOTE:: '\n' is 13,10 for DOS
- // '\n' is 10 for UNIX
+ // NOTE:: '\n' is 13,10 for DOS
+ // '\n' is 10 for UNIX
- // NOTE1: '\n' symbol is not used here,
- // to provide possibility of loading
- // file as binary
+ // NOTE1: '\n' symbol is not used here,
+ // to provide possibility of loading
+ // file as binary
- --cur;
- if ( *cur == 10 )
- {
- ++cur;
- return;
- }
+ --cur;
+ if ( *cur == 10 )
+ {
+ ++cur;
+ return;
+ }
- if ( *cur == 13 ) --cur;
+ if ( *cur == 13 ) --cur;
- while( cur >= _gSrcStart &&
- *cur != 10 &&
- *cur != 13
- ) --cur;
+ while( cur >= _gSrcStart &&
+ *cur != 10 &&
+ *cur != 13
+ ) --cur;
- ++cur; // move to the first character in the line
+ ++cur; // move to the first character in the line
}
static inline void skip_comments( char*& cur )
{
- ++cur; // skip '/' token
+ ++cur; // skip '/' token
- if ( *cur != '/' && *cur != '*' ) return;
+ if ( *cur != '/' && *cur != '*' ) return;
- // first, store position of the comment into the queue
- // (which further will be attached to the next context
- // found)
+ // first, store position of the comment into the queue
+ // (which further will be attached to the next context
+ // found)
- if ( cur-1 != _gLastSuppresedComment )
- {
- if ( _gCQSize == MAX_CQ_ENTRIES )
- {
- size_t i = MAX_CQ_ENTRIES-1;
+ if ( cur-1 != _gLastSuppresedComment )
+ {
+ if ( _gCQSize == MAX_CQ_ENTRIES )
+ {
+ size_t i = MAX_CQ_ENTRIES-1;
- while( i != 0 )
- {
- _gCommentsQueue[i-1] = _gCommentsQueue[i];
- --i;
- }
+ while( i != 0 )
+ {
+ _gCommentsQueue[i-1] = _gCommentsQueue[i];
+ --i;
+ }
- --_gCQSize ;
- }
+ --_gCQSize ;
+ }
- _gCommentsQueue[_gCQSize++] = cur-1;
- }
+ _gCommentsQueue[_gCQSize++] = cur-1;
+ }
- // if signle-line comment, skip it now
- if ( *cur == '/' )
- {
- skip_to_eol( cur );
- skip_eol( cur );
- return;
- }
+ // if signle-line comment, skip it now
+ if ( *cur == '/' )
+ {
+ skip_to_eol( cur );
+ skip_eol( cur );
+ return;
+ }
- size_t level = 1;
+ size_t level = 1;
- // check for multiline comment (handle nested multiline comments!)
+ // check for multiline comment (handle nested multiline comments!)
- int line_len = 0;
+ int line_len = 0;
- ++cur;
- ++cur;
- do
- {
- // TBD:: check eof cond.
+ ++cur;
+ ++cur;
+ do
+ {
+ // TBD:: check eof cond.
- // detect and remove vertical columns of '*''s
+ // detect and remove vertical columns of '*''s
- while ( *cur != '/' && cur < _gSrcEnd )
- {
- switch (*cur)
- {
- case '*' :
- {
- if ( *(cur+1) != '/' )
- {
- if ( line_len == 1 )
+ while ( *cur != '/' && cur < _gSrcEnd )
+ {
+ switch (*cur)
+ {
+ case '*' :
+ {
+ if ( *(cur+1) != '/' )
+ {
+ if ( line_len == 1 )
- *cur = ' ';
- }
+ *cur = ' ';
+ }
- break;
- }
+ break;
+ }
- case 13 : line_len = 0; break;
- case 10 : { line_len = 0; ++_gLineNo; } break;
+ case 13 : line_len = 0; break;
+ case 10 : { line_len = 0; ++_gLineNo; } break;
- default : ++line_len;
- }
+ default : ++line_len;
+ }
- ++cur;
- }
+ ++cur;
+ }
- if ( cur >= _gSrcEnd ) return;
+ if ( cur >= _gSrcEnd ) return;
- ++cur;
+ ++cur;
- if ( *(cur-2) == '*' )
- {
- --level;
- if ( level == 0 )
- break;
- }
- else
- if ( *cur == '*' )
- {
- ++cur;
- ++cur;
+ if ( *(cur-2) == '*' )
+ {
+ --level;
+ if ( level == 0 )
+ break;
+ }
+ else
+ if ( *cur == '*' )
+ {
+ ++cur;
+ ++cur;
- ++level;
- }
+ ++level;
+ }
- } while(1);
+ } while(1);
}
static inline void clear_commets_queue()
{
- _gCQSize = 0;
+ _gCQSize = 0;
}
static inline void skip_quoted_string( char*& cur )
{
- ++cur; // skip first quote '"'
+ ++cur; // skip first quote '"'
- // check if quote wasn't prefixed
- if ( *(cur-2) == '\\' )
- return;
+ // check if quote wasn't prefixed
+ if ( *(cur-2) == '\\' )
+ return;
- do
- {
- while ( *cur != '"' && cur < _gSrcEnd )
- {
- if ( *cur == 10 ) ++_gLineNo;
- ++cur;
- }
+ do
+ {
+ while ( *cur != '"' && cur < _gSrcEnd )
+ {
+ if ( *cur == 10 ) ++_gLineNo;
+ ++cur;
+ }
- if ( cur >= _gSrcEnd ) return;
+ if ( cur >= _gSrcEnd ) return;
- ++cur; // skip the last quote
+ ++cur; // skip the last quote
- // check if it wasn't prefixed
+ // check if it wasn't prefixed
- if ( *(cur-2) != '\\' )
- break;
+ if ( *(cur-2) != '\\' )
+ break;
- } while (1);
+ } while (1);
}
// skips subsequent white space and comments
static inline bool get_next_token( char*& cur )
{
- for( ; cur < _gSrcEnd; ++cur )
- {
- switch( *(cur) )
- {
- case ' ' : continue;
- case '\t': continue;
- case 13 : continue;
-
- case 10 : { ++_gLineNo;continue; }
-
- case '/' : skip_comments( cur );
- --cur;
- continue;
-
- default : break;
- };
-
- break;
- }
-
- if ( cur >= _gSrcEnd )
-
- return FALSE;
- else
- return TRUE;
+ for( ; cur < _gSrcEnd; ++cur )
+ {
+ switch( *(cur) )
+ {
+ case ' ' : continue;
+ case '\t': continue;
+ case 13 : continue;
+
+ case 10 : { ++_gLineNo;continue; }
+
+ case '/' : skip_comments( cur );
+ --cur;
+ continue;
+
+ default : break;
+ };
+
+ break;
+ }
+
+ if ( cur >= _gSrcEnd )
+
+ return FALSE;
+ else
+ return TRUE;
}
static inline void skip_preprocessor_dir( char*& cur )
{
- do
- {
- skip_to_eol(cur);
+ do
+ {
+ skip_to_eol(cur);
- if ( *(cur-1) != '\\' )
- break;
+ if ( *(cur-1) != '\\' )
+ break;
- if ( cur < _gSrcEnd )
- skip_eol( cur );
- else
- break;
+ if ( cur < _gSrcEnd )
+ skip_eol( cur );
+ else
+ break;
- } while(1);
+ } while(1);
}
static void skip_token( char*& cur )
{
- if ( *cur == '"' )
- {
- skip_quoted_string( cur );
- return;
- }
-
- if ( *cur == ',' ||
- *cur == ';' ||
- *cur == ')' ||
- *cur == '('
- )
- {
- ++cur;
- return;
- }
+ if ( *cur == '"' )
+ {
+ skip_quoted_string( cur );
+ return;
+ }
+
+ if ( *cur == ',' ||
+ *cur == ';' ||
+ *cur == ')' ||
+ *cur == '('
+ )
+ {
+ ++cur;
+ return;
+ }
// special case of "!=", "<=", ... 2 character composite tokens
if ( *cur == '<' ||
- *cur == '>' ||
- *cur == '=' ||
+ *cur == '>' ||
+ *cur == '=' ||
*cur == '!'
)
{
return;
}
- ++cur; // leading character is always skipped
-
- for( ; cur < _gSrcEnd ; ++cur )
- {
- switch ( *cur )
- {
- case ' ' : break;
- case '\t': break;
- case 13 : break;
- case 10 : break;
- case ',' : break;
- case ';' : break;
- case '<' : break;
- case '>' : break;
-
- // FIXME:: QUICK-HACK:: to treat scope resolution
- // tokens are a part of the string - e.g. SomeSpace::SubName would
- // become one token
-
- case ':' : if ( *(cur+1) == ':' )
- {
- ++cur;
- continue;
- }
-
- break;
- case '=' : break;
- case '(' : break;
- case ')' : break;
- case '{' : break;
- case '}' : break;
-
- default : continue;
- };
- break;
- }
+ ++cur; // leading character is always skipped
+
+ for( ; cur < _gSrcEnd ; ++cur )
+ {
+ switch ( *cur )
+ {
+ case ' ' : break;
+ case '\t': break;
+ case 13 : break;
+ case 10 : break;
+ case ',' : break;
+ case ';' : break;
+ case '<' : break;
+ case '>' : break;
+
+ // FIXME:: QUICK-HACK:: to treat scope resolution
+ // tokens are a part of the string - e.g. SomeSpace::SubName would
+ // become one token
+
+ case ':' : if ( *(cur+1) == ':' )
+ {
+ ++cur;
+ continue;
+ }
+
+ break;
+ case '=' : break;
+ case '(' : break;
+ case ')' : break;
+ case '{' : break;
+ case '}' : break;
+
+ default : continue;
+ };
+ break;
+ }
}
static inline size_t get_token_len( char* tok )
{
- char* start = tok;
+ char* start = tok;
- skip_token( tok );
+ skip_token( tok );
- return size_t( tok - start );
+ return size_t( tok - start );
}
// returns true, if given tokens are equel
static inline bool cmp_tokens( char* tok1, char* tok2 )
{
- // NOTE:: the case one token includes
- // other in it's entirely is not handled
+ // NOTE:: the case one token includes
+ // other in it's entirely is not handled
- size_t len = get_token_len( tok1 );
+ size_t len = get_token_len( tok1 );
- // assuming that tokens are non-zero length
+ // assuming that tokens are non-zero length
- do
- {
- if ( *(tok1++) != *(tok2++) )
- return FALSE;
+ do
+ {
+ if ( *(tok1++) != *(tok2++) )
+ return FALSE;
- --len;
+ --len;
- } while ( --len );
+ } while ( --len );
- return TRUE;
+ return TRUE;
}
static inline bool cmp_tokens_fast( char* tok1, char* tok2, size_t len )
{
- do
- {
- if ( *(tok1++) != *(tok2++) )
- return FALSE;
+ do
+ {
+ if ( *(tok1++) != *(tok2++) )
+ return FALSE;
- } while ( --len );
+ } while ( --len );
- return TRUE;
+ return TRUE;
}
static inline void skip_tempalate_statement( char*& cur )
{
- size_t level = 0;
+ size_t level = 0;
- // go one level deeper
- while( *cur != '<' && cur < _gSrcEnd )
- {
- if (*cur == 10 ) ++_gLineNo;
- ++cur;
- }
+ // go one level deeper
+ while( *cur != '<' && cur < _gSrcEnd )
+ {
+ if (*cur == 10 ) ++_gLineNo;
+ ++cur;
+ }
- // FIXME:: template should be checked statement for
- // comments inside of it
+ // FIXME:: template should be checked statement for
+ // comments inside of it
- do
- {
- if ( *cur == '<' )
- ++level;
- else
- --level;
+ do
+ {
+ if ( *cur == '<' )
+ ++level;
+ else
+ --level;
- ++cur; // skip '<' or '>' token
+ ++cur; // skip '<' or '>' token
- if ( level == 0 )
- return;
+ if ( level == 0 )
+ return;
- while( *cur != '<' && *cur != '>' && cur < _gSrcEnd )
- {
- if (*cur == 10 ) ++_gLineNo;
- ++cur;
- }
+ while( *cur != '<' && *cur != '>' && cur < _gSrcEnd )
+ {
+ if (*cur == 10 ) ++_gLineNo;
+ ++cur;
+ }
- } while (1);
+ } while (1);
}
static inline void skip_statement( char*& cur )
{
- for( ; cur < _gSrcEnd; ++cur )
+ for( ; cur < _gSrcEnd; ++cur )
- switch (*cur)
- {
- case ';' : ++cur; // skip statement-terminator token
- return;
+ switch (*cur)
+ {
+ case ';' : ++cur; // skip statement-terminator token
+ return;
- case '"' : skip_quoted_string(cur);
- --cur;
- continue;
+ case '"' : skip_quoted_string(cur);
+ --cur;
+ continue;
- case 10 : ++_gLineNo;
+ case 10 : ++_gLineNo;
- continue;
- case '/' : skip_comments( cur );
- --cur;
- continue;
- default : continue;
- }
+ continue;
+ case '/' : skip_comments( cur );
+ --cur;
+ continue;
+ default : continue;
+ }
}
// "reversed" versions of skip_token() and get_next_token()
static inline void skip_token_back( char*& cur )
{
- // FIXME:: now, when moving backwards, neither strings nor
- // comment blocks are checked
+ // FIXME:: now, when moving backwards, neither strings nor
+ // comment blocks are checked
- --cur; // skip to the trailing character
+ --cur; // skip to the trailing character
- if ( *cur == ',' ||
- *cur == ')' ||
- *cur == '('
- )
- return;
+ if ( *cur == ',' ||
+ *cur == ')' ||
+ *cur == '('
+ )
+ return;
- for( ; cur < _gSrcEnd ; --cur )
- {
- switch ( *cur )
- {
- case ' ' : break;
- case '\t': break;
- case 13 : break;
- case 10 : break;
- case ',' : break;
- case '(' : break;
+ for( ; cur < _gSrcEnd ; --cur )
+ {
+ switch ( *cur )
+ {
+ case ' ' : break;
+ case '\t': break;
+ case 13 : break;
+ case 10 : break;
+ case ',' : break;
+ case '(' : break;
- default : continue;
- };
+ default : continue;
+ };
- break;
- }
+ break;
+ }
- ++cur; // get to the leading character of the token
+ ++cur; // get to the leading character of the token
}
static inline void skip_next_token_back( char*& cur )
{
- --cur; // skip leading character of the current token
-
- if ( *cur == ',' ||
- *cur == ')' ||
- *cur == '('
- )
- {
- ++cur;
- return;
- }
-
- for( ; cur < _gSrcEnd; --cur )
- {
- switch ( *cur )
- {
- case ' ' : continue;
- case '\t': continue;
- case 13 : continue;
- case 10 : continue;
- case ',' : continue;
- case '(' : continue;
-
- default : break;
- };
-
- break;
- }
-
- ++cur; // position after the trailing charcter of the prev token
+ --cur; // skip leading character of the current token
+
+ if ( *cur == ',' ||
+ *cur == ')' ||
+ *cur == '('
+ )
+ {
+ ++cur;
+ return;
+ }
+
+ for( ; cur < _gSrcEnd; --cur )
+ {
+ switch ( *cur )
+ {
+ case ' ' : continue;
+ case '\t': continue;
+ case 13 : continue;
+ case 10 : continue;
+ case ',' : continue;
+ case '(' : continue;
+
+ default : break;
+ };
+
+ break;
+ }
+
+ ++cur; // position after the trailing charcter of the prev token
}
static string get_token_str( char* cur )
{
- return string( cur, get_token_len( cur ) );
+ return string( cur, get_token_len( cur ) );
}
// skips token or whole expression which may have
static size_t skip_block( char*& cur )
{
- size_t level = 0; // nesting level
-
- char* start = cur;
-
- // NOTE:: assumed that block not necessarely starts
- // with bracket rightaway
-
- if ( *cur == '(' )
- {
- ++level;
- }
-
- do
- {
- skip_token( cur );
-
- char* savedPos = cur;
- int tmpLnNo;
- store_line_no( tmpLnNo );
-
- get_next_token( cur );
-
- if ( cur >= _gSrcEnd ) return 0;
-
- if ( *cur == '(' )
- {
- ++level;
- }
- else
- if ( *cur == ')' )
- {
- if ( level == 0 )
- {
- cur = savedPos;
- restore_line_no( tmpLnNo );
-
- return size_t(cur-start);
- }
-
- --level;
-
- if ( level == 0 )
- {
- ++cur;
-
- // QUICK-HACK::to easily handle function prototypes ,
- // it works, besause theoretically there should
- // be no cast-expressions in non-implementation
- // scope (e.g. "time( (long*)(ptr+1) )" should not
- // appear in the declarations, thus it is most likelly
- // for the ")(" fragment to be within a function
- // prototype in the declarations scope
-
- if ( *cur == '(' )
- {
- ++level;
- continue;
- }
-
- else return size_t(cur-start);
- }
- }
- else
- {
- if ( level == 0 )
- {
- cur = savedPos;
- restore_line_no( tmpLnNo );
-
- return size_t(cur-start);
- }
- }
-
- } while(1);
+ size_t level = 0; // nesting level
+
+ char* start = cur;
+
+ // NOTE:: assumed that block not necessarely starts
+ // with bracket rightaway
+
+ if ( *cur == '(' )
+ {
+ ++level;
+ }
+
+ do
+ {
+ skip_token( cur );
+
+ char* savedPos = cur;
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
+
+ get_next_token( cur );
+
+ if ( cur >= _gSrcEnd ) return 0;
+
+ if ( *cur == '(' )
+ {
+ ++level;
+ }
+ else
+ if ( *cur == ')' )
+ {
+ if ( level == 0 )
+ {
+ cur = savedPos;
+ restore_line_no( tmpLnNo );
+
+ return size_t(cur-start);
+ }
+
+ --level;
+
+ if ( level == 0 )
+ {
+ ++cur;
+
+ // QUICK-HACK::to easily handle function prototypes ,
+ // it works, besause theoretically there should
+ // be no cast-expressions in non-implementation
+ // scope (e.g. "time( (long*)(ptr+1) )" should not
+ // appear in the declarations, thus it is most likelly
+ // for the ")(" fragment to be within a function
+ // prototype in the declarations scope
+
+ if ( *cur == '(' )
+ {
+ ++level;
+ continue;
+ }
+
+ else return size_t(cur-start);
+ }
+ }
+ else
+ {
+ if ( level == 0 )
+ {
+ cur = savedPos;
+ restore_line_no( tmpLnNo );
+
+ return size_t(cur-start);
+ }
+ }
+
+ } while(1);
}
// returns 0, if end of source reached
static inline bool skip_imp_block( char*& cur )
{
- while( *cur != '{' && cur < _gSrcEnd )
- {
- skip_token( cur );
- if ( !get_next_token( cur ) ) return FALSE;
- }
+ while( *cur != '{' && cur < _gSrcEnd )
+ {
+ skip_token( cur );
+ if ( !get_next_token( cur ) ) return FALSE;
+ }
- while( *cur != '}' && cur < _gSrcEnd )
- {
- skip_token( cur );
- if ( !get_next_token( cur ) ) return FALSE;
- }
+ while( *cur != '}' && cur < _gSrcEnd )
+ {
+ skip_token( cur );
+ if ( !get_next_token( cur ) ) return FALSE;
+ }
- ++cur;
+ ++cur;
- return TRUE;
+ return TRUE;
}
static bool is_class_token( char*& cur )
{
- // FIXME:: the below mess should be cleaned in it's entirely
+ // FIXME:: the below mess should be cleaned in it's entirely
- if ( *cur == 'i' )
- if ( *(cur+1) == 'n' )
+ if ( *cur == 'i' )
+ if ( *(cur+1) == 'n' )
- return cmp_tokens_fast( cur, "interface", 9 );
+ return cmp_tokens_fast( cur, "interface", 9 );
- if ( *cur == 'c' )
- if ( *(cur+1) == 'l' )
+ if ( *cur == 'c' )
+ if ( *(cur+1) == 'l' )
- return cmp_tokens_fast( cur, "class", 5 );
+ return cmp_tokens_fast( cur, "class", 5 );
- if ( *cur == 's' )
- if ( *(cur+1) == 't' )
+ if ( *cur == 's' )
+ if ( *(cur+1) == 't' )
- return cmp_tokens_fast( cur, "struct", 6 );
+ return cmp_tokens_fast( cur, "struct", 6 );
- if ( *cur == 'u' )
- if ( *(cur+1) == 'n' )
+ if ( *cur == 'u' )
+ if ( *(cur+1) == 'n' )
- return cmp_tokens_fast( cur, "union", 5 );
+ return cmp_tokens_fast( cur, "union", 5 );
- return FALSE;
+ return FALSE;
}
inline static bool is_forward_decl( char* cur )
{
- do
- {
- switch( *cur )
- {
- case ':' : return FALSE;
- case '{' : return FALSE;
- case '(' : return FALSE;
+ do
+ {
+ switch( *cur )
+ {
+ case ':' : return FALSE;
+ case '{' : return FALSE;
+ case '(' : return FALSE;
- case ';' : return TRUE;
+ case ';' : return TRUE;
- default : break;
- };
+ default : break;
+ };
- ++cur;
+ ++cur;
- } while (cur < _gSrcEnd); // prevent running out of bounds
+ } while (cur < _gSrcEnd); // prevent running out of bounds
- return FALSE;
+ return FALSE;
}
inline static bool is_function( char* cur, bool& isAMacro )
{
- isAMacro = FALSE;
+ isAMacro = FALSE;
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- // NOTE:: comments and quoted strings are not checked here
+ // NOTE:: comments and quoted strings are not checked here
- // first,check for "single-line hanginging macros" like:
- // ___UNICODE
- //
+ // first,check for "single-line hanginging macros" like:
+ // ___UNICODE
+ //
- char* eol = cur;
- skip_to_eol( eol );
+ char* eol = cur;
+ skip_to_eol( eol );
- skip_token( cur );
- get_next_token( cur );
+ skip_token( cur );
+ get_next_token( cur );
- if ( cur > eol )
- {
- isAMacro = TRUE;
- restore_line_no( tmpLnNo );
+ if ( cur > eol )
+ {
+ isAMacro = TRUE;
+ restore_line_no( tmpLnNo );
- return TRUE;
- }
+ return TRUE;
+ }
- // it's not a macro, go to the begining of arg. list
-
- do
- {
- // if bracket found, it's a function or a begining
- // of some macro
- if ( *cur == '(' )
- {
- restore_line_no( tmpLnNo );
- return TRUE;
- }
+ // it's not a macro, go to the begining of arg. list
- // end of statement found without any brackets in it
- // - it cannot be a function
+ do
+ {
+ // if bracket found, it's a function or a begining
+ // of some macro
+ if ( *cur == '(' )
+ {
+ restore_line_no( tmpLnNo );
+ return TRUE;
+ }
- if ( *cur == ';' )
- {
- restore_line_no( tmpLnNo );
- return FALSE;
- }
+ // end of statement found without any brackets in it
+ // - it cannot be a function
- ++cur;
+ if ( *cur == ';' )
+ {
+ restore_line_no( tmpLnNo );
+ return FALSE;
+ }
- } while( cur < _gSrcEnd);
+ ++cur;
- isAMacro = 1;
- restore_line_no( tmpLnNo );
+ } while( cur < _gSrcEnd);
- return FALSE;
+ isAMacro = 1;
+ restore_line_no( tmpLnNo );
+
+ return FALSE;
}
// upon return the cursor is positioned after the
-// terminating curly brace
+// terminating curly brace
static inline void skip_scope_block( char*& cur )
{
- size_t level = 0;
-
- for( ; cur < _gSrcEnd ; ++cur )
-
- switch( *cur )
- {
- case '/' : skip_comments( cur );
- --cur;
- continue;
- case '"' : skip_quoted_string( cur );
- --cur;
- continue;
+ size_t level = 0;
- case '{' : ++level;
- continue;
+ for( ; cur < _gSrcEnd ; ++cur )
- case '}' :--level;
- if ( level == 0 )
- {
- ++cur; // skip final closing curly brace
- return;
- }
-
- case 10 : ++_gLineNo; continue;
-
- default : continue;
- };
+ switch( *cur )
+ {
+ case '/' : skip_comments( cur );
+ --cur;
+ continue;
+ case '"' : skip_quoted_string( cur );
+ --cur;
+ continue;
+
+ case '{' : ++level;
+ continue;
+
+ case '}' :--level;
+ if ( level == 0 )
+ {
+ ++cur; // skip final closing curly brace
+ return;
+ }
+
+ case 10 : ++_gLineNo; continue;
+
+ default : continue;
+ };
}
// moves tokens like '*' '**', '***', '&' from the name
// to the type
static void arrange_indirection_tokens_between( string& type,
- string& identifier )
+ string& identifier )
{
- // TBD:: FIXME:: return value of operators !
+ // TBD:: FIXME:: return value of operators !
- while ( identifier[0] == '*' ||
- identifier[0] == '&'
- )
- {
- type += identifier[0];
- identifier.erase(0,1);
+ while ( identifier[0] == '*' ||
+ identifier[0] == '&'
+ )
+ {
+ type += identifier[0];
+ identifier.erase(0,1);
- if ( !identifier.length() ) return;
- }
+ if ( !identifier.length() ) return;
+ }
}
static bool is_keyword( char* cur )
{
- size_t len = get_token_len( cur );
+ size_t len = get_token_len( cur );
+
+ // put a terminating zero after the given token
+ char tmp = *(cur + len);
+ *(cur+len) = '\0';
- // put a terminating zero after the given token
- char tmp = *(cur + len);
- *(cur+len) = '\0';
+ KeywordMapT::iterator i;
- KeywordMapT::iterator i;
+ i = __gMultiLangMap.find( cur );
+
+ // restore original character suppresed by terminating zero
+ *(cur + len) = tmp;
- i = __gMultiLangMap.find( cur );
-
- // restore original character suppresed by terminating zero
- *(cur + len) = tmp;
-
return i == __gMultiLangMap.end() ? false : true;
}
-static inline void get_string_between( char* start, char* end,
- string* pStr )
+static inline void get_string_between( char* start, char* end,
+ string* pStr )
{
- char saved = *end;
+ char saved = *end;
- *end = '\0';
- *pStr = start;
- *end = saved;
+ *end = '\0';
+ *pStr = start;
+ *end = saved;
}
static char* set_comment_text( string& text, char* start )
{
- char* end = start;
+ char* end = start;
- // to avoid poluting the queue with this comment
- _gLastSuppresedComment = start;
+ // to avoid poluting the queue with this comment
+ _gLastSuppresedComment = start;
- skip_comments( end );
+ skip_comments( end );
- if ( *(end-1) == '/' )
- end -= 2;
+ if ( *(end-1) == '/' )
+ end -= 2;
- start += 2;
+ start += 2;
- // skip multiple leading '/''s or '*''s
- while( *start == '/' && start < end ) ++start;
- while( *start == '*' && start < end ) ++start;
+ // skip multiple leading '/''s or '*''s
+ while( *start == '/' && start < end ) ++start;
+ while( *start == '*' && start < end ) ++start;
- get_string_between( start, end, &text );
+ get_string_between( start, end, &text );
- return end;
+ return end;
}
/***** Implementation for class CJSourceParser *****/
CJSourceParser::CJSourceParser( bool collectCommnets, bool collectMacros )
- : mpStart(0),
- mpEnd(0),
- mpCurCtx( 0 ),
- mCommentsOn( collectCommnets ),
- mMacrosOn ( collectMacros )
+ : mpStart(0),
+ mpEnd(0),
+ mpCurCtx( 0 ),
+ mCommentsOn( collectCommnets ),
+ mMacrosOn ( collectMacros )
{
- check_keyword_map();
+ check_keyword_map();
}
spFile* CJSourceParser::Parse( char* start, char* end )
{
- // set up state variables
- mCurVis = SP_VIS_PRIVATE;
-
- spFile* pTopCtx = new spFile();
- mpCurCtx = pTopCtx;
-
- mIsVirtual = 0;
- mIsTemplate = 0;
- mNestingLevel = 0;
-
- cur = start;
-
- mpStart = start;
- mpEnd = end;
-
- _gSrcEnd = mpEnd; // let all the C-functions "smell" the end of file
- _gSrcStart = start;
-
- _gLineNo = 0;
-
- clear_commets_queue();
-
- // main parsing loop
-
- do
- {
- if ( !get_next_token( cur ) )
- // end of source reached
- return pTopCtx;
-
- if ( memcmp( cur, "ScriptSection( const string&",
- strlen( "ScriptSection( const string&" )
- ) == 0
- )
- {
- int o = 0;
- ++o;
- }
-
- switch (*cur)
- {
- case '#' :
- {
- AddMacroNode( cur );
- continue;
- }
-
- case ':' :
- {
- skip_token( cur );
- continue;
- }
-
- case ';' :
- {
- skip_token( cur );
- continue;
- }
-
- case ')' :
- {
- skip_token( cur );
- continue;
- }
-
- case '=' :
- {
- skip_token( cur );
- continue;
- }
-
- default: break;
- }
+ // set up state variables
+ mCurVis = SP_VIS_PRIVATE;
+
+ spFile* pTopCtx = new spFile();
+ mpCurCtx = pTopCtx;
+
+ mIsVirtual = 0;
+ mIsTemplate = 0;
+ mNestingLevel = 0;
+
+ cur = start;
+
+ mpStart = start;
+ mpEnd = end;
+
+ _gSrcEnd = mpEnd; // let all the C-functions "smell" the end of file
+ _gSrcStart = start;
+
+ _gLineNo = 0;
+
+ clear_commets_queue();
+
+ // main parsing loop
+
+ do
+ {
+ if ( !get_next_token( cur ) )
+ // end of source reached
+ return pTopCtx;
+
+ if ( memcmp( cur, "ScriptSection( const string&",
+ strlen( "ScriptSection( const string&" )
+ ) == 0
+ )
+ {
+ int o = 0;
+ ++o;
+ }
+
+ switch (*cur)
+ {
+ case '#' :
+ {
+ AddMacroNode( cur );
+ continue;
+ }
+
+ case ':' :
+ {
+ skip_token( cur );
+ continue;
+ }
+
+ case ';' :
+ {
+ skip_token( cur );
+ continue;
+ }
+
+ case ')' :
+ {
+ skip_token( cur );
+ continue;
+ }
+
+ case '=' :
+ {
+ skip_token( cur );
+ continue;
+ }
+
+ default: break;
+ }
// 'const' is a part of the return type, not a keyword here
- if ( strncmp(cur, "const", 5) != 0 && is_keyword( cur ) )
- {
- // parses, token, if token identifies
- // the container context (e.g. class/namespace)
- // the corresponding context object is created
- // and set as current context
+ if ( strncmp(cur, "const", 5) != 0 && is_keyword( cur ) )
+ {
+ // parses, token, if token identifies
+ // the container context (e.g. class/namespace)
+ // the corresponding context object is created
+ // and set as current context
- ParseKeyword( cur );
- continue;
- }
+ ParseKeyword( cur );
+ continue;
+ }
- if ( *cur >= '0' && *cur <= '9' )
- {
- skip_token( cur );
- continue;
- }
-
- if ( *cur == '}' )
- {
- if ( mCurCtxType != SP_CTX_CLASS )
- {
- // FOR NOW:: disable the below assertion
+ if ( *cur >= '0' && *cur <= '9' )
+ {
+ skip_token( cur );
+ continue;
+ }
- // DBG:: unexpected closing-bracket found
- //ASSERT(0);
+ if ( *cur == '}' )
+ {
+ if ( mCurCtxType != SP_CTX_CLASS )
+ {
+ // FOR NOW:: disable the below assertion
- skip_token( cur ); // just skip it
- continue;
- }
+ // DBG:: unexpected closing-bracket found
+ //ASSERT(0);
- if ( mpCurCtx->GetType() == SP_CTX_CLASS )
- {
- int curOfs = ( (cur+1) - _gSrcStart );
+ skip_token( cur ); // just skip it
+ continue;
+ }
- mpCurCtx->mContextLength = ( curOfs - mpCurCtx->mSrcOffset );
- }
+ if ( mpCurCtx->GetType() == SP_CTX_CLASS )
+ {
+ int curOfs = ( (cur+1) - _gSrcStart );
- --mNestingLevel;
+ mpCurCtx->mContextLength = ( curOfs - mpCurCtx->mSrcOffset );
+ }
+
+ --mNestingLevel;
- // terminate operation/class/namespace context
- // TBD:: check if it's really this type of context
+ // terminate operation/class/namespace context
+ // TBD:: check if it's really this type of context
- wxASSERT( mpCurCtx );
- mpCurCtx = mpCurCtx->GetOutterContext();
- wxASSERT( mpCurCtx );
+ wxASSERT( mpCurCtx );
+ mpCurCtx = mpCurCtx->GetOutterContext();
+ wxASSERT( mpCurCtx );
- if ( mNestingLevel == 0 )
- {
+ if ( mNestingLevel == 0 )
+ {
- mCurCtxType = SP_CTX_FILE;
+ mCurCtxType = SP_CTX_FILE;
- // not-nested class delclaration finished,
- // rest template flag in any case
- mIsTemplate = 0;
- }
+ // not-nested class delclaration finished,
+ // rest template flag in any case
+ mIsTemplate = 0;
+ }
- skip_token( cur );
- continue;
- }
+ skip_token( cur );
+ continue;
+ }
- bool isAMacro = 0;
+ bool isAMacro = 0;
- if ( is_function( cur, isAMacro ) )
- {
- if ( isAMacro )
- {
- skip_token( cur );
- continue;
- }
+ if ( is_function( cur, isAMacro ) )
+ {
+ if ( isAMacro )
+ {
+ skip_token( cur );
+ continue;
+ }
- char* savedPos = cur;
+ char* savedPos = cur;
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- isAMacro = FALSE;
+ isAMacro = FALSE;
- if ( !ParseNameAndRetVal( cur, isAMacro ) )
- {
- if ( !isAMacro )
- {
- cur = savedPos;
- SkipFunction( cur );
- }
- continue;
- }
+ if ( !ParseNameAndRetVal( cur, isAMacro ) )
+ {
+ if ( !isAMacro )
+ {
+ cur = savedPos;
+ SkipFunction( cur );
+ }
+ continue;
+ }
- if ( !ParseArguments( cur ) )
- {
- // failure while parsing arguments,
- // remove enclosing operation context
+ if ( !ParseArguments( cur ) )
+ {
+ // failure while parsing arguments,
+ // remove enclosing operation context
- spContext* pFailed = mpCurCtx;
- mpCurCtx = mpCurCtx->GetOutterContext();
- mpCurCtx->RemoveChild( pFailed );
+ spContext* pFailed = mpCurCtx;
+ mpCurCtx = mpCurCtx->GetOutterContext();
+ mpCurCtx->RemoveChild( pFailed );
- skip_to_eol( cur );
- //cur = savedPos;
- }
- else
- {
- // otherwise, successfully close operation context:
+ skip_to_eol( cur );
+ //cur = savedPos;
+ }
+ else
+ {
+ // otherwise, successfully close operation context:
- clear_commets_queue();
+ clear_commets_queue();
- SkipFunctionBody( cur );
+ SkipFunctionBody( cur );
- mpCurCtx = mpCurCtx->GetOutterContext();
+ mpCurCtx = mpCurCtx->GetOutterContext();
- // DBG::
- wxASSERT( mpCurCtx );
+ // DBG::
+ wxASSERT( mpCurCtx );
- }
- }
- else // otherwise it's declaration of a variable;
- {
- // now, the cursor point to the end of statement (';' token)
+ }
+ }
+ else // otherwise it's declaration of a variable;
+ {
+ // now, the cursor point to the end of statement (';' token)
- if ( mCurCtxType != SP_CTX_CLASS )
- {
- // non-class members are ignored
+ if ( mCurCtxType != SP_CTX_CLASS )
+ {
+ // non-class members are ignored
- skip_token( cur ); // skip the end of statement
- continue;
- }
+ skip_token( cur ); // skip the end of statement
+ continue;
+ }
- ParseMemberVar( cur );
- }
+ ParseMemberVar( cur );
+ }
- } while( 1 );
+ } while( 1 );
}
void CJSourceParser::AttachComments( spContext& ctx, char* cur )
{
- if ( !mCommentsOn ) return;
+ if ( !mCommentsOn ) return;
- MCommentListT& lst = ctx.GetCommentList();
+ MCommentListT& lst = ctx.GetCommentList();
- char* prevComEnd = 0;
+ char* prevComEnd = 0;
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- // attach comments which were found before the given context
+ // attach comments which were found before the given context
- for( int i = 0; i != _gCQSize; ++i )
- {
- spComment* pComment = new spComment();
- lst.push_back( pComment );
+ for( int i = 0; i != _gCQSize; ++i )
+ {
+ spComment* pComment = new spComment();
+ lst.push_back( pComment );
- // find the end of comment
- char* start = _gCommentsQueue[i];
+ // find the end of comment
+ char* start = _gCommentsQueue[i];
- pComment->mIsMultiline = ( *(start+1) == '*' );
+ pComment->mIsMultiline = ( *(start+1) == '*' );
- // first comment in the queue and multiline
- // comments are always treated as a begining
- // of the new paragraph in the comment text
+ // first comment in the queue and multiline
+ // comments are always treated as a begining
+ // of the new paragraph in the comment text
- if ( i == 0 )
+ if ( i == 0 )
- pComment->mStartsPar = TRUE;
- else
- if ( pComment->mIsMultiline )
+ pComment->mStartsPar = TRUE;
+ else
+ if ( pComment->mIsMultiline )
- pComment->mStartsPar = TRUE;
- else
- {
- // find out wheather there is a new-line
- // between to adjecent comments
+ pComment->mStartsPar = TRUE;
+ else
+ {
+ // find out wheather there is a new-line
+ // between to adjecent comments
- char* prevLine = start;
- skip_to_prev_line(prevLine);
+ char* prevLine = start;
+ skip_to_prev_line(prevLine);
- if ( prevLine >= prevComEnd )
-
- pComment->mStartsPar = TRUE;
- else
- pComment->mStartsPar = FALSE;
- }
+ if ( prevLine >= prevComEnd )
- prevComEnd = set_comment_text( pComment->mText, start );
- }
+ pComment->mStartsPar = TRUE;
+ else
+ pComment->mStartsPar = FALSE;
+ }
+ prevComEnd = set_comment_text( pComment->mText, start );
+ }
+
+
+ // attach comments which are at the end of the line
+ // of the given context (if any)
- // attach comments which are at the end of the line
- // of the given context (if any)
+ if ( skip_to_next_comment_in_the_line( cur ) )
+ {
+ spComment* pComment = new spComment();
+ lst.push_back( pComment );
- if ( skip_to_next_comment_in_the_line( cur ) )
- {
- spComment* pComment = new spComment();
- lst.push_back( pComment );
-
- set_comment_text( pComment->mText, cur );
+ set_comment_text( pComment->mText, cur );
- pComment->mStartsPar = 1;
- pComment->mIsMultiline = ( *(cur+1) == '*' );
+ pComment->mStartsPar = 1;
+ pComment->mIsMultiline = ( *(cur+1) == '*' );
- // mark this comment, so that it would not
- // get in the comments list of the next context
- _gLastSuppresedComment = cur;
- }
+ // mark this comment, so that it would not
+ // get in the comments list of the next context
+ _gLastSuppresedComment = cur;
+ }
- restore_line_no( tmpLnNo );
+ restore_line_no( tmpLnNo );
- clear_commets_queue();
+ clear_commets_queue();
}
void CJSourceParser::AddMacroNode( char*& cur )
{
- char* start = cur;
+ char* start = cur;
+
+ int lineNo = get_line_no();
- int lineNo = get_line_no();
+ skip_preprocessor_dir( cur );
- skip_preprocessor_dir( cur );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ if ( !mMacrosOn ) return;
- if ( !mMacrosOn ) return;
+ spPreprocessorLine* pPL = new spPreprocessorLine();
+ pPL->mSrcLineNo = lineNo;
- spPreprocessorLine* pPL = new spPreprocessorLine();
- pPL->mSrcLineNo = lineNo;
+ AttachComments( *pPL, cur );
- AttachComments( *pPL, cur );
+ get_string_between( start, cur, &pPL->mLine );
+
+ ++start; // skip '#'
+ get_next_token( start );
+
+ pPL->mDefType = SP_PREP_DEF_OTHER;
+
+ // if we found a definition or redefinition,
+ // determine the type exactly and assign
+ // a name to the context
+
+ if ( *start == 'd' )
+ {
+ if ( cmp_tokens_fast( start, "define", 6 ) )
+ {
+ char* tok = start+6;
- get_string_between( start, cur, &pPL->mLine );
+ get_next_token( tok );
- ++start; // skip '#'
- get_next_token( start );
-
- pPL->mDefType = SP_PREP_DEF_OTHER;
+ pPL->mName = get_token_str( tok );
- // if we found a definition or redefinition,
- // determine the type exactly and assign
- // a name to the context
+ skip_token( tok );
+ get_next_token( tok);
- if ( *start == 'd' )
- {
- if ( cmp_tokens_fast( start, "define", 6 ) )
- {
- char* tok = start+6;
- get_next_token( tok );
+ if ( tok > cur )
+ pPL->mDefType = SP_PREP_DEF_DEFINE_SYMBOL;
+ else
+ pPL->mDefType = SP_PREP_DEF_REDEFINE_SYMBOL;
+ }
+ }
+ else if ( *start == 'i' )
+ {
+ if ( cmp_tokens_fast( start, "include", 7 ) )
+ {
+ pPL->mDefType = SP_PREP_DEF_INCLUDE_FILE;
+ }
+ else if ( *++start == 'f' )
+ {
+ // either "#if" or "#ifdef"
+ cur = start;
+ skip_token( cur );
+ get_next_token( cur );
- pPL->mName = get_token_str( tok );
+ string condition = get_token_str( cur );
- skip_token( tok );
- get_next_token( tok);
+ // currently, everything except '0' is true
+ if ( condition == "0" ) {
+ // skip until the following else or enif
+ while ( cur < _gSrcEnd ) {
+ skip_to_eol( cur );
+ skip_eol( cur );
+ get_next_token( cur );
+ if ( *cur++ == '#' && *cur == 'e' )
+ break;
+ }
+ }
- if ( tok > cur )
- pPL->mDefType = SP_PREP_DEF_DEFINE_SYMBOL;
- else
- pPL->mDefType = SP_PREP_DEF_REDEFINE_SYMBOL;
- }
- }
- else
- if ( *start == 'i' )
+ // TODO parse the condition...
+ }
+ }
+ else if ( cmp_tokens_fast( start, "else", 4 ) )
+ {
+ // skip until "#endif"
+ while ( cur < _gSrcEnd ) {
+ skip_to_eol( cur );
+ skip_eol( cur );
+
+ get_next_token( cur );
+ if ( *cur++ == '#' && cmp_tokens_fast( cur, "endif", 5 ) )
+ break;
+ }
+ }
- if ( cmp_tokens_fast( start, "include", 7 ) )
- {
- pPL->mDefType = SP_PREP_DEF_INCLUDE_FILE;
- }
+ mpCurCtx->AddMember( pPL );
- mpCurCtx->AddMember( pPL );
+ skip_to_eol( cur );
+ skip_eol( cur );
- restore_line_no( tmpLnNo );
+ restore_line_no( tmpLnNo );
- clear_commets_queue();
+ clear_commets_queue();
}
void CJSourceParser::ParseKeyword( char*& cur )
{
- // analyze token, which identifies the begining of a new context
-
- if ( CheckVisibilty( cur ) )
- {
- skip_token( cur );
- return;
- }
-
- if ( is_class_token( cur ) )
- {
- if ( is_forward_decl( cur ) )
- {
- // forward declarations are ignored;
- skip_token( cur );
- return;
- }
-
- if ( mNestingLevel == 0 )
- {
- // change context form global class context
- mCurCtxType = SP_CTX_CLASS;
- }
-
- ++mNestingLevel;
-
- // add information about new class (name, inheritance, etc)
- AddClassNode( cur );
-
- // the default visiblity for class members is 'private'
- mCurVis = SP_VIS_PRIVATE;
-
- return;
- }
-
- size_t len = get_token_len( cur );
-
- if ( cmp_tokens_fast( cur, "typedef", len ) )
- {
- skip_token(cur);
- get_next_token(cur);
-
- if ( cmp_tokens_fast( cur, "struct", len ) ||
- cmp_tokens_fast( cur, "union", len ) ||
- cmp_tokens_fast( cur, "class", len )
- )
- {
- if ( mNestingLevel == 0 )
- {
- // change context form global class context
- mCurCtxType = SP_CTX_CLASS;
- }
-
- ++mNestingLevel;
-
- // add information about new class (name, inheritance, etc)
- AddClassNode( cur );
-
- // the default visiblity for class members is 'private'
- mCurVis = SP_VIS_PRIVATE;
-
- return;
-
- // FOR NOW:: typedef struct, etc are also ignored
- //skip_scope_block( cur );
- }
-
- if ( cmp_tokens_fast( cur, "enum", len ) )
- {
- AddEnumNode( cur );
- return;
- }
-
- AddTypeDefNode( cur );
-
- return;
- }
-
- if ( cmp_tokens_fast( cur, "enum", len ) )
- {
- AddEnumNode( cur );
- return;
- }
-
- if ( cmp_tokens_fast( cur, "extern", len ) )
- {
- // extern's are ignored (both extern "C" and extern vars)
- while ( *cur != '{' &&
- *cur != ';' )
- {
- skip_token( cur );
- get_next_token( cur );
- }
- return;
-
- }
- if ( cmp_tokens_fast( cur, "enum", len ) )
- {
- // enumeration blocks are ignored
-
- skip_scope_block( cur );
-
- get_next_token( cur );
- skip_token( cur ); // skip ';' token;
- return;
- }
-
- if ( cmp_tokens_fast( cur, "package", len ) )
- {
- // packages are ignored
- skip_statement( cur );
- return;
- };
-
- if ( cmp_tokens_fast( cur, "import", len ) )
- {
- // import statements are ignored
- skip_statement( cur );
- return;
- }
-
- if ( cmp_tokens_fast( cur, "virtual", len ) )
- {
- // probably the virtual method is in front of us;
- mIsVirtual = 1;
- skip_token( cur );
- return;
- }
-
- if ( cmp_tokens_fast( cur, "template", len ) )
- {
- mIsTemplate = 1;
- skip_tempalate_statement( cur );
- return;
- }
-
- if ( cmp_tokens_fast( cur, "friend", len ) )
- {
- skip_statement( cur );
- return;
- }
-
- // ingnore "unsigificant" tokens (i.e. which do not
- // affect the current parsing context)
-
- skip_token( cur );
+ // analyze token, which identifies the begining of a new context
+
+ if ( CheckVisibilty( cur ) )
+ {
+ skip_token( cur );
+ return;
+ }
+
+ if ( is_class_token( cur ) )
+ {
+ if ( is_forward_decl( cur ) )
+ {
+ // forward declarations are ignored;
+ skip_token( cur );
+ return;
+ }
+
+ if ( mNestingLevel == 0 )
+ {
+ // change context form global class context
+ mCurCtxType = SP_CTX_CLASS;
+ }
+
+ ++mNestingLevel;
+
+ // add information about new class (name, inheritance, etc)
+ AddClassNode( cur );
+
+ // the default visiblity for class members is 'private'
+ mCurVis = SP_VIS_PRIVATE;
+
+ return;
+ }
+
+ size_t len = get_token_len( cur );
+
+ if ( cmp_tokens_fast( cur, "typedef", len ) )
+ {
+ skip_token(cur);
+ get_next_token(cur);
+
+ if ( cmp_tokens_fast( cur, "struct", len ) ||
+ cmp_tokens_fast( cur, "union", len ) ||
+ cmp_tokens_fast( cur, "class", len )
+ )
+ {
+ if ( mNestingLevel == 0 )
+ {
+ // change context form global class context
+ mCurCtxType = SP_CTX_CLASS;
+ }
+
+ ++mNestingLevel;
+
+ // add information about new class (name, inheritance, etc)
+ AddClassNode( cur );
+
+ // the default visiblity for class members is 'private'
+ mCurVis = SP_VIS_PRIVATE;
+
+ return;
+
+ // FOR NOW:: typedef struct, etc are also ignored
+ //skip_scope_block( cur );
+ }
+
+ if ( cmp_tokens_fast( cur, "enum", len ) )
+ {
+ AddEnumNode( cur );
+ return;
+ }
+
+ AddTypeDefNode( cur );
+
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "enum", len ) )
+ {
+ AddEnumNode( cur );
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "extern", len ) )
+ {
+ // extern's are ignored (both extern "C" and extern vars)
+ while ( *cur != '{' &&
+ *cur != ';' )
+ {
+ skip_token( cur );
+ get_next_token( cur );
+ }
+ return;
+
+ }
+ if ( cmp_tokens_fast( cur, "enum", len ) )
+ {
+ // enumeration blocks are ignored
+
+ skip_scope_block( cur );
+
+ get_next_token( cur );
+ skip_token( cur ); // skip ';' token;
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "package", len ) )
+ {
+ // packages are ignored
+ skip_statement( cur );
+ return;
+ };
+
+ if ( cmp_tokens_fast( cur, "import", len ) )
+ {
+ // import statements are ignored
+ skip_statement( cur );
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "virtual", len ) )
+ {
+ // probably the virtual method is in front of us;
+ mIsVirtual = 1;
+ skip_token( cur );
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "template", len ) )
+ {
+ mIsTemplate = 1;
+ skip_tempalate_statement( cur );
+ return;
+ }
+
+ if ( cmp_tokens_fast( cur, "friend", len ) )
+ {
+ skip_statement( cur );
+ return;
+ }
+
+ // ingnore "unsigificant" tokens (i.e. which do not
+ // affect the current parsing context)
+
+ skip_token( cur );
}
bool CJSourceParser::ParseNameAndRetVal( char*& cur, bool& isAMacro )
{
- isAMacro = FALSE;
+ isAMacro = FALSE;
- // FOR NOW:: all functions in the global
- // scope are ignored
+ // FOR NOW:: all functions in the global
+ // scope are ignored
- int lineNo = get_line_no();
+ int lineNo = get_line_no();
- char* start = cur;
+ char* start = cur;
bool isVirtual = false;
- while( *cur != '(' )
- {
+ while( *cur != '(' )
+ {
if ( get_token_str( cur ) == "virtual" )
isVirtual = true;
- skip_token( cur );
- if ( !get_next_token( cur ) ) return FALSE;
- }
+ skip_token( cur );
+ if ( !get_next_token( cur ) ) return FALSE;
+ }
- char* bracketPos = cur;
- char* savedPos = cur + 1;
+ char* bracketPos = cur;
+ char* savedPos = cur + 1;
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- // skip gap between function name and start of paramters list
- while ( *(cur-1) == ' ' )
- --cur;
+ // skip gap between function name and start of paramters list
+ while ( *(cur-1) == ' ' )
+ --cur;
- // check if it's not a macro, and let plugin handle it, if so
+ // check if it's not a macro, and let plugin handle it, if so
- if ( mpPlugin )
- {
- skip_token_back( cur );
+ if ( mpPlugin )
+ {
+ skip_token_back( cur );
- char* tmp = cur;
+ char* tmp = cur;
- if ( mpPlugin->CanUnderstandContext( tmp, _gSrcEnd, mpCurCtx ) )
- {
- cur = tmp;
+ if ( mpPlugin->CanUnderstandContext( tmp, _gSrcEnd, mpCurCtx ) )
+ {
+ cur = tmp;
- mpPlugin->ParseContext( _gSrcStart, cur, _gSrcEnd, mpCurCtx );
+ mpPlugin->ParseContext( _gSrcStart, cur, _gSrcEnd, mpCurCtx );
- isAMacro = TRUE;
+ isAMacro = TRUE;
- return FALSE;
- }
- }
+ return FALSE;
+ }
+ }
- spOperation* pOp = new spOperation();
+ spOperation* pOp = new spOperation();
- pOp->mSrcLineNo = lineNo;
- pOp->mSrcOffset = int( start - _gSrcStart );
- pOp->mHeaderLength = int( bracketPos - start );
+ pOp->mSrcLineNo = lineNo;
+ pOp->mSrcOffset = int( start - _gSrcStart );
+ pOp->mHeaderLength = int( bracketPos - start );
+ if ( mpCurCtx->GetContextType() == SP_CTX_CLASS )
+ pOp->mScope = mpCurCtx->mName;
- mpCurCtx->AddMember( pOp );
- pOp->mVisibility = mCurVis;
+ mpCurCtx->AddMember( pOp );
+ pOp->mVisibility = mCurVis;
pOp->mIsVirtual = isVirtual;
- // add comments about operation
- AttachComments( *pOp, cur );
+ // add comments about operation
+ AttachComments( *pOp, cur );
- // go backwards to method name
- skip_token_back( cur );
+ // go backwards to method name
+ skip_token_back( cur );
- pOp->mName = get_token_str( cur );
+ pOp->mName = get_token_str( cur );
// checker whether it's not an operator
char chFirst = *pOp->mName.c_str();
- if ( !isalpha(chFirst) && chFirst != '_' && chFirst != '~' )
- {
+ if ( !isalpha(chFirst) && chFirst != '_' && chFirst != '~' ) {
// skip 'operator'
- skip_next_token_back( cur );
+ skip_next_token_back( cur );
skip_token_back( cur );
string lastToken = get_token_str( cur );
- if ( lastToken == "operator" )
- {
+ if ( lastToken == "operator" ) {
lastToken += pOp->mName;
pOp->mName = lastToken;
}
- else
- {
+ else {
// ok, it wasn't an operator after all
skip_token( cur );
}
}
+ else if ( pOp->mName == "operator" ) {
+ skip_token( cur );
+ get_next_token( cur );
+ string oper = get_token_str( cur );
- // go backwards to method return type
- skip_next_token_back( cur );
+ pOp->mName += oper;
+ }
- if ( cur >= start )
+ // go backwards to method return type
+ skip_next_token_back( cur );
- pOp->mRetType = string( start, size_t( cur-start ) );
+ if ( cur >= start )
+ {
+ string rettype = string( start, size_t( cur-start ) );
+ rettype.Replace("WXDLLEXPORT ", ""); // FIXME just for now...
+ pOp->mRetType = rettype;
+ }
- arrange_indirection_tokens_between( pOp->mRetType, pOp->mName );
+ arrange_indirection_tokens_between( pOp->mRetType, pOp->mName );
- cur = savedPos;
- restore_line_no( tmpLnNo );
+ cur = savedPos;
+ restore_line_no( tmpLnNo );
- // now, enter operation context
- mpCurCtx = pOp;
+ // now, enter operation context
+ mpCurCtx = pOp;
- return TRUE;
+ return TRUE;
}
bool CJSourceParser::ParseArguments( char*& cur )
{
- // DANGER-MACROS::
+ // DANGER-MACROS::
- // now cursor position is right after the first opening bracket
- // of the function declaration
+ // now cursor position is right after the first opening bracket
+ // of the function declaration
- char* blocks [16]; // used exclusivelly for iterative "lean out"
- // of macros and misc. not-obviouse grammar
- // (dirty,, but we cannot do it very nice,
- // we're not preprocessor-free C/C++ code)
- int blockSizes[16];
+ char* blocks [16]; // used exclusivelly for iterative "lean out"
+ // of macros and misc. not-obviouse grammar
+ // (dirty,, but we cannot do it very nice,
+ // we're not preprocessor-free C/C++ code)
+ int blockSizes[16];
- do
- {
- size_t blocksSkipped = 0;
+ do
+ {
+ size_t blocksSkipped = 0;
- get_next_token( cur );
+ get_next_token( cur );
- bool first_blk = 1;
+ bool first_blk = 1;
- while( *cur != ')' && *cur != ',' )
- {
- blocks[blocksSkipped] = cur;
+ while( *cur != ')' && *cur != ',' )
+ {
+ blocks[blocksSkipped] = cur;
- if ( first_blk )
- {
- char* prev = cur;
- skip_token( cur );
+ if ( first_blk )
+ {
+ char* prev = cur;
+ skip_token( cur );
- blockSizes[blocksSkipped] = size_t(cur-prev);
+ blockSizes[blocksSkipped] = size_t(cur-prev);
- first_blk = 0;
- }
- else
- blockSizes[blocksSkipped] = skip_block( cur );
+ first_blk = 0;
+ }
+ else
+ blockSizes[blocksSkipped] = skip_block( cur );
- get_next_token( cur );
- ++blocksSkipped;
- }
+ get_next_token( cur );
+ ++blocksSkipped;
+ }
- if ( blocksSkipped == 1 )
- {
- // check if the empty arg. list stressed with "void" inside
+ if ( blocksSkipped == 1 )
+ {
+ // check if the empty arg. list stressed with "void" inside
if ( cmp_tokens_fast( blocks[0] , "void", 4 ) )
{
cur++; // skip ')'
- break;
+ break;
}
- // FIXME:: TBD:: K&R-style function declarations!
+ // FIXME:: TBD:: K&R-style function declarations!
+
+ // if only one block enclosed, than it's probably
+ // some macro, there should be at least two blocks,
+ // one for argument type and another for it's identifier
+ return FALSE;
+ }
- // if only one block enclosed, than it's probably
- // some macro, there should be at least two blocks,
- // one for argument type and another for it's identifier
- return FALSE;
- }
+ if ( blocksSkipped == 0 )
+ {
+ if ( *cur == 10 ) ++_gLineNo;
+ ++cur; // skip ')'
- if ( blocksSkipped == 0 )
- {
- if ( *cur == 10 ) ++_gLineNo;
- ++cur; // skip ')'
+ break; // function without paramters
+ }
- break; // function without paramters
- }
+ // we should be in the operation context now
+ spOperation* pOp = (spOperation*)mpCurCtx;
- // we should be in the operation context now
- spOperation* pOp = (spOperation*)mpCurCtx;
+ spParameter* pPar = new spParameter();
- spParameter* pPar = new spParameter();
+ pOp->AddMember( pPar );
+ // FOR NOW:: line number is not exact if argument list is mutiline
+ pPar->mSrcLineNo = get_line_no();
- pOp->AddMember( pPar );
- // FOR NOW:: line number is not exact if argument list is mutiline
- pPar->mSrcLineNo = get_line_no();
+ size_t nameBlock = blocksSkipped - 1;
+ size_t typeBlock = nameBlock - 1;
- size_t nameBlock = blocksSkipped - 1;
- size_t typeBlock = nameBlock - 1;
+ // check if default values present
+ if ( *blocks[typeBlock] == '=' )
+ {
+ // expressions like "int = 5" are ignored,
+ // since name for paramters is required
+ if ( blocksSkipped == 3 )
+ {
+ if ( *cur == ')' )
+ {
+ ++cur;
+ break;
+ }
+ else
+ continue;
+ }
- // check if default values present
- if ( *blocks[typeBlock] == '=' )
- {
- // expressions like "int = 5" are ignored,
- // since name for paramters is required
- if ( blocksSkipped == 3 )
- {
- if ( *cur == ')' )
- {
- ++cur;
- break;
- }
- else
- continue;
- }
+ pPar->mInitVal = string( blocks[nameBlock], blockSizes[nameBlock] );
- pPar->mInitVal = string( blocks[nameBlock], blockSizes[nameBlock] );
+ nameBlock = nameBlock - 2; // skip '=' token and default value block
+ typeBlock = nameBlock - 1;
+ }
- nameBlock = nameBlock - 2; // skip '=' token and default value block
- typeBlock = nameBlock - 1;
- }
+ // attach comments about the parameter
+ AttachComments( *pPar, blocks[nameBlock] );
- // attach comments about the parameter
- AttachComments( *pPar, blocks[nameBlock] );
+ // retrieve argument name
+ pPar->mName = string( blocks[nameBlock], blockSizes[nameBlock] );
- // retrieve argument name
- pPar->mName = string( blocks[nameBlock], blockSizes[nameBlock] );
+ // retreive argument type
- // retreive argument type
+ size_t len = blockSizes[ typeBlock ];
+ len = size_t ( (blocks[ typeBlock ] + len) - blocks[ 0 ] );
- size_t len = blockSizes[ typeBlock ];
- len = size_t ( (blocks[ typeBlock ] + len) - blocks[ 0 ] );
+ pPar->mType = string( blocks[0], len );
- pPar->mType = string( blocks[0], len );
-
- arrange_indirection_tokens_between( pPar->mType, pOp->mName );
+ arrange_indirection_tokens_between( pPar->mType, pPar->mName );
- if ( *cur == ')' )
- {
- ++cur;
- break;
- }
+ if ( *cur == ')' )
+ {
+ ++cur;
+ break;
+ }
- ++cur; // skip comma
- get_next_token(cur);
+ ++cur; // skip comma
+ get_next_token(cur);
- } while(1);
+ } while(1);
// skip possible whitespace between ')' and following "const"
while ( isspace(*cur) )
cur++;
- // check if it was really a function not a macro,
- // if so, than it should be terminated with semicolon ';'
- // or opening implemenetaton bracket '{'
-
- char* tok = cur;
-
- int tmpLnNo;
- store_line_no( tmpLnNo );
-
- do
- {
- if ( *tok == '{' || *tok == ';' )
- {
- restore_line_no(tmpLnNo);
- return TRUE;
- }
-
- // check for unexpected tokens
- if ( *tok == '=' || *tok == '0' )
- {
- skip_token(tok);
- if ( !get_next_token(tok) ) return FALSE;
- continue;
- }
-
- if ( *tok == '}' ) return FALSE;
-
- // if initialization list found
- if ( *tok == ':' )
- {
- restore_line_no(tmpLnNo);
- return TRUE;
- }
-
- if ( cmp_tokens_fast( tok, "const", 5 ) )
- {
+ // check if it was really a function not a macro,
+ // if so, than it should be terminated with semicolon ';'
+ // or opening implemenetaton bracket '{'
+
+ char* tok = cur;
+
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
+
+ do
+ {
+ if ( *tok == '{' || *tok == ';' )
+ {
+ restore_line_no(tmpLnNo);
+ return TRUE;
+ }
+
+ // check for unexpected tokens
+ if ( *tok == '=' || *tok == '0' )
+ {
+ skip_token(tok);
+ if ( !get_next_token(tok) ) return FALSE;
+ continue;
+ }
+
+ if ( *tok == '}' ) return FALSE;
+
+ // if initialization list found
+ if ( *tok == ':' )
+ {
+ restore_line_no(tmpLnNo);
+ return TRUE;
+ }
+
+ if ( cmp_tokens_fast( tok, "const", 5 ) )
+ {
((spOperation*)mpCurCtx)->mIsConstant = true;
- skip_token(tok);
- if ( !get_next_token(tok) ) return FALSE;
- continue;
- }
+ skip_token(tok);
+ if ( !get_next_token(tok) ) return FALSE;
+ continue;
+ }
+
+ if ( CheckVisibilty( tok ) ) return FALSE;
- if ( CheckVisibilty( tok ) ) return FALSE;
+ // if next context found
+ if ( is_keyword( tok ) ) return FALSE;
- // if next context found
- if ( is_keyword( tok ) ) return FALSE;
+ skip_token(tok);
+ if ( !get_next_token(tok) ) return FALSE;
- skip_token(tok);
- if ( !get_next_token(tok) ) return FALSE;
+ } while(1);
- } while(1);
-
- return TRUE;
+ return TRUE;
}
void CJSourceParser::ParseMemberVar( char*& cur )
{
- MMemberListT& members = mpCurCtx->GetMembers();
+ MMemberListT& members = mpCurCtx->GetMembers();
- bool firstMember = 1;
+ bool firstMember = 1;
- size_t first = 0;
+ size_t first = 0;
- string type;
+ string type;
- // jump to the end of statement
- // and start collecting same-type varibles
- // back-to-front towards the type identifier
+ // jump to the end of statement
+ // and start collecting same-type varibles
+ // back-to-front towards the type identifier
- skip_statement( cur );
- char* savedPos = cur;
+ skip_statement( cur );
+ char* savedPos = cur;
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
--cur; // rewind back to ';'
- do
- {
- spAttribute* pAttr = new spAttribute();
- // FOR NOW:: line not is not exact, if member declaration is multiline
- pAttr->mSrcLineNo = get_line_no();
+ do
+ {
+ spAttribute* pAttr = new spAttribute();
+ // FOR NOW:: line not is not exact, if member declaration is multiline
+ pAttr->mSrcLineNo = get_line_no();
- mpCurCtx->AddMember( pAttr );
- pAttr->mVisibility = mCurVis;
+ mpCurCtx->AddMember( pAttr );
+ pAttr->mVisibility = mCurVis;
- pAttr->mIsConstant = 0;
+ pAttr->mIsConstant = 0;
- if ( firstMember )
- {
- firstMember = 0;
- first = members.size() - 1;;
- }
+ if ( firstMember )
+ {
+ firstMember = 0;
+ first = members.size() - 1;;
+ }
- skip_token_back( cur );
+ skip_token_back( cur );
- // attach comments about the attribute
- AttachComments( *pAttr, cur );
+ // attach comments about the attribute
+ AttachComments( *pAttr, cur );
- pAttr->mName = get_token_str( cur );
+ pAttr->mName = get_token_str( cur );
- // guessing that this going to be variable type
- skip_next_token_back( cur );
- skip_token_back( cur );
+ // guessing that this going to be variable type
+ skip_next_token_back( cur );
+ skip_token_back( cur );
+
+ pAttr->mType = get_token_str( cur );
- pAttr->mType = get_token_str( cur );
+ // if comma, than variable list continues
+ // otherwise the variable type reached - stop
- // if comma, than variable list continues
- // otherwise the variable type reached - stop
+ if ( *cur == '=' )
+ {
+ // yes, we've mistaken, it was not a identifier,
+ // but it's default value
+ pAttr->mInitVal =
+ pAttr->mName;
- if ( *cur == '=' )
- {
- // yes, we've mistaken, it was not a identifier,
- // but it's default value
- pAttr->mInitVal =
- pAttr->mName;
-
- // skip default value and '=' symbol
- skip_next_token_back( cur );
- skip_token_back( cur );
+ // skip default value and '=' symbol
+ skip_next_token_back( cur );
+ skip_token_back( cur );
- pAttr->mName = get_token_str( cur );
+ pAttr->mName = get_token_str( cur );
- skip_next_token_back( cur );
- skip_token_back( cur );
- }
+ skip_next_token_back( cur );
+ skip_token_back( cur );
+ }
- if ( *cur != ',' )
- {
- type = get_token_str( cur );
- break;
- }
+ if ( *cur != ',' )
+ {
+ type = get_token_str( cur );
+ break;
+ }
- } while(1);
+ } while(1);
- // set up types for all collected (same-type) attributes;
- while ( first != members.size() - 1 )
- {
- spAttribute* pAttr = (spAttribute*)members[first];
+ first = 0;
- pAttr->mType = type;
- pAttr->mVisibility = mCurVis;
+ // set up types for all collected (same-type) attributes;
+ while ( first != members.size() - 1 )
+ {
+ spAttribute* pAttr = members[first++]->CastToAttribute();
+ if ( !pAttr )
+ continue;
- arrange_indirection_tokens_between( pAttr->mType, pAttr->mName );
+ if ( !pAttr->mType )
+ pAttr->mType = type;
+ pAttr->mVisibility = mCurVis;
- ++first;
- }
+ if ( !!pAttr->mName )
+ arrange_indirection_tokens_between( pAttr->mType, pAttr->mName );
+ }
- cur = savedPos;
- restore_line_no( tmpLnNo );
+ cur = savedPos;
+ restore_line_no( tmpLnNo );
- clear_commets_queue();
+ clear_commets_queue();
}
void CJSourceParser::SkipFunction( char*& cur )
{
- while ( *cur != '(' && cur < _gSrcEnd )
- {
- if (*cur == 10 ) ++_gLineNo;
- ++cur;
- }
+ while ( *cur != '(' && cur < _gSrcEnd )
+ {
+ if (*cur == 10 ) ++_gLineNo;
+ ++cur;
+ }
- skip_next_token_back( cur ); // go back and skip function identifier
- skip_token_back( cur ); // go back and skip return type
+ skip_next_token_back( cur ); // go back and skip function identifier
+ skip_token_back( cur ); // go back and skip return type
- skip_block( cur ); // now, go ahead and skip whole declaration
+ skip_block( cur ); // now, go ahead and skip whole declaration
- SkipFunctionBody( cur );
+ SkipFunctionBody( cur );
}
void CJSourceParser::SkipFunctionBody( char*& cur )
{
- // FIXME:: check for comments and quoted stirngs here
+ // FIXME:: check for comments and quoted stirngs here
- bool hasDefinition = FALSE;
+ bool hasDefinition = FALSE;
- while( *cur != '{' && *cur != ';' )
- {
- if (*cur == 10 ) ++_gLineNo;
- ++cur;
- }
+ while( *cur != '{' && *cur != ';' )
+ {
+ if (*cur == 10 ) ++_gLineNo;
+ ++cur;
+ }
- if ( *cur == ';' )
- {
- ++cur;
- }
- else
- {
- hasDefinition = TRUE;
+ if ( *cur == ';' )
+ {
+ ++cur;
+ }
+ else
+ {
+ hasDefinition = TRUE;
- skip_scope_block( cur ); // skip the whole imp.
- }
+ skip_scope_block( cur ); // skip the whole imp.
+ }
- if ( mpCurCtx->GetType() == SP_CTX_OPERATION )
- {
- spOperation& op = *((spOperation*)mpCurCtx);
+ if ( mpCurCtx->GetType() == SP_CTX_OPERATION )
+ {
+ spOperation& op = *((spOperation*)mpCurCtx);
- int curOfs = int ( cur - _gSrcStart );
+ int curOfs = int ( cur - _gSrcStart );
- op.mContextLength = curOfs - mpCurCtx->mSrcOffset;
+ op.mContextLength = curOfs - mpCurCtx->mSrcOffset;
- op.mHasDefinition = hasDefinition;
+ op.mHasDefinition = hasDefinition;
- // separate scope resolution token from the name of operation
+ // separate scope resolution token from the name of operation
- for( size_t i = 0; i != op.mName.length(); ++i )
- {
- if ( op.mName[i] == ':' && op.mName[i+1] == ':' )
- {
- string unscoped( op.mName, i+2, op.mName.length() - ( i + 2 ) );
+ for( size_t i = 0; i != op.mName.length(); ++i )
+ {
+ if ( op.mName[i] == ':' && op.mName[i+1] == ':' )
+ {
+ string unscoped( op.mName, i+2, op.mName.length() - ( i + 2 ) );
- op.mScope = string( op.mName, 0, i );
+ op.mScope = string( op.mName, 0, i );
- op.mName = unscoped;
+ op.mName = unscoped;
- break;
- }
- }
- }
+ break;
+ }
+ }
+ }
}
bool CJSourceParser::CheckVisibilty( char*& cur )
{
- size_t len = get_token_len( cur );
-
- if ( cmp_tokens_fast( cur, "public:", len ) )
- {
- mCurVis = SP_VIS_PUBLIC;
- return TRUE;
- }
-
- if ( cmp_tokens_fast( cur, "protected:", len ) )
- {
- mCurVis = SP_VIS_PROTECTED;
- return TRUE;
- }
-
- if ( cmp_tokens_fast( cur, "private:", len ) )
- {
- mCurVis = SP_VIS_PRIVATE;
- return TRUE;
- }
-
- return FALSE;
+ size_t len = get_token_len( cur );
+
+ if ( cmp_tokens_fast( cur, "public:", len ) )
+ {
+ mCurVis = SP_VIS_PUBLIC;
+ return TRUE;
+ }
+
+ if ( cmp_tokens_fast( cur, "protected:", len ) )
+ {
+ mCurVis = SP_VIS_PROTECTED;
+ return TRUE;
+ }
+
+ if ( cmp_tokens_fast( cur, "private:", len ) )
+ {
+ mCurVis = SP_VIS_PRIVATE;
+ return TRUE;
+ }
+
+ return FALSE;
}
void CJSourceParser::AddClassNode( char*& cur )
{
- char* ctxStart = cur;
+ char* ctxStart = cur;
+
+ string classkeyword = get_token_str( cur );
+
+ skip_token( cur ); // skip 'class' keyword
+ if ( !get_next_token( cur ) ) return;
+
+ // in C++
+ if ( *cur == ':' )
+ {
+ skip_token( cur );
+ get_next_token( cur );
+ }
- skip_token( cur ); // skip 'class' keyword
- if ( !get_next_token( cur ) ) return;
+ // by default all class members are private
+ mCurVis = SP_VIS_PRIVATE;
- // in C++
- if ( *cur == ':' )
- {
- skip_token( cur );
- get_next_token( cur );
- }
+ spClass* pClass = new spClass();
+ if ( classkeyword == "class" )
+ pClass->mClassSubType = SP_CLTYPE_CLASS;
+ else if ( classkeyword == "struct" ) {
+ pClass->mClassSubType = SP_CLTYPE_STRUCTURE;
- spClass* pClass = new spClass();
+ mCurVis = SP_VIS_PUBLIC;
+ }
+ else if ( classkeyword == "union" ) {
+ pClass->mClassSubType = SP_CLTYPE_UNION;
+ mCurVis = SP_VIS_PUBLIC;
+ }
+ else if ( classkeyword == "interface" )
+ pClass->mClassSubType = SP_CLTYPE_INTERFACE;
+ else {
+ pClass->mClassSubType = SP_CLTYPE_INVALID;
- mpCurCtx->AddMember( pClass );
+ wxFAIL_MSG("unknown class keyword");
+ }
- // by default all class members are private
- mCurVis = SP_VIS_PRIVATE;
+ mpCurCtx->AddMember( pClass );
- // attach comments about the class
- AttachComments( *pClass, cur );
+ // attach comments about the class
+ AttachComments( *pClass, cur );
- pClass->mSrcLineNo = get_line_no();
+ pClass->mSrcLineNo = get_line_no();
- pClass->mSrcOffset = int( ctxStart - _gSrcStart );
+ pClass->mSrcOffset = int( ctxStart - _gSrcStart );
- char* nameTok = cur;
- pClass->mName = get_token_str( cur );
+ char* nameTok = cur;
+ pClass->mName = get_token_str( cur );
- bool isDerived = 0;
+ bool isDerived = 0;
- // DANGER-MACROS::
+ // DANGER-MACROS::
- do
- {
- skip_token( cur );
- if ( !get_next_token( cur ) ) return;
+ do
+ {
+ skip_token( cur );
+ if ( !get_next_token( cur ) ) return;
- if ( *cur == ':' )
- {
- isDerived = 1;
+ if ( *cur == ':' )
+ {
+ isDerived = 1;
- char* tok = cur;
+ char* tok = cur;
- int tmpLn;
- store_line_no( tmpLn );
+ int tmpLn;
+ store_line_no( tmpLn );
- skip_next_token_back( tok );
- skip_token_back( tok );
+ skip_next_token_back( tok );
+ skip_token_back( tok );
- restore_line_no( tmpLn );
+ restore_line_no( tmpLn );
- // class name should precend ':' colon, thus
- // the one which was captured before was
- // proablty something else (like __dllexport MyClass : ... )
+ // class name should precend ':' colon, thus
+ // the one which was captured before was
+ // proablty something else (like __dllexport MyClass : ... )
- if ( nameTok != tok )
- {
- pClass->mName = get_token_str( tok );
- }
+ if ( nameTok != tok )
+ {
+ pClass->mName = get_token_str( tok );
+ }
- }
+ }
- if ( *cur == '{' )
- break;
+ if ( *cur == '{' )
+ break;
- if ( *cur == ',' )
- continue;
+ if ( *cur == ',' )
+ continue;
- size_t len = get_token_len( cur );
+ size_t len = get_token_len( cur );
- // skip neglectable C++ modifieres
- if ( cmp_tokens_fast( cur, "public", len ) )
- continue;
+ // skip neglectable C++ modifieres
+ if ( cmp_tokens_fast( cur, "public", len ) )
+ continue;
- if ( cmp_tokens_fast( cur, "protected", len ) )
- continue;
+ if ( cmp_tokens_fast( cur, "protected", len ) )
+ continue;
- if ( cmp_tokens_fast( cur, "private", len ) )
- continue;
+ if ( cmp_tokens_fast( cur, "private", len ) )
+ continue;
- if ( cmp_tokens_fast( cur, "virtual", len ) )
- continue;
+ if ( cmp_tokens_fast( cur, "virtual", len ) )
+ continue;
- // skip neglectable JAVA modifieres
+ // skip neglectable JAVA modifieres
- if ( cmp_tokens_fast( cur, "extends", len ) )
- {
- isDerived = 1;
- continue;
- }
+ if ( cmp_tokens_fast( cur, "extends", len ) )
+ {
+ isDerived = 1;
+ continue;
+ }
- if ( cmp_tokens_fast( cur, "implements", len ) )
- {
- isDerived = 1;
- continue;
- }
+ if ( cmp_tokens_fast( cur, "implements", len ) )
+ {
+ isDerived = 1;
+ continue;
+ }
- // all we need to know is superclass or interface
+ // all we need to know is superclass or interface
- char* tok = cur;
- int tmpLn;
- store_line_no( tmpLn );
+ char* tok = cur;
+ int tmpLn;
+ store_line_no( tmpLn );
- skip_token(tok);
- get_next_token(tok);
+ skip_token(tok);
+ get_next_token(tok);
- restore_line_no( tmpLn );
-
- if ( *tok != ':' && *cur != ':' )
-
- pClass->mSuperClassNames.push_back( string( cur, len ) );
+ restore_line_no( tmpLn );
- } while(1);
+ if ( *tok != ':' && *cur != ':' )
- if ( !isDerived )
- {
- int tmpLn;
- store_line_no( tmpLn );
+ pClass->mSuperClassNames.push_back( string( cur, len ) );
- while ( pClass->mSuperClassNames.size() )
+ } while(1);
- pClass->mSuperClassNames.erase( &pClass->mSuperClassNames[0] );
+ if ( !isDerived )
+ {
+ int tmpLn;
+ store_line_no( tmpLn );
+
+ while ( pClass->mSuperClassNames.size() )
+
+ pClass->mSuperClassNames.erase( &pClass->mSuperClassNames[0] );
- char* tok = cur;
+ char* tok = cur;
- // some non-obviouse token was following "class" keyword -
- // we've confused it with class name - thus now we're reverting this mistake
+ // some non-obviouse token was following "class" keyword -
+ // we've confused it with class name - thus now we're reverting this mistake
- skip_next_token_back( tok );
- skip_token_back( tok );
+ skip_next_token_back( tok );
+ skip_token_back( tok );
- pClass->mName = get_token_str( tok );
+ pClass->mName = get_token_str( tok );
- restore_line_no( tmpLn );
- }
+ restore_line_no( tmpLn );
+ }
- ++cur; // skip opening curly brace
+ ++cur; // skip opening curly brace
- pClass->mHeaderLength = ( cur - ctxStart );
+ pClass->mHeaderLength = ( cur - ctxStart );
- // now, enter the class context
- mpCurCtx = pClass;
+ // now, enter the class context
+ mpCurCtx = pClass;
- clear_commets_queue();
+ clear_commets_queue();
}
void CJSourceParser::AddEnumNode( char*& cur )
{
- // now the cursor is at "enum" keyword
- char* start = cur;
+ // now the cursor is at "enum" keyword
+ char* start = cur;
+
+ spEnumeration* pEnum = new spEnumeration();
+ mpCurCtx->AddMember( pEnum );
- spEnumeration* pEnum = new spEnumeration();
- mpCurCtx->AddMember( pEnum );
+ pEnum->mSrcLineNo = get_line_no();
- pEnum->mSrcLineNo = get_line_no();
+ AttachComments( *pEnum, cur );
- AttachComments( *pEnum, cur );
+ skip_token( cur );
+ if ( !get_next_token( cur ) ) return;
- skip_token( cur );
- if ( !get_next_token( cur ) ) return;
+ // check if enumeration has got it's identifier
+ if ( *cur != '{' )
+ {
+ pEnum->mName = get_token_str( cur );
+ }
- // check if enumeration has got it's identifier
- if ( *cur != '{' )
- {
- pEnum->mName = get_token_str( cur );
- }
+ if ( !skip_imp_block( cur ) ) return;
- if ( !skip_imp_block( cur ) ) return;
+ get_string_between( start, cur, &pEnum->mEnumContent );
- get_string_between( start, cur, &pEnum->mEnumContent );
+ if ( get_next_token(cur) )
+ {
+ // check if the identifier if after the {...} block
+ if ( *cur != ';' )
- if ( get_next_token(cur) )
- {
- // check if the identifier if after the {...} block
- if ( *cur != ';' )
-
- pEnum->mName = get_token_str( cur );
- }
+ pEnum->mName = get_token_str( cur );
+ }
- clear_commets_queue();
+ clear_commets_queue();
}
void CJSourceParser::AddTypeDefNode( char*& cur )
{
- // now the cursor at the token next to "typedef" keyword
+ // now the cursor at the token next to "typedef" keyword
- if ( !get_next_token(cur) ) return;
+ if ( !get_next_token(cur) ) return;
- char* start = cur;
+ char* start = cur;
- spTypeDef* pTDef = new spTypeDef();
- mpCurCtx->AddMember( pTDef );
+ spTypeDef* pTDef = new spTypeDef();
+ mpCurCtx->AddMember( pTDef );
- pTDef->mSrcLineNo = get_line_no();
+ pTDef->mSrcLineNo = get_line_no();
- AttachComments( *pTDef, cur );
+ AttachComments( *pTDef, cur );
- skip_statement( cur );
+ skip_statement( cur );
- int tmpLnNo;
- store_line_no( tmpLnNo );
+ int tmpLnNo;
+ store_line_no( tmpLnNo );
- char* tok = cur-1;
- skip_next_token_back( tok );
+ char* tok = cur-1;
+ skip_next_token_back( tok );
- char* nameEnd = tok;
+ char* nameEnd = tok;
- skip_token_back( tok );
+ skip_token_back( tok );
- char* nameStart = tok;
+ char* nameStart = tok;
- skip_next_token_back( tok );
+ skip_next_token_back( tok );
- char* typeEnd = tok;
+ char* typeEnd = tok;
- // check if it's function prototype
- if ( *nameStart == ')' )
- {
- typeEnd = nameStart+1;
+ // check if it's function prototype
+ if ( *nameStart == ')' )
+ {
+ typeEnd = nameStart+1;
+
+ // skip argument list
+ while ( *nameStart != '(' ) --nameStart;
- // skip argument list
- while ( *nameStart != '(' ) --nameStart;
+ // skip to function type definition
+ while ( *nameStart != ')' ) --nameStart;
- // skip to function type definition
- while ( *nameStart != ')' ) --nameStart;
-
- skip_next_token_back( nameStart );
+ skip_next_token_back( nameStart );
- nameEnd = nameStart;
+ nameEnd = nameStart;
- skip_token_back( nameStart );
+ skip_token_back( nameStart );
- if ( *nameStart == '*' ) ++nameStart;
- }
+ if ( *nameStart == '*' ) ++nameStart;
+ }
- get_string_between( start, typeEnd, &pTDef->mOriginalType );
+ get_string_between( start, typeEnd, &pTDef->mOriginalType );
- get_string_between( nameStart, nameEnd, &pTDef->mName );
+ get_string_between( nameStart, nameEnd, &pTDef->mName );
- clear_commets_queue();
+ clear_commets_queue();
- restore_line_no( tmpLnNo );
+ restore_line_no( tmpLnNo );
}
if ( !sz )
{
// DBG::
- int u;
+ int u = 0;
++u;
break;
}
// Created: 22/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleskandars Gluchovas
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
/***** Implementation for class spVisitor *****/
void spVisitor::VisitAll( spContext& atContext,
- bool sortContent
- )
+ bool sortContent
+ )
{
- mSiblingSkipped = FALSE;
- mChildSkipped = FALSE;
- mContextMask = SP_CTX_ANY; // FIXME:: should be an arg.
+ mSiblingSkipped = FALSE;
+ mChildSkipped = FALSE;
+ 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 )
- {
- if ( mSiblingSkipped )
-
- return;
+ for( size_t i = 0; i != members.size(); ++i )
+ {
+ if ( mSiblingSkipped )
+
+ return;
- if ( !mChildSkipped )
- {
- size_t prevSz = members.size();
+ if ( !mChildSkipped )
+ {
+ size_t prevSz = members.size();
- // visit members of the context recursivelly
- VisitAll( *members[i], sortContent );
+ // visit members of the context recursivelly
+ 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()
{
- if ( mpCurCxt->GetParent() )
+ if ( mpCurCxt->GetParent() )
- mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
+ mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
}
void spVisitor::SkipSiblings()
{
- mSiblingSkipped = TRUE;
+ mSiblingSkipped = TRUE;
}
void spVisitor::SkipChildren()
{
- mChildSkipped = TRUE;
+ mChildSkipped = TRUE;
}
void spVisitor::SetFilter( int contextMask )
{
- mContextMask = contextMask;
+ mContextMask = contextMask;
}
/***** Implementation for class spComment *****/
bool spComment::IsMultiline() const
{
- return mIsMultiline;
+ return mIsMultiline;
}
bool spComment::StartsParagraph() const
{
- return mStartsPar;
+ return mStartsPar;
}
string& spComment::GetText()
{
- return mText;
+ return mText;
}
string spComment::GetText() const
{
- return mText;
+ return mText;
}
/***** Implementation for class spContext *****/
spContext::spContext()
- : mpParent ( NULL ),
- mpFirstOccurence( NULL ),
- mAlreadySorted ( FALSE ),
+ : mpParent ( NULL ),
+ mpFirstOccurence( NULL ),
+ mAlreadySorted ( FALSE ),
- mSrcLineNo (-1),
- mSrcOffset (-1),
- mContextLength(-1),
- mLastScrLineNo(-1),
+ mSrcLineNo (-1),
+ mSrcOffset (-1),
+ mContextLength(-1),
+ mLastScrLineNo(-1),
- mHeaderLength (-1),
- mFooterLength (-1),
+ mHeaderLength (-1),
+ mFooterLength (-1),
- mFirstCharPos (-1),
- mLastCharPos (-1),
+ mFirstCharPos (-1),
+ mLastCharPos (-1),
- mVisibility( SP_VIS_PRIVATE ),
+ mVisibility( SP_VIS_PRIVATE ),
- mIsVirtualContext ( FALSE ),
- mVirtualContextHasChildren( FALSE ),
+ mIsVirtualContext ( FALSE ),
+ mVirtualContextHasChildren( FALSE ),
- mpUserData( NULL )
+ mpUserData( NULL )
{}
void spContext::RemoveChildren()
{
- for( size_t i = 0; i != mMembers.size(); ++i )
-
- delete mMembers[i];
+ for( size_t i = 0; i != mMembers.size(); ++i )
+
+ delete mMembers[i];
- mMembers.erase( mMembers.begin(), mMembers.end() );
+ mMembers.erase( mMembers.begin(), mMembers.end() );
}
spContext::~spContext()
{
- RemoveChildren();
+ RemoveChildren();
- for( size_t i = 0; i != mComments.size(); ++i )
-
- delete mComments[i];
+ for( size_t i = 0; i != mComments.size(); ++i )
+
+ delete mComments[i];
}
bool spContext::IsSorted()
{
- return mAlreadySorted;
+ return mAlreadySorted;
}
void spContext::GetContextList( MMemberListT& lst, int contextMask )
{
- for( size_t i = 0; i != mMembers.size(); ++i )
- {
- spContext& member = *mMembers[i];
+ for( size_t i = 0; i != mMembers.size(); ++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
- member.GetContextList( lst, contextMask );
- }
+ // collect required contexts recursively
+ member.GetContextList( lst, contextMask );
+ }
}
bool spContext::HasComments()
{
- return ( mComments.size() != 0 );
+ return ( mComments.size() != 0 );
}
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 )
- {
- mMembers.erase( &mMembers[i] );
+ if ( mMembers[i] == pChild )
+ {
+ mMembers.erase( &mMembers[i] );
- delete pChild;
- return;
- }
+ delete pChild;
+ return;
+ }
- // the given child should exist on the parent's list
- wxASSERT( 0 );
+ // the given child should exist on the parent's list
+ wxASSERT( 0 );
}
spContext* spContext::GetEnclosingContext( int mask )
{
- spContext* cur = this->GetParent();
+ spContext* cur = this->GetParent();
- while ( cur && !(cur->GetContextType() & mask) )
-
- cur = cur->GetParent();
+ while ( cur && !(cur->GetContextType() & mask) )
+
+ cur = cur->GetParent();
- return cur;
+ return cur;
}
bool spContext::PositionIsKnown()
{
- return ( mSrcOffset != (-1) && mContextLength != (-1) );
+ return ( mSrcOffset != (-1) && mContextLength != (-1) );
}
bool spContext::IsVirtualContext()
{
- return mIsVirtualContext;
+ return mIsVirtualContext;
}
bool spContext::VitualContextHasChildren()
{
- return mVirtualContextHasChildren;
+ return mVirtualContextHasChildren;
}
string spContext::GetVirtualContextBody()
{
- wxASSERT( mIsVirtualContext );
+ wxASSERT( mIsVirtualContext );
- return mVirtualContextBody;
+ return mVirtualContextBody;
}
string spContext::GetFooterOfVirtualContextBody()
{
- wxASSERT( mIsVirtualContext );
+ wxASSERT( mIsVirtualContext );
- return mVittualContextFooter;
+ return mVittualContextFooter;
}
void spContext::SetVirtualContextBody( const string& body,
- bool hasChildren,
- const string& footer )
+ bool hasChildren,
+ const string& footer )
{
- mVirtualContextHasChildren = hasChildren;
+ mVirtualContextHasChildren = hasChildren;
- mVirtualContextBody = body;
- mVittualContextFooter = footer;
+ mVirtualContextBody = body;
+ mVittualContextFooter = footer;
- // atuomaticllay becomes virtual context
+ // atuomaticllay becomes virtual context
- mIsVirtualContext = TRUE;
+ mIsVirtualContext = TRUE;
}
string spContext::GetBody( spContext* pCtx )
{
- if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
-
- return mVirtualContextBody;
+ if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
+
+ return mVirtualContextBody;
- if ( GetParent() )
+ if ( GetParent() )
- return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
- else
- return ""; // source-fragment cannot be found
+ return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
+ else
+ return ""; // source-fragment cannot be found
}
string spContext::GetHeader( spContext* pCtx )
{
- if ( GetParent() )
+ if ( GetParent() )
- return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
- else
- return ""; // source-fragment cannot be found
+ return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
+ else
+ return ""; // source-fragment cannot be found
}
bool spContext::IsFirstOccurence()
{
- return ( mpFirstOccurence != 0 );
+ return ( mpFirstOccurence != 0 );
}
spContext* spContext::GetFirstOccurence()
{
- // this object should not itself be
- // the first occurence of the context
- wxASSERT( mpFirstOccurence != 0 );
+ // this object should not itself be
+ // the first occurence of the context
+ wxASSERT( mpFirstOccurence != 0 );
- return mpFirstOccurence;
+ return mpFirstOccurence;
}
void spContext::AddMember( spContext* pMember )
{
- mMembers.push_back( pMember );
+ mMembers.push_back( pMember );
- pMember->mpParent = this;
+ pMember->mpParent = this;
}
void spContext::AddComment( spComment* pComment )
{
- mComments.push_back( pComment );
+ mComments.push_back( pComment );
}
MMemberListT& spContext::GetMembers()
{
- return mMembers;
+ return mMembers;
}
spContext* spContext::FindContext( const string& identifier,
- int contextType,
- bool searchSubMembers
- )
+ int contextType,
+ bool searchSubMembers
+ )
{
- for( size_t i = 0; i != mMembers.size(); ++i )
- {
- spContext& member = *mMembers[i];
+ for( size_t i = 0; i != mMembers.size(); ++i )
+ {
+ spContext& member = *mMembers[i];
- if ( member.GetName() == identifier &&
- ( contextType & member.GetContextType() )
- )
+ if ( member.GetName() == identifier &&
+ ( contextType & member.GetContextType() )
+ )
- return &member;
+ return &member;
- if ( searchSubMembers )
- {
- spContext* result =
- member.FindContext( identifier, contextType, 1 );
+ if ( searchSubMembers )
+ {
+ spContext* result =
+ member.FindContext( identifier, contextType, 1 );
- if ( result ) return result;
- }
- }
+ if ( result ) return result;
+ }
+ }
- return 0;
+ return 0;
}
void spContext::RemoveThisContext()
{
- if ( mpParent )
- mpParent->RemoveChild( this );
- else
- // context should have a parent
- wxASSERT(0);
+ if ( mpParent )
+ mpParent->RemoveChild( this );
+ else
+ // context should have a parent
+ wxASSERT(0);
}
spContext* spContext::GetOutterContext()
{
- return mpParent;
+ return mpParent;
}
bool spContext::HasOutterContext()
{
- return ( mpParent != 0 );
+ return ( mpParent != 0 );
}
bool spContext::IsInFile()
{
- return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
+ return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
}
bool spContext::IsInNameSpace()
{
- return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
+ return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
}
bool spContext::IsInClass()
{
- return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
+ return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
}
bool spContext::IsInOperation()
{
- return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
+ return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
}
spClass& spContext::GetClass()
{
- wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
- return *((spClass*)mpParent );
+ wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
+ return *((spClass*)mpParent );
}
spFile& spContext::GetFile()
{
- wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
- return *((spFile*)mpParent );
+ wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
+ return *((spFile*)mpParent );
}
spNameSpace& spContext::GetNameSpace()
{
- wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
- return *((spNameSpace*)mpParent );
+ wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
+ return *((spNameSpace*)mpParent );
}
spOperation& spContext::GetOperation()
{
- wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
- return *((spOperation*)mpParent );
+ wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
+ return *((spOperation*)mpParent );
}
/***** Implementation for class spClass *****/
void spClass::SortMembers()
{
- // TBD::
+ // TBD::
}
/***** Implementation for class spOperation *****/
spOperation::spOperation()
- : mHasDefinition( FALSE )
+ : mHasDefinition( FALSE )
{
mIsConstant =
mIsVirtual =
string spOperation::GetFullName(MarkupTagsT tags)
{
- string txt = tags[TAG_BOLD].start + mRetType;
- txt += " ";
- txt += mName;
- txt += "( ";
- txt += tags[TAG_BOLD].end;
-
- for( size_t i = 0; i != mMembers.size(); ++i )
- {
- // DBG::
- wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER );
+ string txt = tags[TAG_BOLD].start + mRetType;
+ txt += " ";
+ txt += mName;
+ txt += "( ";
+ txt += tags[TAG_BOLD].end;
+
+ for( size_t i = 0; i != mMembers.size(); ++i )
+ {
+ // DBG::
+ wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER );
- spParameter& param = *((spParameter*)mMembers[i]);
+ spParameter& param = *((spParameter*)mMembers[i]);
- if ( i != 0 )
- txt += ", ";
-
- txt += tags[TAG_BOLD].start;
-
- txt += param.mType;
+ if ( i != 0 )
+ txt += ", ";
+
+ txt += tags[TAG_BOLD].start;
+
+ txt += param.mType;
- txt += tags[TAG_BOLD].end;
- txt += tags[TAG_ITALIC].start;
+ txt += tags[TAG_BOLD].end;
+ txt += tags[TAG_ITALIC].start;
- txt += " ";
- txt += param.mName;
+ txt += " ";
+ txt += param.mName;
- if ( param.mInitVal != "" )
- {
- txt += " = ";
- txt += tags[TAG_BOLD].start;
+ if ( param.mInitVal != "" )
+ {
+ txt += " = ";
+ 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 += " )";
- txt += tags[TAG_BOLD].end;
+ txt += tags[TAG_BOLD].start;
+ txt += " )";
+ txt += tags[TAG_BOLD].end;
- // TBD:: constantness of method
+ // TBD:: constantness of method
- return txt;
+ return txt;
}
/***** 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] != '<' )
-
- ++i;
+ while( i < mLine.length() && mLine[i] != '"' && mLine[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() )
- {
- string fname;
- fname.append( mLine, start, ( i - start ) );
+ if ( start < mLine.length() )
+ {
+ string fname;
+ fname.append( mLine, start, ( i - start ) );
- return fname;
- }
- else
- return ""; // syntax error probably
+ return fname;
+ }
+ else
+ return ""; // syntax error probably
}
SourceParserBase::SourceParserBase()
- : mpFileBuf( NULL ),
- mFileBufSz( 0 ),
+ : mpFileBuf( NULL ),
+ mFileBufSz( 0 ),
- mpPlugin( NULL )
+ mpPlugin( NULL )
{}
SourceParserBase::~SourceParserBase()
{
- if ( mpFileBuf ) free( mpFileBuf );
+ if ( mpFileBuf ) free( mpFileBuf );
- if ( mpPlugin ) delete mpPlugin;
+ if ( mpPlugin ) delete mpPlugin;
}
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 )
{
- 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__