]> git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/scriptbinder.h
glibc's vswprintf doesn't nul terminate on truncation.
[wxWidgets.git] / utils / HelpGen / src / scriptbinder.h
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
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef __SCRIPTBINDER_G__
13 #define __SCRIPTBINDER_G__
14
15 #if defined( wxUSE_TEMPLATE_STL )
16
17 #include <vector>
18
19 #ifdef WIN32
20 #include <bstring.h>
21 #else
22 #include <strclass.h>
23 #include <string.h>
24 #endif
25
26 #else
27
28 #include "wxstlvec.h"
29 #include "wx/string.h"
30
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:
45 char* m_pBuf;
46 size_t m_Size;
47 size_t m_Capacity;
48 public:
49 ScriptStream();
50 ~ScriptStream();
51
52 void WriteBytes( const void* srcBuf, size_t count );
53
54 ScriptStream& operator<<( const char* str );
55 ScriptStream& operator<<( const wxString& str );
56 ScriptStream& operator<<( char ch );
57
58 void endl();
59
60 inline char* GetBuf() { return m_pBuf; }
61 inline size_t GetBufSize() { return m_Size; }
62
63 // clears current contents of the stream
64 void Reset() { m_Size = 0; }
65 };
66
67
68 class ScriptTemplate;
69
70 // used internally by ScriptTemplate
71
72 enum TEMPLATE_VARIABLE_TYPES
73 {
74 TVAR_INTEGER,
75 TVAR_STRING,
76 TVAR_DOUBLE,
77 TVAR_REF_ARRAY
78 };
79
80 // helper structures used only by ScriptTemplate
81
82 struct TVarInfo
83 {
84 public:
85 const char* m_Name;
86 int m_Type;
87 int m_Ofs;
88
89 TVarInfo( const char* name, int ofs, int varType )
90 : m_Name(name),
91 m_Type( varType ),
92 m_Ofs( ofs )
93 {}
94 };
95
96 struct TArrayInfo : public TVarInfo
97 {
98 public:
99 int m_RefOfs;
100 int m_SizeIntOfs;
101 int m_ObjRefTemplOfs;
102
103 TArrayInfo( const char* name )
104 : TVarInfo( name, 0, TVAR_REF_ARRAY )
105 {}
106 };
107
108 // stores offset of the given member (of the given class)
109 // to (*pOfs), though the use of template classes would have
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__
117 #define WEIRD_OFFSET 1
118 #else
119 #define WEIRD_OFFSET 0
120
121 #endif
122
123 #define GET_VAR_OFS( className, varName, pOfs ) \
124 { \
125 int* className::* varPtr; \
126 varPtr = (int* className::*)&className::varName; \
127 \
128 (*pOfs) = int(*(int*)&varPtr)-WEIRD_OFFSET; \
129 }
130
131 class ScriptSection;
132
133 #if defined( wxUSE_TEMPLATE_STL )
134
135 typedef vector<TVarInfo*> TVarListT;
136
137 // container class for sections
138 typedef vector<ScriptSection*> SectListT;
139
140 #else
141
142 typedef TVarInfo* TVarInfoPtrT;
143 typedef ScriptSection* ScriptSectionPtrT;
144
145 typedef WXSTL_VECTOR_SHALLOW_COPY(TVarInfoPtrT) TVarListT;
146
147 // container class for sections
148 typedef WXSTL_VECTOR_SHALLOW_COPY(ScriptSectionPtrT) SectListT;
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:
159 // do not use wxString object here - parsing of
160 // C string can be much faster (in debug v.)
161 char* m_TText;
162
163 TVarListT m_Vars;
164
165 inline void PrintVar( TVarInfo* pInfo,
166 void* dataObj,
167 ScriptStream& stm );
168
169 public:
170 ScriptTemplate( const wxString& templateText );
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 );
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
205 // NOTE:: "$(NAME)", $(ID), "$(BODY)" and "$(REFLIST)" are
206 // reseved template variables of ScriptSection
207
208 // the below there members are registered to ScriptTemplate,
209 // GUID within the section tree (numeric)
210
211 ScriptSection* m_pParent;
212 wxString m_Id; // $(ID)
213 wxString m_Name;// $(NAME)
214 wxString m_Body; // $(BODY)
215
216 // NULL, if this section is not aggregated anywhere
217
218 SectListT m_Subsections; // aggregated sectons
219 SectListT m_References; // registered as $(REFLIST)
220
221 bool m_AutoHide; // see autoHide arg, in constructor
222 bool m_SortOn; // true, if sort subsectons by naem
223
224 // tempalte for this section
225 ScriptTemplate* m_pSectTempl;
226
227 // template used for links (or references) to this section
228 ScriptTemplate* m_pRefTempl;
229
230 // do not call destructor of this object,
231 // call RemoveRef() instead
232 int m_RefCount;
233
234 static int m_IdCounter; // generator of GUIDs
235
236 // fields registered and used by ScriptTemplate object
237 void* m_RefFirst;
238 int m_ArrSize;
239
240 protected:
241 virtual void AddRef();
242 virtual void RemoveRef();
243 void DoRemoveEmptySections(int& nRemoved, SectListT& removedLst);
244 void DoRemoveDeadLinks( SectListT& removedLst);
245
246 public:
247
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
252
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).
257
258 ScriptSection( const wxString& name = wxEmptyString,
259 const wxString& body = wxEmptyString,
260 ScriptTemplate* pSectionTemplate = NULL,
261 ScriptTemplate* pReferenceTemplate = NULL,
262 bool autoHide = false,
263 bool sorted = false
264 );
265
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"
269
270 // NOTE:: do not call destructor directlly, call RemoveRef()
271 // instead
272 virtual ~ScriptSection();
273
274
275 // if addToReferencesToo is true, section is aggregated and
276 // also added to reference list of this section
277
278 void AddSection( ScriptSection* pSection, bool addToReferencesToo = false );
279
280 // add cross-reference to this given section
281 void AddReference( ScriptSection* pReferredSection );
282
283 // subsection may be given of variable depth level,
284 // e.g. "publications/reviews/software"
285
286 ScriptSection* GetSubsection( const char* name );
287
288 // returns list aggregated sections
289 SectListT& GetSubsections();
290
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
294
295 static void RegisterTemplate( ScriptTemplate& sectionTempalte );
296
297 // prints out section tree to the stream, starting from
298 // this section as a root node
299 virtual void Print( ScriptStream& stm );
300
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
304
305 // NOTE:: does not work properly, yet!
306 void RemoveEmptySections();
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:
316 MarkupTagsT m_Tags;
317
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.
322
323 // return false, if something has gone wrong and
324 // document cannot be saved now
325
326 virtual bool OnSaveDocument( ScriptStream& WXUNUSED(stm) )
327 { return 1; }
328
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)
332
333 virtual ScriptSection* GetTopSection()
334 { return 0; }
335
336 public:
337
338 DocGeneratorBase()
339 : m_Tags(0) // no defaul script
340 {}
341
342 // dectrouctors of polymorphic classes SHOULD be virtual
343 virtual ~DocGeneratorBase() {}
344
345 // returns tags, being used for specific target script
346 MarkupTagsT GetScriptMarkupTags() { return m_Tags; }
347
348 // sets tag array for specific script
349
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
355
356 virtual void SetScriptMarkupTags( MarkupTagsT tags )
357 { m_Tags = tags; }
358
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.
362
363 // fopenOptions arg. is string passed to fopen() method,
364 // returns true, if saving was successful
365
366 virtual bool SaveDocument( const char* fname,
367 const char* fopenOptions = "w",
368 ScriptSection* pFromSection = NULL
369 );
370
371 };
372
373 #endif