]>
git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/ifcontext.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 # pragma implementation "ifcontext.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
32 #include "ifcontext.h"
34 /***** Implementation for class spInterFileContext *****/
36 size_t spInterFileContext::GetFileNo( const string
& fname
)
39 for ( i
= 0; i
!= mFiles
.size(); ++i
)
40 if ( fname
== mFiles
[i
] )
43 wxFAIL_MSG("File not found in array in function spInterFileContext::GetFileNo()");
47 size_t spInterFileContext::GetFileNoOfContext( spContext
& ctx
)
49 spContext
* pCtx
= ctx
.GetEnclosingContext( SP_CTX_FILE
);
51 // DBG:: outer-file context should be present
52 wxASSERT( pCtx
&& pCtx
->GetType() == SP_CTX_FILE
);
54 return GetFileNo( ((spFile
*)pCtx
)->mFileName
);
57 /*** public interface ***/
59 spInterFileContext::spInterFileContext()
62 spInterFileContext::~spInterFileContext()
65 void spInterFileContext::AddFile( const string
& fname
, const string
& content
)
67 mFiles
.push_back( fname
);
68 mContents
.push_back( content
);
71 void spInterFileContext::RemoveContext( spContext
& ctx
)
73 wxASSERT( ctx
.PositionIsKnown() ); // DBG:: should be checked by-user code
75 size_t fNo
= GetFileNoOfContext( ctx
);
77 mDeletionMarks
.push_back( spBookmark( ctx
.mSrcOffset
, ctx
.mContextLength
, fNo
) );
80 void spInterFileContext::InsertBookmarkSorted( BookmarkListT
& lst
, spBookmark
& mark
)
82 for( size_t i
= 0; i
!= lst
.size(); ++i
)
84 if ( lst
[i
].mFrom
> mark
.mFrom
)
86 lst
.insert( &lst
[i
], mark
);
90 lst
.push_back( mark
);
93 void spInterFileContext::DoAppendSourceFragment( string
& source
,
95 size_t pos
, size_t len
)
97 mFiltered
.erase( mFiltered
.begin(), mFiltered
.end() );
101 for( i
= 0; i
!= mDeletionMarks
.size(); ++i
)
103 spBookmark
& mark
= mDeletionMarks
[i
];
105 if ( mark
.mFileNo
== mCurFileNo
&&
106 mark
.mFrom
>= pos
&& mark
.mFrom
< pos
+ len
)
108 InsertBookmarkSorted( mFiltered
, mark
);
113 for( i
= 0; i
!= mFiltered
.size(); ++ i
)
115 spBookmark
& mark
= mFiltered
[i
];
117 result
.append( source
, cur
, ( (size_t)mark
.mFrom
- cur
) );
119 cur
= size_t( mark
.mFrom
+ mark
.mLen
);
121 if ( cur
>= pos
+ len
) // check if we've overstepped the current source-fragment
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;
129 result
.append( source
, cur
, ( pos
+ len
) - cur
);
132 void spInterFileContext::GenerateContextBody( spContext
& ctx
,
135 size_t& lastSavedPos
,
136 size_t& lastKnownPos
)
138 if ( ctx
.PositionIsKnown() )
140 lastKnownPos
= ctx
.mSrcOffset
;
142 if ( ctx
.IsVirtualContext() )
144 // add fragment accumulated before this context
146 DoAppendSourceFragment( source
, result
,
147 size_t(lastSavedPos
),
148 size_t(lastKnownPos
- lastSavedPos
) );
152 result
+= ctx
.GetVirtualContextBody();
154 lastSavedPos
= lastKnownPos
;
156 if ( ctx
.PositionIsKnown() )
158 if ( ctx
.VitualContextHasChildren() )
160 lastKnownPos
= ctx
.mSrcOffset
+ ctx
.mHeaderLength
;
162 lastSavedPos
= lastKnownPos
;
166 lastKnownPos
= ctx
.mSrcOffset
+ ctx
.mContextLength
;
168 lastSavedPos
= lastKnownPos
;
170 return; // have not children
175 MMemberListT
& lst
= ctx
.GetMembers();
177 for( size_t i
= 0; i
!= lst
.size(); ++i
)
179 GenerateContextBody( *lst
[i
], source
, result
, lastSavedPos
, lastKnownPos
);
181 if ( ctx
.IsVirtualContext() )
183 if ( ctx
.VitualContextHasChildren() &&
185 ctx
.GetFooterOfVirtualContextBody() != "" )
187 // append the reminder space after children of the context
189 DoAppendSourceFragment( result
, source
,
190 size_t(lastSavedPos
),
191 size_t(lastKnownPos
- lastSavedPos
) );
194 result
+= ctx
.GetFooterOfVirtualContextBody();
196 lastKnownPos
= ctx
.mSrcOffset
+ ctx
.mContextLength
;
198 lastSavedPos
= lastKnownPos
;
202 if ( ctx
.PositionIsKnown() )
204 lastKnownPos
= ctx
.mSrcOffset
+ ctx
.mContextLength
;
207 void spInterFileContext::GenrateContents()
209 MMemberListT
& lst
= GetMembers();
211 for( size_t f
= 0; f
!= lst
.size(); ++f
)
213 string
& fname
= ((spFile
*)lst
[f
])->mFileName
;
215 size_t fileNo
= GetFileNo( fname
);
217 string
& source
= mContents
[ fileNo
];
221 size_t lastKnownPos
= 0, // the begining of the file is always "known"
226 GenerateContextBody( *lst
[f
], source
, result
, lastSavedPos
, lastKnownPos
);
228 // the end of file is always known
230 lastKnownPos
= mContents
[ fileNo
].length();
232 // append the reminder
234 DoAppendSourceFragment( source
, result
,
235 size_t(lastSavedPos
),
236 size_t(lastKnownPos
- lastSavedPos
) );
238 // replace original contnet with newly generated one
240 mContents
[ fileNo
] = result
;
244 void spInterFileContext::ParseContents( SourceParserPlugin
* pPlugin
)
246 mDeletionMarks
.erase( mDeletionMarks
.begin(), mDeletionMarks
.end() );
248 RemoveChildren(); // clean up top-level context
250 mParser
.SetPlugin( pPlugin
);
252 for( size_t i
= 0; i
!= mFiles
.size(); ++i
)
254 char* s
= (char*)(mContents
[i
].c_str());
256 spFile
* pFCtx
= mParser
.Parse( s
, s
+ mContents
[i
].length() );
258 pFCtx
->mFileName
= mFiles
[i
];
264 void spInterFileContext::WriteToFiles()
266 for( size_t i
= 0; i
!= mFiles
.size(); ++i
)
268 FILE* fp
= fopen( mFiles
[i
].c_str(), "w+t" );
272 fwrite( mContents
[i
].c_str(), sizeof(char), mContents
[i
].length(), fp
);
279 string
spInterFileContext::GetBody( spContext
* pCtx
)
281 wxASSERT( pCtx
->PositionIsKnown() ); // DBG:: should be checked by-user code
283 string
& source
= mContents
[ GetFileNoOfContext( *pCtx
) ];
285 return string( source
.c_str() + pCtx
->mSrcOffset
, pCtx
->mContextLength
);
288 string
spInterFileContext::GetHeader( spContext
* pCtx
)
290 wxASSERT( pCtx
->PositionIsKnown() ); // DBG:: should be checked by-user code
292 wxASSERT( pCtx
->mHeaderLength
!= -1 ); // DBG:: -/-
294 string
& source
= mContents
[ GetFileNoOfContext( *pCtx
) ];
296 return string( source
.c_str() + pCtx
->mSrcOffset
, pCtx
->mHeaderLength
);