From df36cd522bda7cb99bb85f480ce775fe31b38dc9 Mon Sep 17 00:00:00 2001 From: FlavioJS Date: Wed, 20 Dec 2006 09:09:21 +0000 Subject: - Replaced our fix for "mes ();" crashing by jA's version. see trunk[8867] and stable[8927] - Merged the fix for & having the same precedence as << and >> from jA. - Merged the C_OP3 operator from jA: test ? if_true : if_false git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9533 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/script.c | 156 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 97 insertions(+), 59 deletions(-) (limited to 'src/map/script.c') diff --git a/src/map/script.c b/src/map/script.c index 74e122786..8c46db172 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -163,7 +163,7 @@ enum { C_NAME,C_EOL, C_RETINFO, C_USERFUNC, C_USERFUNC_POS, // user defined functions - C_LOR,C_LAND,C_LE,C_LT,C_GE,C_GT,C_EQ,C_NE, //operator + C_OP3,C_LOR,C_LAND,C_LE,C_LT,C_GE,C_GT,C_EQ,C_NE, //operator C_XOR,C_OR,C_AND,C_ADD,C_SUB,C_MUL,C_DIV,C_MOD,C_NEG,C_LNOT,C_NOT,C_R_SHIFT,C_L_SHIFT }; @@ -344,7 +344,7 @@ static void check_script_buf(int size) { if(script_pos+size>=script_size){ script_size+=SCRIPT_BLOCK_SIZE; - script_buf=(unsigned char *)aRealloc(script_buf,script_size); + RECREATE(script_buf,unsigned char,script_size); malloc_tsetdword(script_buf + script_size - SCRIPT_BLOCK_SIZE, '\0', SCRIPT_BLOCK_SIZE); } @@ -355,7 +355,7 @@ static void check_script_buf(int size) *------------------------------------------ */ -#define add_scriptb(a) if( script_pos+1>=script_size ) check_script_buf(1); script_buf[script_pos++]=(uint8)(a); +#define add_scriptb(a) if( script_pos+1>=script_size ) check_script_buf(1); script_buf[script_pos++]=(uint8)(a) #if 0 static void add_scriptb(int a) @@ -479,7 +479,7 @@ static const char *skip_space(const char *p) if(*p) ++p; else - disp_error_message("reached end of streams while matching \"*/\"",p); + disp_error_message("unexpected eof @ block comment",p); } else break; } @@ -646,35 +646,39 @@ const char* parse_subexpr(const char* p,int limit) } tmpp=p; if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){ - p=parse_subexpr(p+1,8); + p=parse_subexpr(p+1,10); add_scriptc(op); } else p=parse_simpleexpr(p); p=skip_space(p); while(( - (op=C_ADD,opl=6,len=1,*p=='+') || - (op=C_SUB,opl=6,len=1,*p=='-') || - (op=C_MUL,opl=7,len=1,*p=='*') || - (op=C_DIV,opl=7,len=1,*p=='/') || - (op=C_MOD,opl=7,len=1,*p=='%') || - (op=C_FUNC,opl=9,len=1,*p=='(') || - (op=C_LAND,opl=1,len=2,*p=='&' && p[1]=='&') || - (op=C_AND,opl=5,len=1,*p=='&') || - (op=C_LOR,opl=0,len=2,*p=='|' && p[1]=='|') || - (op=C_OR,opl=4,len=1,*p=='|') || - (op=C_XOR,opl=3,len=1,*p=='^') || - (op=C_EQ,opl=2,len=2,*p=='=' && p[1]=='=') || - (op=C_NE,opl=2,len=2,*p=='!' && p[1]=='=') || - (op=C_R_SHIFT,opl=5,len=2,*p=='>' && p[1]=='>') || - (op=C_GE,opl=2,len=2,*p=='>' && p[1]=='=') || - (op=C_GT,opl=2,len=1,*p=='>') || - (op=C_L_SHIFT,opl=5,len=2,*p=='<' && p[1]=='<') || - (op=C_LE,opl=2,len=2,*p=='<' && p[1]=='=') || - (op=C_LT,opl=2,len=1,*p=='<')) && opl>limit){ + (op=C_OP3,opl=0,len=1,*p=='?') || + (op=C_ADD,opl=8,len=1,*p=='+') || + (op=C_SUB,opl=8,len=1,*p=='-') || + (op=C_MUL,opl=9,len=1,*p=='*') || + (op=C_DIV,opl=9,len=1,*p=='/') || + (op=C_MOD,opl=9,len=1,*p=='%') || + (op=C_FUNC,opl=11,len=1,*p=='(') || + (op=C_LAND,opl=2,len=2,*p=='&' && p[1]=='&') || + (op=C_AND,opl=6,len=1,*p=='&') || + (op=C_LOR,opl=1,len=2,*p=='|' && p[1]=='|') || + (op=C_OR,opl=5,len=1,*p=='|') || + (op=C_XOR,opl=4,len=1,*p=='^') || + (op=C_EQ,opl=3,len=2,*p=='=' && p[1]=='=') || + (op=C_NE,opl=3,len=2,*p=='!' && p[1]=='=') || + (op=C_R_SHIFT,opl=7,len=2,*p=='>' && p[1]=='>') || + (op=C_GE,opl=3,len=2,*p=='>' && p[1]=='=') || + (op=C_GT,opl=3,len=1,*p=='>') || + (op=C_L_SHIFT,opl=7,len=2,*p=='<' && p[1]=='<') || + (op=C_LE,opl=3,len=2,*p=='<' && p[1]=='=') || + (op=C_LT,opl=3,len=1,*p=='<')) && opl>limit){ p+=len; if(op==C_FUNC){ - int i=0,func=parse_cmd; + int i=0; + int j=0; + int func=parse_cmd; const char *plist[128]; + const char *arg = NULL; if(str_data[parse_cmd].type == C_FUNC){ // 通常の関数 @@ -686,35 +690,46 @@ const char* parse_subexpr(const char* p,int limit) } else disp_error_message("expect command, missing function name or calling undeclared function",tmpp); func=parse_cmd; - if( *p == '(' && *(plist[i]=skip_space(p+1)) == ')' ){ - p=plist[i]+1; // empty argument list - } else + p=skip_space(p); + + // check number of arguments of the function + if( str_data[func].type == C_FUNC && script_config.warn_cmd_mismatch_paramnum) { + arg = buildin_func[str_data[func].val].arg; + for(j=0; arg[j]; j++) { + if(arg[j] == '*') + break; + } + } + while(*p && *p!=')' && i<128) { plist[i]=p; p=parse_subexpr(p,-1); p=skip_space(p); - if(*p==',') p++; + if(*p==',') { + if(arg == NULL || arg[j] == '*' || i+1 < j) + p++; // the next argument is valid, skip the comma + } else if(*p!=')' && script_config.warn_func_no_comma){ disp_error_message("expect ',' or ')' at func params",p); } p=skip_space(p); i++; - }; + } plist[i]=p; if(*(p++)!=')'){ disp_error_message("func request '(' ')'",p); - exit(1); + //exit(1); } - - if( str_data[func].type==C_FUNC && script_config.warn_func_mismatch_paramnum){ - const char *arg = buildin_func[str_data[func].val].arg; - int j = 0; - for (; arg[j]; j++) - if (arg[j] == '*') - break; - if (!(i <= 1 && j == 0) && ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j))) + if(arg) { + if( (arg[j]==0 && i!=j) || (arg[j]=='*' && istack->stack_data[st->stack->sp-3])) { + char *str = conv_str(st,& (st->stack->stack_data[st->stack->sp-3])); + flag = str[0]; + } else { + flag = conv_num(st,& (st->stack->stack_data[st->stack->sp-3])); + } + if( flag ) { + push_copy(st->stack, st->stack->sp-2 ); + } else { + push_copy(st->stack, st->stack->sp-1 ); + } + pop_stack(st->stack,st->stack->sp-4,st->stack->sp-1); +} + /*========================================== * 加算演算子 *------------------------------------------ @@ -2687,6 +2721,10 @@ void run_script_main(struct script_state *st) op_1num(st,c); break; + case C_OP3: + op_3(st); + break; + case C_NOP: st->state=END; break; -- cgit v1.2.3-60-g2f50