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