1999-01-08 12:46:08 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: No names yet.
|
|
|
|
// Purpose: Contrib. demo
|
|
|
|
// Author: Aleksandras Gluchovas
|
|
|
|
// Modified by:
|
|
|
|
// Created: 22/09/98
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) Aleskandars Gluchovas
|
2005-05-23 11:22:10 -04:00
|
|
|
// Licence: wxWindows licence
|
1999-01-08 12:46:08 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifndef __SCRIPTBINDER_G__
|
|
|
|
#define __SCRIPTBINDER_G__
|
|
|
|
|
|
|
|
#if defined( wxUSE_TEMPLATE_STL )
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
#include <vector>
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
#ifdef WIN32
|
|
|
|
#include <bstring.h>
|
|
|
|
#else
|
|
|
|
#include <strclass.h>
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
#include "wxstlvec.h"
|
|
|
|
#include "wx/string.h"
|
|
|
|
|
1999-01-08 12:46:08 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef ASSERT
|
|
|
|
// assert yourself
|
|
|
|
#define ASSERT(x) if (!(x) ) throw;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "markup.h"
|
|
|
|
|
|
|
|
// just another portable stream class...
|
|
|
|
|
|
|
|
class ScriptStream
|
|
|
|
{
|
|
|
|
protected:
|
2005-06-02 05:44:45 -04:00
|
|
|
char* m_pBuf;
|
|
|
|
size_t m_Size;
|
|
|
|
size_t m_Capacity;
|
1999-01-08 12:46:08 -05:00
|
|
|
public:
|
2005-05-23 11:22:10 -04:00
|
|
|
ScriptStream();
|
|
|
|
~ScriptStream();
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
void WriteBytes( const void* srcBuf, size_t count );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
ScriptStream& operator<<( const char* str );
|
2005-06-02 05:44:45 -04:00
|
|
|
ScriptStream& operator<<( const wxString& str );
|
2005-05-23 11:22:10 -04:00
|
|
|
ScriptStream& operator<<( char ch );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
void endl();
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
inline char* GetBuf() { return m_pBuf; }
|
|
|
|
inline size_t GetBufSize() { return m_Size; }
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// clears current contents of the stream
|
2005-06-02 05:44:45 -04:00
|
|
|
void Reset() { m_Size = 0; }
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ScriptTemplate;
|
|
|
|
|
|
|
|
// used internally by ScriptTemplate
|
|
|
|
|
|
|
|
enum TEMPLATE_VARIABLE_TYPES
|
|
|
|
{
|
2005-05-23 11:22:10 -04:00
|
|
|
TVAR_INTEGER,
|
|
|
|
TVAR_STRING,
|
|
|
|
TVAR_DOUBLE,
|
|
|
|
TVAR_REF_ARRAY
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// helper structures used only by ScriptTemplate
|
|
|
|
|
|
|
|
struct TVarInfo
|
|
|
|
{
|
|
|
|
public:
|
2005-05-23 11:22:10 -04:00
|
|
|
const char* m_Name;
|
2005-05-24 05:06:21 -04:00
|
|
|
int m_Type;
|
2005-06-02 05:44:45 -04:00
|
|
|
int m_Ofs;
|
2005-05-23 11:22:10 -04:00
|
|
|
|
|
|
|
TVarInfo( const char* name, int ofs, int varType )
|
|
|
|
: m_Name(name),
|
2005-05-24 05:06:21 -04:00
|
|
|
m_Type( varType ),
|
2005-06-02 05:44:45 -04:00
|
|
|
m_Ofs( ofs )
|
2005-05-23 11:22:10 -04:00
|
|
|
{}
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TArrayInfo : public TVarInfo
|
|
|
|
{
|
|
|
|
public:
|
2005-06-02 05:44:45 -04:00
|
|
|
int m_RefOfs;
|
|
|
|
int m_SizeIntOfs;
|
|
|
|
int m_ObjRefTemplOfs;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
TArrayInfo( const char* name )
|
|
|
|
: TVarInfo( name, 0, TVAR_REF_ARRAY )
|
|
|
|
{}
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// stores offset of the given member (of the given class)
|
2005-05-23 11:22:10 -04:00
|
|
|
// to (*pOfs), though the use of template classes would have
|
1999-01-08 12:46:08 -05:00
|
|
|
// solved this problem in much clearer fashion
|
|
|
|
|
|
|
|
// FOR NOW:: obtaining physical offset of class member
|
|
|
|
// does not appeare to be protable across compilers?
|
|
|
|
// FIXME:: +/- 1 problem
|
|
|
|
|
|
|
|
#ifdef __UNIX__
|
2005-05-23 11:22:10 -04:00
|
|
|
#define WEIRD_OFFSET 1
|
1999-01-08 12:46:08 -05:00
|
|
|
#else
|
2005-05-23 11:22:10 -04:00
|
|
|
#define WEIRD_OFFSET 0
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define GET_VAR_OFS( className, varName, pOfs ) \
|
2005-05-23 11:22:10 -04:00
|
|
|
{ \
|
|
|
|
int* className::* varPtr; \
|
|
|
|
varPtr = (int* className::*)&className::varName; \
|
|
|
|
\
|
|
|
|
(*pOfs) = int(*(int*)&varPtr)-WEIRD_OFFSET; \
|
|
|
|
}
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
class ScriptSection;
|
|
|
|
|
|
|
|
#if defined( wxUSE_TEMPLATE_STL )
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
typedef vector<TVarInfo*> TVarListT;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// container class for sections
|
|
|
|
typedef vector<ScriptSection*> SectListT;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
typedef TVarInfo* TVarInfoPtrT;
|
|
|
|
typedef ScriptSection* ScriptSectionPtrT;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
typedef WXSTL_VECTOR_SHALLOW_COPY(TVarInfoPtrT) TVarListT;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// container class for sections
|
|
|
|
typedef WXSTL_VECTOR_SHALLOW_COPY(ScriptSectionPtrT) SectListT;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// class performs preprocessing of arbitrary scripts,
|
|
|
|
// replaces identifiers enclosed in $(..) tag, whith
|
|
|
|
// values of the corresponding class member variables
|
|
|
|
|
|
|
|
class ScriptTemplate
|
|
|
|
{
|
|
|
|
protected:
|
2005-06-02 05:44:45 -04:00
|
|
|
// do not use wxString object here - parsing of
|
2005-05-23 11:22:10 -04:00
|
|
|
// C string can be much faster (in debug v.)
|
2005-06-02 05:44:45 -04:00
|
|
|
char* m_TText;
|
2005-05-23 11:22:10 -04:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
TVarListT m_Vars;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
inline void PrintVar( TVarInfo* pInfo,
|
|
|
|
void* dataObj,
|
|
|
|
ScriptStream& stm );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
public:
|
2005-06-02 05:44:45 -04:00
|
|
|
ScriptTemplate( const wxString& templateText );
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual ~ScriptTemplate();
|
|
|
|
|
|
|
|
bool HasVar( const char* name );
|
|
|
|
|
|
|
|
// Member variables registration methods.
|
|
|
|
|
|
|
|
// NOTE:: GET_VAR_OFS() macro should be used
|
|
|
|
// to get offset of the class member (see #define above)
|
|
|
|
void AddStringVar ( const char* name, int ofs );
|
|
|
|
void AddIntegerVar( const char* name, int ofs );
|
|
|
|
void AddDoubleVar ( const char* name, int ofs );
|
|
|
|
|
|
|
|
void AddObjectRefArray( const char* name,
|
|
|
|
int ofsRefToFirstObj,
|
|
|
|
int ofsObjSizeInt,
|
|
|
|
int ofsObjRefTempl
|
|
|
|
);
|
|
|
|
|
|
|
|
// reads the script, replaces $(..) tags with values
|
|
|
|
// of registered members of dataObj object, and outputs
|
|
|
|
// the result to given text stream
|
|
|
|
|
|
|
|
void PrintScript( void* dataObj, ScriptStream& stm );
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
class ScriptSection;
|
|
|
|
|
|
|
|
// class manages section and aggregated sections of
|
|
|
|
// inter-linked documents
|
|
|
|
|
|
|
|
class ScriptSection
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NOTE:: "$(NAME)", $(ID), "$(BODY)" and "$(REFLIST)" are
|
|
|
|
// reseved template variables of ScriptSection
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// the below there members are registered to ScriptTemplate,
|
|
|
|
// GUID within the section tree (numeric)
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
ScriptSection* m_pParent;
|
|
|
|
wxString m_Id; // $(ID)
|
|
|
|
wxString m_Name;// $(NAME)
|
|
|
|
wxString m_Body; // $(BODY)
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NULL, if this section is not aggregated anywhere
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
SectListT m_Subsections; // aggregated sectons
|
|
|
|
SectListT m_References; // registered as $(REFLIST)
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
bool m_AutoHide; // see autoHide arg, in constructor
|
|
|
|
bool m_SortOn; // true, if sort subsectons by naem
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// tempalte for this section
|
2005-06-02 05:44:45 -04:00
|
|
|
ScriptTemplate* m_pSectTempl;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// template used for links (or references) to this section
|
2005-06-02 05:44:45 -04:00
|
|
|
ScriptTemplate* m_pRefTempl;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// do not call destructor of this object,
|
|
|
|
// call RemoveRef() instead
|
2005-06-02 05:44:45 -04:00
|
|
|
int m_RefCount;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-06-02 05:44:45 -04:00
|
|
|
static int m_IdCounter; // generator of GUIDs
|
2005-05-23 11:22:10 -04:00
|
|
|
|
|
|
|
// fields registered and used by ScriptTemplate object
|
2005-06-02 05:44:45 -04:00
|
|
|
void* m_RefFirst;
|
|
|
|
int m_ArrSize;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
protected:
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual void AddRef();
|
|
|
|
virtual void RemoveRef();
|
|
|
|
void DoRemoveEmptySections(int& nRemoved, SectListT& removedLst);
|
|
|
|
void DoRemoveDeadLinks( SectListT& removedLst);
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NOTE:: pass NULL to certain template, if your sure
|
|
|
|
// this kind of template will never be used,
|
|
|
|
// e.g. if section is contained but never referrenced,
|
|
|
|
// then pReferenceTemplate can be NULL
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// if autoHide option is true, the section will be automatically
|
|
|
|
// collapsed (not shown) if it doesn't contain any references
|
|
|
|
// to other sections (e.g. could be usefull for autoamically
|
|
|
|
// hiding empty index-sections).
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-30 13:01:56 -04:00
|
|
|
ScriptSection( const wxString& name = wxEmptyString,
|
|
|
|
const wxString& body = wxEmptyString,
|
2005-05-23 11:22:10 -04:00
|
|
|
ScriptTemplate* pSectionTemplate = NULL,
|
|
|
|
ScriptTemplate* pReferenceTemplate = NULL,
|
|
|
|
bool autoHide = false,
|
|
|
|
bool sorted = false
|
|
|
|
);
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// calls RemoveRef() to all aggreagated sections first,
|
|
|
|
// then to all referenced section - this way all
|
|
|
|
// sections (even not aggregated ones) become "garbage-collected"
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NOTE:: do not call destructor directlly, call RemoveRef()
|
|
|
|
// instead
|
|
|
|
virtual ~ScriptSection();
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// if addToReferencesToo is true, section is aggregated and
|
|
|
|
// also added to reference list of this section
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
void AddSection( ScriptSection* pSection, bool addToReferencesToo = false );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// add cross-reference to this given section
|
|
|
|
void AddReference( ScriptSection* pReferredSection );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// subsection may be given of variable depth level,
|
|
|
|
// e.g. "publications/reviews/software"
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
ScriptSection* GetSubsection( const char* name );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// returns list aggregated sections
|
|
|
|
SectListT& GetSubsections();
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// binds reserved template names ( $(..) ) to member
|
|
|
|
// vairalbes in the ScriptSection class, should be called
|
|
|
|
// to initialize each user-code provided script template
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
static void RegisterTemplate( ScriptTemplate& sectionTempalte );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// prints out section tree to the stream, starting from
|
|
|
|
// this section as a root node
|
|
|
|
virtual void Print( ScriptStream& stm );
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// searches empty sections which has autoHide == true,
|
|
|
|
// and colapses them (this method should be called )
|
|
|
|
// on the root-section of the sections tree
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NOTE:: does not work properly, yet!
|
|
|
|
void RemoveEmptySections();
|
1999-01-08 12:46:08 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// base class for documnetation generators
|
|
|
|
// (allows user code set up target script type,
|
|
|
|
// independently of documentation type)
|
|
|
|
|
|
|
|
class DocGeneratorBase
|
|
|
|
{
|
|
|
|
protected:
|
2005-06-02 05:44:45 -04:00
|
|
|
MarkupTagsT m_Tags;
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// override this method to do some post processing
|
|
|
|
// after generation of document, or even write some
|
|
|
|
// data into output stream, before the section tree
|
|
|
|
// is flushed into it.
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// return false, if something has gone wrong and
|
|
|
|
// document cannot be saved now
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual bool OnSaveDocument( ScriptStream& WXUNUSED(stm) )
|
|
|
|
{ return 1; }
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// override this method to provide reference to
|
|
|
|
// the top section of the document (used as default
|
|
|
|
// starting section when saving a document)
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual ScriptSection* GetTopSection()
|
|
|
|
{ return 0; }
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
DocGeneratorBase()
|
2005-06-02 05:44:45 -04:00
|
|
|
: m_Tags(0) // no defaul script
|
2005-05-23 11:22:10 -04:00
|
|
|
{}
|
|
|
|
|
|
|
|
// dectrouctors of polymorphic classes SHOULD be virtual
|
|
|
|
virtual ~DocGeneratorBase() {}
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// returns tags, being used for specific target script
|
2005-06-02 05:44:45 -04:00
|
|
|
MarkupTagsT GetScriptMarkupTags() { return m_Tags; }
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// sets tag array for specific script
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// NOTE:: Why virtual? since approach with MarkupTagsT is
|
|
|
|
// "flowless" only in theory. Overriding this method
|
|
|
|
// allows document generators to check the type of the
|
|
|
|
// target script, and perhaps make some modifications
|
|
|
|
// to generator's tamplates, to match the specific script
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual void SetScriptMarkupTags( MarkupTagsT tags )
|
2005-06-02 05:44:45 -04:00
|
|
|
{ m_Tags = tags; }
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// seves document to file starting from the root-node of
|
|
|
|
// the document (provided by GetTopSection() method),
|
|
|
|
// or from "pFromSection" if it's not NULL.
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
// fopenOptions arg. is string passed to fopen() method,
|
2005-05-31 05:29:22 -04:00
|
|
|
// returns true, if saving was successful
|
1999-01-08 12:46:08 -05:00
|
|
|
|
2005-05-23 11:22:10 -04:00
|
|
|
virtual bool SaveDocument( const char* fname,
|
|
|
|
const char* fopenOptions = "w",
|
|
|
|
ScriptSection* pFromSection = NULL
|
|
|
|
);
|
1999-01-08 12:46:08 -05:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|