]>
Commit | Line | Data |
---|---|---|
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 | size_t i; | |
39 | for ( i = 0; i != mFiles.size(); ++i ) | |
40 | if ( fname == mFiles[i] ) | |
41 | return i; | |
42 | ||
43 | wxFAIL_MSG("File not found in array in function spInterFileContext::GetFileNo()"); | |
44 | return 0; | |
45 | } | |
46 | ||
47 | size_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 | ||
59 | spInterFileContext::spInterFileContext() | |
60 | {} | |
61 | ||
62 | spInterFileContext::~spInterFileContext() | |
63 | {} | |
64 | ||
65 | void spInterFileContext::AddFile( const string& fname, const string& content ) | |
66 | { | |
67 | mFiles.push_back( fname ); | |
68 | mContents.push_back( content ); | |
69 | } | |
70 | ||
71 | void 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 | ||
80 | void 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 | ||
93 | void 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 | { | |
123 | // wxASSERT(0); // DBG:: with current imp. this should not happen | |
124 | wxFAIL_MSG("Overstepped the current source fragment in function\nspInterFileContext::DoAppendSourceFragment()"); | |
125 | cur = pos + len; break; | |
126 | } | |
127 | } | |
128 | ||
129 | result.append( source, cur, ( pos + len ) - cur ); | |
130 | } | |
131 | ||
132 | void 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 | ||
207 | void 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 | ||
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 != 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 | ||
264 | void 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 | ||
279 | string 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 | ||
288 | string 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 | } |