HelpGen is a prototype of the tool for automatic generation of the .tex files
for wxWindows documentation from C++ headers git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1347 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
515
utils/HelpGen/src/HelpGen.cpp
Normal file
515
utils/HelpGen/src/HelpGen.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: HelpGen.cpp
|
||||
// Purpose: Main program file for HelpGen
|
||||
// Author: Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// Modified by:
|
||||
// Created: 06/01/99
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1999 VZ
|
||||
// Licence: GPL
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
TODO (+ means fixed)
|
||||
|
||||
(i) small fixes in the current version
|
||||
|
||||
+1. Quote special TeX characters like '&' and '_' (=> derive from wxFile)
|
||||
2. Document typedefs
|
||||
3. Document global variables
|
||||
4. Document #defines
|
||||
|
||||
(ii) plans for version 2
|
||||
1. Use wxTextFile for direct file access to avoid one scan method problems
|
||||
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
// declarations
|
||||
// =============================================================================
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// headers
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// wxWindows
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/string.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/file.h>
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
// C++ parsing classes
|
||||
#include "cjparser.h"
|
||||
|
||||
// standard headers
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// return the label for the given function name
|
||||
static wxString MakeLabel(const char *classname, const char *funcname);
|
||||
|
||||
// quotes special TeX characters in place
|
||||
static void TeXFilter(wxString* str);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// private classes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// add a function which sanitazes the string before writing it to the file
|
||||
class wxTeXFile : public wxFile
|
||||
{
|
||||
public:
|
||||
wxTeXFile() : wxFile() { }
|
||||
|
||||
bool WriteTeX(const wxString& s)
|
||||
{
|
||||
wxString t(s);
|
||||
TeXFilter(&t);
|
||||
|
||||
return wxFile::Write(t);
|
||||
}
|
||||
};
|
||||
|
||||
class HelpGenVisitor : public spVisitor
|
||||
{
|
||||
public:
|
||||
// ctor
|
||||
HelpGenVisitor();
|
||||
|
||||
virtual void VisitFile( spFile& fl );
|
||||
virtual void VisitClass( spClass& cl );
|
||||
virtual void VisitEnumeration( spEnumeration& en );
|
||||
virtual void VisitTypeDef( spTypeDef& td );
|
||||
virtual void VisitAttribute( spAttribute& attr );
|
||||
virtual void VisitOperation( spOperation& op );
|
||||
virtual void VisitParameter( spParameter& param );
|
||||
|
||||
void EndVisit();
|
||||
|
||||
// shut up g++ warning (ain't it stupid?)
|
||||
virtual ~HelpGenVisitor() { }
|
||||
|
||||
protected:
|
||||
// (re)initialize the state
|
||||
void Reset();
|
||||
|
||||
// insert documentation for enums/typedefs coming immediately before the
|
||||
// class declaration into the class documentation
|
||||
void InsertTypedefDocs();
|
||||
void InsertEnumDocs();
|
||||
|
||||
// write the headers for corresponding sections (only once)
|
||||
void InsertDataStructuresHeader();
|
||||
void InsertMethodsHeader();
|
||||
|
||||
// terminate the function documentation if it was started
|
||||
void CloseFunction();
|
||||
|
||||
wxTeXFile m_file; // file we're writing to now
|
||||
|
||||
// state variables
|
||||
bool m_inClass, // TRUE after file successfully opened
|
||||
m_inTypesSection, // enums & typedefs go there
|
||||
m_inMethodSection, // functions go here
|
||||
m_isFirstParam, // first parameter of current function?
|
||||
m_inFunction; // we're parsing a function declaration
|
||||
|
||||
// holders for "saved" documentation
|
||||
wxString m_textStoredEnums,
|
||||
m_textStoredTypedefs,
|
||||
m_textStoredFunctionComment;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// =============================================================================
|
||||
// implementation
|
||||
// =============================================================================
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if ( argc < 2 ) {
|
||||
wxLogError("usage: %s <header files...>\n", argv[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// be verbose
|
||||
wxLog::GetActiveTarget()->SetVerbose();
|
||||
|
||||
// create a parser object and a visitor derivation
|
||||
CJSourceParser parser;
|
||||
HelpGenVisitor visitor;
|
||||
|
||||
// parse all files
|
||||
for ( int i = 1; i < argc; i++ ) {
|
||||
spContext *ctxTop = parser.ParseFile(argv[i]);
|
||||
if ( !ctxTop ) {
|
||||
wxLogWarning("File '%s' couldn't be processed.", argv[i]);
|
||||
}
|
||||
else {
|
||||
((spFile *)ctxTop)->mFileName = argv[i];
|
||||
visitor.VisitAll(*ctxTop);
|
||||
visitor.EndVisit();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// HelpGenVisitor implementation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
HelpGenVisitor::HelpGenVisitor()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void HelpGenVisitor::Reset()
|
||||
{
|
||||
m_inClass =
|
||||
m_inFunction =
|
||||
m_inTypesSection =
|
||||
m_inMethodSection = false;
|
||||
}
|
||||
|
||||
void HelpGenVisitor::InsertTypedefDocs()
|
||||
{
|
||||
m_file.WriteTeX(m_textStoredTypedefs);
|
||||
m_textStoredTypedefs.Empty();
|
||||
}
|
||||
|
||||
void HelpGenVisitor::InsertEnumDocs()
|
||||
{
|
||||
m_file.WriteTeX(m_textStoredEnums);
|
||||
m_textStoredEnums.Empty();
|
||||
}
|
||||
|
||||
void HelpGenVisitor::InsertDataStructuresHeader()
|
||||
{
|
||||
if ( !m_inTypesSection ) {
|
||||
m_inTypesSection = true;
|
||||
|
||||
m_file.WriteTeX("\\wxheading{Data structures}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
void HelpGenVisitor::InsertMethodsHeader()
|
||||
{
|
||||
if ( !m_inMethodSection ) {
|
||||
m_inMethodSection = true;
|
||||
|
||||
m_file.WriteTeX( "\\latexignore{\\rtfignore{\\wxheading{Members}}}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
void HelpGenVisitor::CloseFunction()
|
||||
{
|
||||
if ( m_inFunction ) {
|
||||
m_inFunction = false;
|
||||
|
||||
wxString totalText;
|
||||
if ( m_isFirstParam ) {
|
||||
// no params found
|
||||
totalText << "\\void";
|
||||
}
|
||||
|
||||
totalText << "}\n\n";
|
||||
|
||||
if ( !m_textStoredFunctionComment.IsEmpty() )
|
||||
totalText << m_textStoredFunctionComment << '\n';
|
||||
|
||||
m_file.WriteTeX(totalText);
|
||||
}
|
||||
}
|
||||
|
||||
void HelpGenVisitor::EndVisit()
|
||||
{
|
||||
CloseFunction();
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitFile( spFile& file )
|
||||
{
|
||||
wxLogInfo("Parsing classes from file '%s'...", file.mFileName.c_str());
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitClass( spClass& cl )
|
||||
{
|
||||
wxString name = cl.GetName();
|
||||
|
||||
// the file name is built from the class name by removing the leading "wx"
|
||||
// if any and converting it to the lower case
|
||||
wxString filename = name;
|
||||
if ( filename(0, 2) == "wx" ) {
|
||||
filename.erase(0, 2);
|
||||
}
|
||||
|
||||
filename.MakeLower();
|
||||
filename += ".tex";
|
||||
|
||||
m_inClass = m_file.Open(filename, wxFile::write);
|
||||
if ( !m_inClass ) {
|
||||
wxLogError("Can't generate documentation for the class '%s'.",
|
||||
name.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_inMethodSection =
|
||||
m_inTypesSection = false;
|
||||
|
||||
wxLogInfo("Created new file '%s' for class '%s'.",
|
||||
filename.c_str(), name.c_str());
|
||||
|
||||
// the entire text we're writing to file
|
||||
wxString totalText;
|
||||
|
||||
// write out the header
|
||||
{
|
||||
time_t timeNow = time(NULL);
|
||||
wxString header;
|
||||
header.Printf("% automatically generated by HelpGen from %s at "
|
||||
"%s" // no '\n' here because ctime() inserts one
|
||||
"\\section{\\class{%s}}\\label{%s}\n",
|
||||
filename.c_str(), ctime(&timeNow),
|
||||
name.c_str(), wxString(name).MakeLower().c_str());
|
||||
|
||||
totalText << header << '\n';
|
||||
}
|
||||
|
||||
// the comment before the class generally explains what is it for so put it
|
||||
// in place of the class description
|
||||
if ( cl.HasComments() ) {
|
||||
wxString comment;
|
||||
const MCommentListT& comments = cl.GetCommentList();
|
||||
for ( MCommentListT::const_iterator i = comments.begin();
|
||||
i != comments.end();
|
||||
i++ ) {
|
||||
comment << (*i)->GetText();
|
||||
}
|
||||
|
||||
totalText << '\n' << comment << '\n';
|
||||
}
|
||||
|
||||
// derived from section
|
||||
wxString derived = "\\wxheading{Derived from}\n\n";
|
||||
|
||||
const StrListT& baseClasses = cl.mSuperClassNames;
|
||||
if ( baseClasses.size() == 0 ) {
|
||||
derived << "No base class";
|
||||
}
|
||||
else {
|
||||
bool first = true;
|
||||
for ( StrListT::const_iterator i = baseClasses.begin();
|
||||
i != baseClasses.end();
|
||||
i++ ) {
|
||||
if ( !first ) {
|
||||
// separate from the previous one
|
||||
derived << "\\\\\n";
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
wxString baseclass = *i;
|
||||
derived << "\\helpref{" << baseclass << "}"
|
||||
"{ " << baseclass.MakeLower() << "}";
|
||||
}
|
||||
}
|
||||
totalText << derived << "\n\n";
|
||||
|
||||
// write all this to file
|
||||
m_file.WriteTeX(totalText);
|
||||
|
||||
// if there were any enums/typedefs before, insert their documentation now
|
||||
InsertDataStructuresHeader();
|
||||
InsertTypedefDocs();
|
||||
InsertEnumDocs();
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitEnumeration( spEnumeration& en )
|
||||
{
|
||||
CloseFunction();
|
||||
|
||||
if ( m_inMethodSection ) {
|
||||
// FIXME that's a bug, but tell the user aboit it nevertheless... we
|
||||
// should be smart enough to process even the enums which come after the
|
||||
// functions
|
||||
wxLogWarning("enum '%s' ignored, please put it before the class "
|
||||
"methods.", en.GetName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// simply copy the enum text in the docs
|
||||
wxString enumeration;
|
||||
enumeration << "{\\small \\begin{verbatim}\n"
|
||||
<< en.mEnumContent
|
||||
<< "\n\\end{verbatim}}\n";
|
||||
|
||||
// remember for later use if we're not inside a class yet
|
||||
if ( !m_inClass ) {
|
||||
if ( !m_textStoredEnums.IsEmpty() ) {
|
||||
m_textStoredEnums << '\n';
|
||||
}
|
||||
|
||||
m_textStoredEnums << enumeration;
|
||||
}
|
||||
else {
|
||||
// write the header for this section if not done yet
|
||||
InsertDataStructuresHeader();
|
||||
|
||||
enumeration << '\n';
|
||||
m_file.WriteTeX(enumeration);
|
||||
}
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitTypeDef( spTypeDef& td )
|
||||
{
|
||||
CloseFunction();
|
||||
|
||||
wxFAIL_MSG("don't know how to document typedefs yet");
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitAttribute( spAttribute& attr )
|
||||
{
|
||||
CloseFunction();
|
||||
|
||||
// only document the public member variables
|
||||
if ( !m_inClass || !attr.IsPublic() )
|
||||
return;
|
||||
|
||||
wxFAIL_MSG("don't know how to document member vars yet");
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitOperation( spOperation& op )
|
||||
{
|
||||
CloseFunction();
|
||||
|
||||
if ( !m_inClass || !op.IsInClass() ) {
|
||||
// FIXME that's a bug too
|
||||
wxLogWarning("skipped global function '%s'.", op.GetName().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( op.mVisibility == SP_VIS_PRIVATE ) {
|
||||
// FIXME should we document protected functions?
|
||||
return;
|
||||
}
|
||||
|
||||
InsertMethodsHeader();
|
||||
|
||||
// save state info
|
||||
m_inFunction =
|
||||
m_isFirstParam = true;
|
||||
|
||||
m_textStoredFunctionComment.Empty();
|
||||
const MCommentListT& comments = op.GetCommentList();
|
||||
for ( MCommentListT::const_iterator i = comments.begin();
|
||||
i != comments.end();
|
||||
i++ ) {
|
||||
m_textStoredFunctionComment << (*i)->GetText();
|
||||
}
|
||||
|
||||
// start function documentation
|
||||
wxString totalText;
|
||||
const char *funcname = op.GetName().c_str();
|
||||
const char *classname = op.GetClass().GetName().c_str();
|
||||
|
||||
// check for the special case of dtor
|
||||
wxString dtor;
|
||||
if ( (funcname[0] == '~') && (strcmp(funcname + 1, classname) == 0) ) {
|
||||
dtor.Printf("\\destruct{%s}", classname);
|
||||
funcname = dtor;
|
||||
}
|
||||
|
||||
totalText.Printf("\\membersection{%s::%s}\\label{%s}\n"
|
||||
"\\%sfunc{%s}{%s}{",
|
||||
classname, funcname,
|
||||
MakeLabel(classname, funcname).c_str(),
|
||||
op.mIsConstant ? "const" : "",
|
||||
op.mRetType.c_str(),
|
||||
funcname);
|
||||
|
||||
m_file.WriteTeX(totalText);
|
||||
}
|
||||
|
||||
void HelpGenVisitor::VisitParameter( spParameter& param )
|
||||
{
|
||||
if ( !m_inFunction )
|
||||
return;
|
||||
|
||||
wxString totalText;
|
||||
if ( m_isFirstParam ) {
|
||||
m_isFirstParam = false;
|
||||
}
|
||||
else {
|
||||
totalText << ", ";
|
||||
}
|
||||
|
||||
totalText << "\\param{" << param.mType << " }{" << param.GetName();
|
||||
wxString defvalue = param.mInitVal;
|
||||
if ( !defvalue.IsEmpty() ) {
|
||||
totalText << " = " << defvalue;
|
||||
}
|
||||
|
||||
totalText << '}';
|
||||
|
||||
m_file.WriteTeX(totalText);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// global function implementation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static wxString MakeLabel(const char *classname, const char *funcname)
|
||||
{
|
||||
wxString label(classname);
|
||||
if ( funcname[0] == '\\' ) {
|
||||
// we may have some special TeX macro - so far only \destruct exists,
|
||||
// but may be later others will be added
|
||||
static const char *macros[] = { "destruct" };
|
||||
static const char *replacement[] = { "dtor" };
|
||||
|
||||
size_t n;
|
||||
for ( n = 0; n < WXSIZEOF(macros); n++ ) {
|
||||
if ( strncmp(funcname + 1, macros[n], strlen(macros[n])) == 0 ) {
|
||||
// found
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( n == WXSIZEOF(macros) ) {
|
||||
wxLogWarning("unknown function name '%s' - leaving as is.",
|
||||
funcname);
|
||||
}
|
||||
else {
|
||||
funcname = replacement[n];
|
||||
}
|
||||
}
|
||||
|
||||
label << funcname;
|
||||
|
||||
label.MakeLower();
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
static void TeXFilter(wxString* str)
|
||||
{
|
||||
// FIXME may be done much more quickly
|
||||
str->Replace("&", "\\&");
|
||||
str->Replace("_", "\\_");
|
||||
}
|
||||
|
||||
/* vi: set tw=80 et ts=4 sw=4: */
|
2173
utils/HelpGen/src/cjparser.cpp
Normal file
2173
utils/HelpGen/src/cjparser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
568
utils/HelpGen/src/docripper.cpp
Normal file
568
utils/HelpGen/src/docripper.cpp
Normal file
@@ -0,0 +1,568 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// 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"
|
||||
|
||||
#include <iostream.h>
|
||||
|
||||
// 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" , "", &mTopTempl , 0 );
|
||||
mpClassIdx = new ScriptSection( "Classes Reference" , "", &mContentIdxTempl, &mRefTempl );
|
||||
mpEnumIdx = new ScriptSection( "Enumerations Reference" , "", &mContentIdxTempl, &mRefTempl );
|
||||
mpTypeDefIdx = new ScriptSection( "Type Definitions Reference" , "", &mContentIdxTempl, &mRefTempl );
|
||||
mpMacroIdx = new ScriptSection( "Macros Reference" , "", &mContentIdxTempl, &mRefTempl );
|
||||
mpGlobalVarsIdx = new ScriptSection( "Global Variables Reference" , "", &mContentIdxTempl, &mRefTempl );
|
||||
mpGlobalFuncIdx = new ScriptSection( "Global Functions Reference", "", &mContentIdxTempl, &mRefTempl );
|
||||
mpConstIdx = new ScriptSection( "Constants Reference" , "", &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
|
||||
mTags = 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, string& str )
|
||||
{
|
||||
if ( !fromContext.HasComments() ) return;
|
||||
|
||||
size_t start = str.length();
|
||||
|
||||
str += mTags[TAG_BOLD].end;
|
||||
str += mTags[TAG_PARAGRAPH].start;
|
||||
|
||||
MCommentListT& lst = fromContext.GetCommentList();
|
||||
|
||||
for( size_t i = 0; i != lst.size(); ++i )
|
||||
{
|
||||
|
||||
if ( i != 0 )
|
||||
|
||||
if ( lst[i]->StartsParagraph() )
|
||||
{
|
||||
str += mTags[TAG_PARAGRAPH].start;
|
||||
}
|
||||
|
||||
str += lst[i]->mText;
|
||||
}
|
||||
|
||||
// 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, "<p>" ); // FIXME:: quick-hack
|
||||
len += 3;
|
||||
}
|
||||
}
|
||||
|
||||
str[n] = ' ';
|
||||
}
|
||||
|
||||
str += mTags[TAG_PARAGRAPH].end;
|
||||
}
|
||||
|
||||
void RipperDocGen::AppendMulitilineStr( string& st, string& mlStr )
|
||||
{
|
||||
st = mTags[TAG_FIXED_FONT].start;
|
||||
st += mlStr;
|
||||
st += mTags[TAG_FIXED_FONT].end;
|
||||
}
|
||||
|
||||
void RipperDocGen::AppendHighlightedSource( string& st, string source )
|
||||
{
|
||||
// FIXME:: below should not be fixed :)
|
||||
char buf[1024*32];
|
||||
|
||||
// DBG:::
|
||||
ASSERT( source.length() + 1 < sizeof(buf) );
|
||||
|
||||
strcpy( buf, source.c_str() );
|
||||
|
||||
// highlight things
|
||||
mSrcPainter.Init();
|
||||
mSrcPainter.ProcessSource( buf, strlen(buf) );
|
||||
mSrcPainter.GetResultString( st, mTags );
|
||||
}
|
||||
|
||||
bool RipperDocGen::CheckIfUncommented( spContext& ctx, ScriptSection& toSect )
|
||||
{
|
||||
if ( ctx.HasComments() ) return 0;
|
||||
|
||||
toSect.AddReference(
|
||||
new ScriptSection( GetScopedName( ctx ), "", 0, &mDeadRefTempl )
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ScriptTemplate* RipperDocGen::GetRefTemplFor( spContext& ctx )
|
||||
{
|
||||
if ( ctx.HasComments() )
|
||||
|
||||
return &mRefTempl;
|
||||
else
|
||||
return &mDeadRefTempl;
|
||||
}
|
||||
|
||||
string RipperDocGen::GetScopedName( spContext& ofCtx )
|
||||
{
|
||||
if ( ofCtx.IsInFile() ) return ofCtx.GetName();
|
||||
else
|
||||
return ofCtx.GetOutterContext()->GetName() +
|
||||
"::" + ofCtx.GetName();
|
||||
}
|
||||
|
||||
void RipperDocGen::AddToCurrentClass( ScriptSection* pSection, spContext& ctx,
|
||||
const char* subSectionName )
|
||||
{
|
||||
string 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.mSuperClassNames.size(); ++n )
|
||||
{
|
||||
string& superClName = cl.mSuperClassNames[n];
|
||||
|
||||
spClass* pFound = NULL;
|
||||
|
||||
string* name;
|
||||
|
||||
for( size_t k = 0; k != clLst.size(); ++k )
|
||||
{
|
||||
name = &clLst[k]->GetName();
|
||||
|
||||
if ( clLst[k]->GetName() == superClName )
|
||||
{
|
||||
pFound = (spClass*)clLst[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !pFound )
|
||||
{
|
||||
ScriptSection* pNotFound =
|
||||
new ScriptSection( superClName, "", 0, &mDeadRefTempl );
|
||||
|
||||
pSuperSect->AddReference( pNotFound );
|
||||
}
|
||||
else
|
||||
if ( pFound->GetUserData() )
|
||||
|
||||
pSuperSect->AddReference(
|
||||
(ScriptSection*)pFound->GetUserData() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RipperDocGen::ProcessFile( const char* sourceFile )
|
||||
{
|
||||
cout << "Processing file " << sourceFile << "..." << endl;
|
||||
|
||||
spFile* pCtx = mpParser->ParseFile( sourceFile );
|
||||
|
||||
if ( pCtx == NULL )
|
||||
{
|
||||
cout << "Cannot open file " << sourceFile << ", skipped..." << 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() == "" ) return;
|
||||
|
||||
if ( CheckIfUncommented( en, *mpEnumIdx ) )
|
||||
return;
|
||||
|
||||
string body;
|
||||
body += mTags[TAG_BOLD].start;
|
||||
|
||||
AppendMulitilineStr( body, en.mEnumContent );
|
||||
|
||||
body += mTags[TAG_BOLD].end;
|
||||
|
||||
string 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;
|
||||
|
||||
string body;
|
||||
body += mTags[TAG_BOLD].start;
|
||||
body += "typdef ";
|
||||
body += mTags[TAG_BOLD].end;
|
||||
|
||||
AppendMulitilineStr( body, td.mOriginalType );
|
||||
body += td.mOriginalType;
|
||||
body += ' ';
|
||||
|
||||
body += mTags[TAG_BOLD].start;
|
||||
body += td.GetName();
|
||||
body += mTags[TAG_BOLD].end;
|
||||
|
||||
string 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;
|
||||
|
||||
string body;
|
||||
body += mTags[TAG_FIXED_FONT].start;
|
||||
|
||||
string coloredLine = pd.mLine;
|
||||
AppendHighlightedSource( coloredLine, pd.mLine );
|
||||
|
||||
AppendMulitilineStr( body, coloredLine );
|
||||
|
||||
body += mTags[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;
|
||||
}
|
||||
|
||||
string 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" ,"", &mOutLine1Templ,0, 1 );
|
||||
|
||||
ScriptSection* pPublic = new ScriptSection( "Public members" ,"", &mOutLineTempl,0, 1 );
|
||||
ScriptSection* pProtected = new ScriptSection( "Protected members" ,"", &mOutLineTempl,0, 1 );
|
||||
ScriptSection* pPrivate = new ScriptSection( "Private members" ,"", &mOutLineTempl,0, 1 );
|
||||
|
||||
pPublic->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
|
||||
pPublic->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
|
||||
|
||||
|
||||
pProtected->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
|
||||
pProtected->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
|
||||
|
||||
|
||||
pPrivate->AddSection( new ScriptSection( "Operations", "", &mOutLine1Templ, 0, 1 ) );
|
||||
pPrivate->AddSection( new ScriptSection( "Attributes", "", &mOutLine1Templ, 0, 1 ) );
|
||||
|
||||
mpCurClassSect->AddSection( pSuper );
|
||||
mpCurClassSect->AddSection( pPublic );
|
||||
mpCurClassSect->AddSection( pProtected );
|
||||
mpCurClassSect->AddSection( pPrivate );
|
||||
|
||||
mpClassIdx->AddSection( mpCurClassSect, TRUE );
|
||||
}
|
||||
|
||||
void RipperDocGen::VisitAttribute( spAttribute& attr )
|
||||
{
|
||||
string body;
|
||||
body += mTags[TAG_BOLD].start;
|
||||
body += attr.mType;
|
||||
body += mTags[TAG_BOLD].end;
|
||||
|
||||
body += mTags[TAG_ITALIC].start;
|
||||
body += ' ';
|
||||
body += attr.GetName();
|
||||
body += mTags[TAG_ITALIC].end;
|
||||
|
||||
string 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 )
|
||||
{
|
||||
string body;
|
||||
|
||||
AppendHighlightedSource( body, op.GetFullName(mTags) );
|
||||
|
||||
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& stm )
|
||||
{
|
||||
LinkSuperClassRefs();
|
||||
|
||||
// FOR NOW:: doesn't work yet
|
||||
//mpTopIdx->RemoveEmptySections();
|
||||
|
||||
return 1; // saving can proceed now
|
||||
}
|
||||
|
295
utils/HelpGen/src/ifcontext.cpp
Normal file
295
utils/HelpGen/src/ifcontext.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 27/12/98
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Aleskandars Gluchovas
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "ifcontext.h"
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// 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 <malloc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ifcontext.h"
|
||||
|
||||
/***** Implementation for class spInterFileContext *****/
|
||||
|
||||
size_t spInterFileContext::GetFileNo( const string& fname )
|
||||
{
|
||||
for( size_t i = 0; i != mFiles.size(); ++i )
|
||||
|
||||
if ( fname == mFiles[i] ) return i;
|
||||
|
||||
wxASSERT(0); // DBG::
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t spInterFileContext::GetFileNoOfContext( spContext& ctx )
|
||||
{
|
||||
spContext* pCtx = ctx.GetEnclosingContext( SP_CTX_FILE );
|
||||
|
||||
// DBG:: outer-file context should be present
|
||||
wxASSERT( pCtx && pCtx->GetType() == SP_CTX_FILE );
|
||||
|
||||
return GetFileNo( ((spFile*)pCtx)->mFileName );
|
||||
}
|
||||
|
||||
/*** public interface ***/
|
||||
|
||||
spInterFileContext::spInterFileContext()
|
||||
{}
|
||||
|
||||
spInterFileContext::~spInterFileContext()
|
||||
{}
|
||||
|
||||
void spInterFileContext::AddFile( const string& fname, const string& content )
|
||||
{
|
||||
mFiles.push_back( fname );
|
||||
mContents.push_back( content );
|
||||
}
|
||||
|
||||
void spInterFileContext::RemoveContext( spContext& ctx )
|
||||
{
|
||||
wxASSERT( ctx.PositionIsKnown() ); // DBG:: should be checked by-user code
|
||||
|
||||
size_t fNo = GetFileNoOfContext( ctx );
|
||||
|
||||
mDeletionMarks.push_back( spBookmark( ctx.mSrcOffset, ctx.mContextLength, fNo ) );
|
||||
}
|
||||
|
||||
void spInterFileContext::InsertBookmarkSorted( BookmarkListT& lst, spBookmark& mark )
|
||||
{
|
||||
for( size_t i = 0; i != lst.size(); ++i )
|
||||
|
||||
if ( lst[i].mFrom > mark.mFrom )
|
||||
{
|
||||
lst.insert( &lst[i], mark );
|
||||
return;
|
||||
}
|
||||
|
||||
lst.push_back( mark );
|
||||
}
|
||||
|
||||
void spInterFileContext::DoAppendSourceFragment( string& source,
|
||||
string& result,
|
||||
size_t pos, size_t len )
|
||||
{
|
||||
mFiltered.erase( mFiltered.begin(), mFiltered.end() );
|
||||
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i != mDeletionMarks.size(); ++i )
|
||||
{
|
||||
spBookmark& mark = mDeletionMarks[i];
|
||||
|
||||
if ( mark.mFileNo == mCurFileNo &&
|
||||
mark.mFrom >= pos && mark.mFrom < pos + len )
|
||||
|
||||
InsertBookmarkSorted( mFiltered, mark );
|
||||
}
|
||||
|
||||
size_t cur = pos;
|
||||
|
||||
for( i = 0; i != mFiltered.size(); ++ i )
|
||||
{
|
||||
spBookmark& mark = mFiltered[i];
|
||||
|
||||
result.append( source, cur, ( (size_t)mark.mFrom - cur ) );
|
||||
|
||||
cur = size_t( mark.mFrom + mark.mLen );
|
||||
|
||||
if ( cur >= pos + len ) // check if we've overstepped the current source-fragment
|
||||
{
|
||||
wxASSERT(0); // DBG:: with current imp. this should not happen
|
||||
|
||||
cur = pos + len; break;
|
||||
}
|
||||
}
|
||||
|
||||
result.append( source, cur, ( pos + len ) - cur );
|
||||
}
|
||||
|
||||
void spInterFileContext::GenerateContextBody( spContext& ctx,
|
||||
string& source,
|
||||
string& result,
|
||||
size_t& lastSavedPos,
|
||||
size_t& lastKnownPos )
|
||||
{
|
||||
if ( ctx.PositionIsKnown() )
|
||||
|
||||
lastKnownPos = ctx.mSrcOffset;
|
||||
|
||||
if ( ctx.IsVirtualContext() )
|
||||
{
|
||||
// add fragment accumulated before this context
|
||||
|
||||
DoAppendSourceFragment( source, result,
|
||||
size_t(lastSavedPos),
|
||||
size_t(lastKnownPos - lastSavedPos) );
|
||||
|
||||
// add context body
|
||||
|
||||
result += ctx.GetVirtualContextBody();
|
||||
|
||||
lastSavedPos = lastKnownPos;
|
||||
|
||||
if ( ctx.PositionIsKnown() )
|
||||
{
|
||||
if ( ctx.VitualContextHasChildren() )
|
||||
{
|
||||
lastKnownPos = ctx.mSrcOffset + ctx.mHeaderLength;
|
||||
|
||||
lastSavedPos = lastKnownPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
|
||||
|
||||
lastSavedPos = lastKnownPos;
|
||||
|
||||
return; // have not children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MMemberListT& lst = ctx.GetMembers();
|
||||
|
||||
for( size_t i = 0; i != lst.size(); ++i )
|
||||
|
||||
GenerateContextBody( *lst[i], source, result, lastSavedPos, lastKnownPos );
|
||||
|
||||
if ( ctx.IsVirtualContext() )
|
||||
{
|
||||
if ( ctx.VitualContextHasChildren() &&
|
||||
|
||||
ctx.GetFooterOfVirtualContextBody() != "" )
|
||||
{
|
||||
// append the reminder space after children of the context
|
||||
|
||||
DoAppendSourceFragment( result, source,
|
||||
size_t(lastSavedPos),
|
||||
size_t(lastKnownPos - lastSavedPos) );
|
||||
|
||||
// add footer
|
||||
result += ctx.GetFooterOfVirtualContextBody();
|
||||
|
||||
lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
|
||||
|
||||
lastSavedPos = lastKnownPos;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ctx.PositionIsKnown() )
|
||||
|
||||
lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
|
||||
}
|
||||
|
||||
void spInterFileContext::GenrateContents()
|
||||
{
|
||||
MMemberListT& lst = GetMembers();
|
||||
|
||||
for( size_t f = 0; f != lst.size(); ++f )
|
||||
{
|
||||
string& fname = ((spFile*)lst[f])->mFileName;
|
||||
|
||||
size_t fileNo = GetFileNo( fname );
|
||||
|
||||
string& source = mContents[ fileNo ];
|
||||
|
||||
string result;
|
||||
|
||||
size_t lastKnownPos = 0, // the begining of the file is always "known"
|
||||
lastSavedPos = 0;
|
||||
|
||||
mCurFileNo = fileNo;
|
||||
|
||||
GenerateContextBody( *lst[f], source, result, lastSavedPos, lastKnownPos );
|
||||
|
||||
// the end of file is always known
|
||||
|
||||
lastKnownPos = mContents[ fileNo ].length();
|
||||
|
||||
// append the reminder
|
||||
|
||||
DoAppendSourceFragment( source, result,
|
||||
size_t(lastSavedPos),
|
||||
size_t(lastKnownPos - lastSavedPos) );
|
||||
|
||||
// replace original contnet with newly generated one
|
||||
|
||||
mContents[ fileNo ] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void spInterFileContext::ParseContents( SourceParserPlugin* pPlugin )
|
||||
{
|
||||
mDeletionMarks.erase( mDeletionMarks.begin(), mDeletionMarks.end() );
|
||||
|
||||
RemoveChildren(); // clean up top-level context
|
||||
|
||||
mParser.SetPlugin( pPlugin );
|
||||
|
||||
for( size_t i = 0; i != mFiles.size(); ++i )
|
||||
{
|
||||
char* s = (char*)(mContents[i].c_str());
|
||||
|
||||
spFile* pFCtx = mParser.Parse( s, s + mContents[i].length() );
|
||||
|
||||
pFCtx->mFileName = mFiles[i];
|
||||
|
||||
AddMember( pFCtx );
|
||||
}
|
||||
}
|
||||
|
||||
void spInterFileContext::WriteToFiles()
|
||||
{
|
||||
for( size_t i = 0; i != mFiles.size(); ++i )
|
||||
{
|
||||
FILE* fp = fopen( mFiles[i].c_str(), "w+t" );
|
||||
|
||||
if ( int(fp) > 0 )
|
||||
{
|
||||
fwrite( mContents[i].c_str(), sizeof(char), mContents[i].length(), fp );
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string spInterFileContext::GetBody( spContext* pCtx )
|
||||
{
|
||||
wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
|
||||
|
||||
string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
|
||||
|
||||
return string( source.c_str() + pCtx->mSrcOffset, pCtx->mContextLength );
|
||||
}
|
||||
|
||||
string spInterFileContext::GetHeader( spContext* pCtx )
|
||||
{
|
||||
wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
|
||||
|
||||
wxASSERT( pCtx->mHeaderLength != -1 ); // DBG:: -/-
|
||||
|
||||
string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
|
||||
|
||||
return string( source.c_str() + pCtx->mSrcOffset, pCtx->mHeaderLength );
|
||||
}
|
46
utils/HelpGen/src/markup.cpp
Normal file
46
utils/HelpGen/src/markup.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// 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 "markup.h"
|
||||
|
||||
static TagStructT htmlTags[] =
|
||||
{
|
||||
{ "<b>","</b>" }, // 0
|
||||
{ "<i>","</i>" }, // 1
|
||||
{ "<pre>","</pre>" }, // 2
|
||||
{ "<font color=\"#000000\">","</font>" }, // 3
|
||||
{ "<font color=\"#8F0000\">","</font>" }, // 4
|
||||
{ "<font color=\"#008F00\">","</font>" }, // 5
|
||||
{ "<font color=\"#0000CF\">","</font>" }, // 6
|
||||
{ "<p>","</p>" }, // 7
|
||||
{ "<br>","" }, // 8
|
||||
{ "<h1>","</h1>" }, // 9
|
||||
{ "<h2>","</h2>" }, // 10
|
||||
{ "<h3>","</h3>" }, // 11
|
||||
{ "<ul>","</ul>" }, // 12
|
||||
{ "<li>","</li>" }, // 13
|
||||
};
|
||||
|
||||
MarkupTagsT get_HTML_markup_tags()
|
||||
{
|
||||
return htmlTags;
|
||||
}
|
157
utils/HelpGen/src/ripper_main.cpp
Normal file
157
utils/HelpGen/src/ripper_main.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// 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
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "markup.h" // get_HTML_markup_tags() will be used
|
||||
|
||||
#include "docripper.h"
|
||||
#include "cjparser.h" // C++/Java will be parsed here
|
||||
|
||||
/***** Main funciton *****/
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// NOTE:: under Windows this generator parses all .h files
|
||||
// int the current directory
|
||||
|
||||
#include "direct.h"
|
||||
|
||||
|
||||
void main(int argc, char** argv)
|
||||
{
|
||||
cout << "C++/JAVA Source Documentation Generator (\"wxDocRipper\")" << endl
|
||||
<< "(C) 1998, Aleksandras Gluchovas (mailto:alex@soften.ktu.lt)"
|
||||
<< endl << endl;
|
||||
|
||||
|
||||
RipperDocGen gen;
|
||||
|
||||
// set up target script
|
||||
gen.SetScriptMarkupTags( get_HTML_markup_tags() );
|
||||
|
||||
// setup source langauge
|
||||
CJSourceParser* pParser = new CJSourceParser();
|
||||
|
||||
gen.Init( pParser );
|
||||
|
||||
// read process all files in the current directory
|
||||
|
||||
struct _finddata_t c_file; // NT-specific?
|
||||
long hFile;
|
||||
|
||||
hFile = _findfirst( "*.h", &c_file );
|
||||
int total = 0;
|
||||
|
||||
while( hFile != -1L )
|
||||
{
|
||||
gen.ProcessFile( c_file.name );
|
||||
++total;
|
||||
|
||||
if ( _findnext( hFile, &c_file ) == -1L )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( total )
|
||||
{
|
||||
cout << endl
|
||||
<< "*** storing source documenation into ./srcref.html ***"
|
||||
<< endl << endl;
|
||||
|
||||
if ( !gen.SaveDocument( "srcref.html" ) )
|
||||
|
||||
cout << "\nERROR: document cannot be saved" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "\nno .h files found in this directory - You must be running Windows now :-)"
|
||||
<< endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
printf( "\nTotal %d file(s) processed, done.\n", total );
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// NOTE:: on platfroms other then Windows this generator parses all files
|
||||
// given from the command line
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cout << "C++/JAVA Source Documentation Generator (\"wxDocRipper\")" << endl
|
||||
<< "(C) 1998, Aleksandras Gluchovas (mailto:alex@soften.ktu.lt)"
|
||||
<< endl << endl;
|
||||
|
||||
if ( argc < 2 )
|
||||
{
|
||||
cout << "Usage: list of files with .h, .hpp, .cpp or .java extentions"
|
||||
<< endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int from = 1, no_dump = 0;
|
||||
|
||||
if ( strcmp( argv[1], "-x" ) == 0 )
|
||||
{
|
||||
from = 2;
|
||||
no_dump = 1;
|
||||
}
|
||||
|
||||
RipperDocGen gen;
|
||||
|
||||
// set up target script
|
||||
gen.SetScriptMarkupTags( get_HTML_markup_tags() );
|
||||
|
||||
// setup source langauge
|
||||
CJSourceParser* pParser = new CJSourceParser();
|
||||
|
||||
gen.Init( pParser );
|
||||
|
||||
for( int i = from; i != argc; ++i )
|
||||
|
||||
gen.ProcessFile( argv[i] );
|
||||
|
||||
if ( !no_dump )
|
||||
{
|
||||
cout << endl
|
||||
<< "*** storing source documenation into ./srcref.html ***"
|
||||
<< endl << endl;
|
||||
|
||||
if ( !gen.SaveDocument( "srcref.html" ) )
|
||||
|
||||
cout << "\nERROR: document cannot be saved" << endl;
|
||||
}
|
||||
|
||||
printf( "\nTotal %d file(s) processed, done.\n", argc-from );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
618
utils/HelpGen/src/scriptbinder.cpp
Normal file
618
utils/HelpGen/src/scriptbinder.cpp
Normal file
@@ -0,0 +1,618 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// 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 <malloc.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <stdio.h> // import sprintf() (for doubles)
|
||||
#include <stdlib.h> // import atoi() (for integers)
|
||||
|
||||
#include "scriptbinder.h"
|
||||
|
||||
// helper functions
|
||||
|
||||
static size_t log2(size_t nr)
|
||||
{
|
||||
size_t tmp = 0;
|
||||
while (nr >= 2 )
|
||||
{
|
||||
nr /= 2;
|
||||
++tmp;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/***** Implementation for class ScriptStream *****/
|
||||
|
||||
ScriptStream::ScriptStream()
|
||||
: mpBuf(0),
|
||||
mSize(0),
|
||||
mCapacity(0)
|
||||
{}
|
||||
|
||||
ScriptStream::~ScriptStream()
|
||||
{
|
||||
if ( mpBuf ) delete mpBuf;
|
||||
}
|
||||
|
||||
void ScriptStream::WriteBytes( const void* srcBuf, size_t count )
|
||||
{
|
||||
if ( !count ) return;
|
||||
|
||||
// increase the capacity if necessary
|
||||
if ( mSize + count > mCapacity )
|
||||
{
|
||||
mCapacity =
|
||||
( 0x2 << (log2( mSize + count ) + 1 ) );
|
||||
|
||||
if ( mCapacity < 128 ) mCapacity = 128;
|
||||
|
||||
char* oldBuf = mpBuf;
|
||||
|
||||
mpBuf = new char[mCapacity];
|
||||
|
||||
if ( oldBuf )
|
||||
{
|
||||
memcpy( mpBuf, oldBuf, mSize );
|
||||
delete oldBuf;
|
||||
}
|
||||
}
|
||||
|
||||
// append new data
|
||||
memcpy( &mpBuf[mSize], srcBuf, count );
|
||||
|
||||
mSize += count;
|
||||
}
|
||||
|
||||
ScriptStream& ScriptStream::operator<<( const char* str )
|
||||
{
|
||||
WriteBytes( str, strlen( str ) );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScriptStream& ScriptStream::operator<<( const string& str )
|
||||
{
|
||||
if ( str.length() < 512 )
|
||||
{
|
||||
char buf[512];
|
||||
size_t len = str.length();
|
||||
|
||||
for( size_t i = 0; i != len; ++i )
|
||||
buf[i] = str[i];
|
||||
|
||||
WriteBytes( buf, len );
|
||||
}
|
||||
else
|
||||
WriteBytes( str.c_str(), str.length() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScriptStream& ScriptStream::operator<<( char ch )
|
||||
{
|
||||
WriteBytes( &ch, 1 );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ScriptStream::endl()
|
||||
{
|
||||
char ch = '\n';
|
||||
WriteBytes( &ch, 1 );
|
||||
}
|
||||
|
||||
/***** Implementation for class ScriptTemplate *****/
|
||||
|
||||
ScriptTemplate::ScriptTemplate( const string& templateText )
|
||||
{
|
||||
string tmp = templateText;
|
||||
|
||||
mTText = (char*)malloc( tmp.length() + 1 );
|
||||
|
||||
strcpy( mTText, tmp.c_str() );
|
||||
}
|
||||
|
||||
ScriptTemplate::~ScriptTemplate()
|
||||
{
|
||||
for( size_t i = 0; i != mVars.size(); ++i )
|
||||
|
||||
delete mVars[i];
|
||||
|
||||
free( mTText );
|
||||
}
|
||||
|
||||
bool ScriptTemplate::HasVar( const char* name )
|
||||
{
|
||||
for( size_t i = 0; i != mVars.size(); ++i )
|
||||
|
||||
if ( strcmp( mVars[i]->mName, name ) == 0 )
|
||||
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScriptTemplate::AddStringVar ( const char* name, int ofs )
|
||||
{
|
||||
mVars.push_back( new TVarInfo( name, ofs, TVAR_STRING ) );
|
||||
}
|
||||
|
||||
void ScriptTemplate::AddIntegerVar( const char* name, int ofs )
|
||||
{
|
||||
mVars.push_back( new TVarInfo( name, ofs, TVAR_INTEGER ) );
|
||||
}
|
||||
|
||||
void ScriptTemplate::AddDoubleVar ( const char* name, int ofs )
|
||||
{
|
||||
mVars.push_back( new TVarInfo( name, ofs, TVAR_DOUBLE ) );
|
||||
}
|
||||
|
||||
void ScriptTemplate::AddObjectRefArray( const char* name,
|
||||
int ofsRefToFirstObj,
|
||||
int ofsObjSizeInt,
|
||||
int ofsObjRefTempl
|
||||
)
|
||||
{
|
||||
TArrayInfo* pInfo = new TArrayInfo( name );
|
||||
|
||||
mVars.push_back( pInfo );
|
||||
|
||||
pInfo->mRefOfs = ofsRefToFirstObj;
|
||||
pInfo->mSizeIntOfs = ofsObjSizeInt;
|
||||
pInfo->mObjRefTemplOfs = ofsObjRefTempl;
|
||||
}
|
||||
|
||||
inline void ScriptTemplate::PrintVar( TVarInfo* pInfo,
|
||||
void* dataObj,
|
||||
ScriptStream& stm )
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
switch ( pInfo->mType )
|
||||
{
|
||||
case TVAR_INTEGER :
|
||||
{
|
||||
sprintf(buf, "%d",*( (int*) ((char*)dataObj + pInfo->mOfs) ) );
|
||||
|
||||
stm.WriteBytes( buf, strlen(buf ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case TVAR_STRING :
|
||||
{
|
||||
string& str = *( (string*) ((char*)dataObj+pInfo->mOfs) );
|
||||
|
||||
const char* cs = str.c_str();
|
||||
#ifdef DEBUG_WEIRED_OFFSETS
|
||||
cout << "DBG:: cs address is " << (int)cs << endl;
|
||||
cout << "DBG:: str address is " << (int)(&str) << endl;
|
||||
cout << "DBG:: dataObj points to " << (int)dataObj << endl;
|
||||
cout << "DBG:: pInfo->mOfs value is " << (int)pInfo->mOfs << endl;
|
||||
cout << "DBG:: d+pInfo->mOfs is " << (int)((char*)dataObj + pInfo->mOfs) << endl;
|
||||
cout << "DBG:: pInfo->mName is " << pInfo->mName << endl;
|
||||
cout << "DBG:: pInfo->mType is " << pInfo->mType << endl;
|
||||
cout << "DBG:: end of dump. " << endl;
|
||||
|
||||
cout << "DBG:: cs value is " << endl << cs << endl;
|
||||
#endif
|
||||
stm.WriteBytes( cs, strlen(cs) );
|
||||
break;
|
||||
}
|
||||
|
||||
case TVAR_DOUBLE :
|
||||
{
|
||||
sprintf( buf, "%f",
|
||||
*( (double*)( (char*)dataObj+pInfo->mOfs) ) );
|
||||
|
||||
stm.WriteBytes( buf, strlen(buf ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case TVAR_REF_ARRAY :
|
||||
{
|
||||
TArrayInfo& info = *((TArrayInfo*)pInfo);
|
||||
|
||||
int sz = *((int*) ( (char*)dataObj+info.mSizeIntOfs ));
|
||||
if ( !sz )
|
||||
{
|
||||
// DBG::
|
||||
int u;
|
||||
++u;
|
||||
break;
|
||||
}
|
||||
|
||||
int* array = *((int**)( (char*)dataObj+info.mRefOfs ));
|
||||
|
||||
ScriptTemplate* pRefTempl;
|
||||
|
||||
for( int i = 0; i != sz; ++i )
|
||||
{
|
||||
pRefTempl =
|
||||
*((ScriptTemplate**)((char*)(array[i])+info.mObjRefTemplOfs));
|
||||
|
||||
pRefTempl->PrintScript( (void*)array[i], stm );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptTemplate::PrintScript( void* dataObj, ScriptStream& stm )
|
||||
{
|
||||
char* cur = mTText;
|
||||
|
||||
// template parsing loop
|
||||
do
|
||||
{
|
||||
char* start = cur;
|
||||
|
||||
while( *cur != '\0' && *cur != '$' ) ++cur;
|
||||
|
||||
// flush text collected between variables
|
||||
stm.WriteBytes( start, cur - start );
|
||||
|
||||
if ( *cur == '\0' ) break;
|
||||
|
||||
cur += 2; // skip to the name of the var
|
||||
|
||||
start = cur;
|
||||
|
||||
while( *cur != ')' ) ++cur;
|
||||
|
||||
// put terminating zero temorarely
|
||||
|
||||
*cur = '\0';
|
||||
|
||||
// look up variable
|
||||
|
||||
size_t sz = mVars.size();
|
||||
bool found = 0;
|
||||
|
||||
for( size_t i = 0; i != sz; ++i )
|
||||
{
|
||||
if ( strcmp( mVars[i]->mName, start ) == 0 )
|
||||
{
|
||||
PrintVar( mVars[i], dataObj, stm );
|
||||
|
||||
*cur = ')'; // remove terminating zero
|
||||
++cur;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// variable referred by template script is not
|
||||
// registered to this tempalte object
|
||||
ASSERT( found );
|
||||
|
||||
} while(1);
|
||||
}
|
||||
|
||||
/***** implementation for class ScriptSection *****/
|
||||
|
||||
int ScriptSection::mIdCounter = 0;
|
||||
|
||||
ScriptSection::ScriptSection( const string& name,
|
||||
const string& body,
|
||||
ScriptTemplate* pSectionTemplate,
|
||||
ScriptTemplate* pReferenceTemplate,
|
||||
bool autoHide,
|
||||
bool sorted
|
||||
)
|
||||
: mpParent ( NULL ),
|
||||
|
||||
mName ( name ),
|
||||
mBody ( body ),
|
||||
|
||||
mAutoHide( autoHide ),
|
||||
mSortOn ( sorted ),
|
||||
|
||||
mpSectTempl( pSectionTemplate ),
|
||||
mpRefTempl ( pReferenceTemplate ),
|
||||
|
||||
mRefCount( 0 ),
|
||||
mArrSize( 0 )
|
||||
{
|
||||
// generate GUID
|
||||
|
||||
char buf[32];
|
||||
sprintf( buf, "%d", ++mIdCounter );
|
||||
mId = buf;
|
||||
}
|
||||
|
||||
ScriptSection::~ScriptSection()
|
||||
{
|
||||
SectListT lst = mSubsections;
|
||||
|
||||
while( mSubsections.size() )
|
||||
|
||||
mSubsections[0]->RemoveRef();
|
||||
|
||||
for( size_t i = 0; i != mReferences.size(); ++i )
|
||||
|
||||
mReferences[i]->RemoveRef();
|
||||
}
|
||||
|
||||
void ScriptSection::AddRef()
|
||||
{
|
||||
++mRefCount;
|
||||
}
|
||||
|
||||
void ScriptSection::RemoveRef()
|
||||
{
|
||||
if ( !mRefCount || !(--mRefCount) )
|
||||
{
|
||||
if (mpParent)
|
||||
{
|
||||
// remove ourselves from parent's list
|
||||
|
||||
SectListT& lst = mpParent->mSubsections;
|
||||
for( size_t i = 0; i != lst.size(); ++i )
|
||||
|
||||
if ( lst[i] == this )
|
||||
{
|
||||
lst.erase( &lst[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptSection* ScriptSection::GetSubsection( const char* name )
|
||||
{
|
||||
// FOR NOW:: fixed section name length
|
||||
char buf[128];
|
||||
|
||||
size_t cur = 0;
|
||||
|
||||
while( name[cur] && name[cur] != '/' )
|
||||
{
|
||||
buf[cur] = name[cur];
|
||||
++cur;
|
||||
}
|
||||
|
||||
ASSERT( cur < sizeof(buf) );
|
||||
|
||||
buf[cur] = '\0';
|
||||
|
||||
size_t sz = mSubsections.size();
|
||||
|
||||
for( size_t i = 0; i != sz; ++i )
|
||||
{
|
||||
// DBG::
|
||||
//ScriptSection& sect = *mSubsections[i];
|
||||
|
||||
if ( mSubsections[i]->mName == buf )
|
||||
{
|
||||
if ( name[cur] == '/' )
|
||||
|
||||
// search recursivelly
|
||||
return mSubsections[i]->GetSubsection( &name[cur+1] );
|
||||
else
|
||||
return mSubsections[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScriptSection::AddSection( ScriptSection* pSection,
|
||||
bool addToReferencesToo
|
||||
)
|
||||
{
|
||||
mSubsections.push_back( pSection );
|
||||
|
||||
pSection->AddRef();
|
||||
|
||||
// can add section to multiple containers
|
||||
ASSERT( pSection->mpParent == 0 );
|
||||
|
||||
pSection->mpParent = this;
|
||||
|
||||
if ( addToReferencesToo )
|
||||
|
||||
AddReference( pSection );
|
||||
}
|
||||
|
||||
void ScriptSection::AddReference( ScriptSection* pReferredSection )
|
||||
{
|
||||
mReferences.push_back( pReferredSection );
|
||||
|
||||
pReferredSection->AddRef();
|
||||
|
||||
// set up mandatory fields used by ScriptTemplate
|
||||
mArrSize = mReferences.size();
|
||||
if ( mArrSize )
|
||||
mRefFirst = (void*)&mReferences[0];
|
||||
}
|
||||
|
||||
SectListT& ScriptSection::GetSubsections()
|
||||
{
|
||||
return mSubsections;
|
||||
}
|
||||
|
||||
// static method:
|
||||
void ScriptSection::RegisterTemplate( ScriptTemplate& sectionTempalte )
|
||||
{
|
||||
int nameOfs, bodyOfs, idOfs,
|
||||
arrRefOfs, arrSizeOfs, refTemplOfs;
|
||||
|
||||
// obtaining offsets of member vars
|
||||
|
||||
GET_VAR_OFS( ScriptSection, mName, &nameOfs )
|
||||
GET_VAR_OFS( ScriptSection, mBody, &bodyOfs )
|
||||
GET_VAR_OFS( ScriptSection, mId, &idOfs )
|
||||
GET_VAR_OFS( ScriptSection, mRefFirst, &arrRefOfs )
|
||||
GET_VAR_OFS( ScriptSection, mArrSize, &arrSizeOfs )
|
||||
|
||||
GET_VAR_OFS( ScriptSection, mpRefTempl, &refTemplOfs )
|
||||
|
||||
// registering member variables with given script template
|
||||
|
||||
sectionTempalte.AddStringVar( "NAME", nameOfs );
|
||||
sectionTempalte.AddStringVar( "BODY", bodyOfs );
|
||||
sectionTempalte.AddStringVar( "ID", idOfs );
|
||||
|
||||
sectionTempalte.AddObjectRefArray( "REFLIST",
|
||||
arrRefOfs, arrSizeOfs, refTemplOfs );
|
||||
}
|
||||
|
||||
void ScriptSection::Print( ScriptStream& stm )
|
||||
{
|
||||
// TBD:: sorting
|
||||
|
||||
// print out this content first
|
||||
if ( mpSectTempl )
|
||||
|
||||
mpSectTempl->PrintScript( this, stm );
|
||||
|
||||
// attach contents subsections at the end of this content
|
||||
|
||||
for( size_t i = 0; i != mSubsections.size(); ++i )
|
||||
|
||||
mSubsections[i]->Print( stm );
|
||||
}
|
||||
|
||||
void ScriptSection::DoRemoveEmptySections(int& nRemoved, SectListT& removedLst)
|
||||
{
|
||||
for( size_t i = 0; i != mSubsections.size(); ++i )
|
||||
{
|
||||
ScriptSection& sect = *mSubsections[i];
|
||||
|
||||
sect.DoRemoveEmptySections( nRemoved, removedLst );
|
||||
|
||||
if (sect.mAutoHide )
|
||||
|
||||
if ( sect.mReferences.size() == 0 )
|
||||
{
|
||||
bool found = 0;
|
||||
for( size_t k = 0; k != removedLst.size(); ++k )
|
||||
|
||||
if ( removedLst[k] == § )
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
removedLst.push_back( § );
|
||||
++nRemoved;
|
||||
|
||||
delete §
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptSection::DoRemoveDeadLinks( SectListT& removedLst)
|
||||
{
|
||||
size_t dsz = removedLst.size();
|
||||
|
||||
for( size_t i = 0; i != mSubsections.size(); ++i )
|
||||
{
|
||||
mSubsections[i]->DoRemoveDeadLinks( removedLst );
|
||||
}
|
||||
|
||||
for( size_t n = 0; n != mReferences.size(); ++n )
|
||||
{
|
||||
for( size_t k = 0; k != dsz; ++k )
|
||||
|
||||
if ( removedLst[k] == mReferences[n] )
|
||||
{
|
||||
mReferences.erase( &mReferences[n] );
|
||||
--n;
|
||||
|
||||
// set up mandatory fields used by ScriptTemplate
|
||||
mArrSize = mReferences.size();
|
||||
if ( mArrSize )
|
||||
mRefFirst = (void*)&mReferences[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScriptSection::RemoveEmptySections()
|
||||
{
|
||||
// FIXME:: this is very_very_very slow alg.! +"doesn't work"
|
||||
|
||||
int nRemoved = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SectListT removedLst;
|
||||
nRemoved = 0;
|
||||
|
||||
DoRemoveEmptySections( nRemoved, removedLst );
|
||||
|
||||
DoRemoveDeadLinks( removedLst );
|
||||
}
|
||||
while( nRemoved );
|
||||
}
|
||||
|
||||
/***** Iimplementation for class DocGeneratorBase *****/
|
||||
|
||||
bool DocGeneratorBase::SaveDocument( const char* fname,
|
||||
const char* fopenOptions,
|
||||
ScriptSection* pFromSection
|
||||
)
|
||||
{
|
||||
FILE* fp = fopen( fname, fopenOptions );
|
||||
|
||||
if ( (int)fp == -1 ) return 0;
|
||||
|
||||
ScriptStream stm;
|
||||
|
||||
// check if derived class agrees about saving it
|
||||
if ( !OnSaveDocument( stm ) ) return 0;
|
||||
|
||||
if ( pFromSection )
|
||||
|
||||
pFromSection->Print( stm );
|
||||
else
|
||||
{
|
||||
ScriptSection* pTopSect = GetTopSection();
|
||||
ASSERT( pTopSect );
|
||||
pTopSect->Print( stm );
|
||||
}
|
||||
|
||||
size_t nWrite = fwrite( stm.GetBuf(), 1, stm.GetBufSize(), fp );
|
||||
|
||||
if ( nWrite != stm.GetBufSize() ) return 0;
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return 1;
|
||||
|
||||
// that^s it
|
||||
}
|
676
utils/HelpGen/src/sourcepainter.cpp
Normal file
676
utils/HelpGen/src/sourcepainter.cpp
Normal file
@@ -0,0 +1,676 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// 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
|
||||
|
||||
#if defined( wxUSE_TEMPLATE_STL )
|
||||
|
||||
#include <map>
|
||||
#else
|
||||
|
||||
#include <wxstlac.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "sourcepainter.h"
|
||||
|
||||
const int MAX_KEYWORD_LEN = 16;
|
||||
|
||||
struct KeywordT
|
||||
{
|
||||
char keyWord[MAX_KEYWORD_LEN];
|
||||
int rank;
|
||||
};
|
||||
|
||||
// source fragment ranks :
|
||||
|
||||
// 0 - nomral text
|
||||
// 1 - basic types
|
||||
// 2 - reserved words
|
||||
|
||||
// multil-language keywords map
|
||||
|
||||
static KeywordT __gKeyWords[] =
|
||||
{
|
||||
{ "for", 1 },
|
||||
{ "FOR", 1 },
|
||||
{ "For", 1 },
|
||||
|
||||
{ "next", 1 },
|
||||
{ "Next", 1 },
|
||||
{ "NEXT", 1 },
|
||||
|
||||
{ "if", 1 },
|
||||
{ "If", 1 },
|
||||
{ "IF", 1 },
|
||||
|
||||
{ "then", 1 },
|
||||
{ "Then", 1 },
|
||||
{ "THEN", 1 },
|
||||
|
||||
{ "else", 1 },
|
||||
{ "Else", 1 },
|
||||
{ "ELSE", 1 },
|
||||
|
||||
{ "do", 1 },
|
||||
{ "Do", 1 },
|
||||
{ "DO", 1 },
|
||||
|
||||
|
||||
{ "break", 1 },
|
||||
{ "Break", 1 },
|
||||
{ "BREAK", 1 },
|
||||
|
||||
{ "continue", 1 },
|
||||
|
||||
{ "goto", 1 },
|
||||
{ "Goto", 1 },
|
||||
{ "GOTO", 1 },
|
||||
|
||||
{ "switch", 1 },
|
||||
{ "default", 1 },
|
||||
{ "case", 1 },
|
||||
|
||||
{ "repeat", 1 },
|
||||
{ "Repeat", 1 },
|
||||
{ "REPEAT", 1 },
|
||||
|
||||
{ "until", 1 },
|
||||
{ "Until", 1 },
|
||||
{ "UNTIL", 1 },
|
||||
|
||||
{ "return", 1 },
|
||||
{ "Return", 1 },
|
||||
{ "RETURN", 1 },
|
||||
|
||||
{ "unit", 1 },
|
||||
{ "Unit", 1 },
|
||||
{ "UNIT", 1 },
|
||||
|
||||
{ "procedure", 1 },
|
||||
{ "Procedure", 1 },
|
||||
{ "PROCEDURE", 1 },
|
||||
|
||||
{ "function", 1 },
|
||||
{ "Function", 1 },
|
||||
{ "FUNCTION", 1 },
|
||||
|
||||
{ "begin", 1 },
|
||||
{ "Begin", 1 },
|
||||
{ "BEGIN", 1 },
|
||||
|
||||
{ "End", 1 },
|
||||
{ "END", 1 },
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{ "enum", 1 },
|
||||
{ "static", 1 },
|
||||
{ "const", 1 },
|
||||
{ "mutable", 1 },
|
||||
{ "volatile", 1 },
|
||||
{ "__asm", 1 },
|
||||
{ "asm", 1 },
|
||||
|
||||
{ "typeid", 1 },
|
||||
{ "sizeof", 1 },
|
||||
{ "typeof", 1 },
|
||||
|
||||
|
||||
{ "native", 1 },
|
||||
|
||||
{ "#include", 1 },
|
||||
{ "#define", 1 },
|
||||
{ "#def", 1 },
|
||||
{ "#undef", 1 },
|
||||
{ "#ifdef", 1 },
|
||||
{ "#ifndef", 1 },
|
||||
{ "#if", 1 },
|
||||
{ "#endif", 1 },
|
||||
{ "#elif", 1 },
|
||||
{ "#else", 1 },
|
||||
{ "#pragma", 1 },
|
||||
{ "#line", 1 },
|
||||
|
||||
{ "package", 1 },
|
||||
{ "import", 1 },
|
||||
{ "export", 1 },
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{ "dynamic_cast", 1 },
|
||||
{ "const_cast", 1 },
|
||||
|
||||
//////// some hacks for VB /////////
|
||||
|
||||
{ "sub", 1 },
|
||||
{ "Sub", 1 },
|
||||
{ "SUB", 1 },
|
||||
{ "as", 1 },
|
||||
{ "As", 1 },
|
||||
{ "AS", 1 },
|
||||
|
||||
/////// data types ///////
|
||||
|
||||
{ "int" , 1 },
|
||||
{ "integer", 1 },
|
||||
{ "Integer", 1 },
|
||||
{ "INTEGER", 1 },
|
||||
|
||||
{ "real", 1 },
|
||||
{ "Real", 1 },
|
||||
{ "REAL", 1 },
|
||||
|
||||
{ "float", 1 },
|
||||
{ "Float", 1 },
|
||||
{ "FLOAT", 1 },
|
||||
|
||||
{ "char", 1 },
|
||||
{ "Char", 1 },
|
||||
{ "CHAR", 1 },
|
||||
|
||||
{ "register", 1 },
|
||||
|
||||
{ "string", 1 },
|
||||
{ "String", 1 },
|
||||
{ "STRING", 1 },
|
||||
|
||||
{ "array", 1 },
|
||||
{ "Array", 1 },
|
||||
{ "ARRAY", 1 },
|
||||
|
||||
{ "packed", 1 },
|
||||
{ "Packed", 1 },
|
||||
{ "PACKED", 1 },
|
||||
|
||||
{ "property", 1 },
|
||||
{ "Property", 1 },
|
||||
{ "PROPERTY", 1 },
|
||||
|
||||
{ "unsigned", 1 },
|
||||
|
||||
{ "long", 1 },
|
||||
{ "double", 1 },
|
||||
{ "short", 1 },
|
||||
{ "bool", 1 },
|
||||
|
||||
{ "longint", 1 },
|
||||
{ "Longint", 1 },
|
||||
{ "LONGINT", 1 },
|
||||
|
||||
{ "extended", 1 },
|
||||
{ "Extended", 1 },
|
||||
{ "EXTENTED", 1 },
|
||||
|
||||
{ "pointer", 1 },
|
||||
{ "Pointer", 1 },
|
||||
{ "POINTER", 1 },
|
||||
|
||||
{ "and", 1 },
|
||||
{ "And", 1 },
|
||||
{ "AND", 1 },
|
||||
{ "or", 1 },
|
||||
{ "Or", 1 },
|
||||
{ "OR", 1 },
|
||||
{ "xor", 1 },
|
||||
{ "Xor", 1 },
|
||||
{ "XOR", 1 },
|
||||
|
||||
{ "void", 1 },
|
||||
{ "__stdcall", 1 },
|
||||
{ "__declspec", 1 },
|
||||
{ "extern", 1 },
|
||||
{ "stdcall", 1 },
|
||||
{ "dllimport", 1 },
|
||||
{ "dllexport", 1 },
|
||||
{ "__cdecl", 1 },
|
||||
{ "cdecl", 1 },
|
||||
{ "template", 1 },
|
||||
{ "typedef", 1 },
|
||||
{ "naked", 1 },
|
||||
|
||||
{ "try", 1 },
|
||||
{ "catch", 1 },
|
||||
{ "throw", 2 }, // C++
|
||||
{ "throws", 1 }, // Java
|
||||
|
||||
|
||||
{ "finalize", 1 },
|
||||
|
||||
// "STL-suport"
|
||||
|
||||
{ "size_t", 1 },
|
||||
{ "NPOS", 1 },
|
||||
{ "vector", 1 },
|
||||
{ "list", 1 },
|
||||
{ "map", 1 },
|
||||
{ "multimap", 1 },
|
||||
|
||||
{ "external", 1 },
|
||||
{ "External", 1 },
|
||||
{ "EXTERNAL", 1 },
|
||||
|
||||
//////////// meta-information //////////////
|
||||
|
||||
{ "virtual", 2 },
|
||||
{ "Virtual", 2 },
|
||||
|
||||
{ "override", 2 },
|
||||
{ "Override", 2 },
|
||||
|
||||
{ "class", 2 },
|
||||
{ "Class", 2 },
|
||||
{ "CLASS", 2 },
|
||||
|
||||
{ "struct", 2 },
|
||||
{ "union", 2 },
|
||||
|
||||
{ "record", 2 },
|
||||
{ "Record", 2 },
|
||||
{ "RECORD", 2 },
|
||||
|
||||
{ "form", 1 },
|
||||
{ "Form", 1 },
|
||||
{ "FORM", 1 },
|
||||
|
||||
{ "namespace", 2 },
|
||||
|
||||
{ "interface" , 2 },
|
||||
{ "abstract", 2 },
|
||||
|
||||
{ "Interface" , 2 },
|
||||
{ "INTERFACE" , 2 },
|
||||
|
||||
{ "implementation", 2 },
|
||||
{ "Implementation", 2 },
|
||||
{ "IMPLEMENTATION", 2 },
|
||||
|
||||
{ "label", 2 },
|
||||
{ "Label", 2 },
|
||||
{ "LABEL", 2 },
|
||||
|
||||
{ "implements", 2 },
|
||||
|
||||
{ "public", 2 },
|
||||
{ "private", 2 },
|
||||
{ "protected", 2 },
|
||||
|
||||
{ "this", 2 },
|
||||
{ "This", 2 },
|
||||
{ "THIS", 2 },
|
||||
|
||||
{ "new", 2 },
|
||||
{ "New", 2 },
|
||||
{ "NEW", 2 },
|
||||
|
||||
{ "delete", 2 },
|
||||
{ "inline", 2 },
|
||||
|
||||
{ "operator", 2 },
|
||||
|
||||
{ "Inherited", 2 },
|
||||
{ "Inherited", 2 },
|
||||
|
||||
{ "final", 2 },
|
||||
{ "implements", 2 },
|
||||
{ "super", 2 },
|
||||
|
||||
// even more...
|
||||
{ "java", 2 },
|
||||
{ "Java", 2 },
|
||||
{ "JAVA", 2 },
|
||||
{ "delphi", 2 },
|
||||
{ "Delphi", 2 },
|
||||
{ "SmallTalk", 2 },
|
||||
{ "Smalltalk", 2 },
|
||||
{ "smalltalk", 2 },
|
||||
{ "assembler", 2 },
|
||||
{ "Assembler", 2 },
|
||||
{ "Basic", 2 },
|
||||
{ "BASIC", 2 },
|
||||
{ "basic", 2 },
|
||||
{ "CORBA", 2 },
|
||||
{ "COBOL", 2 },
|
||||
{ "ADA", 2 },
|
||||
{ "LISP", 2 },
|
||||
|
||||
// just for fun...
|
||||
{ "life", 2 },
|
||||
{ "sucks", 2 },
|
||||
{ "rules", 2 },
|
||||
{ "Quake", 2 },
|
||||
{ "QuakeWorld", 2 },
|
||||
{ "[ag_slammer]",2 },
|
||||
{ "Aleksandras", 2 },
|
||||
{ "Gluchovas" , 2 },
|
||||
{ "Alex", 2 },
|
||||
{ "alex", 2 },
|
||||
{ "aleks", 2 },
|
||||
{ "aleksas", 3 },
|
||||
{ "AlexSoft", 2 },
|
||||
{ "Alexsoft", 2 },
|
||||
{ "SpringSky", 2 },
|
||||
{ "SK_Team", 2 },
|
||||
{ "soften", 2 },
|
||||
{ "UB40", 2 },
|
||||
{ "U96", 2 }
|
||||
};
|
||||
|
||||
struct less_c_str
|
||||
{
|
||||
inline bool operator()( char* x, char* y) const
|
||||
{ return ( strcmp( x,y ) < 0 );
|
||||
}
|
||||
};
|
||||
|
||||
#if defined( wxUSE_TEMPLATE_STL )
|
||||
|
||||
typedef map< char*, char*, less_c_str > KeywordMapT;
|
||||
|
||||
#else
|
||||
|
||||
typedef char* CharPtrT;
|
||||
typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
|
||||
|
||||
#endif
|
||||
|
||||
static KeywordMapT __gMultiLangMap;
|
||||
static int __gMapReady = 0;
|
||||
|
||||
void check_keyword_map( int keywordMapNr )
|
||||
{
|
||||
if ( !__gMapReady )
|
||||
{
|
||||
__gMapReady = 1;
|
||||
|
||||
// "make sure" the address of the first member of non-polimorphic class
|
||||
// coinsides with the address of the instance
|
||||
|
||||
KeywordT dummy;
|
||||
|
||||
if ( (char*)& dummy != &dummy.keyWord[0] )
|
||||
throw;
|
||||
|
||||
int size = sizeof(__gKeyWords) / sizeof( KeywordT );
|
||||
|
||||
for( int i = 0; i != size; ++i )
|
||||
|
||||
__gMultiLangMap.insert(
|
||||
KeywordMapT::value_type( (char*)&__gKeyWords[i],
|
||||
(char*)&__gKeyWords[i]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int get_rank( char* start, char* end )
|
||||
{
|
||||
// FIXME:: what if end is no longer leagal adress?
|
||||
|
||||
char tmp = *end;
|
||||
*end = '\0'; // put temporary terminator
|
||||
|
||||
KeywordMapT::iterator i;
|
||||
|
||||
if ( (i = __gMultiLangMap.find( start ) ) != __gMultiLangMap.end() )
|
||||
{
|
||||
KeywordT* pKey = (KeywordT*)(*i).second;
|
||||
|
||||
*end = tmp;
|
||||
|
||||
return pKey->rank;
|
||||
}
|
||||
else
|
||||
{
|
||||
*end = tmp;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void store_range( SPBlockListT& results, int rank, int range_len )
|
||||
{
|
||||
if ( !range_len ) return;
|
||||
|
||||
results.push_back ( ( rank << 16 ) | ( range_len ) );
|
||||
}
|
||||
|
||||
|
||||
#define STORE_RANGE store_range( results, cur_rank, cur_range_len );\
|
||||
cur_rank = cur_range_len = 0;
|
||||
|
||||
#define NEXT_CHAR cur_range_len++; \
|
||||
++cur; \
|
||||
continue;
|
||||
|
||||
static inline int is_alpha( char ch )
|
||||
{
|
||||
return ( (( ch >= '_' ) && ( ch <= 'z' )) ||
|
||||
(( ch >= 'A' ) && ( ch <= 'Z' ))
|
||||
);
|
||||
}
|
||||
|
||||
// _ . .
|
||||
// Ziema atEjo netikEtai
|
||||
|
||||
static void heighlight_syntax( char* str, int strLen,
|
||||
SPBlockListT& results, bool& isComment )
|
||||
{
|
||||
bool isMultiline = 0;
|
||||
char* cur = str;
|
||||
char* end = str + strLen;
|
||||
|
||||
int cur_rank = ( isComment == 1 ) ? RANK_GREEN : RANK_BLACK;
|
||||
int cur_range_len = 0;
|
||||
|
||||
while ( cur != end )
|
||||
{
|
||||
int has_next = ( cur+1 != end );
|
||||
|
||||
if ( isComment )
|
||||
{
|
||||
if ( *cur == '*' )
|
||||
if ( has_next && *(cur+1) == '/' )
|
||||
{
|
||||
// turn off multiline comment mode
|
||||
cur += 2;
|
||||
cur_range_len += 2;
|
||||
isComment = 0;
|
||||
isMultiline = 0;
|
||||
STORE_RANGE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
++cur_range_len;
|
||||
++cur;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( *cur == 10 )
|
||||
if ( isComment )
|
||||
if ( isMultiline )
|
||||
{
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = end - cur;
|
||||
STORE_RANGE;
|
||||
isComment = 0;
|
||||
isMultiline = 0;
|
||||
continue;
|
||||
}*/
|
||||
|
||||
if ( *cur == '/' )
|
||||
{
|
||||
if ( has_next )
|
||||
{
|
||||
if ( *(cur+1) == '/' )
|
||||
{
|
||||
STORE_RANGE;
|
||||
|
||||
char* eol = cur;
|
||||
while ( eol < end && *eol != 10 )
|
||||
++eol;
|
||||
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = eol - cur;
|
||||
cur = eol;
|
||||
STORE_RANGE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( *(cur+1) == '*' )
|
||||
{
|
||||
STORE_RANGE;
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = 2;
|
||||
isComment = 1;
|
||||
cur += 2;
|
||||
isMultiline = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
if ( ( is_alpha( *cur ) || *(cur) == '#' )
|
||||
&& has_next
|
||||
)
|
||||
{
|
||||
if ( is_alpha( *(cur+1) ) )
|
||||
{
|
||||
char* start = cur;
|
||||
cur += 2;
|
||||
|
||||
while ( cur != end && is_alpha(*cur) ) ++cur;
|
||||
|
||||
int wordRank;
|
||||
|
||||
if ( (wordRank = get_rank( start, cur )) > 0 )
|
||||
{
|
||||
STORE_RANGE;
|
||||
|
||||
store_range( results, wordRank, int(cur-start) );
|
||||
cur_rank = cur_range_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
cur_range_len += ( cur-start );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
if ( cur_range_len > 0 ) STORE_RANGE;
|
||||
}
|
||||
|
||||
/***** Implementation for class SourcePainter ******/
|
||||
|
||||
SourcePainter::SourcePainter( bool assembleResultString )
|
||||
: mCollectResultsOn( assembleResultString ),
|
||||
mIsInComment( FALSE ),
|
||||
mCommentIsMultiline( FALSE )
|
||||
{
|
||||
check_keyword_map(0);
|
||||
}
|
||||
|
||||
void SourcePainter::ProcessSource( char* src, int srcLen )
|
||||
{
|
||||
// TBD:: multilne state...
|
||||
|
||||
heighlight_syntax( src, srcLen, mBlocks, mIsInComment );
|
||||
|
||||
if ( mCollectResultsOn )
|
||||
|
||||
mResultStr += string( src, srcLen );
|
||||
}
|
||||
|
||||
void SourcePainter::SetState( bool isInComment,
|
||||
bool commentIsMultiline )
|
||||
{
|
||||
mIsInComment = isInComment;
|
||||
mCommentIsMultiline = commentIsMultiline;
|
||||
}
|
||||
|
||||
void SourcePainter::Init(bool assembleResultString)
|
||||
{
|
||||
mIsInComment = 0;
|
||||
mCommentIsMultiline = 0;
|
||||
mCollectResultsOn = assembleResultString;
|
||||
|
||||
mResultStr = "";
|
||||
|
||||
mBlocks.erase( mBlocks.begin(), mBlocks.end() );
|
||||
}
|
||||
|
||||
static int rank_tags_map[] =
|
||||
{
|
||||
TAG_BLACK_FONT,
|
||||
TAG_BLUE_FONT,
|
||||
TAG_RED_FONT,
|
||||
TAG_GREEN_FONT
|
||||
};
|
||||
|
||||
void SourcePainter::GetResultString(string& result, MarkupTagsT tags)
|
||||
{
|
||||
// this method works, only if results of processing
|
||||
// are collected
|
||||
ASSERT( mCollectResultsOn );
|
||||
result = "";
|
||||
|
||||
int pos = 0;
|
||||
|
||||
for( size_t i = 0; i != mBlocks.size(); ++i )
|
||||
{
|
||||
int desc = mBlocks[i];
|
||||
|
||||
int len = desc & 0xFFFF;
|
||||
int rank = (desc >> 16) & 0xFFFF;
|
||||
|
||||
result += tags[ rank_tags_map[rank] ].start;
|
||||
|
||||
for( int n = 0; n != len; ++n )
|
||||
|
||||
result += mResultStr[pos+n];
|
||||
|
||||
pos += len;
|
||||
|
||||
result += tags[ rank_tags_map[rank] ].end;
|
||||
}
|
||||
}
|
||||
|
||||
SPBlockListT& SourcePainter::GetBlocks()
|
||||
{
|
||||
return mBlocks;
|
||||
}
|
||||
|
||||
bool SourcePainter::IsKeyword( char* word, int wordLen )
|
||||
{
|
||||
check_keyword_map(0);
|
||||
|
||||
int rank = get_rank( word, word + wordLen );
|
||||
|
||||
return ( rank == RANK_BLUE || rank == RANK_RED );
|
||||
}
|
543
utils/HelpGen/src/srcparser.cpp
Normal file
543
utils/HelpGen/src/srcparser.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Aleskandars Gluchovas
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "srcparser.h"
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// 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 <malloc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "srcparser.h"
|
||||
|
||||
/***** Implementation for class spVisitor *****/
|
||||
|
||||
void spVisitor::VisitAll( spContext& atContext,
|
||||
bool sortContent
|
||||
)
|
||||
{
|
||||
mSiblingSkipped = FALSE;
|
||||
mChildSkipped = FALSE;
|
||||
mContextMask = SP_CTX_ANY; // FIXME:: should be an arg.
|
||||
|
||||
if ( sortContent && !atContext.IsSorted() )
|
||||
|
||||
atContext.SortMembers();
|
||||
|
||||
mpCurCxt = &atContext; // FIXME:: this is dirty, restoring it each time
|
||||
|
||||
if ( atContext.GetContextType() & mContextMask )
|
||||
|
||||
atContext.AcceptVisitor( *this );
|
||||
|
||||
MMemberListT& members = atContext.GetMembers();
|
||||
|
||||
for( size_t i = 0; i != members.size(); ++i )
|
||||
{
|
||||
if ( mSiblingSkipped )
|
||||
|
||||
return;
|
||||
|
||||
if ( !mChildSkipped )
|
||||
{
|
||||
size_t prevSz = members.size();
|
||||
|
||||
// visit members of the context recursivelly
|
||||
VisitAll( *members[i], sortContent );
|
||||
|
||||
if ( members.size() != prevSz )
|
||||
|
||||
--i; // current member was removed!
|
||||
|
||||
mChildSkipped = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spVisitor::RemoveCurrentContext()
|
||||
{
|
||||
if ( mpCurCxt->GetParent() )
|
||||
|
||||
mpCurCxt->GetParent()->RemoveChild( mpCurCxt );
|
||||
}
|
||||
|
||||
void spVisitor::SkipSiblings()
|
||||
{
|
||||
mSiblingSkipped = TRUE;
|
||||
}
|
||||
|
||||
void spVisitor::SkipChildren()
|
||||
{
|
||||
mChildSkipped = TRUE;
|
||||
}
|
||||
|
||||
void spVisitor::SetFilter( int contextMask )
|
||||
{
|
||||
mContextMask = contextMask;
|
||||
}
|
||||
|
||||
/***** Implementation for class spComment *****/
|
||||
|
||||
bool spComment::IsMultiline() const
|
||||
{
|
||||
return mIsMultiline;
|
||||
}
|
||||
|
||||
bool spComment::StartsParagraph() const
|
||||
{
|
||||
return mStartsPar;
|
||||
}
|
||||
|
||||
string& spComment::GetText()
|
||||
{
|
||||
return mText;
|
||||
}
|
||||
|
||||
string spComment::GetText() const
|
||||
{
|
||||
return mText;
|
||||
}
|
||||
|
||||
/***** Implementation for class spContext *****/
|
||||
|
||||
spContext::spContext()
|
||||
|
||||
: mpParent ( NULL ),
|
||||
mpFirstOccurence( NULL ),
|
||||
mAlreadySorted ( FALSE ),
|
||||
|
||||
mSrcLineNo (-1),
|
||||
mSrcOffset (-1),
|
||||
mContextLength(-1),
|
||||
mLastScrLineNo(-1),
|
||||
|
||||
mHeaderLength (-1),
|
||||
mFooterLength (-1),
|
||||
|
||||
mFirstCharPos (-1),
|
||||
mLastCharPos (-1),
|
||||
|
||||
mVisibility( SP_VIS_PRIVATE ),
|
||||
|
||||
mIsVirtualContext ( FALSE ),
|
||||
mVirtualContextHasChildren( FALSE ),
|
||||
|
||||
mpUserData( NULL )
|
||||
{}
|
||||
|
||||
void spContext::RemoveChildren()
|
||||
{
|
||||
for( size_t i = 0; i != mMembers.size(); ++i )
|
||||
|
||||
delete mMembers[i];
|
||||
|
||||
mMembers.erase( mMembers.begin(), mMembers.end() );
|
||||
}
|
||||
|
||||
spContext::~spContext()
|
||||
{
|
||||
RemoveChildren();
|
||||
|
||||
for( size_t i = 0; i != mComments.size(); ++i )
|
||||
|
||||
delete mComments[i];
|
||||
}
|
||||
|
||||
bool spContext::IsSorted()
|
||||
{
|
||||
return mAlreadySorted;
|
||||
}
|
||||
|
||||
void spContext::GetContextList( MMemberListT& lst, int contextMask )
|
||||
{
|
||||
for( size_t i = 0; i != mMembers.size(); ++i )
|
||||
{
|
||||
spContext& member = *mMembers[i];
|
||||
|
||||
if ( member.GetContextType() & contextMask )
|
||||
|
||||
lst.push_back( &member );
|
||||
|
||||
// collect required contexts recursively
|
||||
member.GetContextList( lst, contextMask );
|
||||
}
|
||||
}
|
||||
|
||||
bool spContext::HasComments()
|
||||
{
|
||||
return ( mComments.size() != 0 );
|
||||
}
|
||||
|
||||
void spContext::RemoveChild( spContext* pChild )
|
||||
{
|
||||
for( size_t i = 0; i != mMembers.size(); ++i )
|
||||
|
||||
if ( mMembers[i] == pChild )
|
||||
{
|
||||
mMembers.erase( &mMembers[i] );
|
||||
|
||||
delete pChild;
|
||||
return;
|
||||
}
|
||||
|
||||
// the given child should exist on the parent's list
|
||||
wxASSERT( 0 );
|
||||
}
|
||||
|
||||
spContext* spContext::GetEnclosingContext( int mask )
|
||||
{
|
||||
spContext* cur = this->GetParent();
|
||||
|
||||
while ( cur && !(cur->GetContextType() & mask) )
|
||||
|
||||
cur = cur->GetParent();
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
bool spContext::PositionIsKnown()
|
||||
{
|
||||
return ( mSrcOffset != (-1) && mContextLength != (-1) );
|
||||
}
|
||||
|
||||
bool spContext::IsVirtualContext()
|
||||
{
|
||||
return mIsVirtualContext;
|
||||
}
|
||||
|
||||
bool spContext::VitualContextHasChildren()
|
||||
{
|
||||
return mVirtualContextHasChildren;
|
||||
}
|
||||
|
||||
string spContext::GetVirtualContextBody()
|
||||
{
|
||||
wxASSERT( mIsVirtualContext );
|
||||
|
||||
return mVirtualContextBody;
|
||||
}
|
||||
|
||||
string spContext::GetFooterOfVirtualContextBody()
|
||||
{
|
||||
wxASSERT( mIsVirtualContext );
|
||||
|
||||
return mVittualContextFooter;
|
||||
}
|
||||
|
||||
|
||||
void spContext::SetVirtualContextBody( const string& body,
|
||||
bool hasChildren,
|
||||
const string& footer )
|
||||
{
|
||||
mVirtualContextHasChildren = hasChildren;
|
||||
|
||||
mVirtualContextBody = body;
|
||||
mVittualContextFooter = footer;
|
||||
|
||||
// atuomaticllay becomes virtual context
|
||||
|
||||
mIsVirtualContext = TRUE;
|
||||
}
|
||||
|
||||
string spContext::GetBody( spContext* pCtx )
|
||||
{
|
||||
if ( ( pCtx == NULL || pCtx == this ) && mIsVirtualContext )
|
||||
|
||||
return mVirtualContextBody;
|
||||
|
||||
if ( GetParent() )
|
||||
|
||||
return GetParent()->GetBody( ( pCtx != NULL ) ? pCtx : this );
|
||||
else
|
||||
return ""; // source-fragment cannot be found
|
||||
}
|
||||
|
||||
string spContext::GetHeader( spContext* pCtx )
|
||||
{
|
||||
if ( GetParent() )
|
||||
|
||||
return GetParent()->GetHeader( ( pCtx != NULL ) ? pCtx : this );
|
||||
else
|
||||
return ""; // source-fragment cannot be found
|
||||
}
|
||||
|
||||
bool spContext::IsFirstOccurence()
|
||||
{
|
||||
return ( mpFirstOccurence != 0 );
|
||||
}
|
||||
|
||||
spContext* spContext::GetFirstOccurence()
|
||||
{
|
||||
// this object should not itself be
|
||||
// the first occurence of the context
|
||||
wxASSERT( mpFirstOccurence != 0 );
|
||||
|
||||
return mpFirstOccurence;
|
||||
}
|
||||
|
||||
void spContext::AddMember( spContext* pMember )
|
||||
{
|
||||
mMembers.push_back( pMember );
|
||||
|
||||
pMember->mpParent = this;
|
||||
}
|
||||
|
||||
void spContext::AddComment( spComment* pComment )
|
||||
{
|
||||
mComments.push_back( pComment );
|
||||
}
|
||||
|
||||
MMemberListT& spContext::GetMembers()
|
||||
{
|
||||
return mMembers;
|
||||
}
|
||||
|
||||
spContext* spContext::FindContext( const string& identifier,
|
||||
int contextType,
|
||||
bool searchSubMembers
|
||||
)
|
||||
{
|
||||
for( size_t i = 0; i != mMembers.size(); ++i )
|
||||
{
|
||||
spContext& member = *mMembers[i];
|
||||
|
||||
if ( member.GetName() == identifier &&
|
||||
( contextType & member.GetContextType() )
|
||||
)
|
||||
|
||||
return &member;
|
||||
|
||||
if ( searchSubMembers )
|
||||
{
|
||||
spContext* result =
|
||||
member.FindContext( identifier, contextType, 1 );
|
||||
|
||||
if ( result ) return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spContext::RemoveThisContext()
|
||||
{
|
||||
if ( mpParent )
|
||||
mpParent->RemoveChild( this );
|
||||
else
|
||||
// context should have a parent
|
||||
wxASSERT(0);
|
||||
}
|
||||
|
||||
spContext* spContext::GetOutterContext()
|
||||
{
|
||||
return mpParent;
|
||||
}
|
||||
|
||||
bool spContext::HasOutterContext()
|
||||
{
|
||||
return ( mpParent != 0 );
|
||||
}
|
||||
|
||||
bool spContext::IsInFile()
|
||||
{
|
||||
return ( GetOutterContext()->GetContextType() == SP_CTX_FILE );
|
||||
}
|
||||
|
||||
bool spContext::IsInNameSpace()
|
||||
{
|
||||
return ( GetOutterContext()->GetContextType() == SP_CTX_NAMESPACE );
|
||||
}
|
||||
|
||||
bool spContext::IsInClass()
|
||||
{
|
||||
return ( GetOutterContext()->GetContextType() == SP_CTX_CLASS );
|
||||
}
|
||||
|
||||
bool spContext::IsInOperation()
|
||||
{
|
||||
return ( GetOutterContext()->GetContextType() == SP_CTX_OPERATION );
|
||||
}
|
||||
|
||||
spClass& spContext::GetClass()
|
||||
{
|
||||
wxASSERT( GetOutterContext()->GetType() == SP_CTX_CLASS );
|
||||
return *((spClass*)mpParent );
|
||||
}
|
||||
|
||||
spFile& spContext::GetFile()
|
||||
{
|
||||
wxASSERT( GetOutterContext()->GetType() == SP_CTX_FILE );
|
||||
return *((spFile*)mpParent );
|
||||
}
|
||||
|
||||
spNameSpace& spContext::GetNameSpace()
|
||||
{
|
||||
wxASSERT( GetOutterContext()->GetType() == SP_CTX_NAMESPACE );
|
||||
return *((spNameSpace*)mpParent );
|
||||
}
|
||||
|
||||
spOperation& spContext::GetOperation()
|
||||
{
|
||||
wxASSERT( GetOutterContext()->GetType() == SP_CTX_OPERATION );
|
||||
return *((spOperation*)mpParent );
|
||||
}
|
||||
|
||||
/***** Implementation for class spClass *****/
|
||||
|
||||
void spClass::SortMembers()
|
||||
{
|
||||
// TBD::
|
||||
}
|
||||
|
||||
/***** Implementation for class spOperation *****/
|
||||
|
||||
spOperation::spOperation()
|
||||
|
||||
: mHasDefinition( FALSE )
|
||||
{}
|
||||
|
||||
string spOperation::GetFullName(MarkupTagsT tags)
|
||||
{
|
||||
string txt = tags[TAG_BOLD].start + mRetType;
|
||||
txt += " ";
|
||||
txt += mName;
|
||||
txt += "( ";
|
||||
txt += tags[TAG_BOLD].end;
|
||||
|
||||
for( size_t i = 0; i != mMembers.size(); ++i )
|
||||
{
|
||||
// DBG::
|
||||
wxASSERT( mMembers[i]->GetContextType() == SP_CTX_PARAMETER );
|
||||
|
||||
spParameter& param = *((spParameter*)mMembers[i]);
|
||||
|
||||
if ( i != 0 )
|
||||
txt += ", ";
|
||||
|
||||
txt += tags[TAG_BOLD].start;
|
||||
|
||||
txt += param.mType;
|
||||
|
||||
txt += tags[TAG_BOLD].end;
|
||||
txt += tags[TAG_ITALIC].start;
|
||||
|
||||
txt += " ";
|
||||
txt += param.mName;
|
||||
|
||||
if ( param.mInitVal != "" )
|
||||
{
|
||||
txt += " = ";
|
||||
txt += tags[TAG_BOLD].start;
|
||||
|
||||
txt += param.mInitVal;
|
||||
|
||||
txt += tags[TAG_BOLD].end;
|
||||
}
|
||||
|
||||
txt += tags[TAG_ITALIC].end;;
|
||||
}
|
||||
|
||||
txt += tags[TAG_BOLD].start;
|
||||
txt += " )";
|
||||
txt += tags[TAG_BOLD].end;
|
||||
|
||||
// TBD:: constantness of method
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
/***** Implemenentation for class spPreprocessorLine *****/
|
||||
|
||||
string spPreprocessorLine::CPP_GetIncludedFileNeme()
|
||||
{
|
||||
wxASSERT( GetStatementType() == SP_PREP_DEF_INCLUDE_FILE );
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '<' )
|
||||
|
||||
++i;
|
||||
|
||||
++i;
|
||||
|
||||
size_t start = i;
|
||||
|
||||
while( i < mLine.length() && mLine[i] != '"' && mLine[i] != '>' )
|
||||
|
||||
++i;
|
||||
|
||||
if ( start < mLine.length() )
|
||||
{
|
||||
string fname;
|
||||
fname.append( mLine, start, ( i - start ) );
|
||||
|
||||
return fname;
|
||||
}
|
||||
else
|
||||
return ""; // syntax error probably
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***** Implemenentation for class SourceParserBase *****/
|
||||
|
||||
SourceParserBase::SourceParserBase()
|
||||
|
||||
: mpFileBuf( NULL ),
|
||||
mFileBufSz( 0 ),
|
||||
|
||||
mpPlugin( NULL )
|
||||
{}
|
||||
|
||||
SourceParserBase::~SourceParserBase()
|
||||
{
|
||||
if ( mpFileBuf ) free( mpFileBuf );
|
||||
|
||||
if ( mpPlugin ) delete mpPlugin;
|
||||
}
|
||||
|
||||
spFile* SourceParserBase::ParseFile( const char* fname )
|
||||
{
|
||||
// FIXME:: the below should not be fixed!
|
||||
|
||||
const size_t MAX_BUF_SIZE = 1024*256;
|
||||
|
||||
if ( !mpFileBuf ) mpFileBuf = (char*)malloc( MAX_BUF_SIZE );
|
||||
|
||||
mFileBufSz = MAX_BUF_SIZE;
|
||||
|
||||
FILE* fp = fopen( fname, "rt" );
|
||||
|
||||
if ( (int)fp == -1 || !fp ) return NULL;
|
||||
|
||||
int sz = fread( mpFileBuf, 1, mFileBufSz, fp );
|
||||
|
||||
return Parse( mpFileBuf, mpFileBuf + sz );
|
||||
}
|
||||
|
||||
void SourceParserBase::SetPlugin( SourceParserPlugin* pPlugin )
|
||||
{
|
||||
if ( mpPlugin ) delete mpPlugin;
|
||||
|
||||
mpPlugin = pPlugin;
|
||||
}
|
31
utils/HelpGen/src/wx_extra_imps.cpp
Normal file
31
utils/HelpGen/src/wx_extra_imps.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
////////////////////
|
||||
//
|
||||
// craeted by Alex
|
||||
//
|
||||
////////////////////
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/defs.h"
|
||||
#endif
|
||||
|
||||
char *
|
||||
copystring (const char *s)
|
||||
{
|
||||
if (s == NULL) s = "";
|
||||
size_t len = strlen (s) + 1;
|
||||
|
||||
char *news = new char[len];
|
||||
memcpy (news, s, len); // Should be the fastest
|
||||
|
||||
return news;
|
||||
}
|
||||
|
||||
const char *wxGetTranslation(const char *str)
|
||||
{
|
||||
return str;
|
||||
}
|
Reference in New Issue
Block a user