]> git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/srcparser.cpp
Moved wxRichTextCtrl to its own library
[wxWidgets.git] / utils / HelpGen / src / srcparser.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: No names yet.
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
5 // Modified by:
6 // Created: 22/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 #ifndef __DARWIN__
24 # include <malloc.h>
25 #endif
26 #include <stdio.h>
27
28 #include "srcparser.h"
29
30 /***** Implementation for class spVisitor *****/
31
32 void spVisitor::VisitAll( spContext& atContext,
33 bool sortContent
34 )
35 {
36 mSiblingSkipped = false;
37 mChildSkipped = false;
38 mContextMask = SP_CTX_ANY; // FIXME:: should be an arg.
39
40 if ( sortContent && !atContext.IsSorted() )
41
42 atContext.SortMembers();
43
44 mpCurCxt = &atContext; // FIXME:: this is dirty, restoring it each time
45
46 if ( atContext.GetContextType() & mContextMask )
47
48 atContext.AcceptVisitor( *this );
49
50 MMemberListT& members = atContext.GetMembers();
51
52 for( size_t i = 0; i != members.size(); ++i )
53 {
54 if ( mSiblingSkipped )
55
56 return;
57
58 if ( !mChildSkipped )
59 {
60 size_t prevSz = members.size();
61
62 // visit members of the context recursivelly
63 VisitAll( *members[i], sortContent );
64
65 if ( members.size() != prevSz )
66
67 --i; // current member was removed!
68
69 mChildSkipped = 0;
70 }
71 }
72 }
73
74 void spVisitor::RemoveCurrentContext()
75 {
76 if ( mpCurCxt->GetParent() )
77
78 mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
79 }
80
81 void spVisitor::SkipSiblings()
82 {
83 mSiblingSkipped = true;
84 }
85
86 void spVisitor::SkipChildren()
87 {
88 mChildSkipped = true;
89 }
90
91 void spVisitor::SetFilter( int contextMask )
92 {
93 mContextMask = contextMask;
94 }
95
96 /***** Implementation for class spComment *****/
97
98 bool spComment::IsMultiline() const
99 {
100 return mIsMultiline;
101 }
102
103 bool spComment::StartsParagraph() const
104 {
105 return mStartsPar;
106 }
107
108 wxString& spComment::GetText()
109 {
110 return m_Text;
111 }
112
113 wxString spComment::GetText() const
114 {
115 return m_Text;
116 }
117
118 /***** Implementation for class spContext *****/
119
120 spContext::spContext()
121
122 : m_pParent ( NULL ),
123 mpFirstOccurence( NULL ),
124 mAlreadySorted ( false ),
125
126 mSrcLineNo (-1),
127 mSrcOffset (-1),
128 mContextLength(-1),
129 mLastScrLineNo(-1),
130
131 mHeaderLength (-1),
132 mFooterLength (-1),
133
134 mFirstCharPos (-1),
135 mLastCharPos (-1),
136
137 mVisibility( SP_VIS_PRIVATE ),
138
139 mIsVirtualContext ( false ),
140 mVirtualContextHasChildren( false ),
141
142 mpUserData( NULL )
143 {}
144
145 void spContext::RemoveChildren()
146 {
147 for( size_t i = 0; i != mMembers.size(); ++i )
148
149 delete mMembers[i];
150
151 mMembers.erase( mMembers.begin(), mMembers.end() );
152 }
153
154 spContext::~spContext()
155 {
156 RemoveChildren();
157
158 for( size_t i = 0; i != mComments.size(); ++i )
159
160 delete mComments[i];
161 }
162
163 bool spContext::IsSorted()
164 {
165 return mAlreadySorted;
166 }
167
168 void spContext::GetContextList( MMemberListT& lst, int contextMask )
169 {
170 for( size_t i = 0; i != mMembers.size(); ++i )
171 {
172 spContext& member = *mMembers[i];
173
174 if ( member.GetContextType() & contextMask )
175
176 lst.push_back( &member );
177
178 // collect required contexts recursively
179 member.GetContextList( lst, contextMask );
180 }
181 }
182
183 bool spContext::HasComments()
184 {
185 return ( mComments.size() != 0 );
186 }
187
188 void spContext::RemoveChild( spContext* pChild )
189 {
190 for( size_t i = 0; i != mMembers.size(); ++i )
191
192 if ( mMembers[i] == pChild )
193 {
194 mMembers.erase( &mMembers[i] );
195
196 delete pChild;
197 return;
198 }
199
200 // the given child should exist on the parent's list
201 wxASSERT( 0 );
202 }
203
204 spContext* spContext::GetEnclosingContext( int mask )
205 {
206 spContext* cur = this->GetParent();
207
208 while ( cur && !(cur->GetContextType() & mask) )
209
210 cur = cur->GetParent();
211
212 return cur;
213 }
214
215 bool spContext::PositionIsKnown()
216 {
217 return ( mSrcOffset != (-1) && mContextLength != (-1) );
218 }
219
220 bool spContext::IsVirtualContext()
221 {
222 return mIsVirtualContext;
223 }
224
225 bool spContext::VitualContextHasChildren()
226 {
227 return mVirtualContextHasChildren;
228 }
229
230 wxString spContext::GetVirtualContextBody()
231 {
232 wxASSERT( mIsVirtualContext );
233
234 return mVirtualContextBody;
235 }
236
237 wxString spContext::GetFooterOfVirtualContextBody()
238 {
239 wxASSERT( mIsVirtualContext );
240
241 return mVittualContextFooter;
242 }
243
244
245 void spContext::SetVirtualContextBody( const wxString& body,
246 bool hasChildren,
247 const wxString& footer )
248 {
249 mVirtualContextHasChildren = hasChildren;
250
251 mVirtualContextBody = body;
252 mVittualContextFooter = footer;
253
254 // atuomaticllay becomes virtual context
255
256 mIsVirtualContext = true;
257 }
258
259 wxString spContext::GetBody( spContext* pCtx )
260 {
261 if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
262 return mVirtualContextBody;
263
264 if ( GetParent() )
265 return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
266 else
267 return wxEmptyString; // source-fragment cannot be found
268 }
269
270 wxString spContext::GetHeader( spContext* pCtx )
271 {
272 if ( GetParent() )
273 return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
274 else
275 return wxEmptyString; // source-fragment cannot be found
276 }
277
278 bool spContext::IsFirstOccurence()
279 {
280 return ( mpFirstOccurence != 0 );
281 }
282
283 spContext* spContext::GetFirstOccurence()
284 {
285 // this object should not itself be
286 // the first occurence of the context
287 wxASSERT( mpFirstOccurence != 0 );
288
289 return mpFirstOccurence;
290 }
291
292 void spContext::AddMember( spContext* pMember )
293 {
294 mMembers.push_back( pMember );
295
296 pMember->m_pParent = this;
297 }
298
299 void spContext::AddComment( spComment* pComment )
300 {
301 mComments.push_back( pComment );
302 }
303
304 MMemberListT& spContext::GetMembers()
305 {
306 return mMembers;
307 }
308
309 spContext* spContext::FindContext( const wxString& identifier,
310 int contextType,
311 bool searchSubMembers
312 )
313 {
314 for( size_t i = 0; i != mMembers.size(); ++i )
315 {
316 spContext& member = *mMembers[i];
317
318 if ( member.GetName() == identifier &&
319 ( contextType & member.GetContextType() )
320 )
321
322 return &member;
323
324 if ( searchSubMembers )
325 {
326 spContext* result =
327 member.FindContext( identifier, contextType, 1 );
328
329 if ( result ) return result;
330 }
331 }
332
333 return 0;
334 }
335
336 void spContext::RemoveThisContext()
337 {
338 if ( m_pParent )
339 m_pParent->RemoveChild( this );
340 else
341 // context should have a parent
342 wxFAIL_MSG("Context should have a parent");
343 }
344
345 spContext* spContext::GetOutterContext()
346 {
347 return m_pParent;
348 }
349
350 bool spContext::HasOutterContext()
351 {
352 return ( m_pParent != 0 );
353 }
354
355 bool spContext::IsInFile()
356 {
357 return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
358 }
359
360 bool spContext::IsInNameSpace()
361 {
362 return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
363 }
364
365 bool spContext::IsInClass()
366 {
367 return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
368 }
369
370 bool spContext::IsInOperation()
371 {
372 return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
373 }
374
375 spClass& spContext::GetClass()
376 {
377 wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
378 return *((spClass*)m_pParent );
379 }
380
381 spFile& spContext::GetFile()
382 {
383 wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
384 return *((spFile*)m_pParent );
385 }
386
387 spNameSpace& spContext::GetNameSpace()
388 {
389 wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
390 return *((spNameSpace*)m_pParent );
391 }
392
393 spOperation& spContext::GetOperation()
394 {
395 wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
396 return *((spOperation*)m_pParent );
397 }
398
399 /***** Implementation for class spClass *****/
400
401 void spClass::SortMembers()
402 {
403 // TBD::
404 }
405
406 /***** Implementation for class spOperation *****/
407
408 spOperation::spOperation()
409
410 : mHasDefinition( false )
411 {
412 mIsConstant =
413 mIsVirtual =
414 mHasDefinition = false;
415 }
416
417 wxString spOperation::GetFullName(MarkupTagsT tags)
418 {
419 wxString txt = tags[TAG_BOLD].start + m_RetType;
420 txt += _T(" ");
421 txt += m_Name;
422 txt += _T("( ");
423 txt += tags[TAG_BOLD].end;
424
425 for( size_t i = 0; i != mMembers.size(); ++i )
426 {
427 // DBG::
428 wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER );
429
430 spParameter& param = *((spParameter*)mMembers[i]);
431
432 if ( i != 0 )
433 txt += _T(", ");
434
435 txt += tags[TAG_BOLD].start;
436
437 txt += param.m_Type;
438
439 txt += tags[TAG_BOLD].end;
440 txt += tags[TAG_ITALIC].start;
441
442 txt += _T(" ");
443 txt += param.m_Name;
444
445 if ( !param.m_InitVal.empty() )
446 {
447 txt += _T(" = ");
448 txt += tags[TAG_BOLD].start;
449
450 txt += param.m_InitVal;
451
452 txt += tags[TAG_BOLD].end;
453 }
454
455 txt += tags[TAG_ITALIC].end;;
456 }
457
458 txt += tags[TAG_BOLD].start;
459 txt += " )";
460 txt += tags[TAG_BOLD].end;
461
462 // TBD:: constantness of method
463
464 return txt;
465 }
466
467 /***** Implemenentation for class spPreprocessorLine *****/
468
469 wxString spPreprocessorLine::CPP_GetIncludedFileNeme() const
470 {
471 wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE );
472
473 size_t i = 0;
474
475 while( i < m_Line.length() && m_Line[i] != _T('"') && m_Line[i] != _T('<') )
476
477 ++i;
478
479 ++i;
480
481 size_t start = i;
482
483 while( i < m_Line.length() && m_Line[i] != _T('"') && m_Line[i] != _T('>') )
484
485 ++i;
486
487 if ( start < m_Line.length() )
488 {
489 wxString fname;
490 fname.append( m_Line, start, ( i - start ) );
491
492 return fname;
493 }
494 else
495 return wxEmptyString; // syntax error probably
496 }
497
498
499
500 /***** Implemenentation for class SourceParserBase *****/
501
502 SourceParserBase::SourceParserBase()
503
504 : mpFileBuf( NULL ),
505 mFileBufSz( 0 ),
506
507 mpPlugin( NULL )
508 {}
509
510 SourceParserBase::~SourceParserBase()
511 {
512 if ( mpFileBuf ) free( mpFileBuf );
513
514 if ( mpPlugin ) delete mpPlugin;
515 }
516
517 spFile* SourceParserBase::ParseFile( const char* fname )
518 {
519 // FIXME:: the below should not be fixed!
520
521 const size_t MAX_BUF_SIZE = 1024*256;
522
523 if ( !mpFileBuf ) mpFileBuf = (char*)malloc( MAX_BUF_SIZE );
524
525 mFileBufSz = MAX_BUF_SIZE;
526
527 FILE* fp = fopen( fname, "rt" );
528
529 if ( !fp ) return NULL;
530
531 int sz = fread( mpFileBuf, 1, mFileBufSz, fp );
532
533 return Parse( mpFileBuf, mpFileBuf + sz );
534 }
535
536 void SourceParserBase::SetPlugin( SourceParserPlugin* pPlugin )
537 {
538 if ( mpPlugin ) delete mpPlugin;
539
540 mpPlugin = pPlugin;
541 }
542
543 // ===========================================================================
544 // debug methods
545 // ===========================================================================
546
547 #ifdef __WXDEBUG__
548
549 void spContext::Dump(const wxString& indent) const
550 {
551 DumpThis(indent);
552
553 // increase it for the children
554 wxString indentChild = indent + " ";
555
556 for ( MMemberListT::const_iterator i = mMembers.begin();
557 i != mMembers.end();
558 i++ ) {
559 (*i)->Dump(indentChild);
560 }
561 }
562
563 void spContext::DumpThis(const wxString& WXUNUSED(indent)) const
564 {
565 wxFAIL_MSG("abstract base class can't be found in parser tree!");
566 }
567
568 void spParameter::DumpThis(const wxString& indent) const
569 {
570 wxLogDebug("%sparam named '%s' of type '%s'",
571 indent.c_str(), m_Name.c_str(), m_Type.c_str());
572 }
573
574 void spAttribute::DumpThis(const wxString& indent) const
575 {
576 wxLogDebug("%svariable named '%s' of type '%s'",
577 indent.c_str(), m_Name.c_str(), m_Type.c_str());
578 }
579
580 void spOperation::DumpThis(const wxString& indent) const
581 {
582 wxString protection;
583 if ( !mScope.empty() ) {
584 switch ( mVisibility ) {
585 case SP_VIS_PUBLIC:
586 protection = "public";
587 break;
588
589 case SP_VIS_PROTECTED:
590 protection = "protected";
591 break;
592
593 case SP_VIS_PRIVATE:
594 protection = "private";
595 break;
596
597 default:
598 wxFAIL_MSG("unknown protection type");
599 }
600 }
601 else {
602 protection = "global";
603 }
604
605 wxString constStr,virtualStr;
606 if(mIsConstant) constStr = _T("const ");
607 if(mIsVirtual) virtualStr = _T("virtual ");
608
609 wxLogDebug("%s%s%s%s function named '%s::%s' of type '%s'",
610 indent.c_str(),
611 constStr.c_str(),
612 virtualStr.c_str(),
613 protection.c_str(),
614 mScope.c_str(), m_Name.c_str(), m_RetType.c_str());
615 }
616
617 void spPreprocessorLine::DumpThis(const wxString& indent) const
618 {
619 wxString kind;
620 switch ( mDefType ) {
621 case SP_PREP_DEF_DEFINE_SYMBOL:
622 kind = "define";
623 break;
624
625 case SP_PREP_DEF_REDEFINE_SYMBOL:
626 kind = "redefine";
627 break;
628
629 case SP_PREP_DEF_INCLUDE_FILE:
630 kind.Printf("include (%s)", CPP_GetIncludedFileNeme().c_str());
631 break;
632
633 case SP_PREP_DEF_OTHER:
634 kind = "other";
635 break;
636
637 }
638
639 wxLogDebug("%spreprocessor statement: %s",
640 indent.c_str(), kind.c_str());
641 }
642
643 void spClass::DumpThis(const wxString& indent) const
644 {
645 wxString base;
646 for ( StrListT::const_iterator i = m_SuperClassNames.begin();
647 i != m_SuperClassNames.end();
648 i++ ) {
649 if ( !base.empty() )
650 base += ", ";
651 base += *i;
652 }
653
654 if ( !base )
655 base = "none";
656
657 wxString kind;
658 switch ( mClassSubType ) {
659 case SP_CLTYPE_CLASS:
660 kind = "class";
661 break;
662
663 case SP_CLTYPE_TEMPLATE_CLASS:
664 kind = "template class";
665 break;
666
667 case SP_CLTYPE_STRUCTURE:
668 kind = "struc";
669 break;
670
671 case SP_CLTYPE_UNION:
672 kind = "union";
673 break;
674
675 case SP_CLTYPE_INTERFACE:
676 kind = "interface";
677 break;
678
679 default:
680 wxFAIL_MSG("unknown class subtype");
681 }
682
683 wxLogDebug("%s%s named '%s' (base classes: %s)",
684 indent.c_str(), kind.c_str(),
685 m_Name.c_str(), base.c_str());
686 }
687
688 void spEnumeration::DumpThis(const wxString& indent) const
689 {
690 wxLogDebug("%senum named '%s'",
691 indent.c_str(), m_Name.c_str());
692 }
693
694 void spTypeDef::DumpThis(const wxString& indent) const
695 {
696 wxLogDebug("%stypedef %s = %s",
697 indent.c_str(), m_Name.c_str(), m_OriginalType.c_str());
698 }
699
700 void spFile::DumpThis(const wxString& indent) const
701 {
702 wxLogDebug("%sfile '%s'",
703 indent.c_str(), m_FileName.c_str());
704 }
705
706 #endif // __WXDEBUG__