]> git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/ifcontext.cpp
1. removed wxObject::CopyObject() and Clone() - some objects just can't be
[wxWidgets.git] / utils / HelpGen / src / ifcontext.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: No names yet.
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
5 // Modified by:
6 // Created: 27/12/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 # pragma implementation "ifcontext.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #ifndef __DARWIN__
28 # include <malloc.h>
29 #endif
30 #include <stdio.h>
31
32 #include "ifcontext.h"
33
34 /***** Implementation for class spInterFileContext *****/
35
36 size_t spInterFileContext::GetFileNo( const string& fname )
37 {
38 for( size_t i = 0; i != mFiles.size(); ++i )
39
40 if ( fname == mFiles[i] ) return i;
41
42 wxASSERT(0); // DBG::
43 return 0;
44 }
45
46 size_t spInterFileContext::GetFileNoOfContext( spContext& ctx )
47 {
48 spContext* pCtx = ctx.GetEnclosingContext( SP_CTX_FILE );
49
50 // DBG:: outer-file context should be present
51 wxASSERT( pCtx && pCtx->GetType() == SP_CTX_FILE );
52
53 return GetFileNo( ((spFile*)pCtx)->mFileName );
54 }
55
56 /*** public interface ***/
57
58 spInterFileContext::spInterFileContext()
59 {}
60
61 spInterFileContext::~spInterFileContext()
62 {}
63
64 void spInterFileContext::AddFile( const string& fname, const string& content )
65 {
66 mFiles.push_back( fname );
67 mContents.push_back( content );
68 }
69
70 void spInterFileContext::RemoveContext( spContext& ctx )
71 {
72 wxASSERT( ctx.PositionIsKnown() ); // DBG:: should be checked by-user code
73
74 size_t fNo = GetFileNoOfContext( ctx );
75
76 mDeletionMarks.push_back( spBookmark( ctx.mSrcOffset, ctx.mContextLength, fNo ) );
77 }
78
79 void spInterFileContext::InsertBookmarkSorted( BookmarkListT& lst, spBookmark& mark )
80 {
81 for( size_t i = 0; i != lst.size(); ++i )
82
83 if ( lst[i].mFrom > mark.mFrom )
84 {
85 lst.insert( &lst[i], mark );
86 return;
87 }
88
89 lst.push_back( mark );
90 }
91
92 void spInterFileContext::DoAppendSourceFragment( string& source,
93 string& result,
94 size_t pos, size_t len )
95 {
96 mFiltered.erase( mFiltered.begin(), mFiltered.end() );
97
98 size_t i;
99
100 for( i = 0; i != mDeletionMarks.size(); ++i )
101 {
102 spBookmark& mark = mDeletionMarks[i];
103
104 if ( mark.mFileNo == mCurFileNo &&
105 mark.mFrom >= pos && mark.mFrom < pos + len )
106
107 InsertBookmarkSorted( mFiltered, mark );
108 }
109
110 size_t cur = pos;
111
112 for( i = 0; i != mFiltered.size(); ++ i )
113 {
114 spBookmark& mark = mFiltered[i];
115
116 result.append( source, cur, ( (size_t)mark.mFrom - cur ) );
117
118 cur = size_t( mark.mFrom + mark.mLen );
119
120 if ( cur >= pos + len ) // check if we've overstepped the current source-fragment
121 {
122 wxASSERT(0); // DBG:: with current imp. this should not happen
123
124 cur = pos + len; break;
125 }
126 }
127
128 result.append( source, cur, ( pos + len ) - cur );
129 }
130
131 void spInterFileContext::GenerateContextBody( spContext& ctx,
132 string& source,
133 string& result,
134 size_t& lastSavedPos,
135 size_t& lastKnownPos )
136 {
137 if ( ctx.PositionIsKnown() )
138
139 lastKnownPos = ctx.mSrcOffset;
140
141 if ( ctx.IsVirtualContext() )
142 {
143 // add fragment accumulated before this context
144
145 DoAppendSourceFragment( source, result,
146 size_t(lastSavedPos),
147 size_t(lastKnownPos - lastSavedPos) );
148
149 // add context body
150
151 result += ctx.GetVirtualContextBody();
152
153 lastSavedPos = lastKnownPos;
154
155 if ( ctx.PositionIsKnown() )
156 {
157 if ( ctx.VitualContextHasChildren() )
158 {
159 lastKnownPos = ctx.mSrcOffset + ctx.mHeaderLength;
160
161 lastSavedPos = lastKnownPos;
162 }
163 else
164 {
165 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
166
167 lastSavedPos = lastKnownPos;
168
169 return; // have not children
170 }
171 }
172 }
173
174 MMemberListT& lst = ctx.GetMembers();
175
176 for( size_t i = 0; i != lst.size(); ++i )
177
178 GenerateContextBody( *lst[i], source, result, lastSavedPos, lastKnownPos );
179
180 if ( ctx.IsVirtualContext() )
181 {
182 if ( ctx.VitualContextHasChildren() &&
183
184 ctx.GetFooterOfVirtualContextBody() != "" )
185 {
186 // append the reminder space after children of the context
187
188 DoAppendSourceFragment( result, source,
189 size_t(lastSavedPos),
190 size_t(lastKnownPos - lastSavedPos) );
191
192 // add footer
193 result += ctx.GetFooterOfVirtualContextBody();
194
195 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
196
197 lastSavedPos = lastKnownPos;
198 }
199 }
200
201 if ( ctx.PositionIsKnown() )
202
203 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
204 }
205
206 void spInterFileContext::GenrateContents()
207 {
208 MMemberListT& lst = GetMembers();
209
210 for( size_t f = 0; f != lst.size(); ++f )
211 {
212 string& fname = ((spFile*)lst[f])->mFileName;
213
214 size_t fileNo = GetFileNo( fname );
215
216 string& source = mContents[ fileNo ];
217
218 string result;
219
220 size_t lastKnownPos = 0, // the begining of the file is always "known"
221 lastSavedPos = 0;
222
223 mCurFileNo = fileNo;
224
225 GenerateContextBody( *lst[f], source, result, lastSavedPos, lastKnownPos );
226
227 // the end of file is always known
228
229 lastKnownPos = mContents[ fileNo ].length();
230
231 // append the reminder
232
233 DoAppendSourceFragment( source, result,
234 size_t(lastSavedPos),
235 size_t(lastKnownPos - lastSavedPos) );
236
237 // replace original contnet with newly generated one
238
239 mContents[ fileNo ] = result;
240 }
241 }
242
243 void spInterFileContext::ParseContents( SourceParserPlugin* pPlugin )
244 {
245 mDeletionMarks.erase( mDeletionMarks.begin(), mDeletionMarks.end() );
246
247 RemoveChildren(); // clean up top-level context
248
249 mParser.SetPlugin( pPlugin );
250
251 for( size_t i = 0; i != mFiles.size(); ++i )
252 {
253 char* s = (char*)(mContents[i].c_str());
254
255 spFile* pFCtx = mParser.Parse( s, s + mContents[i].length() );
256
257 pFCtx->mFileName = mFiles[i];
258
259 AddMember( pFCtx );
260 }
261 }
262
263 void spInterFileContext::WriteToFiles()
264 {
265 for( size_t i = 0; i != mFiles.size(); ++i )
266 {
267 FILE* fp = fopen( mFiles[i].c_str(), "w+t" );
268
269 if ( int(fp) > 0 )
270 {
271 fwrite( mContents[i].c_str(), sizeof(char), mContents[i].length(), fp );
272
273 fclose( fp );
274 }
275 }
276 }
277
278 string spInterFileContext::GetBody( spContext* pCtx )
279 {
280 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
281
282 string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
283
284 return string( source.c_str() + pCtx->mSrcOffset, pCtx->mContextLength );
285 }
286
287 string spInterFileContext::GetHeader( spContext* pCtx )
288 {
289 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
290
291 wxASSERT( pCtx->mHeaderLength != -1 ); // DBG:: -/-
292
293 string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
294
295 return string( source.c_str() + pCtx->mSrcOffset, pCtx->mHeaderLength );
296 }