X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=src%2Fswfc.c;fp=src%2Fswfc.c;h=a8cbdfcaf3dac7f91f825c1d48916ec5127d0978;hp=fafa388df28b095ddfde30adbed6be8eb44e6f0d;hb=91d738fe108905d2103f735f564e123d78d07b29;hpb=53206a6ffa652bc3e867836c9c88e55a17ca0ebf diff --git a/src/swfc.c b/src/swfc.c index fafa388..a8cbdfc 100644 --- a/src/swfc.c +++ b/src/swfc.c @@ -2360,7 +2360,7 @@ int parseInt(char*str) syntaxerror("Not an Integer: \"%s\"", str); return atoi(str); } -int parseRawTwip(char*str) +static double parseRawTwip(char*str) { char*dot; int sign=1; @@ -2373,23 +2373,25 @@ int parseRawTwip(char*str) if(!dot) { int l=strlen(str); int t; - return sign*parseInt(str)*20; + return sign*parseInt(str); } else { char* old = strdup(str); int l=strlen(dot+1); char*s; *dot++ = 0; - for(s=str;s'9') - { - free(old); - syntaxerror("Not a coordinate: \"%s\"", str); + for(s=str;s'9') + { + free(old); + syntaxerror("Not a coordinate: \"%s\"", str); + } } - for(s=dot;*s;s++) - if(*s<'0' || *s>'9') - { - free(old); - syntaxerror("Not a coordinate: \"%s\"", str); + for(s=dot;*s;s++) { + if(*s<'0' || *s>'9') + { + free(old); + syntaxerror("Not a coordinate: \"%s\"", str); + } } if(l>2 || (l==2 && (dot[1]!='0' && dot[1]!='5'))) { dot[1] = ((dot[1]-0x30)/5)*5 + 0x30; @@ -2399,11 +2401,11 @@ int parseRawTwip(char*str) } free(old); if(l==0) - return sign*(atoi(str)*20); + return sign*(atoi(str)); if(l==1) - return sign*(atoi(str)*20+atoi(dot)*2); + return sign*(atoi(str)+0.1*atoi(dot)); if(l==2) - return sign*(atoi(str)*20+atoi(dot)/5); + return sign*(atoi(str)+0.01*atoi(dot)); } return 0; } @@ -2412,49 +2414,131 @@ static dictionary_t defines; static int defines_initialized = 0; static mem_t define_values; -int parseTwip(char*str) +static double parseNameOrTwip(char*s) { - /* TODO: make this a proper expression parser */ - char*p = str; - int val = 0; - char ex = 0; - char*lastpos = 0; - while(*p) { - if(*p == '+' || *p == '-' || *p == '/' || *p == '*') - ex = *p; - else if(!lastpos) - lastpos = p; - p++; - if((*p == '+' || *p == '-' || *p == '/' || *p == '*' || *p == 0) && lastpos) { - char save = *p; - *p = 0; - - int l = 0; - int v = 0; - if(defines_initialized) { - l = (int)dictionary_lookup(&defines, lastpos); - } - if(l) { - v = *(int*)&define_values.buffer[l-1]; - } else { - v = parseRawTwip(lastpos); - } - *p = save; - if(ex == '+') - val += v; - else if(ex == '-') - val -= v; - else if(ex == '/') - val = (val*20) / v; - else if(ex == '*') - val = (val*v) / 20; - else - val += v; - ex = 0; - lastpos = 0; - } + int l = 0; + double v; + if(defines_initialized) { + l = (int)dictionary_lookup(&defines, s); } - return val; + if(l) { + return *(int*)&define_values.buffer[l-1]; + } else { + return parseRawTwip(s); + } +} + +/* automatically generated by yiyiyacc, http://www.quiss.org/yiyiyacc/ */ +static double parseExpression(char*s) +{ + int chr2index[256]; + memset(chr2index, -1, sizeof(chr2index)); + chr2index['+'] = 0; + chr2index['-'] = 1; + chr2index['*'] = 2; + chr2index['/'] = 3; + chr2index['('] = 5; + chr2index[')'] = 6; + chr2index['\0'] = 7; + + int stackpos = 1; + int stack[256]; + double values[256]; + stack[0]=0; + values[0]=0; + int accept = 18; + int left[10]={11,8,8,8,8,9,9,9,10,10}; //production left side + int plen[10]={1,3,2,3,1,3,3,1,1,3}; //production size + int table[18][12] = { + {0, 4, 0, 0, 5, 6, 0, 0, 1, 2, 3, 0}, + {7, 8, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0}, + {-4, -4, 9, 10, 0, 0, -4, -4, 0, 0, 0, 0}, + {-7, -7, -7, -7, 0, 0, -7, -7, 0, 0, 0, 0}, + {0, 0, 0, 0, 5, 6, 0, 0, 0, 11, 3, 0}, + {-8, -8, -8, -8, 0, 0, -8, -8, 0, 0, 0, 0}, + {0, 4, 0, 0, 5, 6, 0, 0, 12, 2, 3, 0}, + {0, 0, 0, 0, 5, 6, 0, 0, 0, 13, 3, 0}, + {0, 0, 0, 0, 5, 6, 0, 0, 0, 14, 3, 0}, + {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 15, 0}, + {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 16, 0}, + {-2, -2, 9, 10, 0, 0, -2, -2, 0, 0, 0, 0}, + {7, 8, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0}, + {-1, -1, 9, 10, 0, 0, -1, -1, 0, 0, 0, 0}, + {-3, -3, 9, 10, 0, 0, -3, -3, 0, 0, 0, 0}, + {-5, -5, -5, -5, 0, 0, -5, -5, 0, 0, 0, 0}, + {-6, -6, -6, -6, 0, 0, -6, -6, 0, 0, 0, 0}, + {-9, -9, -9, -9, 0, 0, -9, -9, 0, 0, 0, 0}}; + + char*p = s; + while(1) { + char*pnext = p+1; + int action; + double value = 0; + if(!stackpos) { + fprintf(stderr, "Error in expression\n"); + return 0.0; + } + + if(chr2index[*p]<0) { + action = table[stack[stackpos-1]][4]; + if(action>0) { + while(chr2index[*pnext]<0) + pnext++; + char save = *pnext; + *pnext = 0; + value = parseNameOrTwip(p); + *pnext = save; + } + } else { + action = table[stack[stackpos-1]][chr2index[*p]]; + } + + if(action == accept) { + return values[stack[stackpos-1]]; + } else if(action>0) { // shift + if(stackpos>254) { + fprintf(stderr, "Stack overflow while parsing expression\n"); + return 0.0; + } + values[stackpos]=value; + stack[stackpos++]=action; + p=pnext; + } else if(action<0) { // reduce + stackpos-=plen[-action]; + stack[stackpos] = table[stack[stackpos-1]][left[-action]]; + switch(-action) { + case 1: + values[stackpos] = values[stackpos+0] + values[stackpos+2]; + break; + case 2: + values[stackpos] = 0 - values[stackpos+1]; + break; + case 3: + values[stackpos] = values[stackpos+0] - values[stackpos+2]; + break; + case 5: + values[stackpos] = values[stackpos+0] * values[stackpos+2]; + break; + case 6: + values[stackpos] = values[stackpos+0] / values[stackpos+2]; + break; + case 9: + values[stackpos] = values[stackpos+1]; + break; + } + stackpos++; + } else { + fprintf(stderr, "Syntax error in expression\n"); + return 0.0; + } + } +} + +int parseTwip(char*str) +{ + int v = (int)(parseExpression(str)*20); + printf("%s = %.2f\n", str, v/20.0); + return v; } int parseArc(char* str)