]> git.saurik.com Git - wxWidgets.git/blame - utils/HelpGen/src/srcparser.cpp
fixed array tests compilation and a bug in obj array test
[wxWidgets.git] / utils / HelpGen / src / srcparser.cpp
CommitLineData
cecfc5e7
VZ
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
d12e3536 9// Licence: wxWindows licence
cecfc5e7
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
ad053960 13# pragma implementation "srcparser.h"
cecfc5e7
VZ
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
d5939a20 27#ifndef __DARWIN__
ad053960
GD
28# include <malloc.h>
29#endif
cecfc5e7
VZ
30#include <stdio.h>
31
32#include "srcparser.h"
33
34/***** Implementation for class spVisitor *****/
35
36void spVisitor::VisitAll( spContext& atContext,
d12e3536
VZ
37 bool sortContent
38 )
cecfc5e7 39{
d12e3536
VZ
40 mSiblingSkipped = FALSE;
41 mChildSkipped = FALSE;
42 mContextMask = SP_CTX_ANY; // FIXME:: should be an arg.
cecfc5e7 43
d12e3536 44 if ( sortContent && !atContext.IsSorted() )
cecfc5e7 45
d12e3536 46 atContext.SortMembers();
cecfc5e7 47
d12e3536 48 mpCurCxt = &atContext; // FIXME:: this is dirty, restoring it each time
cecfc5e7 49
d12e3536 50 if ( atContext.GetContextType() & mContextMask )
cecfc5e7 51
d12e3536 52 atContext.AcceptVisitor( *this );
cecfc5e7 53
d12e3536 54 MMemberListT& members = atContext.GetMembers();
cecfc5e7 55
d12e3536
VZ
56 for( size_t i = 0; i != members.size(); ++i )
57 {
58 if ( mSiblingSkipped )
59
60 return;
cecfc5e7 61
d12e3536
VZ
62 if ( !mChildSkipped )
63 {
64 size_t prevSz = members.size();
cecfc5e7 65
d12e3536
VZ
66 // visit members of the context recursivelly
67 VisitAll( *members[i], sortContent );
cecfc5e7 68
d12e3536 69 if ( members.size() != prevSz )
cecfc5e7 70
d12e3536 71 --i; // current member was removed!
cecfc5e7 72
d12e3536
VZ
73 mChildSkipped = 0;
74 }
75 }
cecfc5e7
VZ
76}
77
78void spVisitor::RemoveCurrentContext()
79{
d12e3536 80 if ( mpCurCxt->GetParent() )
cecfc5e7 81
d12e3536 82 mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
cecfc5e7
VZ
83}
84
85void spVisitor::SkipSiblings()
86{
d12e3536 87 mSiblingSkipped = TRUE;
cecfc5e7
VZ
88}
89
90void spVisitor::SkipChildren()
91{
d12e3536 92 mChildSkipped = TRUE;
cecfc5e7
VZ
93}
94
95void spVisitor::SetFilter( int contextMask )
96{
d12e3536 97 mContextMask = contextMask;
cecfc5e7
VZ
98}
99
100/***** Implementation for class spComment *****/
101
102bool spComment::IsMultiline() const
103{
d12e3536 104 return mIsMultiline;
cecfc5e7
VZ
105}
106
107bool spComment::StartsParagraph() const
108{
d12e3536 109 return mStartsPar;
cecfc5e7
VZ
110}
111
112string& spComment::GetText()
113{
d12e3536 114 return mText;
cecfc5e7
VZ
115}
116
117string spComment::GetText() const
118{
d12e3536 119 return mText;
cecfc5e7
VZ
120}
121
122/***** Implementation for class spContext *****/
123
124spContext::spContext()
125
d12e3536
VZ
126 : mpParent ( NULL ),
127 mpFirstOccurence( NULL ),
128 mAlreadySorted ( FALSE ),
cecfc5e7 129
d12e3536
VZ
130 mSrcLineNo (-1),
131 mSrcOffset (-1),
132 mContextLength(-1),
133 mLastScrLineNo(-1),
cecfc5e7 134
d12e3536
VZ
135 mHeaderLength (-1),
136 mFooterLength (-1),
cecfc5e7 137
d12e3536
VZ
138 mFirstCharPos (-1),
139 mLastCharPos (-1),
cecfc5e7 140
d12e3536 141 mVisibility( SP_VIS_PRIVATE ),
cecfc5e7 142
d12e3536
VZ
143 mIsVirtualContext ( FALSE ),
144 mVirtualContextHasChildren( FALSE ),
cecfc5e7 145
d12e3536 146 mpUserData( NULL )
cecfc5e7
VZ
147{}
148
149void spContext::RemoveChildren()
150{
d12e3536
VZ
151 for( size_t i = 0; i != mMembers.size(); ++i )
152
153 delete mMembers[i];
cecfc5e7 154
d12e3536 155 mMembers.erase( mMembers.begin(), mMembers.end() );
cecfc5e7
VZ
156}
157
158spContext::~spContext()
159{
d12e3536 160 RemoveChildren();
cecfc5e7 161
d12e3536
VZ
162 for( size_t i = 0; i != mComments.size(); ++i )
163
164 delete mComments[i];
cecfc5e7
VZ
165}
166
167bool spContext::IsSorted()
168{
d12e3536 169 return mAlreadySorted;
cecfc5e7
VZ
170}
171
172void spContext::GetContextList( MMemberListT& lst, int contextMask )
173{
d12e3536
VZ
174 for( size_t i = 0; i != mMembers.size(); ++i )
175 {
176 spContext& member = *mMembers[i];
cecfc5e7 177
d12e3536 178 if ( member.GetContextType() & contextMask )
cecfc5e7 179
d12e3536 180 lst.push_back( &member );
cecfc5e7 181
d12e3536
VZ
182 // collect required contexts recursively
183 member.GetContextList( lst, contextMask );
184 }
cecfc5e7
VZ
185}
186
187bool spContext::HasComments()
188{
d12e3536 189 return ( mComments.size() != 0 );
cecfc5e7
VZ
190}
191
192void spContext::RemoveChild( spContext* pChild )
193{
d12e3536 194 for( size_t i = 0; i != mMembers.size(); ++i )
cecfc5e7 195
d12e3536
VZ
196 if ( mMembers[i] == pChild )
197 {
198 mMembers.erase( &mMembers[i] );
cecfc5e7 199
d12e3536
VZ
200 delete pChild;
201 return;
202 }
cecfc5e7 203
d12e3536
VZ
204 // the given child should exist on the parent's list
205 wxASSERT( 0 );
cecfc5e7
VZ
206}
207
208spContext* spContext::GetEnclosingContext( int mask )
209{
d12e3536 210 spContext* cur = this->GetParent();
cecfc5e7 211
d12e3536
VZ
212 while ( cur && !(cur->GetContextType() & mask) )
213
214 cur = cur->GetParent();
cecfc5e7 215
d12e3536 216 return cur;
cecfc5e7
VZ
217}
218
219bool spContext::PositionIsKnown()
220{
d12e3536 221 return ( mSrcOffset != (-1) && mContextLength != (-1) );
cecfc5e7
VZ
222}
223
224bool spContext::IsVirtualContext()
225{
d12e3536 226 return mIsVirtualContext;
cecfc5e7
VZ
227}
228
229bool spContext::VitualContextHasChildren()
230{
d12e3536 231 return mVirtualContextHasChildren;
cecfc5e7
VZ
232}
233
234string spContext::GetVirtualContextBody()
235{
d12e3536 236 wxASSERT( mIsVirtualContext );
cecfc5e7 237
d12e3536 238 return mVirtualContextBody;
cecfc5e7
VZ
239}
240
241string spContext::GetFooterOfVirtualContextBody()
242{
d12e3536 243 wxASSERT( mIsVirtualContext );
cecfc5e7 244
d12e3536 245 return mVittualContextFooter;
cecfc5e7
VZ
246}
247
248
249void spContext::SetVirtualContextBody( const string& body,
d12e3536
VZ
250 bool hasChildren,
251 const string& footer )
cecfc5e7 252{
d12e3536 253 mVirtualContextHasChildren = hasChildren;
cecfc5e7 254
d12e3536
VZ
255 mVirtualContextBody = body;
256 mVittualContextFooter = footer;
cecfc5e7 257
d12e3536 258 // atuomaticllay becomes virtual context
cecfc5e7 259
d12e3536 260 mIsVirtualContext = TRUE;
cecfc5e7
VZ
261}
262
263string spContext::GetBody( spContext* pCtx )
264{
d12e3536
VZ
265 if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
266
267 return mVirtualContextBody;
cecfc5e7 268
d12e3536 269 if ( GetParent() )
cecfc5e7 270
d12e3536
VZ
271 return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
272 else
273 return ""; // source-fragment cannot be found
cecfc5e7
VZ
274}
275
276string spContext::GetHeader( spContext* pCtx )
277{
d12e3536 278 if ( GetParent() )
cecfc5e7 279
d12e3536
VZ
280 return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
281 else
282 return ""; // source-fragment cannot be found
cecfc5e7
VZ
283}
284
285bool spContext::IsFirstOccurence()
286{
d12e3536 287 return ( mpFirstOccurence != 0 );
cecfc5e7
VZ
288}
289
290spContext* spContext::GetFirstOccurence()
291{
d12e3536
VZ
292 // this object should not itself be
293 // the first occurence of the context
294 wxASSERT( mpFirstOccurence != 0 );
cecfc5e7 295
d12e3536 296 return mpFirstOccurence;
cecfc5e7
VZ
297}
298
299void spContext::AddMember( spContext* pMember )
300{
d12e3536 301 mMembers.push_back( pMember );
cecfc5e7 302
d12e3536 303 pMember->mpParent = this;
cecfc5e7
VZ
304}
305
306void spContext::AddComment( spComment* pComment )
307{
d12e3536 308 mComments.push_back( pComment );
cecfc5e7
VZ
309}
310
311MMemberListT& spContext::GetMembers()
312{
d12e3536 313 return mMembers;
cecfc5e7
VZ
314}
315
316spContext* spContext::FindContext( const string& identifier,
d12e3536
VZ
317 int contextType,
318 bool searchSubMembers
319 )
cecfc5e7 320{
d12e3536
VZ
321 for( size_t i = 0; i != mMembers.size(); ++i )
322 {
323 spContext& member = *mMembers[i];
cecfc5e7 324
d12e3536
VZ
325 if ( member.GetName() == identifier &&
326 ( contextType & member.GetContextType() )
327 )
cecfc5e7 328
d12e3536 329 return &member;
cecfc5e7 330
d12e3536
VZ
331 if ( searchSubMembers )
332 {
333 spContext* result =
334 member.FindContext( identifier, contextType, 1 );
cecfc5e7 335
d12e3536
VZ
336 if ( result ) return result;
337 }
338 }
cecfc5e7 339
d12e3536 340 return 0;
cecfc5e7
VZ
341}
342
343void spContext::RemoveThisContext()
344{
d12e3536
VZ
345 if ( mpParent )
346 mpParent->RemoveChild( this );
347 else
348 // context should have a parent
3a87625f 349 wxFAIL_MSG("Context should have a parent");
cecfc5e7
VZ
350}
351
352spContext* spContext::GetOutterContext()
353{
d12e3536 354 return mpParent;
cecfc5e7
VZ
355}
356
357bool spContext::HasOutterContext()
358{
d12e3536 359 return ( mpParent != 0 );
cecfc5e7
VZ
360}
361
362bool spContext::IsInFile()
363{
d12e3536 364 return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
cecfc5e7
VZ
365}
366
367bool spContext::IsInNameSpace()
368{
d12e3536 369 return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
cecfc5e7
VZ
370}
371
372bool spContext::IsInClass()
373{
d12e3536 374 return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
cecfc5e7
VZ
375}
376
377bool spContext::IsInOperation()
378{
d12e3536 379 return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
cecfc5e7
VZ
380}
381
382spClass& spContext::GetClass()
383{
d12e3536
VZ
384 wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
385 return *((spClass*)mpParent );
cecfc5e7
VZ
386}
387
388spFile& spContext::GetFile()
389{
d12e3536
VZ
390 wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
391 return *((spFile*)mpParent );
cecfc5e7
VZ
392}
393
394spNameSpace& spContext::GetNameSpace()
395{
d12e3536
VZ
396 wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
397 return *((spNameSpace*)mpParent );
cecfc5e7
VZ
398}
399
400spOperation& spContext::GetOperation()
401{
d12e3536
VZ
402 wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
403 return *((spOperation*)mpParent );
cecfc5e7
VZ
404}
405
406/***** Implementation for class spClass *****/
407
408void spClass::SortMembers()
409{
d12e3536 410 // TBD::
cecfc5e7
VZ
411}
412
413/***** Implementation for class spOperation *****/
414
415spOperation::spOperation()
416
d12e3536 417 : mHasDefinition( FALSE )
59734eb5
VZ
418{
419 mIsConstant =
420 mIsVirtual =
421 mHasDefinition = false;
422}
cecfc5e7
VZ
423
424string spOperation::GetFullName(MarkupTagsT tags)
425{
d12e3536
VZ
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 );
cecfc5e7 436
d12e3536 437 spParameter& param = *((spParameter*)mMembers[i]);
cecfc5e7 438
d12e3536
VZ
439 if ( i != 0 )
440 txt += ", ";
441
442 txt += tags[TAG_BOLD].start;
443
444 txt += param.mType;
cecfc5e7 445
d12e3536
VZ
446 txt += tags[TAG_BOLD].end;
447 txt += tags[TAG_ITALIC].start;
cecfc5e7 448
d12e3536
VZ
449 txt += " ";
450 txt += param.mName;
cecfc5e7 451
d12e3536
VZ
452 if ( param.mInitVal != "" )
453 {
454 txt += " = ";
455 txt += tags[TAG_BOLD].start;
cecfc5e7 456
d12e3536 457 txt += param.mInitVal;
cecfc5e7 458
d12e3536
VZ
459 txt += tags[TAG_BOLD].end;
460 }
cecfc5e7 461
d12e3536
VZ
462 txt += tags[TAG_ITALIC].end;;
463 }
cecfc5e7 464
d12e3536
VZ
465 txt += tags[TAG_BOLD].start;
466 txt += " )";
467 txt += tags[TAG_BOLD].end;
cecfc5e7 468
d12e3536 469 // TBD:: constantness of method
cecfc5e7 470
d12e3536 471 return txt;
cecfc5e7
VZ
472}
473
474/***** Implemenentation for class spPreprocessorLine *****/
475
d12e3536 476string spPreprocessorLine::CPP_GetIncludedFileNeme() const
cecfc5e7 477{
d12e3536 478 wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE );
cecfc5e7 479
d12e3536 480 size_t i = 0;
cecfc5e7 481
d12e3536
VZ
482 while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '<' )
483
484 ++i;
cecfc5e7 485
d12e3536 486 ++i;
cecfc5e7 487
d12e3536 488 size_t start = i;
cecfc5e7 489
d12e3536 490 while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '>' )
cecfc5e7 491
d12e3536 492 ++i;
cecfc5e7 493
d12e3536
VZ
494 if ( start < mLine.length() )
495 {
496 string fname;
497 fname.append( mLine, start, ( i - start ) );
cecfc5e7 498
d12e3536
VZ
499 return fname;
500 }
501 else
502 return ""; // syntax error probably
cecfc5e7
VZ
503}
504
505
506
507/***** Implemenentation for class SourceParserBase *****/
508
509SourceParserBase::SourceParserBase()
510
d12e3536
VZ
511 : mpFileBuf( NULL ),
512 mFileBufSz( 0 ),
cecfc5e7 513
d12e3536 514 mpPlugin( NULL )
cecfc5e7
VZ
515{}
516
517SourceParserBase::~SourceParserBase()
518{
d12e3536 519 if ( mpFileBuf ) free( mpFileBuf );
cecfc5e7 520
d12e3536 521 if ( mpPlugin ) delete mpPlugin;
cecfc5e7
VZ
522}
523
524spFile* SourceParserBase::ParseFile( const char* fname )
525{
d12e3536 526 // FIXME:: the below should not be fixed!
cecfc5e7 527
d12e3536 528 const size_t MAX_BUF_SIZE = 1024*256;
cecfc5e7 529
d12e3536 530 if ( !mpFileBuf ) mpFileBuf = (char*)malloc( MAX_BUF_SIZE );
cecfc5e7 531
d12e3536 532 mFileBufSz = MAX_BUF_SIZE;
cecfc5e7 533
d12e3536 534 FILE* fp = fopen( fname, "rt" );
cecfc5e7 535
d12e3536 536 if ( (int)fp == -1 || !fp ) return NULL;
cecfc5e7 537
d12e3536 538 int sz = fread( mpFileBuf, 1, mFileBufSz, fp );
cecfc5e7 539
d12e3536 540 return Parse( mpFileBuf, mpFileBuf + sz );
cecfc5e7
VZ
541}
542
543void SourceParserBase::SetPlugin( SourceParserPlugin* pPlugin )
544{
d12e3536 545 if ( mpPlugin ) delete mpPlugin;
cecfc5e7 546
d12e3536 547 mpPlugin = pPlugin;
cecfc5e7 548}
d12e3536
VZ
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__