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