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