diff options
author | FlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-12-20 09:09:21 +0000 |
---|---|---|
committer | FlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-12-20 09:09:21 +0000 |
commit | df36cd522bda7cb99bb85f480ce775fe31b38dc9 (patch) | |
tree | 244a0bec64d1669db0d6dba029dc3c28641112ec | |
parent | 38daeba66b5d2a9f6fc4eda795b6c9b8c77a7b54 (diff) | |
download | hercules-df36cd522bda7cb99bb85f480ce775fe31b38dc9.tar.gz hercules-df36cd522bda7cb99bb85f480ce775fe31b38dc9.tar.bz2 hercules-df36cd522bda7cb99bb85f480ce775fe31b38dc9.tar.xz hercules-df36cd522bda7cb99bb85f480ce775fe31b38dc9.zip |
- 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
-rw-r--r-- | Changelog-Trunk.txt | 3 | ||||
-rw-r--r-- | src/map/script.c | 156 |
2 files changed, 100 insertions, 59 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 2efa61cbf..b40cdcd3a 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2006/12/20 + * Replaced our fix for "mes ();" crashing by jA's version. + * Merged the fix for & having the same precedence as << and >> from jA. + * Merged the C_OP3 operator from jA: test ? if_true : if_false * Changed the script source from unsigned char* to const char*. * Updated plugins Makefile. [FlavioJS] 2006/12/19 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]=='*' && i<j) ) disp_error_message("illegal number of parameters",plist[min(i,j)]); } + } else if(op == C_OP3) { + p=parse_subexpr(p,-1); + p=skip_space(p); + if( *(p++) != ':') + disp_error_message("need ':'", p); + p=parse_subexpr(p,-1); } else { p=parse_subexpr(p,opl); } @@ -744,14 +759,6 @@ const char* parse_expr(const char *p) disp_error_message("unexpected char",p); exit(1); } - /* - if(*p == '(') { - const char *p2 = skip_space(p + 1); - if(*p2 == ')') { - return p2 + 1; - } - } - */ p=parse_subexpr(p,-1); #ifdef DEBUG_FUNCIN if(battle_config.etc_log) @@ -767,9 +774,11 @@ const char* parse_expr(const char *p) const char* parse_line(const char* p) { int i=0; + int j=0; int cmd; const char* plist[128]; const char* p2; + const char *arg=NULL; char end; p=skip_space(p); @@ -820,17 +829,26 @@ const char* parse_line(const char* p) end = ';'; } - if( p && *p == '(' && *(p2=(char *)skip_space(p+1)) == ')' ){ - p= p2+1; // empty argument list - } else + // Check number of arguments of the function + if( str_data[cmd].type == C_FUNC && script_config.warn_cmd_mismatch_paramnum) { + arg = buildin_func[str_data[cmd].val].arg; + for(j=0; arg[j]; j++) { + if(arg[j] == '*') + break; + } + } + while(p && *p && *p != end && i<128){ plist[i]=p; p=parse_expr(p); p=skip_space(p); // 引数区切りの,処理 - if(*p==',') p++; - else if(*p!=end && script_config.warn_cmd_no_comma && 0 <= i ){ + if(*p==',') { + if(arg == NULL || arg[j] == '*' || i+1 < j) + p++; // the next argument is valid, skip the comma + } + else if(*p!=end && script_config.warn_cmd_no_comma){ if(parse_syntax_for_flag) { disp_error_message("expect ',' or ')' at cmd params",p); } else { @@ -840,7 +858,7 @@ const char* parse_line(const char* p) p=skip_space(p); i++; } - plist[i]=(char *) p; + plist[i]=p; if(!p || *(p++)!=end){ if(parse_syntax_for_flag) { disp_error_message("need ')'",p); @@ -853,12 +871,7 @@ const char* parse_line(const char* p) // if, for , while の閉じ判定 p = parse_syntax_close(p); - if( str_data[cmd].type==C_FUNC && script_config.warn_cmd_mismatch_paramnum){ - const char *arg=buildin_func[str_data[cmd].val].arg; - int j; - for(j=0;arg[j];j++) - if(arg[j]=='*') - break; + if(arg) { if( (arg[j]==0 && i!=j) || (arg[j]=='*' && i<j) ) disp_error_message("illegal number of parameters",plist[min(i,j)]); } @@ -2173,6 +2186,27 @@ int isstr(struct script_data *c) { } /*========================================== + * Three-section operator + * test ? if_true : if_false + *------------------------------------------ + */ +void op_3(struct script_state *st) { + int flag = 0; + if( isstr(&st->stack->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; |