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