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 / docripper.cpp < prev    next >
Text File  |  2002-01-18  |  14KB  |  594 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: docripper.cpp,v 1.3 2002/01/15 14:49:31 GT Exp $
  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. #include "docripper.h"
  24.  
  25. #if wxUSE_IOSTREAMH
  26.     #include <iostream.h>
  27. #else
  28.     #include <iostream>
  29. #endif
  30.  
  31. // script templates
  32.  
  33. // ***** currently only HTML versions of variouse templates available ***** //
  34.  
  35. static const char* HTM_TopTempl = 
  36.  
  37. "<html><body bgcolor=#FFFFFF>\n\
  38. \n\n<!------ Automatically Generated by \"wxDocRipper\"------->\n\n\n\
  39. <p><h2>$(NAME)</h2><p>\n\
  40. <ul>\n\
  41. $(REFLIST)\
  42. </ul><p>\n\n\
  43. ";
  44.  
  45. static const char* HTM_ContentIdxTempl = 
  46.  
  47. "\
  48. <a name=\"r$(ID)_$(NAME)\">\n\
  49. <p><hr>\n\
  50. <h2><p>$(NAME)<p></h2>\
  51. <ul>\n\
  52. $(REFLIST)\
  53. </ul><p>\n\n\
  54. ";
  55.  
  56. static const char* HTM_SuperContentTempl = 
  57.  
  58. "\
  59. <a name=\"r$(ID)_$(NAME)\">\n\
  60. <p><hr>\n\
  61. <p><h2>$(NAME)<p></h2>\
  62. $(BODY)\n\
  63. ";
  64.  
  65. static const char* HTM_SubContentTempl = 
  66.  
  67. "\
  68. <a name=\"r$(ID)_$(NAME)\">\n\
  69. <p><hr>\n\
  70. <p><h3>$(NAME)<p></h3>\
  71. $(BODY)\n\
  72. ";
  73.  
  74. static const char* HTM_OutLineTempl =
  75.  
  76. "\
  77. <p>\n\
  78. <b><font color=\"#FF0000\">$(NAME)</font></b><p>\n\
  79. ";
  80.  
  81. static const char* HTM_OutLine1Templ =
  82.  
  83. "\
  84. <p>\n\
  85. <b><i><font color=\"#101010\">$(NAME)</font></i></b>\n\
  86. <ul>\n\
  87. $(REFLIST)\
  88. </ul>\n\n\
  89. ";
  90.  
  91. static const char* HTM_RefTempl =
  92.  
  93. "\
  94. <li><a href=\"#r$(ID)_$(NAME)\">$(NAME)</A>\n\
  95. ";
  96.  
  97. static const char* HTM_DeadRefTempl =
  98.  
  99. "\
  100. <li></b>$(NAME)\n\
  101. ";
  102.  
  103. /***** Implementation for class RipperDocGen *****/
  104.  
  105. RipperDocGen::RipperDocGen()
  106.  
  107.     : mTopTempl         ( HTM_TopTempl ),
  108.       mContentIdxTempl  ( HTM_ContentIdxTempl ),
  109.       mSuperContentTempl( HTM_SuperContentTempl ),
  110.       mSubContentTempl  ( HTM_SubContentTempl ),
  111.       mOutLineTempl     ( HTM_OutLineTempl ),
  112.       mOutLine1Templ    ( HTM_OutLine1Templ ),
  113.  
  114.       mRefTempl         ( HTM_RefTempl ),
  115.       mDeadRefTempl     ( HTM_DeadRefTempl ),
  116.  
  117.       mpCurClassSect(0)
  118. {                                                                                               // topIndex is not referenced
  119.     mpTopIdx        = new ScriptSection( "Source Code Contents"       , "", &mTopTempl       , 0          );
  120.     mpClassIdx      = new ScriptSection( "Classes Reference"          , "", &mContentIdxTempl, &mRefTempl );
  121.     mpEnumIdx       = new ScriptSection( "Enumerations  Reference"    , "", &mContentIdxTempl,  &mRefTempl );
  122.     mpTypeDefIdx    = new ScriptSection( "Type Definitions Reference" , "", &mContentIdxTempl, &mRefTempl );
  123.     mpMacroIdx      = new ScriptSection( "Macros Reference"           , "", &mContentIdxTempl, &mRefTempl );
  124.     mpGlobalVarsIdx = new ScriptSection( "Global Variables Reference" , "", &mContentIdxTempl, &mRefTempl );
  125.     mpGlobalFuncIdx = new ScriptSection( "Global Functions  Reference", "", &mContentIdxTempl, &mRefTempl );
  126.     mpConstIdx      = new ScriptSection( "Constants  Reference"       , "", &mContentIdxTempl, &mRefTempl );
  127.  
  128.     // assemble top index
  129.     mpTopIdx->AddSection( mpClassIdx     , 1 );
  130.     mpTopIdx->AddSection( mpEnumIdx      , 1 );
  131.     mpTopIdx->AddSection( mpTypeDefIdx   , 1 );
  132.     mpTopIdx->AddSection( mpMacroIdx     , 1 );
  133.     mpTopIdx->AddSection( mpGlobalVarsIdx, 1 );
  134.     mpTopIdx->AddSection( mpGlobalFuncIdx, 1 );
  135.     mpTopIdx->AddSection( mpConstIdx     , 1 );
  136.  
  137.     // register reserved variables for index and description templates
  138.     ScriptSection::RegisterTemplate( mTopTempl );
  139.     ScriptSection::RegisterTemplate( mContentIdxTempl );
  140.     ScriptSection::RegisterTemplate( mSuperContentTempl );
  141.     ScriptSection::RegisterTemplate( mSubContentTempl );
  142.     ScriptSection::RegisterTemplate( mOutLineTempl );
  143.     ScriptSection::RegisterTemplate( mOutLine1Templ );
  144.     ScriptSection::RegisterTemplate( mRefTempl );
  145.     ScriptSection::RegisterTemplate( mDeadRefTempl );
  146.  
  147.     // create the top-most (interfile) context
  148.     mpFileBinderCtx = new spFile();
  149.  
  150.     // the default script is HTML
  151.     mTags = get_HTML_markup_tags();
  152.  
  153.     mpParser = 0; // no default parser!
  154. }
  155.  
  156. void RipperDocGen::Init( SourceParserBase* pParser )
  157. {
  158.     mpParser = pParser;
  159. }
  160.  
  161. RipperDocGen::~RipperDocGen()
  162. {
  163.     delete mpFileBinderCtx;
  164. }
  165.  
  166. void RipperDocGen::AppendComments( spContext& fromContext, string& str )
  167. {
  168.     if ( !fromContext.HasComments() ) return;
  169.  
  170.     size_t start = str.length();
  171.  
  172.     str += mTags[TAG_BOLD].end;
  173.     str += mTags[TAG_PARAGRAPH].start;
  174.  
  175.     MCommentListT& lst = fromContext.GetCommentList();
  176.  
  177.     for( size_t i = 0; i != lst.size(); ++i )
  178.     {
  179.     
  180.         if ( i != 0 )
  181.             
  182.             if ( lst[i]->StartsParagraph() )
  183.             {
  184.                 str += mTags[TAG_PARAGRAPH].start;
  185.  
  186.             }
  187.     
  188.         str += lst[i]->mText;
  189.     }
  190.  
  191.     // remove new lines, and insert paragraph breaks
  192.  
  193.     // if empty lines found
  194.  
  195.     size_t len = str.length();
  196.  
  197.     for( size_t n = start; n != len; ++n )
  198.     
  199.         if ( str[n] == 10 || 
  200.              str[n] == 13  ) 
  201.  
  202.         {
  203.  
  204.             if ( n + 2 < len )
  205.  
  206.             {
  207.  
  208.                 if ( ( str[n] == 13 && str[n+1] == 10 &&  // FIXME:: quick-hack
  209.  
  210.                        str[n+2] == 13 ) ||
  211.  
  212.                      ( str[n] == 10 && str[n+1] == 10 )
  213.  
  214.                 )
  215.  
  216.                 {
  217.  
  218.                     str.insert( n + 1, "<p>" ); // FIXME:: quick-hack
  219.  
  220.                     len += 3;
  221.  
  222.                 }
  223.  
  224.             }
  225.  
  226.  
  227.  
  228.             str[n] = ' ';
  229.  
  230.         }
  231.  
  232.  
  233.     str += mTags[TAG_PARAGRAPH].end;
  234. }
  235.  
  236. void RipperDocGen::AppendMulitilineStr( string& st, string& mlStr )
  237. {
  238.     st = mTags[TAG_FIXED_FONT].start;
  239.     st += mlStr;
  240.     st += mTags[TAG_FIXED_FONT].end;
  241. }
  242.  
  243. void RipperDocGen::AppendHighlightedSource( string& st, string source )
  244. {
  245.     // FIXME:: below should not be fixed :)
  246.     char buf[1024*32];
  247.  
  248.     // DBG:::
  249. //    ASSERT( source.length() + 1 < sizeof(buf) );
  250.  
  251.     strcpy( buf, source.c_str() );
  252.                         
  253.     // highlight things
  254.     mSrcPainter.Init();
  255.     mSrcPainter.ProcessSource( buf, strlen(buf) );
  256.     mSrcPainter.GetResultString( st, mTags );
  257. }
  258.  
  259. bool RipperDocGen::CheckIfUncommented( spContext& ctx, ScriptSection& toSect )
  260. {
  261.     if ( ctx.HasComments() ) return 0;
  262.  
  263.     toSect.AddReference( 
  264.         new ScriptSection( GetScopedName( ctx ), "", 0, &mDeadRefTempl )
  265.     );
  266.  
  267.     return 1;
  268. }
  269.  
  270. ScriptTemplate* RipperDocGen::GetRefTemplFor( spContext& ctx )
  271. {
  272.     if ( ctx.HasComments() )
  273.  
  274.         return &mRefTempl;
  275.     else
  276.         return &mDeadRefTempl;
  277. }
  278.  
  279. string RipperDocGen::GetScopedName( spContext& ofCtx )
  280. {
  281.     if ( ofCtx.IsInFile() ) return ofCtx.GetName();
  282.     else
  283.         return ofCtx.GetOutterContext()->GetName() + 
  284.                "::" + ofCtx.GetName();
  285. }
  286.  
  287. void RipperDocGen::AddToCurrentClass( ScriptSection* pSection, spContext& ctx, 
  288.                                       const char* subSectionName )
  289. {
  290.     string sName;
  291.  
  292.     if ( ctx.mVisibility == SP_VIS_PROTECTED )
  293.  
  294.         sName = "Protected members/";
  295.     else
  296.     if ( ctx.mVisibility == SP_VIS_PRIVATE )
  297.  
  298.         sName = "Private members/";
  299.     else
  300.         sName = "Public members/";
  301.  
  302.     sName += subSectionName;
  303.  
  304.     ScriptSection* pSect = mpCurClassSect->GetSubsection( sName.c_str() );
  305.  
  306.     if ( CheckIfUncommented( ctx, *pSect ) )
  307.     {
  308.         delete pSection;
  309.         return;
  310.     }
  311.  
  312.     pSect->AddReference( pSection );
  313.  
  314.     mpCurClassSect->AddSection( pSection );
  315. }
  316.  
  317. void RipperDocGen::LinkSuperClassRefs()
  318. {
  319.     MMemberListT clLst;
  320.  
  321.     // collect all classes in the context tree
  322.     mpFileBinderCtx->GetContextList( clLst, SP_CTX_CLASS );
  323.  
  324.     for( size_t i = 0; i != clLst.size(); ++i )
  325.     {
  326.         spClass& cl = *((spClass*)clLst[i]);
  327.  
  328.         // FIXME:: why sometimes GetUserData() returns NULL?
  329.         if ( !cl.GetUserData() )
  330.             continue;
  331.  
  332.         ScriptSection* pClSect = (ScriptSection*)cl.GetUserData();
  333.         ScriptSection* pSuperSect = pClSect->GetSubsection("Derived from");
  334.  
  335.         for( size_t n = 0; n != cl.mSuperClassNames.size(); ++n )
  336.         {
  337.             string& superClName = cl.mSuperClassNames[n];
  338.  
  339.             spClass* pFound = NULL;
  340.  
  341.             string* name;
  342.  
  343.             for( size_t k = 0; k != clLst.size(); ++k )
  344.             {
  345.                 name = &clLst[k]->GetName();
  346.  
  347.                 if ( clLst[k]->GetName() == superClName )
  348.                 {
  349.                     pFound = (spClass*)clLst[k];
  350.                     break;
  351.                 }
  352.             }
  353.  
  354.             if ( !pFound )
  355.             {
  356.                 ScriptSection* pNotFound = 
  357.                     new ScriptSection( superClName, "", 0, &mDeadRefTempl );
  358.  
  359.                 pSuperSect->AddReference( pNotFound );
  360.             }
  361.             else
  362.                 if ( pFound->GetUserData() )
  363.                 
  364.                     pSuperSect->AddReference( 
  365.                         (ScriptSection*)pFound->GetUserData() );
  366.         }
  367.     }
  368. }
  369.  
  370. void RipperDocGen::ProcessFile( const char* sourceFile )
  371. {
  372.     cout << "Processing file " << sourceFile << "..." << endl;
  373.  
  374.     spFile* pCtx = mpParser->ParseFile( sourceFile );
  375.  
  376.     if ( pCtx == NULL )
  377.     {
  378.         cout << "Cannot open file " << sourceFile << ", skipped..." << endl;
  379.  
  380.         return;
  381.     }
  382.  
  383.     VisitAll( *pCtx, TRUE );
  384.  
  385.     mpFileBinderCtx->AddMember( pCtx );
  386. }
  387.  
  388. // implementations of "visiting procedures"
  389.  
  390. void RipperDocGen::VisitEnumeration( spEnumeration& en )
  391. {
  392.     // FOR NOW:: do not reference "nameless" enums
  393.     if ( en.GetName() == "" ) return;
  394.  
  395.     if ( CheckIfUncommented( en, *mpEnumIdx ) )
  396.         return;
  397.  
  398.     string body;
  399.     body += mTags[TAG_BOLD].start;
  400.  
  401.     AppendMulitilineStr( body, en.mEnumContent );
  402.  
  403.     body += mTags[TAG_BOLD].end;
  404.  
  405.     string line;
  406.     AppendHighlightedSource( line, body );
  407.     AppendComments( en, line );
  408.  
  409.     mpEnumIdx->AddSection( 
  410.         new ScriptSection( en.GetName(), line, 
  411.                            &mSubContentTempl,
  412.                            GetRefTemplFor( en ) ), 1
  413.     );
  414. }
  415.  
  416. void RipperDocGen::VisitTypeDef( spTypeDef& td )
  417. {
  418.     if ( CheckIfUncommented( td, *mpTypeDefIdx ) )
  419.         return;
  420.  
  421.     string body;
  422.     body += mTags[TAG_BOLD].start;
  423.     body += "typdef ";
  424.     body += mTags[TAG_BOLD].end;
  425.  
  426.     AppendMulitilineStr( body, td.mOriginalType );
  427.     body += td.mOriginalType;
  428.     body += ' ';
  429.  
  430.     body += mTags[TAG_BOLD].start;
  431.     body += td.GetName();
  432.     body += mTags[TAG_BOLD].end;
  433.  
  434.     string line;
  435.     AppendHighlightedSource( line, body );
  436.     AppendComments( td, line );
  437.  
  438.     mpTypeDefIdx->AddSection( 
  439.         new ScriptSection( td.GetName(), line, 
  440.                            &mSubContentTempl,
  441.                            GetRefTemplFor( td ) ), TRUE
  442.     );
  443. }
  444.  
  445. void RipperDocGen::VisitPreprocessorLine( spPreprocessorLine& pd )
  446. {
  447.     if ( pd.mDefType != SP_PREP_DEF_REDEFINE_SYMBOL )
  448.  
  449.     
  450.  
  451.         return;
  452.  
  453.  
  454.     if ( CheckIfUncommented( pd, *mpMacroIdx ) )
  455.         return;
  456.  
  457.     string body;
  458.     body += mTags[TAG_FIXED_FONT].start;
  459.  
  460.     string coloredLine = pd.mLine;
  461.     AppendHighlightedSource( coloredLine, pd.mLine );
  462.  
  463.     AppendMulitilineStr( body, coloredLine );
  464.  
  465.     body += mTags[TAG_FIXED_FONT].end;
  466.  
  467.     AppendComments( pd, body );
  468.  
  469.     mpMacroIdx->AddSection( 
  470.         new ScriptSection( pd.GetName(), body, 
  471.                            &mSubContentTempl,
  472.                            GetRefTemplFor( pd ) ), TRUE
  473.     );
  474. }
  475.  
  476. void RipperDocGen::VisitClass( spClass& cl )
  477. {
  478.     // FOR NOW:: do not document nested classes -
  479.     //           nicier visiting method yet needed
  480.  
  481.     if ( cl.IsInClass() )
  482.     {
  483.         SkipChildren(); // spVisitor's method
  484.         return;
  485.     }
  486.  
  487.     string body;
  488.     AppendComments( cl, body );
  489.  
  490.     mpCurClassSect =         
  491.         new ScriptSection( cl.GetName(), body, &mSuperContentTempl, &mRefTempl );
  492.  
  493.     // set up reference in the class context, pointing back
  494.     // to the section where this class is represented
  495.     cl.SetUserData( mpCurClassSect );
  496.  
  497.     ScriptSection* pSuper    = new ScriptSection( "Derived from"    ,"", &mOutLine1Templ,0, 1 );
  498.  
  499.     ScriptSection* pPublic    = new ScriptSection( "Public members"    ,"", &mOutLineTempl,0, 1 );
  500.     ScriptSection* pProtected = new ScriptSection( "Protected members" ,"", &mOutLineTempl,0, 1 );
  501.     ScriptSection* pPrivate   = new ScriptSection( "Private members"   ,"", &mOutLineTempl,0, 1 );
  502.  
  503.     pPublic->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
  504.     pPublic->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
  505.  
  506.  
  507.     pProtected->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
  508.     pProtected->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
  509.  
  510.  
  511.     pPrivate->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
  512.     pPrivate->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
  513.  
  514.     mpCurClassSect->AddSection( pSuper    );
  515.     mpCurClassSect->AddSection( pPublic    );
  516.     mpCurClassSect->AddSection( pProtected );
  517.     mpCurClassSect->AddSection( pPrivate   );
  518.  
  519.     mpClassIdx->AddSection( mpCurClassSect, TRUE );
  520. }
  521.  
  522. void RipperDocGen::VisitAttribute( spAttribute& attr )
  523. {
  524.     string body;
  525.     body += mTags[TAG_BOLD].start;
  526.     body += attr.mType;
  527.     body += mTags[TAG_BOLD].end;
  528.  
  529.     body += mTags[TAG_ITALIC].start;
  530.     body += ' ';
  531.     body += attr.GetName();
  532.     body += mTags[TAG_ITALIC].end;
  533.  
  534.     string line;
  535.     AppendHighlightedSource( line, body );
  536.     AppendComments( attr, line );
  537.  
  538.     ScriptSection* pSection = 
  539.         new ScriptSection( GetScopedName( attr ), line, 
  540.                            &mSubContentTempl,
  541.                            GetRefTemplFor( attr ) );
  542.  
  543.     if ( attr.mIsConstant )
  544.     
  545.         mpConstIdx->AddSection( pSection, TRUE );
  546.     
  547.     else
  548.     if ( !attr.IsInClass() )
  549.     {
  550.         if ( CheckIfUncommented( attr, *mpGlobalVarsIdx ) )
  551.             return;
  552.  
  553.         mpGlobalVarsIdx->AddSection( pSection, TRUE );
  554.     }
  555.     else
  556.  
  557.         AddToCurrentClass( pSection, attr, "Attributes" );
  558. }
  559.  
  560. void RipperDocGen::VisitOperation( spOperation& op )
  561. {
  562.     string body;
  563.  
  564.     AppendHighlightedSource( body, op.GetFullName(mTags) );
  565.  
  566.     AppendComments( op, body );
  567.  
  568.     ScriptSection* pSection = 
  569.         new ScriptSection( GetScopedName( op ), body, 
  570.                            &mSubContentTempl,
  571.                            GetRefTemplFor( op ) );
  572.  
  573.     if ( !op.IsInClass() )
  574.     {
  575.         if ( CheckIfUncommented( op, *mpGlobalFuncIdx ) )
  576.             return;
  577.  
  578.         mpGlobalFuncIdx->AddSection( pSection, 1 );
  579.     }
  580.     else
  581.         AddToCurrentClass( pSection, op, "Operations" );
  582. }
  583.  
  584. bool RipperDocGen::OnSaveDocument( ScriptStream& stm )
  585. {
  586.     LinkSuperClassRefs();
  587.  
  588.     // FOR NOW:: doesn't work yet
  589.     //mpTopIdx->RemoveEmptySections();
  590.  
  591.     return 1; // saving can proceed now 
  592. }
  593.  
  594.