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