- 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://svn.code.sf.net/p/rathena/svn/trunk@9533 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
FlavioJS 2006-12-20 09:09:21 +00:00
parent 40b389bc42
commit 78b52bbb4b
2 changed files with 100 additions and 59 deletions

View File

@ -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

View File

@ -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)]);
}
@ -2172,6 +2185,27 @@ int isstr(struct script_data *c) {
return 0;
}
/*==========================================
* 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;