Subversion Repositories spk

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "bod_text_parser.h"
2
#include "../common/strutils.h"
3
 
4
#include <memory.h>
5
//---------------------------------------------------------------------------------
114 cycrow 6
// ERROR
7
const char* bod_text_parser::Error::m_messages[]={
8
	"No error",
9
	"Newline in constant"
10
};
11
 
1 cycrow 12
// TOKEN
114 cycrow 13
const char* bod_text_parser::token::specialChars[]={ "{", "}", ";", ":", "=", "/!", "!/", "/#", "(", ")", "/", ".", "+" };
1 cycrow 14
char bod_text_parser::token::tabWidth;
15
 
16
const char* bod_text_parser::token::getText() const
17
{ 
18
	if(type >= t_text)
19
		return text;
20
	else
21
		return specialChars[(int)type];
22
}
23
//---------------------------------------------------------------------------------
24
void bod_text_parser::preParseBuffer(char *pszBuffer, size_t size)
25
{
26
	m_pszBuffer=pszBuffer;
27
	m_buffLen=size;
28
}	
29
//---------------------------------------------------------------------------------
30
size_t bod_text_parser::parseBuffer(size_t limit)
31
{
114 cycrow 32
	char *ln;
1 cycrow 33
	size_t old=tokens.size();
114 cycrow 34
	while(ln=nextLine()){
35
		if(parseLine(ln, ++m_lineIdx)==false)
1 cycrow 36
			break;
114 cycrow 37
 
1 cycrow 38
		if(limit!=-1 && ((tokens.size() - old) >= limit)){
39
			break;
40
		}
41
	}
42
	return tokens.size() - old;
43
}
44
//---------------------------------------------------------------------------------
114 cycrow 45
#define PUSH_PREVIOUS_STRING() { t=new token(); \
46
t->type=token::t_text; \
47
t->line=idx; \
48
t->text=old; \
49
t->col=(int)(old - line + 1); \
50
tokens.push_back(t); }
51
 
52
#define PUSH_TOKEN(_type, _col, _text) { t=new token(); \
53
t->type=_type; \
54
t->line=idx; \
55
t->col=(int)(_col); \
56
t->text=_text; \
57
tokens.push_back(t); }
58
 
