]> git.saurik.com Git - wxWidgets.git/blame - utils/HelpGen/src/ifcontext.cpp
HelpGen is a prototype of the tool for automatic generation of the .tex files
[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__
13#pragma implementation "ifcontext.h"
14#pragma interface
15#endif
16
17// For compilers that support precompilation, includes "wx/wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25#include "wx/wx.h"
26#endif
27
28#include <malloc.h>
29#include <stdio.h>
30
31#include "ifcontext.h"
32
33/***** Implementation for class spInterFileContext *****/
34
35size_t spInterFileContext::GetFileNo( const string& fname )
36{
37 for( size_t i = 0; i != mFiles.size(); ++i )
38
39 if ( fname == mFiles[i] ) return i;
40
41 wxASSERT(0); // DBG::
42 return 0;
43}
44
45size_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)->mFileName );
53}
54
55/*** public interface ***/
56
57spInterFileContext::spInterFileContext()
58{}
59
60spInterFileContext::~spInterFileContext()
61{}
62
63void spInterFileContext::AddFile( const string& fname, const string& content )
64{
65 mFiles.push_back( fname );
66 mContents.push_back( content );
67}
68
69void 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
78void 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
91void spInterFileContext::DoAppendSourceFragment( string& source,
92 string& 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
123 cur = pos + len; break;
124 }
125 }
126
127 result.append( source, cur, ( pos + len ) - cur );
128}
129
130void spInterFileContext::GenerateContextBody( spContext& ctx,
131 string& source,
132 string& result,
133 size_t& lastSavedPos,
134 size_t& lastKnownPos )
135{
136 if ( ctx.PositionIsKnown() )
137
138 lastKnownPos = ctx.mSrcOffset;
139
140 if ( ctx.IsVirtualContext() )
141 {
142 // add fragment accumulated before this context
143
144 DoAppendSourceFragment( source, result,
145 size_t(lastSavedPos),
146 size_t(lastKnownPos - lastSavedPos) );
147
148 // add context body
149
150 result += ctx.GetVirtualContextBody();
151
152 lastSavedPos = lastKnownPos;
153
154 if ( ctx.PositionIsKnown() )
155 {
156 if ( ctx.VitualContextHasChildren() )
157 {
158 lastKnownPos = ctx.mSrcOffset + ctx.mHeaderLength;
159
160 lastSavedPos = lastKnownPos;
161 }
162 else
163 {
164 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
165
166 lastSavedPos = lastKnownPos;
167
168 return; // have not children
169 }
170 }
171 }
172
173 MMemberListT& lst = ctx.GetMembers();
174
175 for( size_t i = 0; i != lst.size(); ++i )
176
177 GenerateContextBody( *lst[i], source, result, lastSavedPos, lastKnownPos );
178
179 if ( ctx.IsVirtualContext() )
180 {
181 if ( ctx.VitualContextHasChildren() &&
182
183 ctx.GetFooterOfVirtualContextBody() != "" )
184 {
185 // append the reminder space after children of the context
186
187 DoAppendSourceFragment( result, source,
188 size_t(lastSavedPos),
189 size_t(lastKnownPos - lastSavedPos) );
190
191 // add footer
192 result += ctx.GetFooterOfVirtualContextBody();
193
194 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
195
196 lastSavedPos = lastKnownPos;
197 }
198 }
199
200 if ( ctx.PositionIsKnown() )
201
202 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
203}
204
205void spInterFileContext::GenrateContents()
206{
207 MMemberListT& lst = GetMembers();
208
209 for( size_t f = 0; f != lst.size(); ++f )
210 {
211 string& fname = ((spFile*)lst[f])->mFileName;
212
213 size_t fileNo = GetFileNo( fname );
214
215 string& source = mContents[ fileNo ];
216
217 string result;
218
219 size_t lastKnownPos = 0, // the begining of the file is always "known"
220 lastSavedPos = 0;
221
222 mCurFileNo = fileNo;
223
224 GenerateContextBody( *lst[f], source, result, lastSavedPos, lastKnownPos );
225
226 // the end of file is always known
227
228 lastKnownPos = mContents[ fileNo ].length();
229
230 // append the reminder
231
232 DoAppendSourceFragment( source, result,
233 size_t(lastSavedPos),
234 size_t(lastKnownPos - lastSavedPos) );
235
236 // replace original contnet with newly generated one
237
238 mContents[ fileNo ] = result;
239 }
240}
241
242void spInterFileContext::ParseContents( SourceParserPlugin* pPlugin )
243{
244 mDeletionMarks.erase( mDeletionMarks.begin(), mDeletionMarks.end() );
245
246 RemoveChildren(); // clean up top-level context
247
248 mParser.SetPlugin( pPlugin );
249
250 for( size_t i = 0; i != mFiles.size(); ++i )
251 {
252 char* s = (char*)(mContents[i].c_str());
253
254 spFile* pFCtx = mParser.Parse( s, s + mContents[i].length() );
255
256 pFCtx->mFileName = mFiles[i];
257
258 AddMember( pFCtx );
259 }
260}
261
262void spInterFileContext::WriteToFiles()
263{
264 for( size_t i = 0; i != mFiles.size(); ++i )
265 {
266 FILE* fp = fopen( mFiles[i].c_str(), "w+t" );
267
268 if ( int(fp) > 0 )
269 {
270 fwrite( mContents[i].c_str(), sizeof(char), mContents[i].length(), fp );
271
272 fclose( fp );
273 }
274 }
275}
276
277string spInterFileContext::GetBody( spContext* pCtx )
278{
279 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
280
281 string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
282
283 return string( source.c_str() + pCtx->mSrcOffset, pCtx->mContextLength );
284}
285
286string spInterFileContext::GetHeader( spContext* pCtx )
287{
288 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
289
290 wxASSERT( pCtx->mHeaderLength != -1 ); // DBG:: -/-
291
292 string& source = mContents[ GetFileNoOfContext( *pCtx ) ];
293
294 return string( source.c_str() + pCtx->mSrcOffset, pCtx->mHeaderLength );
295}