8 #include "../lib/utf8.h"
10 //RVALUE {NUMBER}|{PERCENT}|{NAME}|\"{STRING}\"|{DIM}
11 //<a>. {printf("<a>%s\n", yytext);}
12 // %x: exclusive, %s: inclusive
13 char*type_names[] = {"twip","number","command","string","assignment","identifier","label","end"};
20 static void count(char*text, int len, int condition)
33 static char*prefix = 0;
35 static void unescapeString(string_t * tmp)
38 /* fixme - this routine expects the string to be
41 for (p1=(char*)tmp->str; (p=strchr(p1, '\\')); p1 = p+1)
47 case '\\': p[0] = '\\'; break;
48 case '"': p[0] = '"'; break;
49 case 'b': p[0] = '\b'; break;
50 case 'f': p[0] = '\f'; break;
51 case 'n': p[0] = '\n'; break;
52 case 'r': p[0] = '\r'; break;
53 case 't': p[0] = '\t'; break;
62 bracket = 1;nr++;max++;
64 while(strchr("0123456789abcdefABCDEF", p[nr]) && (bracket || nr < max)) {
66 if(p[nr]>='0' && p[nr]<='9') num |= p[nr] - '0';
67 if(p[nr]>='a' && p[nr]<='f') num |= p[nr] - 'a' + 10;
68 if(p[nr]>='A' && p[nr]<='F') num |= p[nr] - 'A' + 10;
71 if(bracket && p[nr]=='}') {
77 memcpy(p, utf8, new); // do not copy the terminating zero
86 char*to=p+new,*from=p+nr;
96 static void store(enum type_t type, int line, int column, char*text, int length)
102 token.column = column;
103 //printf("->%d(%s) %s\n", type, type_names[type], text);fflush(stdout);
109 string_set2(&tmp, "", 0);
110 token.text_pos = mem_putstring(&strings, tmp);
113 string_set2(&tmp, text+1, length-2);
114 unescapeString(&tmp);
115 token.text_pos = mem_putstring(&strings, tmp);
120 string_set2(&tmp, text, length);
123 token.text_pos = mem_put(&strings, prefix, strlen(prefix));
124 mem_putstring(&strings, tmp);
126 token.text_pos = mem_putstring(&strings, tmp);
131 string_set2(&tmp, text+1/*:*/, length-5/*.end*/);
132 token.text_pos = mem_putstring(&strings, tmp);
135 string_set2(&tmp, text+1, length-1);
136 token.text_pos = mem_putstring(&strings, tmp);
139 char*x = &text[length-1];
140 if(x[-1] == '-' || x[-1] == '+')
142 do{x--;} while(*x==32 || *x==10 || *x==13 || *x=='\t');
144 string_set2(&tmp, text, x-text);
145 token.text_pos = mem_putstring(&strings, tmp);
146 /*char*y,*x = strchr(text, '=');
149 do{y--;} while(*y==32 || *y==10 || *y==13 || *y=='\t');
150 do{x++;} while(*x==32 || *x==10 || *x==13 || *x=='\t');
151 token.text1 = (char*)put(&strings, text, y-text + 1, 1);
152 token.text2 = (char*)put(&strings, x, length-(x-text), 1);*/
156 mem_put(&tokens, &token, sizeof(struct token_t));
160 #define MAX_INCLUDE_DEPTH 16
161 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
162 static int line_stack[MAX_INCLUDE_DEPTH];
163 static int column_stack[MAX_INCLUDE_DEPTH];
164 static int include_stack_ptr = 0;
166 static void handleInclude(char*text, int len)
169 while(len >=1 && (text[0] == ' ' || text[0] == '\t')) {
173 (text[len-1] == ' ' ||
174 text[len-1] == '\r' ||
175 text[len-1] == '\n')) {
178 if(len >= 2 && text[0] == '"' && text[len-1] == '"') {
182 if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
183 fprintf( stderr, "Includes nested too deeply" );
186 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
187 line_stack[include_stack_ptr] = line;
188 column_stack[include_stack_ptr] = column;
190 yyin = fopen(text, "rb");
192 fprintf(stderr, "Couldn't open %s\n", text);
195 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
205 #define c() {count(yytext, yyleng, YY_START);}
206 #define s(type) {store(type, line, column, yytext, yyleng);}
212 NAME [a-zA-Z_./](-*[a-zA-Z0-9_./])*
213 TWIP (-?[0-9]+(\.([0-9]([05])?)?)?)
214 NUMBER -?[0-9]+(\.[0-9]*)?
216 STRING (\\.|[^\\"\n])*
218 RVALUE \"{STRING}\"|([^ \n\r\t]+)
222 <BINARY>\] {c();BEGIN(0);}
225 {TWIP}/[ \n\r\t] {s(TWIP);c();BEGIN(0);}
226 {NUMBER}/[ \n\r\t] {s(NUMBER);c();BEGIN(0);}
228 [ \t\r]#[^\n]*\n {c();}
229 \"{STRING}\" {s(STRING);c();BEGIN(0);}
230 \"{STRING}$ {c();printf("unterminated string in line %d: %s\n", line, yytext);exit(1);yyterminate();}
231 {NAME}{S}*\+= {s(ASSIGNMENT);prefix="<plus>";c();BEGIN(R);}
232 {NAME}{S}*-= {s(ASSIGNMENT);prefix="<minus>";c();BEGIN(R);}
233 {NAME}{S}*= {s(ASSIGNMENT);c();BEGIN(R);}
234 <R>{ /* values which appear only on the right-hand side of assignments, like: x=50% */
235 [^ :\n\t\r]* {s(IDENTIFIER);c();BEGIN(0);}
237 \.include{S}.*\n {handleInclude(yytext, yyleng);}
238 \.{NAME} {s(COMMAND);c();}
239 :([^.]|\.[^e]|\.e[^n]|\.en[^d]|\.end[^ \n\r\t]|[ \n\r\t])*\.end {s(RAWDATA);c();}
240 {NAME} {s(IDENTIFIER);c();}
241 "[" {c();BEGIN(BINARY);}
243 . {char c,c1=yytext[0];
244 printf("Syntax error in line %d, %d: %s", line, column, yytext);
247 if(c=='\n' || c==EOF)
251 if(c1>='0' && c1<='9')
252 printf(" (identifiers must not start with a digit)");
258 if ( --include_stack_ptr < 0 ) {
262 yy_delete_buffer( YY_CURRENT_BUFFER );
264 include_stack[include_stack_ptr] );
265 column = column_stack[include_stack_ptr];
266 line = line_stack[include_stack_ptr];
277 void freeTokens(struct token_t*file)
283 struct token_t* generateTokens(char*filename)
287 struct token_t*result;
293 if(!strcmp(filename,"-"))
296 fi = fopen(filename, "rb");
299 printf("Couldn't find file %s\n", filename);
306 mem_put(&strings, &t, 1); //hack- make all valid strings start at position >0
312 #ifdef YY_CURRENT_BUFFER
313 // some newer flex versions require it like this:
314 yy_delete_buffer(YY_CURRENT_BUFFER);
316 yy_delete_buffer(yy_current_buffer);
319 result = (struct token_t*)tokens.buffer;
320 num = tokens.pos/sizeof(struct token_t);
322 for(t=0;t<tokens.pos/sizeof(struct token_t);t++) {
323 if(result[t].text_pos) {
324 result[t].text = &strings.buffer[result[t].text_pos];