]> git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/ifcontext.cpp
include wx/defs.h (and hence wx/platform.h and so really fix the bug 1105676)
[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 wxString& fname )
37 {
38 for ( size_t i = 0; i != m_Files.size(); ++i )
39 {
40 if ( fname == m_Files[i] )
41 return i;
42 }
43
44 wxFAIL_MSG("File not found in array in function spInterFileContext::GetFileNo()");
45
46 return 0;
47 }
48
49 size_t spInterFileContext::GetFileNoOfContext( spContext& ctx )
50 {
51 spContext* pCtx = ctx.GetEnclosingContext( SP_CTX_FILE );
52
53 // DBG:: outer-file context should be present
54 wxASSERT( pCtx && pCtx->GetType() == SP_CTX_FILE );
55
56 return GetFileNo( ((spFile*)pCtx)->m_FileName );
57 }
58
59 /*** public interface ***/
60
61 spInterFileContext::spInterFileContext()
62 {}
63
64 spInterFileContext::~spInterFileContext()
65 {}
66
67 void spInterFileContext::AddFile( const wxString& fname, const wxString& content )
68 {
69 m_Files.push_back( fname );
70 m_Contents.push_back( content );
71 }
72
73 void spInterFileContext::RemoveContext( spContext& ctx )
74 {
75 wxASSERT( ctx.PositionIsKnown() ); // DBG:: should be checked by-user code
76
77 size_t fNo = GetFileNoOfContext( ctx );
78
79 mDeletionMarks.push_back( spBookmark( ctx.mSrcOffset, ctx.mContextLength, fNo ) );
80 }
81
82 void spInterFileContext::InsertBookmarkSorted( BookmarkListT& lst, spBookmark& mark )
83 {
84 for( size_t i = 0; i != lst.size(); ++i )
85
86 if ( lst[i].mFrom > mark.mFrom )
87 {
88 lst.insert( &lst[i], mark );
89 return;
90 }
91
92 lst.push_back( mark );
93 }
94
95 void spInterFileContext::DoAppendSourceFragment( wxString& source,
96 wxString& result,
97 size_t pos, size_t len )
98 {
99 mFiltered.erase( mFiltered.begin(), mFiltered.end() );
100
101 size_t i;
102
103 for( i = 0; i != mDeletionMarks.size(); ++i )
104 {
105 spBookmark& mark = mDeletionMarks[i];
106
107 if ( mark.mFileNo == mCurFileNo &&
108 mark.mFrom >= pos && mark.mFrom < pos + len )
109
110 InsertBookmarkSorted( mFiltered, mark );
111 }
112
113 size_t cur = pos;
114
115 for( i = 0; i != mFiltered.size(); ++ i )
116 {
117 spBookmark& mark = mFiltered[i];
118
119 result.append( source, cur, ( (size_t)mark.mFrom - cur ) );
120
121 cur = size_t( mark.mFrom + mark.mLen );
122
123 if ( cur >= pos + len ) // check if we've overstepped the current source-fragment
124 {
125 // wxASSERT(0); // DBG:: with current imp. this should not happen
126 wxFAIL_MSG("Overstepped the current source fragment in function\nspInterFileContext::DoAppendSourceFragment()");
127 cur = pos + len; break;
128 }
129 }
130
131 result.append( source, cur, ( pos + len ) - cur );
132 }
133
134 void spInterFileContext::GenerateContextBody( spContext& ctx,
135 wxString& source,
136 wxString& result,
137 size_t& lastSavedPos,
138 size_t& lastKnownPos )
139 {
140 if ( ctx.PositionIsKnown() )
141 lastKnownPos = ctx.mSrcOffset;
142
143 if ( ctx.IsVirtualContext() )
144 {
145 // add fragment accumulated before this context
146
147 DoAppendSourceFragment( source, result,
148 size_t(lastSavedPos),
149 size_t(lastKnownPos - lastSavedPos) );
150
151 // add context body
152
153 result += ctx.GetVirtualContextBody();
154
155 lastSavedPos = lastKnownPos;
156
157 if ( ctx.PositionIsKnown() )
158 {
159 if ( ctx.VitualContextHasChildren() )
160 {
161 lastKnownPos = ctx.mSrcOffset + ctx.mHeaderLength;
162
163 lastSavedPos = lastKnownPos;
164 }
165 else
166 {
167 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
168
169 lastSavedPos = lastKnownPos;
170
171 return; // have not children
172 }
173 }
174 }
175
176 MMemberListT& lst = ctx.GetMembers();
177
178 for( size_t i = 0; i != lst.size(); ++i )
179 {
180 GenerateContextBody( *lst[i], source, result, lastSavedPos, lastKnownPos );
181 }
182
183 if ( ctx.IsVirtualContext() )
184 {
185 if ( ctx.VitualContextHasChildren() && !ctx.GetFooterOfVirtualContextBody().empty() )
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
207 void spInterFileContext::GenrateContents()
208 {
209 MMemberListT& lst = GetMembers();
210
211 for( size_t f = 0; f != lst.size(); ++f )
212 {
213 wxString& fname = ((spFile*)lst[f])->m_FileName;
214
215 size_t fileNo = GetFileNo( fname );
216
217 wxString& source = m_Contents[ fileNo ];
218
219 wxString 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 = m_Contents[ 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 m_Contents[ fileNo ] = result;
241 }
242 }
243
244 void 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 != m_Files.size(); ++i )
253 {
254 wxChar* s = (char*)(m_Contents[i].c_str());
255
256 spFile* pFCtx = mParser.Parse( s, s + m_Contents[i].length() );
257
258 pFCtx->m_FileName = m_Files[i];
259
260 AddMember( pFCtx );
261 }
262 }
263
264 void spInterFileContext::WriteToFiles()
265 {
266 for( size_t i = 0; i != m_Files.size(); ++i )
267 {
268 FILE* fp = fopen( m_Files[i].c_str(), "w+t" );
269
270 if ( fp != NULL )
271 {
272 fwrite( m_Contents[i].c_str(), sizeof(char), m_Contents[i].length(), fp );
273
274 fclose( fp );
275 }
276 }
277 }
278
279 wxString spInterFileContext::GetBody( spContext* pCtx )
280 {
281 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
282
283 wxString& source = m_Contents[ GetFileNoOfContext( *pCtx ) ];
284
285 return wxString( source.c_str() + pCtx->mSrcOffset, pCtx->mContextLength );
286 }
287
288 wxString 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 wxString& source = m_Contents[ GetFileNoOfContext( *pCtx ) ];
295
296 return wxString( source.c_str() + pCtx->mSrcOffset, pCtx->mHeaderLength );
297 }