]>
Commit | Line | Data |
---|---|---|
cecfc5e7 VZ |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: No names yet. | |
3 | // Purpose: Contrib. demo | |
4 | // Author: Aleksandras Gluchovas | |
5 | // Modified by: | |
6 | // Created: 22/09/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Aleskandars Gluchovas | |
8bc17f14 | 9 | // Licence: wxWindows licence |
cecfc5e7 VZ |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
12 | #ifndef __SCRIPTBINDER_G__ | |
13 | #define __SCRIPTBINDER_G__ | |
14 | ||
15 | #if defined( wxUSE_TEMPLATE_STL ) | |
16 | ||
8bc17f14 | 17 | #include <vector> |
cecfc5e7 | 18 | |
8bc17f14 WS |
19 | #ifdef WIN32 |
20 | #include <bstring.h> | |
21 | #else | |
22 | #include <strclass.h> | |
23 | #include <string.h> | |
24 | #endif | |
cecfc5e7 VZ |
25 | |
26 | #else | |
27 | ||
8bc17f14 WS |
28 | #include "wxstlvec.h" |
29 | #include "wx/string.h" | |
30 | ||
31 | #if wxUSE_STD_STRING | |
32 | using std::string; | |
33 | #else | |
34 | // FIXME:: dirty! | |
35 | typedef wxString string; | |
36 | #endif | |
cecfc5e7 VZ |
37 | |
38 | #endif | |
39 | ||
40 | #ifndef ASSERT | |
41 | // assert yourself | |
42 | #define ASSERT(x) if (!(x) ) throw; | |
43 | #endif | |
44 | ||
45 | #include "markup.h" | |
46 | ||
47 | // just another portable stream class... | |
48 | ||
49 | class ScriptStream | |
50 | { | |
51 | protected: | |
8bc17f14 WS |
52 | char* mpBuf; |
53 | size_t mSize; | |
54 | size_t mCapacity; | |
cecfc5e7 | 55 | public: |
8bc17f14 WS |
56 | ScriptStream(); |
57 | ~ScriptStream(); | |
cecfc5e7 | 58 | |
8bc17f14 | 59 | void WriteBytes( const void* srcBuf, size_t count ); |
cecfc5e7 | 60 | |
8bc17f14 WS |
61 | ScriptStream& operator<<( const char* str ); |
62 | ScriptStream& operator<<( const string& str ); | |
63 | ScriptStream& operator<<( char ch ); | |
cecfc5e7 | 64 | |
8bc17f14 | 65 | void endl(); |
cecfc5e7 | 66 | |
8bc17f14 WS |
67 | inline char* GetBuf() { return mpBuf; } |
68 | inline size_t GetBufSize() { return mSize; } | |
cecfc5e7 | 69 | |
8bc17f14 WS |
70 | // clears current contents of the stream |
71 | void Reset() { mSize = 0; } | |
cecfc5e7 VZ |
72 | }; |
73 | ||
74 | ||
75 | class ScriptTemplate; | |
76 | ||
77 | // used internally by ScriptTemplate | |
78 | ||
79 | enum TEMPLATE_VARIABLE_TYPES | |
80 | { | |
8bc17f14 WS |
81 | TVAR_INTEGER, |
82 | TVAR_STRING, | |
83 | TVAR_DOUBLE, | |
84 | TVAR_REF_ARRAY | |
cecfc5e7 VZ |
85 | }; |
86 | ||
87 | // helper structures used only by ScriptTemplate | |
88 | ||
89 | struct TVarInfo | |
90 | { | |
91 | public: | |
8bc17f14 | 92 | const char* m_Name; |
821d644d | 93 | int m_Type; |
8bc17f14 WS |
94 | int mOfs; |
95 | ||
96 | TVarInfo( const char* name, int ofs, int varType ) | |
97 | : m_Name(name), | |
821d644d | 98 | m_Type( varType ), |
8bc17f14 WS |
99 | mOfs( ofs ) |
100 | {} | |
cecfc5e7 VZ |
101 | }; |
102 | ||
103 | struct TArrayInfo : public TVarInfo | |
104 | { | |
105 | public: | |
8bc17f14 WS |
106 | int mRefOfs; |
107 | int mSizeIntOfs; | |
108 | int mObjRefTemplOfs; | |
cecfc5e7 | 109 | |
8bc17f14 WS |
110 | TArrayInfo( const char* name ) |
111 | : TVarInfo( name, 0, TVAR_REF_ARRAY ) | |
112 | {} | |
cecfc5e7 VZ |
113 | }; |
114 | ||
115 | // stores offset of the given member (of the given class) | |
8bc17f14 | 116 | // to (*pOfs), though the use of template classes would have |
cecfc5e7 VZ |
117 | // solved this problem in much clearer fashion |
118 | ||
119 | // FOR NOW:: obtaining physical offset of class member | |
120 | // does not appeare to be protable across compilers? | |
121 | // FIXME:: +/- 1 problem | |
122 | ||
123 | #ifdef __UNIX__ | |
8bc17f14 | 124 | #define WEIRD_OFFSET 1 |
cecfc5e7 | 125 | #else |
8bc17f14 | 126 | #define WEIRD_OFFSET 0 |
cecfc5e7 VZ |
127 | |
128 | #endif | |
129 | ||
130 | #define GET_VAR_OFS( className, varName, pOfs ) \ | |
8bc17f14 WS |
131 | { \ |
132 | int* className::* varPtr; \ | |
133 | varPtr = (int* className::*)&className::varName; \ | |
134 | \ | |
135 | (*pOfs) = int(*(int*)&varPtr)-WEIRD_OFFSET; \ | |
136 | } | |
cecfc5e7 VZ |
137 | |
138 | class ScriptSection; | |
139 | ||
140 | #if defined( wxUSE_TEMPLATE_STL ) | |
141 | ||
8bc17f14 | 142 | typedef vector<TVarInfo*> TVarListT; |
cecfc5e7 | 143 | |
8bc17f14 WS |
144 | // container class for sections |
145 | typedef vector<ScriptSection*> SectListT; | |
cecfc5e7 VZ |
146 | |
147 | #else | |
148 | ||
8bc17f14 WS |
149 | typedef TVarInfo* TVarInfoPtrT; |
150 | typedef ScriptSection* ScriptSectionPtrT; | |
cecfc5e7 | 151 | |
8bc17f14 | 152 | typedef WXSTL_VECTOR_SHALLOW_COPY(TVarInfoPtrT) TVarListT; |
cecfc5e7 | 153 | |
8bc17f14 WS |
154 | // container class for sections |
155 | typedef WXSTL_VECTOR_SHALLOW_COPY(ScriptSectionPtrT) SectListT; | |
cecfc5e7 VZ |
156 | |
157 | #endif | |
158 | ||
159 | // class performs preprocessing of arbitrary scripts, | |
160 | // replaces identifiers enclosed in $(..) tag, whith | |
161 | // values of the corresponding class member variables | |
162 | ||
163 | class ScriptTemplate | |
164 | { | |
165 | protected: | |
8bc17f14 WS |
166 | // do not use string object here - parsing of |
167 | // C string can be much faster (in debug v.) | |
168 | char* mTText; | |
169 | ||
170 | TVarListT mVars; | |
cecfc5e7 | 171 | |
8bc17f14 WS |
172 | inline void PrintVar( TVarInfo* pInfo, |
173 | void* dataObj, | |
174 | ScriptStream& stm ); | |
cecfc5e7 | 175 | |
cecfc5e7 | 176 | public: |
8bc17f14 WS |
177 | ScriptTemplate( const string& templateText ); |
178 | virtual ~ScriptTemplate(); | |
179 | ||
180 | bool HasVar( const char* name ); | |
181 | ||
182 | // Member variables registration methods. | |
183 | ||
184 | // NOTE:: GET_VAR_OFS() macro should be used | |
185 | // to get offset of the class member (see #define above) | |
186 | void AddStringVar ( const char* name, int ofs ); | |
187 | void AddIntegerVar( const char* name, int ofs ); | |
188 | void AddDoubleVar ( const char* name, int ofs ); | |
189 | ||
190 | void AddObjectRefArray( const char* name, | |
191 | int ofsRefToFirstObj, | |
192 | int ofsObjSizeInt, | |
193 | int ofsObjRefTempl | |
194 | ); | |
195 | ||
196 | // reads the script, replaces $(..) tags with values | |
197 | // of registered members of dataObj object, and outputs | |
198 | // the result to given text stream | |
199 | ||
200 | void PrintScript( void* dataObj, ScriptStream& stm ); | |
cecfc5e7 VZ |
201 | }; |
202 | ||
203 | class ScriptSection; | |
204 | ||
205 | // class manages section and aggregated sections of | |
206 | // inter-linked documents | |
207 | ||
208 | class ScriptSection | |
209 | { | |
210 | protected: | |
211 | ||
8bc17f14 WS |
212 | // NOTE:: "$(NAME)", $(ID), "$(BODY)" and "$(REFLIST)" are |
213 | // reseved template variables of ScriptSection | |
cecfc5e7 | 214 | |
8bc17f14 WS |
215 | // the below there members are registered to ScriptTemplate, |
216 | // GUID within the section tree (numeric) | |
cecfc5e7 | 217 | |
8bc17f14 WS |
218 | ScriptSection* mpParent; |
219 | string mId; // $(ID) | |
220 | string m_Name;// $(NAME) | |
221 | string mBody; // $(BODY) | |
cecfc5e7 | 222 | |
8bc17f14 | 223 | // NULL, if this section is not aggregated anywhere |
cecfc5e7 | 224 | |
8bc17f14 WS |
225 | SectListT mSubsections; // aggregated sectons |
226 | SectListT mReferences; // registered as $(REFLIST) | |
cecfc5e7 | 227 | |
8bc17f14 WS |
228 | bool mAutoHide; // see autoHide arg, in constructor |
229 | bool mSortOn; // true, if sort subsectons by naem | |
cecfc5e7 | 230 | |
8bc17f14 WS |
231 | // tempalte for this section |
232 | ScriptTemplate* mpSectTempl; | |
cecfc5e7 | 233 | |
8bc17f14 WS |
234 | // template used for links (or references) to this section |
235 | ScriptTemplate* mpRefTempl; | |
cecfc5e7 | 236 | |
8bc17f14 WS |
237 | // do not call destructor of this object, |
238 | // call RemoveRef() instead | |
239 | int mRefCount; | |
cecfc5e7 | 240 | |
8bc17f14 WS |
241 | static int mIdCounter; // generator of GUIDs |
242 | ||
243 | // fields registered and used by ScriptTemplate object | |
244 | void* mRefFirst; | |
245 | int mArrSize; | |
cecfc5e7 VZ |
246 | |
247 | protected: | |
8bc17f14 WS |
248 | virtual void AddRef(); |
249 | virtual void RemoveRef(); | |
250 | void DoRemoveEmptySections(int& nRemoved, SectListT& removedLst); | |
251 | void DoRemoveDeadLinks( SectListT& removedLst); | |
cecfc5e7 VZ |
252 | |
253 | public: | |
254 | ||
8bc17f14 WS |
255 | // NOTE:: pass NULL to certain template, if your sure |
256 | // this kind of template will never be used, | |
257 | // e.g. if section is contained but never referrenced, | |
258 | // then pReferenceTemplate can be NULL | |
cecfc5e7 | 259 | |
8bc17f14 WS |
260 | // if autoHide option is true, the section will be automatically |
261 | // collapsed (not shown) if it doesn't contain any references | |
262 | // to other sections (e.g. could be usefull for autoamically | |
263 | // hiding empty index-sections). | |
cecfc5e7 | 264 | |
8bc17f14 WS |
265 | ScriptSection( const string& name = "", |
266 | const string& body = "", | |
267 | ScriptTemplate* pSectionTemplate = NULL, | |
268 | ScriptTemplate* pReferenceTemplate = NULL, | |
269 | bool autoHide = false, | |
270 | bool sorted = false | |
271 | ); | |
cecfc5e7 | 272 | |
8bc17f14 WS |
273 | // calls RemoveRef() to all aggreagated sections first, |
274 | // then to all referenced section - this way all | |
275 | // sections (even not aggregated ones) become "garbage-collected" | |
cecfc5e7 | 276 | |
8bc17f14 WS |
277 | // NOTE:: do not call destructor directlly, call RemoveRef() |
278 | // instead | |
279 | virtual ~ScriptSection(); | |
cecfc5e7 VZ |
280 | |
281 | ||
8bc17f14 WS |
282 | // if addToReferencesToo is true, section is aggregated and |
283 | // also added to reference list of this section | |
cecfc5e7 | 284 | |
8bc17f14 | 285 | void AddSection( ScriptSection* pSection, bool addToReferencesToo = false ); |
cecfc5e7 | 286 | |
8bc17f14 WS |
287 | // add cross-reference to this given section |
288 | void AddReference( ScriptSection* pReferredSection ); | |
cecfc5e7 | 289 | |
8bc17f14 WS |
290 | // subsection may be given of variable depth level, |
291 | // e.g. "publications/reviews/software" | |
cecfc5e7 | 292 | |
8bc17f14 | 293 | ScriptSection* GetSubsection( const char* name ); |
cecfc5e7 | 294 | |
8bc17f14 WS |
295 | // returns list aggregated sections |
296 | SectListT& GetSubsections(); | |
cecfc5e7 | 297 | |
8bc17f14 WS |
298 | // binds reserved template names ( $(..) ) to member |
299 | // vairalbes in the ScriptSection class, should be called | |
300 | // to initialize each user-code provided script template | |
cecfc5e7 | 301 | |
8bc17f14 | 302 | static void RegisterTemplate( ScriptTemplate& sectionTempalte ); |
cecfc5e7 | 303 | |
8bc17f14 WS |
304 | // prints out section tree to the stream, starting from |
305 | // this section as a root node | |
306 | virtual void Print( ScriptStream& stm ); | |
cecfc5e7 | 307 | |
8bc17f14 WS |
308 | // searches empty sections which has autoHide == true, |
309 | // and colapses them (this method should be called ) | |
310 | // on the root-section of the sections tree | |
cecfc5e7 | 311 | |
8bc17f14 WS |
312 | // NOTE:: does not work properly, yet! |
313 | void RemoveEmptySections(); | |
cecfc5e7 VZ |
314 | }; |
315 | ||
316 | // base class for documnetation generators | |
317 | // (allows user code set up target script type, | |
318 | // independently of documentation type) | |
319 | ||
320 | class DocGeneratorBase | |
321 | { | |
322 | protected: | |
8bc17f14 | 323 | MarkupTagsT mTags; |
cecfc5e7 | 324 | |
8bc17f14 WS |
325 | // override this method to do some post processing |
326 | // after generation of document, or even write some | |
327 | // data into output stream, before the section tree | |
328 | // is flushed into it. | |
cecfc5e7 | 329 | |
8bc17f14 WS |
330 | // return false, if something has gone wrong and |
331 | // document cannot be saved now | |
cecfc5e7 | 332 | |
8bc17f14 WS |
333 | virtual bool OnSaveDocument( ScriptStream& WXUNUSED(stm) ) |
334 | { return 1; } | |
cecfc5e7 | 335 | |
8bc17f14 WS |
336 | // override this method to provide reference to |
337 | // the top section of the document (used as default | |
338 | // starting section when saving a document) | |
cecfc5e7 | 339 | |
8bc17f14 WS |
340 | virtual ScriptSection* GetTopSection() |
341 | { return 0; } | |
cecfc5e7 VZ |
342 | |
343 | public: | |
344 | ||
8bc17f14 WS |
345 | DocGeneratorBase() |
346 | : mTags(0) // no defaul script | |
347 | {} | |
348 | ||
349 | // dectrouctors of polymorphic classes SHOULD be virtual | |
350 | virtual ~DocGeneratorBase() {} | |
cecfc5e7 | 351 | |
8bc17f14 WS |
352 | // returns tags, being used for specific target script |
353 | MarkupTagsT GetScriptMarkupTags() { return mTags; } | |
cecfc5e7 | 354 | |
8bc17f14 | 355 | // sets tag array for specific script |
cecfc5e7 | 356 | |
8bc17f14 WS |
357 | // NOTE:: Why virtual? since approach with MarkupTagsT is |
358 | // "flowless" only in theory. Overriding this method | |
359 | // allows document generators to check the type of the | |
360 | // target script, and perhaps make some modifications | |
361 | // to generator's tamplates, to match the specific script | |
cecfc5e7 | 362 | |
8bc17f14 WS |
363 | virtual void SetScriptMarkupTags( MarkupTagsT tags ) |
364 | { mTags = tags; } | |
cecfc5e7 | 365 | |
8bc17f14 WS |
366 | // seves document to file starting from the root-node of |
367 | // the document (provided by GetTopSection() method), | |
368 | // or from "pFromSection" if it's not NULL. | |
cecfc5e7 | 369 | |
8bc17f14 WS |
370 | // fopenOptions arg. is string passed to fopen() method, |
371 | // returns true, if saving was successfull | |
cecfc5e7 | 372 | |
8bc17f14 WS |
373 | virtual bool SaveDocument( const char* fname, |
374 | const char* fopenOptions = "w", | |
375 | ScriptSection* pFromSection = NULL | |
376 | ); | |
cecfc5e7 | 377 | |
cecfc5e7 VZ |
378 | }; |
379 | ||
380 | #endif |