Files correlati : Commento : Spostamento in libraries delle librerie esterne di Campo per una maggiore pulizia e organizzazione git-svn-id: svn://10.65.10.50/branches/R_10_00@24150 c028cbd2-c16b-5b4b-a496-9718f37d4682
560 lines
15 KiB
C++
560 lines
15 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: No names yet.
|
|
// Purpose: Contrib. demo
|
|
// Author: Aleksandras Gluchovas
|
|
// Modified by:
|
|
// Created: 22/09/98
|
|
// RCS-ID: $Id: docripper.cpp 34519 2005-06-02 09:44:45Z ABX $
|
|
// Copyright: (c) Aleskandars Gluchovas
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "docripper.h"
|
|
|
|
#if wxUSE_IOSTREAMH
|
|
#include <iostream.h>
|
|
#else
|
|
#include <iostream>
|
|
#endif
|
|
|
|
// script templates
|
|
|
|
// ***** currently only HTML versions of variouse templates available ***** //
|
|
|
|
static const char* HTM_TopTempl =
|
|
|
|
"<html><body bgcolor=#FFFFFF>\n\
|
|
\n\n<!------ Automatically Generated by \"wxDocRipper\"------->\n\n\n\
|
|
<p><h2>$(NAME)</h2><p>\n\
|
|
<ul>\n\
|
|
$(REFLIST)\
|
|
</ul><p>\n\n\
|
|
";
|
|
|
|
static const char* HTM_ContentIdxTempl =
|
|
|
|
"\
|
|
<a name=\"r$(ID)_$(NAME)\">\n\
|
|
<p><hr>\n\
|
|
<h2><p>$(NAME)<p></h2>\
|
|
<ul>\n\
|
|
$(REFLIST)\
|
|
</ul><p>\n\n\
|
|
";
|
|
|
|
static const char* HTM_SuperContentTempl =
|
|
|
|
"\
|
|
<a name=\"r$(ID)_$(NAME)\">\n\
|
|
<p><hr>\n\
|
|
<p><h2>$(NAME)<p></h2>\
|
|
$(BODY)\n\
|
|
";
|
|
|
|
static const char* HTM_SubContentTempl =
|
|
|
|
"\
|
|
<a name=\"r$(ID)_$(NAME)\">\n\
|
|
<p><hr>\n\
|
|
<p><h3>$(NAME)<p></h3>\
|
|
$(BODY)\n\
|
|
";
|
|
|
|
static const char* HTM_OutLineTempl =
|
|
|
|
"\
|
|
<p>\n\
|
|
<b><font color=\"#FF0000\">$(NAME)</font></b><p>\n\
|
|
";
|
|
|
|
static const char* HTM_OutLine1Templ =
|
|
|
|
"\
|
|
<p>\n\
|
|
<b><i><font color=\"#101010\">$(NAME)</font></i></b>\n\
|
|
<ul>\n\
|
|
$(REFLIST)\
|
|
</ul>\n\n\
|
|
";
|
|
|
|
static const char* HTM_RefTempl =
|
|
|
|
"\
|
|
<li><a href=\"#r$(ID)_$(NAME)\">$(NAME)</A>\n\
|
|
";
|
|
|
|
static const char* HTM_DeadRefTempl =
|
|
|
|
"\
|
|
<li></b>$(NAME)\n\
|
|
";
|
|
|
|
/***** Implementation for class RipperDocGen *****/
|
|
|
|
RipperDocGen::RipperDocGen()
|
|
|
|
: mTopTempl ( HTM_TopTempl ),
|
|
mContentIdxTempl ( HTM_ContentIdxTempl ),
|
|
mSuperContentTempl( HTM_SuperContentTempl ),
|
|
mSubContentTempl ( HTM_SubContentTempl ),
|
|
mOutLineTempl ( HTM_OutLineTempl ),
|
|
mOutLine1Templ ( HTM_OutLine1Templ ),
|
|
|
|
mRefTempl ( HTM_RefTempl ),
|
|
mDeadRefTempl ( HTM_DeadRefTempl ),
|
|
|
|
mpCurClassSect(0)
|
|
{
|
|
// topIndex is not referenced
|
|
mpTopIdx = new ScriptSection( "Source Code Contents" , wxEmptyString, &mTopTempl , 0 );
|
|
mpClassIdx = new ScriptSection( "Classes Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpEnumIdx = new ScriptSection( "Enumerations Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpTypeDefIdx = new ScriptSection( "Type Definitions Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpMacroIdx = new ScriptSection( "Macros Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpGlobalVarsIdx = new ScriptSection( "Global Variables Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpGlobalFuncIdx = new ScriptSection( "Global Functions Reference", wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
mpConstIdx = new ScriptSection( "Constants Reference" , wxEmptyString, &mContentIdxTempl, &mRefTempl );
|
|
|
|
// assemble top index
|
|
mpTopIdx->AddSection( mpClassIdx , 1 );
|
|
mpTopIdx->AddSection( mpEnumIdx , 1 );
|
|
mpTopIdx->AddSection( mpTypeDefIdx , 1 );
|
|
mpTopIdx->AddSection( mpMacroIdx , 1 );
|
|
mpTopIdx->AddSection( mpGlobalVarsIdx, 1 );
|
|
mpTopIdx->AddSection( mpGlobalFuncIdx, 1 );
|
|
mpTopIdx->AddSection( mpConstIdx , 1 );
|
|
|
|
// register reserved variables for index and description templates
|
|
ScriptSection::RegisterTemplate( mTopTempl );
|
|
ScriptSection::RegisterTemplate( mContentIdxTempl );
|
|
ScriptSection::RegisterTemplate( mSuperContentTempl );
|
|
ScriptSection::RegisterTemplate( mSubContentTempl );
|
|
ScriptSection::RegisterTemplate( mOutLineTempl );
|
|
ScriptSection::RegisterTemplate( mOutLine1Templ );
|
|
ScriptSection::RegisterTemplate( mRefTempl );
|
|
ScriptSection::RegisterTemplate( mDeadRefTempl );
|
|
|
|
// create the top-most (interfile) context
|
|
mpFileBinderCtx = new spFile();
|
|
|
|
// the default script is HTML
|
|
m_Tags = get_HTML_markup_tags();
|
|
|
|
mpParser = 0; // no default parser!
|
|
}
|
|
|
|
void RipperDocGen::Init( SourceParserBase* pParser )
|
|
{
|
|
mpParser = pParser;
|
|
}
|
|
|
|
RipperDocGen::~RipperDocGen()
|
|
{
|
|
delete mpFileBinderCtx;
|
|
}
|
|
|
|
void RipperDocGen::AppendComments( spContext& fromContext, wxString& str )
|
|
{
|
|
if ( !fromContext.HasComments() ) return;
|
|
|
|
size_t start = str.length();
|
|
|
|
str += m_Tags[TAG_BOLD].end;
|
|
str += m_Tags[TAG_PARAGRAPH].start;
|
|
|
|
MCommentListT& lst = fromContext.GetCommentList();
|
|
|
|
for( size_t i = 0; i != lst.size(); ++i )
|
|
{
|
|
|
|
if ( i != 0 )
|
|
|
|
if ( lst[i]->StartsParagraph() )
|
|
{
|
|
str += m_Tags[TAG_PARAGRAPH].start;
|
|
}
|
|
|
|
str += lst[i]->m_Text;
|
|
}
|
|
|
|
// remove new lines, and insert paragraph breaks
|
|
|
|
// if empty lines found
|
|
|
|
size_t len = str.length();
|
|
|
|
for( size_t n = start; n != len; ++n )
|
|
|
|
if ( str[n] == 10 ||
|
|
str[n] == 13 )
|
|
{
|
|
if ( n + 2 < len )
|
|
{
|
|
if ( ( str[n] == 13 && str[n+1] == 10 && // FIXME:: quick-hack
|
|
str[n+2] == 13 ) ||
|
|
( str[n] == 10 && str[n+1] == 10 )
|
|
)
|
|
{
|
|
str.insert( n + 1, _T("<p>") ); // FIXME:: quick-hack
|
|
len += 3;
|
|
}
|
|
}
|
|
str[n] = _T(' ');
|
|
}
|
|
str += m_Tags[TAG_PARAGRAPH].end;
|
|
}
|
|
|
|
void RipperDocGen::AppendMulitilineStr( wxString& st, wxString& mlStr )
|
|
{
|
|
st = m_Tags[TAG_FIXED_FONT].start;
|
|
st += mlStr;
|
|
st += m_Tags[TAG_FIXED_FONT].end;
|
|
}
|
|
|
|
void RipperDocGen::AppendHighlightedSource( wxString& st, wxString source )
|
|
{
|
|
// FIXME:: below should not be fixed :)
|
|
wxChar buf[1024*32];
|
|
|
|
// DBG:::
|
|
// ASSERT( source.length() + 1 < sizeof(buf) );
|
|
|
|
wxStrcpy( buf, source.c_str() );
|
|
|
|
// highlight things
|
|
mSrcPainter.Init();
|
|
mSrcPainter.ProcessSource( buf, strlen(buf) );
|
|
mSrcPainter.GetResultString( st, m_Tags );
|
|
}
|
|
|
|
bool RipperDocGen::CheckIfUncommented( spContext& ctx, ScriptSection& toSect )
|
|
{
|
|
if ( ctx.HasComments() ) return 0;
|
|
|
|
toSect.AddReference(
|
|
new ScriptSection( GetScopedName( ctx ), wxEmptyString, 0, &mDeadRefTempl )
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
ScriptTemplate* RipperDocGen::GetRefTemplFor( spContext& ctx )
|
|
{
|
|
if ( ctx.HasComments() )
|
|
return &mRefTempl;
|
|
else
|
|
return &mDeadRefTempl;
|
|
}
|
|
|
|
wxString RipperDocGen::GetScopedName( spContext& ofCtx )
|
|
{
|
|
if ( ofCtx.IsInFile() )
|
|
return ofCtx.GetName();
|
|
else
|
|
return ofCtx.GetOutterContext()->GetName() +
|
|
_T("::") + ofCtx.GetName();
|
|
}
|
|
|
|
void RipperDocGen::AddToCurrentClass( ScriptSection* pSection, spContext& ctx,
|
|
const char* subSectionName )
|
|
{
|
|
wxString sName;
|
|
|
|
if ( ctx.mVisibility == SP_VIS_PROTECTED )
|
|
sName = "Protected members/";
|
|
else
|
|
if ( ctx.mVisibility == SP_VIS_PRIVATE )
|
|
sName = "Private members/";
|
|
else
|
|
sName = "Public members/";
|
|
|
|
sName += subSectionName;
|
|
|
|
ScriptSection* pSect = mpCurClassSect->GetSubsection( sName.c_str() );
|
|
|
|
if ( CheckIfUncommented( ctx, *pSect ) )
|
|
{
|
|
delete pSection;
|
|
return;
|
|
}
|
|
|
|
pSect->AddReference( pSection );
|
|
|
|
mpCurClassSect->AddSection( pSection );
|
|
}
|
|
|
|
void RipperDocGen::LinkSuperClassRefs()
|
|
{
|
|
MMemberListT clLst;
|
|
|
|
// collect all classes in the context tree
|
|
mpFileBinderCtx->GetContextList( clLst, SP_CTX_CLASS );
|
|
|
|
for( size_t i = 0; i != clLst.size(); ++i )
|
|
{
|
|
spClass& cl = *((spClass*)clLst[i]);
|
|
|
|
// FIXME:: why sometimes GetUserData() returns NULL?
|
|
if ( !cl.GetUserData() )
|
|
continue;
|
|
|
|
ScriptSection* pClSect = (ScriptSection*)cl.GetUserData();
|
|
ScriptSection* pSuperSect = pClSect->GetSubsection("Derived from");
|
|
|
|
for( size_t n = 0; n != cl.m_SuperClassNames.size(); ++n )
|
|
{
|
|
wxString& superClName = cl.m_SuperClassNames[n];
|
|
|
|
spClass* pFound = NULL;
|
|
|
|
for( size_t k = 0; k != clLst.size(); ++k )
|
|
{
|
|
if ( clLst[k]->GetName() == superClName )
|
|
{
|
|
pFound = (spClass*)clLst[k];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !pFound )
|
|
{
|
|
ScriptSection* pNotFound =
|
|
new ScriptSection( superClName, wxEmptyString, 0, &mDeadRefTempl );
|
|
|
|
pSuperSect->AddReference( pNotFound );
|
|
}
|
|
else
|
|
if ( pFound->GetUserData() )
|
|
|
|
pSuperSect->AddReference(
|
|
(ScriptSection*)pFound->GetUserData() );
|
|
}
|
|
}
|
|
}
|
|
|
|
void RipperDocGen::ProcessFile( const char* sourceFile )
|
|
{
|
|
wxSTD cout << "Processing file " << sourceFile << "..." << wxSTD endl;
|
|
|
|
spFile* pCtx = mpParser->ParseFile( sourceFile );
|
|
|
|
if ( pCtx == NULL )
|
|
{
|
|
wxSTD cout << "Cannot open file " << sourceFile << ", skipped..." << wxSTD endl;
|
|
|
|
return;
|
|
}
|
|
|
|
VisitAll( *pCtx, true );
|
|
|
|
mpFileBinderCtx->AddMember( pCtx );
|
|
}
|
|
|
|
// implementations of "visiting procedures"
|
|
|
|
void RipperDocGen::VisitEnumeration( spEnumeration& en )
|
|
{
|
|
// FOR NOW:: do not reference "nameless" enums
|
|
if ( en.GetName().empty() ) return;
|
|
|
|
if ( CheckIfUncommented( en, *mpEnumIdx ) )
|
|
return;
|
|
|
|
wxString body;
|
|
body += m_Tags[TAG_BOLD].start;
|
|
|
|
AppendMulitilineStr( body, en.m_EnumContent );
|
|
|
|
body += m_Tags[TAG_BOLD].end;
|
|
|
|
wxString line;
|
|
AppendHighlightedSource( line, body );
|
|
AppendComments( en, line );
|
|
|
|
mpEnumIdx->AddSection(
|
|
new ScriptSection( en.GetName(), line,
|
|
&mSubContentTempl,
|
|
GetRefTemplFor( en ) ), 1
|
|
);
|
|
}
|
|
|
|
void RipperDocGen::VisitTypeDef( spTypeDef& td )
|
|
{
|
|
if ( CheckIfUncommented( td, *mpTypeDefIdx ) )
|
|
return;
|
|
|
|
wxString body;
|
|
body += m_Tags[TAG_BOLD].start;
|
|
body += "typdef ";
|
|
body += m_Tags[TAG_BOLD].end;
|
|
|
|
AppendMulitilineStr( body, td.m_OriginalType );
|
|
body += td.m_OriginalType;
|
|
body += ' ';
|
|
|
|
body += m_Tags[TAG_BOLD].start;
|
|
body += td.GetName();
|
|
body += m_Tags[TAG_BOLD].end;
|
|
|
|
wxString line;
|
|
AppendHighlightedSource( line, body );
|
|
AppendComments( td, line );
|
|
|
|
mpTypeDefIdx->AddSection(
|
|
new ScriptSection( td.GetName(), line,
|
|
&mSubContentTempl,
|
|
GetRefTemplFor( td ) ), true
|
|
);
|
|
}
|
|
|
|
void RipperDocGen::VisitPreprocessorLine( spPreprocessorLine& pd )
|
|
{
|
|
if ( pd.mDefType != SP_PREP_DEF_REDEFINE_SYMBOL )
|
|
return;
|
|
|
|
if ( CheckIfUncommented( pd, *mpMacroIdx ) )
|
|
return;
|
|
|
|
wxString body;
|
|
body += m_Tags[TAG_FIXED_FONT].start;
|
|
|
|
wxString coloredLine = pd.m_Line;
|
|
AppendHighlightedSource( coloredLine, pd.m_Line );
|
|
|
|
AppendMulitilineStr( body, coloredLine );
|
|
|
|
body += m_Tags[TAG_FIXED_FONT].end;
|
|
|
|
AppendComments( pd, body );
|
|
|
|
mpMacroIdx->AddSection(
|
|
new ScriptSection( pd.GetName(), body,
|
|
&mSubContentTempl,
|
|
GetRefTemplFor( pd ) ), true
|
|
);
|
|
}
|
|
|
|
void RipperDocGen::VisitClass( spClass& cl )
|
|
{
|
|
// FOR NOW:: do not document nested classes -
|
|
// nicier visiting method yet needed
|
|
|
|
if ( cl.IsInClass() )
|
|
{
|
|
SkipChildren(); // spVisitor's method
|
|
return;
|
|
}
|
|
|
|
wxString body;
|
|
AppendComments( cl, body );
|
|
|
|
mpCurClassSect =
|
|
new ScriptSection( cl.GetName(), body, &mSuperContentTempl, &mRefTempl );
|
|
|
|
// set up reference in the class context, pointing back
|
|
// to the section where this class is represented
|
|
cl.SetUserData( mpCurClassSect );
|
|
|
|
ScriptSection* pSuper = new ScriptSection( "Derived from" ,wxEmptyString, &mOutLine1Templ,0, 1 );
|
|
|
|
ScriptSection* pPublic = new ScriptSection( "Public members" ,wxEmptyString, &mOutLineTempl,0, 1 );
|
|
ScriptSection* pProtected = new ScriptSection( "Protected members" ,wxEmptyString, &mOutLineTempl,0, 1 );
|
|
ScriptSection* pPrivate = new ScriptSection( "Private members" ,wxEmptyString, &mOutLineTempl,0, 1 );
|
|
|
|
pPublic->AddSection( new ScriptSection( "Operations", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
pPublic->AddSection( new ScriptSection( "Attributes", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
|
|
pProtected->AddSection( new ScriptSection( "Operations", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
pProtected->AddSection( new ScriptSection( "Attributes", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
|
|
pPrivate->AddSection( new ScriptSection( "Operations", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
pPrivate->AddSection( new ScriptSection( "Attributes", wxEmptyString, &mOutLine1Templ, 0, 1 ) );
|
|
|
|
mpCurClassSect->AddSection( pSuper );
|
|
mpCurClassSect->AddSection( pPublic );
|
|
mpCurClassSect->AddSection( pProtected );
|
|
mpCurClassSect->AddSection( pPrivate );
|
|
|
|
mpClassIdx->AddSection( mpCurClassSect, true );
|
|
}
|
|
|
|
void RipperDocGen::VisitAttribute( spAttribute& attr )
|
|
{
|
|
wxString body;
|
|
body += m_Tags[TAG_BOLD].start;
|
|
body += attr.m_Type;
|
|
body += m_Tags[TAG_BOLD].end;
|
|
|
|
body += m_Tags[TAG_ITALIC].start;
|
|
body += ' ';
|
|
body += attr.GetName();
|
|
body += m_Tags[TAG_ITALIC].end;
|
|
|
|
wxString line;
|
|
AppendHighlightedSource( line, body );
|
|
AppendComments( attr, line );
|
|
|
|
ScriptSection* pSection =
|
|
new ScriptSection( GetScopedName( attr ), line,
|
|
&mSubContentTempl,
|
|
GetRefTemplFor( attr ) );
|
|
|
|
if ( attr.mIsConstant )
|
|
mpConstIdx->AddSection( pSection, true );
|
|
else
|
|
if ( !attr.IsInClass() )
|
|
{
|
|
if ( CheckIfUncommented( attr, *mpGlobalVarsIdx ) )
|
|
return;
|
|
mpGlobalVarsIdx->AddSection( pSection, true );
|
|
}
|
|
else
|
|
AddToCurrentClass( pSection, attr, "Attributes" );
|
|
}
|
|
|
|
void RipperDocGen::VisitOperation( spOperation& op )
|
|
{
|
|
wxString body;
|
|
|
|
AppendHighlightedSource( body, op.GetFullName(m_Tags) );
|
|
|
|
AppendComments( op, body );
|
|
|
|
ScriptSection* pSection =
|
|
new ScriptSection( GetScopedName( op ), body,
|
|
&mSubContentTempl,
|
|
GetRefTemplFor( op ) );
|
|
|
|
if ( !op.IsInClass() )
|
|
{
|
|
if ( CheckIfUncommented( op, *mpGlobalFuncIdx ) )
|
|
return;
|
|
|
|
mpGlobalFuncIdx->AddSection( pSection, 1 );
|
|
}
|
|
else
|
|
AddToCurrentClass( pSection, op, "Operations" );
|
|
}
|
|
|
|
bool RipperDocGen::OnSaveDocument( ScriptStream& WXUNUSED(stm) )
|
|
{
|
|
LinkSuperClassRefs();
|
|
|
|
// FOR NOW:: doesn't work yet
|
|
//mpTopIdx->RemoveEmptySections();
|
|
|
|
return 1; // saving can proceed now
|
|
}
|
|
|