59
bool bod_text_parser::parseLine(char *line, int idx)
1 cycrow 60
{
61
	char *old=line, *pos=line, ch;
62
	token *t;
114 cycrow 63
	bool bInQuotedString=false;
1 cycrow 64
 
65
	while(*pos!=0){
66
		ch=*pos;
114 cycrow 67
 
68
		if(bInQuotedString || (ch=='"' && testFlag(parseQuotedStrings))){
69
			if(ch=='"'){
70
				bInQuotedString=!bInQuotedString;
71
 
72
				*pos=0;
73
				if(bInQuotedString){
74
					if(*old!=0)
75
						PUSH_PREVIOUS_STRING();
76
				}	
77
				// got string
78
				else
79
					PUSH_TOKEN(token::t_quotedString, old - line, old);
80
 
81
				old=pos + 1;
82
			}
83
			else{
84
				++pos;
85
				continue;
86
			}
87
		}
88
 
89
		else if(ch==';' || ch==':' || (ch=='=' && testFlag(parseEqual)) || 
90
		(testFlag(parseOperators) && (ch=='.' || ch=='+'))) {
1 cycrow 91
			*pos=0;
92
 
114 cycrow 93
			if(*old!=0)
94
				PUSH_PREVIOUS_STRING();
1 cycrow 95
 
114 cycrow 96
			token::Type ty;
97
			switch(ch){
98
				case ';':
99
					ty=token::t_semicolon;
100
					break;
101
				case ':':
102
					ty=token::t_colon;
103
					break;
104
				case '=':
105
					ty=token::t_equal;
106
					break;
107
				case '.':
108
					ty=token::t_dot;
109
					break;
110
				case '+':
111
					ty=token::t_plus;
112
					break;
113
			}
114
			PUSH_TOKEN(ty, pos - line + 1, 0);
115
 
1 cycrow 116
			old=pos + 1;
117
		}
118
		// space or tabulator
119
		else if(ch==' ' || ch==0x9){
120
			*pos=0;
114 cycrow 121
			if(*old!=0)
122
				PUSH_PREVIOUS_STRING();
123
 
1 cycrow 124
			old=pos + 1;
125
		}
114 cycrow 126
		// brackets
127
		else if(ch=='{' || ch=='}' || (testFlag(parseStdBrackets) && (ch=='(' || ch==')'))) {
1 cycrow 128
			*pos=0;
114 cycrow 129
			if(*old!=0)
130
				PUSH_PREVIOUS_STRING();
131
 
132
			token::Type ty;
133
			switch(ch){
134
				case '{':
135
					ty=token::t_openCrBracket;
136
					break;
137
				case '}':
138
					ty=token::t_closeCrBracket;
139
					break;
140
				case '(':
141
					ty=token::t_openStdBracket;
142
					break;
143
				case ')':
144
					ty=token::t_closeStdBracket;
145
					break;
1 cycrow 146
			}
114 cycrow 147
			PUSH_TOKEN(ty, pos - line + 1, 0);
148
 
1 cycrow 149
			old=pos + 1;
150
		}
151
		// either comment, header info or processing instruction
152
		else if(ch=='/') {
153
			if(pos[1]=='#'){
154
				t=new token();
155
				t->text=pos + 2;
156
				while(*t->text!=0 && *t->text==' ')
157
					t->text++;
158
				if(*t->text==0)
159
					delete t;
160
				else{
161
					t->line=idx;
162
					t->col=(int)(pos - line) + 1;
163
					t->type=token::t_hdrinfo;
164
					tokens.push_back(t);
165
				}
166
			}
167
			// open proc instruction /!
168
			if(pos[1]=='!') {
114 cycrow 169
				PUSH_TOKEN(token::t_openInstrBlock, pos - line + 1, 0);
1 cycrow 170
				old=pos + 2;
171
				pos++;
172
			}
114 cycrow 173
			// slash
174
			else{
175
				/* if ignore slash is on then do nothing
176
				  else treat it as comment unless C comments are specified, in which case there must
177
				  be // to make comment, otherwise / is treated as token
178
				*/
179
				if(testFlag(parseIgnoreSlash)==false){
180
					if(testFlag(parseBODComments)) {
181
						*pos=0;
182
						pos--;
183
					}
184
					else if(testFlag(parseCComments) && pos[1]=='/') {
185
						*pos=0;
186
						pos--;
187
					}
188
					else {
189
						*pos=0;
190
						if(*old!=0)
191
							PUSH_PREVIOUS_STRING();
192
 
193
						PUSH_TOKEN(token::t_slash, pos - line + 1, 0);
194
						old=pos + 1;
195
					}
196
				}
1 cycrow 197
			}
198
		}
199
		// close proc instruction !/
200
		else if(ch=='!' && pos[1]=='/'){
201
			*pos=0;
114 cycrow 202
			if(*old!=0)
203
				PUSH_PREVIOUS_STRING();
204
 
205
			PUSH_TOKEN(token::t_closeInstrBlock, pos - line + 1, 0);
1 cycrow 206
			old=pos + 2;
207
			pos++;
208
		}
114 cycrow 209
 
1 cycrow 210
		pos++;
211
	}
114 cycrow 212
 
213
	if(bInQuotedString){
214
		error(idx, (int)strlen(line), Error::errNewLineInConstant);
215
		return false;
216
	}
1 cycrow 217
	// if there are some chars left after last delimeter (usually ;) this will process them
218
	if(old!=pos){
114 cycrow 219
		PUSH_TOKEN(token::t_text, old - line + 1, old);
1 cycrow 220
	}
114 cycrow 221
	return true;
1 cycrow 222
}
223
//---------------------------------------------------------------------------------
224
char * bod_text_parser::nextLine()
225
{
226
	size_t i, size=m_buffLen;
227
	char *line=0, *buffer=(char*)m_pszBuffer;
228
 
229
	for(i=m_lastPos; i < size; i++){
230
		if(buffer[i]==0xD){
231
			buffer[i]=0;
232
			m_newPos=i;
233
			if(((i + 1) < size) && buffer[i+1]==0xA) {
234
				m_newPos++;
235
			}
236
			m_newPos++;
237
			line=buffer + m_lastPos;
238
 
239
			break;
240
		}
241
		else if(buffer[i]==0xA){
242
			buffer[i]=0;
243
			m_newPos=i + 1;
244
 
245
			line=buffer + m_lastPos;
246
			break;
247
		}
248
	}
249
	if(m_lastPos > size) return NULL;
250
 
251
	if(line==0) {
252
		line=buffer + m_lastPos;
253
		m_newPos=size + 1;
254
	}
255
 
256
	m_lastPos=m_newPos;
257
 
258
	return line;
259
}
260
//---------------------------------------------------------------------------------