-
Notifications
You must be signed in to change notification settings - Fork 8
/
KAGParser.h
342 lines (278 loc) · 9.4 KB
/
KAGParser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
//---------------------------------------------------------------------------
/*
TVP2 ( T Visual Presenter 2 ) A script authoring tool
Copyright (C) 2000 W.Dee <[email protected]> and contributors
See details of license at "license.txt"
*/
//---------------------------------------------------------------------------
// KAG Parser Utility Class
//---------------------------------------------------------------------------
#ifndef KAGParserH
#define KAGParserH
//---------------------------------------------------------------------------
#ifdef _WIN32
#include <windows.h>
#endif
#include "tp_stub.h"
#include "tjsHashSearch.h"
#include <vector>
using namespace TJS;
/*[*/
//---------------------------------------------------------------------------
// KAG Parser debug level
//---------------------------------------------------------------------------
enum tTVPKAGDebugLevel
{
tkdlNone, // none is reported
tkdlSimple, // simple report
tkdlVerbose // complete report ( verbose )
};
/*]*/
//---------------------------------------------------------------------------
// tTVPCharHolder
//---------------------------------------------------------------------------
class tTVPCharHolder
{
tjs_char *Buffer;
size_t BufferSize;
public:
tTVPCharHolder() : Buffer(nullptr), BufferSize(0)
{
}
~tTVPCharHolder()
{
Clear();
}
tTVPCharHolder(const tTVPCharHolder &ref) : Buffer(nullptr), BufferSize(0)
{
operator =(ref);
}
void Clear()
{
if(Buffer) delete [] Buffer, Buffer = nullptr;
BufferSize = 0;
}
void operator =(const tTVPCharHolder &ref)
{
Clear();
BufferSize = ref.BufferSize;
Buffer = new tjs_char[BufferSize];
memcpy(Buffer, ref.Buffer, BufferSize *sizeof(tjs_char));
}
void operator =(const tjs_char *ref)
{
Clear();
if(ref)
{
BufferSize = TJS_strlen(ref) + 1;
Buffer = new tjs_char[BufferSize];
memcpy(Buffer, ref, BufferSize*sizeof(tjs_char));
}
}
operator const tjs_char *() const
{
return Buffer;
}
operator tjs_char *()
{
return Buffer;
}
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// tTVPScenarioCacheItem : Scenario Cache Item
//---------------------------------------------------------------------------
class tTVPScenarioCacheItem
{
public:
struct tLine
{
const tjs_char *Start;
tjs_int Length;
};
private:
tTVPCharHolder Buffer;
tLine *Lines;
tjs_int LineCount;
public:
struct tLabelCacheData
{
tjs_int Line;
tjs_int Count;
tLabelCacheData(tjs_int line, tjs_int count)
{
Line = line;
Count = count;
}
};
public:
typedef tTJSHashTable<ttstr, tLabelCacheData> tLabelCacheHash;
private:
tLabelCacheHash LabelCache; // Label cache
std::vector<ttstr> LabelAliases;
bool LabelCached; // whether the label is cached
tjs_int RefCount;
public:
tTVPScenarioCacheItem(const ttstr & name, bool istring);
protected:
~tTVPScenarioCacheItem();
public:
void AddRef();
void Release();
private:
void LoadScenario(const ttstr & name, bool isstring);
// load file or string to buffer
public:
const ttstr & GetLabelAliasFromLine(tjs_int line) const
{ return LabelAliases[line]; }
void EnsureLabelCache();
tLine * GetLines() const { return Lines; }
tjs_int GetLineCount() const { return LineCount; }
const tLabelCacheHash & GetLabelCache() const { return LabelCache; }
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// tTJSNI_KAGParser
//---------------------------------------------------------------------------
class tTJSNI_KAGParser : public tTJSNativeInstance
{
typedef tTJSNativeInstance inherited;
public:
tTJSNI_KAGParser();
tjs_error TJS_INTF_METHOD
Construct(tjs_int numparams, tTJSVariant **param,
iTJSDispatch2 *tjs_obj);
void TJS_INTF_METHOD Invalidate();
private:
iTJSDispatch2 * Owner; // owner object
iTJSDispatch2 * DicClear; // Dictionary.Clear method pointer
iTJSDispatch2 * DicAssign; // Dictionary
iTJSDispatch2 * DicObj; // DictionaryObject
iTJSDispatch2 * Macros; // Macro Dictionary Object
std::vector<iTJSDispatch2 *> MacroArgs; // Macro arguments
tjs_uint MacroArgStackDepth;
tjs_uint MacroArgStackBase;
struct tCallStackData
{
ttstr Storage; // caller storage
ttstr Label; // caller nearest label
tjs_int Offset; // line offset from the label
ttstr OrgLineStr; // original line string
ttstr LineBuffer; // line string (if alive)
tjs_int Pos;
bool LineBufferUsing; // whether LineBuffer is used or not
tjs_uint MacroArgStackBase;
tjs_uint MacroArgStackDepth;
std::vector<tjs_int> ExcludeLevelStack;
std::vector<bool> IfLevelExecutedStack;
tjs_int ExcludeLevel;
tjs_int IfLevel;
tCallStackData(const ttstr &storage, const ttstr &label,
tjs_int offset, const ttstr &orglinestr, const ttstr &linebuffer,
tjs_int pos, bool linebufferusing, tjs_uint macroargstackbase,
tjs_uint macroargstackdepth,
const std::vector<tjs_int> &excludelevelstack, tjs_int excludelevel,
const std::vector<bool> &iflevelexecutedstack, tjs_int iflevel) :
Storage(storage), Label(label), Offset(offset), OrgLineStr(orglinestr),
LineBuffer(linebuffer), Pos(pos), LineBufferUsing(linebufferusing),
MacroArgStackBase(macroargstackbase),
MacroArgStackDepth(macroargstackdepth),
ExcludeLevelStack(excludelevelstack), ExcludeLevel(excludelevel),
IfLevelExecutedStack(iflevelexecutedstack), IfLevel(iflevel) {;}
};
std::vector<tCallStackData> CallStack;
tTVPScenarioCacheItem * Scenario;
tTVPScenarioCacheItem::tLine * Lines; // is copied from Scenario
tjs_int LineCount; // is copied from Scenario
ttstr StorageName;
ttstr StorageShortName;
tjs_int CurLine; // current processing line
tjs_int CurPos; // current processing position ( column )
const tjs_char *CurLineStr; // current line string
ttstr LineBuffer; // line buffer ( if any macro/emb was expanded )
bool LineBufferUsing;
ttstr CurLabel; // Current Label
ttstr CurPage; // Current Page Name
tjs_int TagLine; // line number of previous tag
tTVPKAGDebugLevel DebugLevel; // debugging log level
bool ProcessSpecialTags; // whether to process special tags
bool IgnoreCR; // CR is not interpreted as [r] tag when this is true
bool RecordingMacro; // recording a macro
ttstr RecordingMacroStr; // recording macro content
ttstr RecordingMacroName; // recording macro's name
tTJSVariant ValueVariant;
tjs_int ExcludeLevel;
tjs_int IfLevel;
std::vector<tjs_int> ExcludeLevelStack;
std::vector<bool> IfLevelExecutedStack;
bool Interrupted;
public:
void operator = (const tTJSNI_KAGParser & ref);
iTJSDispatch2 *Store();
void Restore(iTJSDispatch2 *dic);
void Clear(); // clear all states
private:
void ClearBuffer(); // clear internal buffer
void Rewind(); // set current position to first
void BreakConditionAndMacro(); // break condition state and macro expansion
public:
void LoadScenario(const ttstr & name);
const ttstr & GetStorageName() const { return StorageName; }
void GoToLabel(const ttstr &name); // search label and set current position
void GoToStorageAndLabel(const ttstr &storage, const ttstr &label);
void CallLabel(const ttstr &name);
private:
bool SkipCommentOrLabel(); // skip comment or label and go to next line
void PushMacroArgs(iTJSDispatch2 *args);
public:
void PopMacroArgs();
private:
void ClearMacroArgs();
void PopMacroArgsTo(tjs_uint base);
void FindNearestLabel(tjs_int start, tjs_int &labelline, ttstr &labelname);
void PushCallStack();
void PopCallStack(const ttstr &storage, const ttstr &label);
void StoreIntStackToDic(iTJSDispatch2 *dic, std::vector<tjs_int> &stack, const tjs_char *membername);
void StoreBoolStackToDic(iTJSDispatch2 *dic, std::vector<bool> &stack, const tjs_char *membername);
void RestoreIntStackFromStr(std::vector<tjs_int> &stack, const ttstr &str);
void RestoreBoolStackFromStr(std::vector<bool> &stack, const ttstr &str);
public:
void ClearCallStack();
void Interrupt() { Interrupted = true; };
void ResetInterrupt() { Interrupted = false; };
private:
iTJSDispatch2 * _GetNextTag();
public:
iTJSDispatch2 * GetNextTag();
const ttstr & GetCurLabel() const { return CurLabel; }
tjs_int GetCurLine() const { return CurLine; }
tjs_int GetCurPos() const { return CurPos; }
const tjs_char* GetCurLineStr() const { return CurLineStr; }
void SetProcessSpecialTags(bool b) { ProcessSpecialTags = b; }
bool GetProcessSpecialTags() const { return ProcessSpecialTags; }
void SetIgnoreCR(bool b) { IgnoreCR = b; }
bool GetIgnoreCR() const { return IgnoreCR; }
void SetDebugLevel(tTVPKAGDebugLevel level) { DebugLevel = level; }
tTVPKAGDebugLevel GetDebugLevel(void) const { return DebugLevel; }
iTJSDispatch2 *GetMacrosNoAddRef() const { return Macros; }
iTJSDispatch2 *GetMacroTopNoAddRef() const;
// get current macro argument (parameters)
tjs_int GetCallStackDepth() const { return CallStack.size(); }
void Assign(const tTJSNI_KAGParser &ref) { operator =(ref); }
};
extern iTJSDispatch2 * TVPCreateNativeClass_KAGParser();
#if 0
//---------------------------------------------------------------------------
// tTJSNC_KAGParser
//---------------------------------------------------------------------------
class tTJSNC_KAGParser : public tTJSNativeClass
{
public:
tTJSNC_KAGParser();
static tjs_uint32 ClassID;
private:
iTJSNativeInstance *CreateNativeInstance();
};
//---------------------------------------------------------------------------
#endif
#endif