From 00da6b5977574a0564169172227d8aab45be188f Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 3 Jan 2015 21:07:56 -0800 Subject: Switch MATCH to separate begin/end macros The for loop trick turned out to be very prone to infinite loops at runtime. It's better to force compiler errors even if it's ugly. --- src/map/script-fun.cpp | 122 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 41 deletions(-) (limited to 'src/map/script-fun.cpp') diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index f9334bc..cc28cd2 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -122,29 +122,33 @@ void builtin_callfunc(ScriptState *st) RString str = conv_str(st, &AARG(0)); Option> scr_ = userfunc_db.get(str); - if OPTION_IS_SOME_NOLOOP(scr, scr_) + OMATCH_BEGIN (scr_) { - int j = 0; - assert (st->start + 3 == st->end); + OMATCH_CASE_SOME (scr) + { + int j = 0; + assert (st->start + 3 == st->end); #if 0 - for (int i = st->start + 3; i < st->end; i++, j++) - push_copy(st->stack, i); + for (int i = st->start + 3; i < st->end; i++, j++) + push_copy(st->stack, i); #endif - push_int(st->stack, j); // 引数の数をプッシュ - push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ - push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ - push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ + push_int(st->stack, j); // 引数の数をプッシュ + push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ + push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ + push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ - st->scriptp = ScriptPointer(scr, 0); - st->defsp = st->start + 4 + j; - st->state = ScriptEndState::GOTO; - } - else - { - PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str); - st->state = ScriptEndState::END; + st->scriptp = ScriptPointer(scr, 0); + st->defsp = st->start + 4 + j; + st->state = ScriptEndState::GOTO; + } + OMATCH_CASE_NONE () + { + PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str); + st->state = ScriptEndState::END; + } } + OMATCH_END (); } /*========================================== @@ -618,24 +622,23 @@ int getarraysize(ScriptState *st, SIR reg) for (; i < 256; i++) { struct script_data vd = get_val2(st, reg.iplus(i)); - MATCH (vd) + MATCH_BEGIN (vd) { - CASE (const ScriptDataStr&, u) + MATCH_CASE (const ScriptDataStr&, u) { if (u.str[0]) c = i; - goto continue_outer; + continue; } - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { if (u.numi) c = i; - goto continue_outer; + continue; } } + MATCH_END (); abort(); - continue_outer: - ; } return c + 1; } @@ -720,8 +723,11 @@ void builtin_countitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -763,8 +769,11 @@ void builtin_checkweight(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -808,8 +817,11 @@ void builtin_getitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -861,8 +873,11 @@ void builtin_makeitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -905,8 +920,11 @@ void builtin_delitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -1080,10 +1098,18 @@ void builtin_getequipid(ScriptState *st) if (i.ok()) { Option> item_ = sd->inventory_data[i]; - if OPTION_IS_SOME_NOLOOP(item, item_) - push_int(st->stack, unwrap(item->nameid)); - else - push_int(st->stack, 0); + OMATCH_BEGIN (item_) + { + OMATCH_CASE_SOME (item) + { + push_int(st->stack, unwrap(item->nameid)); + } + OMATCH_CASE_NONE () + { + push_int(st->stack, 0); + } + } + OMATCH_END (); } else { @@ -1109,10 +1135,18 @@ void builtin_getequipname(ScriptState *st) if (i.ok()) { Option> item_ = sd->inventory_data[i]; - if OPTION_IS_SOME_NOLOOP(item, item_) - buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname); - else - buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); + OMATCH_BEGIN (item_) + { + OMATCH_CASE_SOME (item) + { + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname); + } + OMATCH_CASE_NONE () + { + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); + } + } + OMATCH_END (); } else { @@ -1832,8 +1866,11 @@ void builtin_getareadropitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { item = item_data->nameid; + } + OMATCH_END (); } else item = wrap(conv_num(st, data)); @@ -2013,10 +2050,11 @@ void builtin_setmapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { m->flag.set(mf, 1); } + OMATCH_END (); } static @@ -2026,10 +2064,11 @@ void builtin_removemapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { m->flag.set(mf, 0); } + OMATCH_END (); } static @@ -2041,10 +2080,11 @@ void builtin_getmapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { r = m->flag.get(mf); } + OMATCH_END (); push_int(st->stack, r); } -- cgit v1.2.3-70-g09d2