home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / utils / HelpGen / src / srcparser.cpp < prev    next >
C/C++ Source or Header  |  2001-12-04  |  16KB  |  710 lines

  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: srcparser.cpp,v 1.6 2001/12/03 10:54:59 GT Exp $
  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.  
  36. void 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.  
  78. void spVisitor::RemoveCurrentContext()
  79. {
  80.     if ( mpCurCxt->GetParent() )
  81.  
  82.         mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
  83. }
  84.  
  85. void spVisitor::SkipSiblings()
  86. {
  87.     mSiblingSkipped = TRUE;
  88. }
  89.  
  90. void spVisitor::SkipChildren()
  91. {
  92.     mChildSkipped = TRUE;
  93. }
  94.  
  95. void spVisitor::SetFilter( int contextMask )
  96. {
  97.     mContextMask = contextMask;
  98. }
  99.  
  100. /***** Implementation for class spComment *****/
  101.  
  102. bool spComment::IsMultiline()  const
  103. {
  104.     return mIsMultiline;
  105. }
  106.  
  107. bool spComment::StartsParagraph() const
  108. {
  109.     return mStartsPar;
  110. }
  111.  
  112. string& spComment::GetText()
  113. {
  114.     return mText;
  115. }
  116.  
  117. string spComment::GetText() const
  118. {
  119.     return mText;
  120. }
  121.  
  122. /***** Implementation for class spContext *****/
  123.  
  124. spContext::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.  
  149. void 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.  
  158. spContext::~spContext()
  159. {
  160.     RemoveChildren();
  161.  
  162.     for( size_t i = 0; i != mComments.size(); ++i )
  163.     
  164.         delete mComments[i];
  165. }
  166.  
  167. bool spContext::IsSorted()
  168. {
  169.     return mAlreadySorted;
  170. }
  171.  
  172. void 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.  
  187. bool spContext::HasComments()
  188. {
  189.     return ( mComments.size() != 0 );
  190. }
  191.  
  192. void 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.  
  208. spContext* 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.  
  219. bool spContext::PositionIsKnown()
  220. {
  221.     return ( mSrcOffset != (-1) && mContextLength != (-1) );
  222. }
  223.  
  224. bool spContext::IsVirtualContext()
  225. {
  226.     return mIsVirtualContext;
  227. }
  228.  
  229. bool spContext::VitualContextHasChildren()
  230. {
  231.     return mVirtualContextHasChildren;
  232. }
  233.  
  234. string spContext::GetVirtualContextBody()
  235. {
  236.     wxASSERT( mIsVirtualContext );
  237.  
  238.     return mVirtualContextBody;
  239. }
  240.  
  241. string spContext::GetFooterOfVirtualContextBody()
  242. {
  243.     wxASSERT( mIsVirtualContext );
  244.  
  245.     return mVittualContextFooter;
  246. }
  247.  
  248.  
  249. void 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.  
  263. string 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.  
  276. string 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.  
  285. bool spContext::IsFirstOccurence()
  286. {
  287.     return ( mpFirstOccurence != 0 );
  288. }
  289.  
  290. spContext* 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.  
  299. void spContext::AddMember( spContext* pMember )
  300. {
  301.     mMembers.push_back( pMember );
  302.  
  303.     pMember->mpParent = this;
  304. }
  305.  
  306. void spContext::AddComment( spComment* pComment )
  307. {
  308.     mComments.push_back( pComment );
  309. }
  310.  
  311. MMemberListT& spContext::GetMembers()
  312. {
  313.     return mMembers;
  314. }
  315.  
  316. spContext* 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.  
  343. void 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.  
  352. spContext* spContext::GetOutterContext()
  353. {
  354.     return mpParent;
  355. }
  356.  
  357. bool spContext::HasOutterContext()
  358. {
  359.     return ( mpParent != 0 );
  360. }
  361.  
  362. bool spContext::IsInFile()
  363. {
  364.     return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
  365. }
  366.  
  367. bool spContext::IsInNameSpace()
  368. {
  369.     return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
  370. }
  371.  
  372. bool spContext::IsInClass()
  373. {
  374.     return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
  375. }
  376.  
  377. bool spContext::IsInOperation()
  378. {
  379.     return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
  380. }
  381.  
  382. spClass& spContext::GetClass()
  383. {
  384.     wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
  385.     return *((spClass*)mpParent );
  386. }
  387.  
  388. spFile& spContext::GetFile()
  389. {
  390.     wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
  391.     return *((spFile*)mpParent );
  392. }
  393.  
  394. spNameSpace& spContext::GetNameSpace()
  395. {
  396.     wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
  397.     return *((spNameSpace*)mpParent );
  398. }
  399.  
  400. spOperation& spContext::GetOperation()
  401. {
  402.     wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
  403.     return *((spOperation*)mpParent );
  404. }
  405.  
  406. /***** Implementation for class spClass *****/
  407.  
  408. void spClass::SortMembers()
  409. {
  410.     // TBD::
  411. }
  412.  
  413. /***** Implementation for class spOperation *****/
  414.  
  415. spOperation::spOperation()
  416.  
  417.     : mHasDefinition( FALSE )
  418. {
  419.     mIsConstant =
  420.     mIsVirtual =
  421.     mHasDefinition = false;
  422. }
  423.  
  424. string 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.  
  476. string 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.  
  509. SourceParserBase::SourceParserBase()
  510.  
  511.     : mpFileBuf( NULL ),
  512.       mFileBufSz( 0 ),
  513.  
  514.       mpPlugin( NULL )
  515. {}
  516.  
  517. SourceParserBase::~SourceParserBase()
  518. {
  519.     if ( mpFileBuf ) free( mpFileBuf );
  520.  
  521.     if ( mpPlugin ) delete mpPlugin;
  522. }
  523.  
  524. spFile* 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.  
  543. void 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.  
  556. void 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.  
  570. void spContext::DumpThis(const wxString& indent) const
  571. {
  572.     wxFAIL_MSG("abstract base class can't be found in parser tree!");
  573. }
  574.  
  575. void 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.  
  581. void 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.  
  587. void 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.  
  620. void 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.  
  646. void 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.  
  691. void spEnumeration::DumpThis(const wxString& indent) const
  692. {
  693.     wxLogDebug("%senum named '%s'",
  694.                indent.c_str(), mName.c_str());
  695. }
  696.  
  697. void spTypeDef::DumpThis(const wxString& indent) const
  698. {
  699.     wxLogDebug("%stypedef %s = %s",
  700.                indent.c_str(), mName.c_str(), mOriginalType.c_str());
  701. }
  702.  
  703. void spFile::DumpThis(const wxString& indent) const
  704. {
  705.     wxLogDebug("%sfile '%s'",
  706.                indent.c_str(), mFileName.c_str());
  707. }
  708.  
  709. #endif // __WXDEBUG__
  710.