1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 # pragma implementation "srcparser.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
32 #include "srcparser.h"
34 /***** Implementation for class spVisitor *****/
36 void spVisitor::VisitAll( spContext
& atContext
,
40 mSiblingSkipped
= false;
41 mChildSkipped
= false;
42 mContextMask
= SP_CTX_ANY
; // FIXME:: should be an arg.
44 if ( sortContent
&& !atContext
.IsSorted() )
46 atContext
.SortMembers();
48 mpCurCxt
= &atContext
; // FIXME:: this is dirty, restoring it each time
50 if ( atContext
.GetContextType() & mContextMask
)
52 atContext
.AcceptVisitor( *this );
54 MMemberListT
& members
= atContext
.GetMembers();
56 for( size_t i
= 0; i
!= members
.size(); ++i
)
58 if ( mSiblingSkipped
)
64 size_t prevSz
= members
.size();
66 // visit members of the context recursivelly
67 VisitAll( *members
[i
], sortContent
);
69 if ( members
.size() != prevSz
)
71 --i
; // current member was removed!
78 void spVisitor::RemoveCurrentContext()
80 if ( mpCurCxt
->GetParent() )
82 mpCurCxt
->GetParent()->RemoveChild( mpCurCxt
);
85 void spVisitor::SkipSiblings()
87 mSiblingSkipped
= true;
90 void spVisitor::SkipChildren()
95 void spVisitor::SetFilter( int contextMask
)
97 mContextMask
= contextMask
;
100 /***** Implementation for class spComment *****/
102 bool spComment::IsMultiline() const
107 bool spComment::StartsParagraph() const
112 wxString
& spComment::GetText()
117 wxString
spComment::GetText() const
122 /***** Implementation for class spContext *****/
124 spContext::spContext()
127 mpFirstOccurence( NULL
),
128 mAlreadySorted ( false ),
141 mVisibility( SP_VIS_PRIVATE
),
143 mIsVirtualContext ( false ),
144 mVirtualContextHasChildren( false ),
149 void spContext::RemoveChildren()
151 for( size_t i
= 0; i
!= mMembers
.size(); ++i
)
155 mMembers
.erase( mMembers
.begin(), mMembers
.end() );
158 spContext::~spContext()
162 for( size_t i
= 0; i
!= mComments
.size(); ++i
)
167 bool spContext::IsSorted()
169 return mAlreadySorted
;
172 void spContext::GetContextList( MMemberListT
& lst
, int contextMask
)
174 for( size_t i
= 0; i
!= mMembers
.size(); ++i
)
176 spContext
& member
= *mMembers
[i
];
178 if ( member
.GetContextType() & contextMask
)
180 lst
.push_back( &member
);
182 // collect required contexts recursively
183 member
.GetContextList( lst
, contextMask
);
187 bool spContext::HasComments()
189 return ( mComments
.size() != 0 );
192 void spContext::RemoveChild( spContext
* pChild
)
194 for( size_t i
= 0; i
!= mMembers
.size(); ++i
)
196 if ( mMembers
[i
] == pChild
)
198 mMembers
.erase( &mMembers
[i
] );
204 // the given child should exist on the parent's list
208 spContext
* spContext::GetEnclosingContext( int mask
)
210 spContext
* cur
= this->GetParent();
212 while ( cur
&& !(cur
->GetContextType() & mask
) )
214 cur
= cur
->GetParent();
219 bool spContext::PositionIsKnown()
221 return ( mSrcOffset
!= (-1) && mContextLength
!= (-1) );
224 bool spContext::IsVirtualContext()
226 return mIsVirtualContext
;
229 bool spContext::VitualContextHasChildren()
231 return mVirtualContextHasChildren
;
234 string
spContext::GetVirtualContextBody()
236 wxASSERT( mIsVirtualContext
);
238 return mVirtualContextBody
;
241 string
spContext::GetFooterOfVirtualContextBody()
243 wxASSERT( mIsVirtualContext
);
245 return mVittualContextFooter
;
249 void spContext::SetVirtualContextBody( const string
& body
,
251 const string
& footer
)
253 mVirtualContextHasChildren
= hasChildren
;
255 mVirtualContextBody
= body
;
256 mVittualContextFooter
= footer
;
258 // atuomaticllay becomes virtual context
260 mIsVirtualContext
= true;
263 wxString
spContext::GetBody( spContext
* pCtx
)
265 if ( ( pCtx
== NULL
|| pCtx
== this ) && mIsVirtualContext
)
266 return mVirtualContextBody
;
269 return GetParent()->GetBody( ( pCtx
!= NULL
) ? pCtx
: this );
271 return wxEmptyString
; // source-fragment cannot be found
274 wxString
spContext::GetHeader( spContext
* pCtx
)
277 return GetParent()->GetHeader( ( pCtx
!= NULL
) ? pCtx
: this );
279 return wxEmptyString
; // source-fragment cannot be found
282 bool spContext::IsFirstOccurence()
284 return ( mpFirstOccurence
!= 0 );
287 spContext
* spContext::GetFirstOccurence()
289 // this object should not itself be
290 // the first occurence of the context
291 wxASSERT( mpFirstOccurence
!= 0 );
293 return mpFirstOccurence
;
296 void spContext::AddMember( spContext
* pMember
)
298 mMembers
.push_back( pMember
);
300 pMember
->mpParent
= this;
303 void spContext::AddComment( spComment
* pComment
)
305 mComments
.push_back( pComment
);
308 MMemberListT
& spContext::GetMembers()
313 spContext
* spContext::FindContext( const string
& identifier
,
315 bool searchSubMembers
318 for( size_t i
= 0; i
!= mMembers
.size(); ++i
)
320 spContext
& member
= *mMembers
[i
];
322 if ( member
.GetName() == identifier
&&
323 ( contextType
& member
.GetContextType() )
328 if ( searchSubMembers
)
331 member
.FindContext( identifier
, contextType
, 1 );
333 if ( result
) return result
;
340 void spContext::RemoveThisContext()
343 mpParent
->RemoveChild( this );
345 // context should have a parent
346 wxFAIL_MSG("Context should have a parent");
349 spContext
* spContext::GetOutterContext()
354 bool spContext::HasOutterContext()
356 return ( mpParent
!= 0 );
359 bool spContext::IsInFile()
361 return ( GetOutterContext()->GetContextType() == SP_CTX_FILE
);
364 bool spContext::IsInNameSpace()
366 return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE
);
369 bool spContext::IsInClass()
371 return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS
);
374 bool spContext::IsInOperation()
376 return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION
);
379 spClass
& spContext::GetClass()
381 wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS
);
382 return *((spClass
*)mpParent
);
385 spFile
& spContext::GetFile()
387 wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE
);
388 return *((spFile
*)mpParent
);
391 spNameSpace
& spContext::GetNameSpace()
393 wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE
);
394 return *((spNameSpace
*)mpParent
);
397 spOperation
& spContext::GetOperation()
399 wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION
);
400 return *((spOperation
*)mpParent
);
403 /***** Implementation for class spClass *****/
405 void spClass::SortMembers()
410 /***** Implementation for class spOperation *****/
412 spOperation::spOperation()
414 : mHasDefinition( false )
418 mHasDefinition
= false;
421 wxString
spOperation::GetFullName(MarkupTagsT tags
)
423 wxString txt
= tags
[TAG_BOLD
].start
+ m_RetType
;
427 txt
+= tags
[TAG_BOLD
].end
;
429 for( size_t i
= 0; i
!= mMembers
.size(); ++i
)
432 wxASSERT( mMembers
[i
]->GetContextType() == SP_CTX_PARAMETER
);
434 spParameter
& param
= *((spParameter
*)mMembers
[i
]);
439 txt
+= tags
[TAG_BOLD
].start
;
443 txt
+= tags
[TAG_BOLD
].end
;
444 txt
+= tags
[TAG_ITALIC
].start
;
449 if ( !param
.m_InitVal
.empty() )
452 txt
+= tags
[TAG_BOLD
].start
;
454 txt
+= param
.m_InitVal
;
456 txt
+= tags
[TAG_BOLD
].end
;
459 txt
+= tags
[TAG_ITALIC
].end
;;
462 txt
+= tags
[TAG_BOLD
].start
;
464 txt
+= tags
[TAG_BOLD
].end
;
466 // TBD:: constantness of method
471 /***** Implemenentation for class spPreprocessorLine *****/
473 wxString
spPreprocessorLine::CPP_GetIncludedFileNeme() const
475 wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE
);
479 while( i
< m_Line
.length() && m_Line
[i
] != _T('"') && m_Line
[i
] != _T('<') )
487 while( i
< m_Line
.length() && m_Line
[i
] != _T('"') && m_Line
[i
] != _T('>') )
491 if ( start
< m_Line
.length() )
494 fname
.append( m_Line
, start
, ( i
- start
) );
499 return wxEmptyString
; // syntax error probably
504 /***** Implemenentation for class SourceParserBase *****/
506 SourceParserBase::SourceParserBase()
514 SourceParserBase::~SourceParserBase()
516 if ( mpFileBuf
) free( mpFileBuf
);
518 if ( mpPlugin
) delete mpPlugin
;
521 spFile
* SourceParserBase::ParseFile( const char* fname
)
523 // FIXME:: the below should not be fixed!
525 const size_t MAX_BUF_SIZE
= 1024*256;
527 if ( !mpFileBuf
) mpFileBuf
= (char*)malloc( MAX_BUF_SIZE
);
529 mFileBufSz
= MAX_BUF_SIZE
;
531 FILE* fp
= fopen( fname
, "rt" );
533 if ( !fp
) return NULL
;
535 int sz
= fread( mpFileBuf
, 1, mFileBufSz
, fp
);
537 return Parse( mpFileBuf
, mpFileBuf
+ sz
);
540 void SourceParserBase::SetPlugin( SourceParserPlugin
* pPlugin
)
542 if ( mpPlugin
) delete mpPlugin
;
547 // ===========================================================================
549 // ===========================================================================
553 void spContext::Dump(const wxString
& indent
) const
557 // increase it for the children
558 wxString indentChild
= indent
+ " ";
560 for ( MMemberListT::const_iterator i
= mMembers
.begin();
563 (*i
)->Dump(indentChild
);
567 void spContext::DumpThis(const wxString
& WXUNUSED(indent
)) const
569 wxFAIL_MSG("abstract base class can't be found in parser tree!");
572 void spParameter::DumpThis(const wxString
& indent
) const
574 wxLogDebug("%sparam named '%s' of type '%s'",
575 indent
.c_str(), m_Name
.c_str(), m_Type
.c_str());
578 void spAttribute::DumpThis(const wxString
& indent
) const
580 wxLogDebug("%svariable named '%s' of type '%s'",
581 indent
.c_str(), m_Name
.c_str(), m_Type
.c_str());
584 void spOperation::DumpThis(const wxString
& indent
) const
587 if ( !mScope
.empty() ) {
588 switch ( mVisibility
) {
590 protection
= "public";
593 case SP_VIS_PROTECTED
:
594 protection
= "protected";
598 protection
= "private";
602 wxFAIL_MSG("unknown protection type");
606 protection
= "global";
609 wxLogDebug("%s%s%s%s function named '%s::%s' of type '%s'",
611 mIsConstant
? "const " : "",
612 mIsVirtual
? "virtual " : "",
614 mScope
.c_str(), m_Name
.c_str(), m_RetType
.c_str());
617 void spPreprocessorLine::DumpThis(const wxString
& indent
) const
620 switch ( mDefType
) {
621 case SP_PREP_DEF_DEFINE_SYMBOL
:
625 case SP_PREP_DEF_REDEFINE_SYMBOL
:
629 case SP_PREP_DEF_INCLUDE_FILE
:
630 kind
.Printf("include (%s)", CPP_GetIncludedFileNeme().c_str());
633 case SP_PREP_DEF_OTHER
:
639 wxLogDebug("%spreprocessor statement: %s",
640 indent
.c_str(), kind
.c_str());
643 void spClass::DumpThis(const wxString
& indent
) const
646 for ( StrListT::const_iterator i
= m_SuperClassNames
.begin();
647 i
!= m_SuperClassNames
.end();
658 switch ( mClassSubType
) {
659 case SP_CLTYPE_CLASS
:
663 case SP_CLTYPE_TEMPLATE_CLASS
:
664 kind
= "template class";
667 case SP_CLTYPE_STRUCTURE
:
671 case SP_CLTYPE_UNION
:
675 case SP_CLTYPE_INTERFACE
:
680 wxFAIL_MSG("unknown class subtype");
683 wxLogDebug("%s%s named '%s' (base classes: %s)",
684 indent
.c_str(), kind
.c_str(),
685 m_Name
.c_str(), base
.c_str());
688 void spEnumeration::DumpThis(const wxString
& indent
) const
690 wxLogDebug("%senum named '%s'",
691 indent
.c_str(), m_Name
.c_str());
694 void spTypeDef::DumpThis(const wxString
& indent
) const
696 wxLogDebug("%stypedef %s = %s",
697 indent
.c_str(), m_Name
.c_str(), m_OriginalType
.c_str());
700 void spFile::DumpThis(const wxString
& indent
) const
702 wxLogDebug("%sfile '%s'",
703 indent
.c_str(), mFileName
.c_str());
706 #endif // __WXDEBUG__