diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2015-01-03 21:07:56 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2015-01-03 21:58:26 -0800 |
commit | 00da6b5977574a0564169172227d8aab45be188f (patch) | |
tree | dd52eee506a98e1eb9fcdea52e7db25079a7ad28 /src | |
parent | 4c91abd6a020ee030114ae3f22d8f6066e7528be (diff) | |
download | tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.gz tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.bz2 tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.xz tmwa-00da6b5977574a0564169172227d8aab45be188f.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/char/int_party.cpp | 42 | ||||
-rw-r--r-- | src/char/inter.cpp | 3 | ||||
-rw-r--r-- | src/compat/attr.hpp | 24 | ||||
-rw-r--r-- | src/compat/attr_test.cpp | 50 | ||||
-rw-r--r-- | src/compat/option.hpp | 49 | ||||
-rw-r--r-- | src/compat/option_test.cpp | 32 | ||||
-rw-r--r-- | src/generic/db.hpp | 6 | ||||
-rw-r--r-- | src/map/atcommand.cpp | 188 | ||||
-rw-r--r-- | src/map/battle.cpp | 8 | ||||
-rw-r--r-- | src/map/clif.cpp | 16 | ||||
-rw-r--r-- | src/map/itemdb.cpp | 12 | ||||
-rw-r--r-- | src/map/magic-expr.cpp | 144 | ||||
-rw-r--r-- | src/map/magic-interpreter-base.cpp | 17 | ||||
-rw-r--r-- | src/map/magic-stmt.cpp | 54 | ||||
-rw-r--r-- | src/map/magic-v2.cpp | 10 | ||||
-rw-r--r-- | src/map/map.cpp | 44 | ||||
-rw-r--r-- | src/map/mob.cpp | 3 | ||||
-rw-r--r-- | src/map/npc-parse.cpp | 26 | ||||
-rw-r--r-- | src/map/party.cpp | 6 | ||||
-rw-r--r-- | src/map/pc.cpp | 70 | ||||
-rw-r--r-- | src/map/script-call.cpp | 44 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 122 | ||||
-rw-r--r-- | src/map/script-parse.cpp | 5 | ||||
-rw-r--r-- | src/map/trade.cpp | 14 | ||||
-rw-r--r-- | src/sexpr/fwd.hpp | 1 | ||||
-rw-r--r-- | src/sexpr/variant.hpp | 46 | ||||
-rw-r--r-- | src/sexpr/variant_test.cpp | 32 |
27 files changed, 607 insertions, 461 deletions
diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 5000ff2..731669a 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -327,19 +327,23 @@ void mapif_party_created(Session *s, AccountId account_id, Option<PartyPair> p_) { Packet_Fixed<0x3820> fixed_20; fixed_20.account_id = account_id; - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - fixed_20.error = 0; - fixed_20.party_id = p.party_id; - fixed_20.party_name = p->name; - PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); - } - else - { - fixed_20.error = 1; - fixed_20.party_id = PartyId(); - fixed_20.party_name = stringish<PartyName>("error"_s); + OMATCH_CASE_SOME (p) + { + fixed_20.error = 0; + fixed_20.party_id = p.party_id; + fixed_20.party_name = p->name; + PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); + } + OMATCH_CASE_NONE () + { + fixed_20.error = 1; + fixed_20.party_id = PartyId(); + fixed_20.party_name = stringish<PartyName>("error"_s); + } } + OMATCH_END (); send_fpacket<0x3820, 35>(s, fixed_20); } @@ -524,10 +528,18 @@ static void mapif_parse_PartyInfo(Session *s, PartyId party_id) { Option<P<PartyMost>> maybe_party_most = party_db.search(party_id); - if OPTION_IS_SOME_NOLOOP(party_most, maybe_party_most) - mapif_party_info(s, PartyPair{party_id, party_most}); - else - mapif_party_noinfo(s, party_id); + OMATCH_BEGIN (maybe_party_most) + { + OMATCH_CASE_SOME (party_most) + { + mapif_party_info(s, PartyPair{party_id, party_most}); + } + OMATCH_CASE_NONE () + { + mapif_party_noinfo(s, party_id); + } + } + OMATCH_END (); } // パーティ追加要求 diff --git a/src/char/inter.cpp b/src/char/inter.cpp index eccfc1b..c081825 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -270,7 +270,7 @@ void mapif_account_reg_reply(Session *s, AccountId account_id) Packet_Head<0x3804> head_04; head_04.account_id = account_id; std::vector<Packet_Repeat<0x3804>> repeat_04; - if OPTION_IS_SOME_NOLOOP(reg, reg_) + OMATCH_BEGIN_SOME (reg, reg_) { repeat_04.resize(reg->reg_num); assert (reg->reg_num < ACCOUNT_REG_NUM); @@ -280,6 +280,7 @@ void mapif_account_reg_reply(Session *s, AccountId account_id) repeat_04[j].value = reg->reg[j].value; } } + OMATCH_END (); send_vpacket<0x3804, 8, 36>(s, head_04, repeat_04); } diff --git a/src/compat/attr.hpp b/src/compat/attr.hpp index 9ddf654..5ebef6d 100644 --- a/src/compat/attr.hpp +++ b/src/compat/attr.hpp @@ -30,28 +30,4 @@ namespace tmwa #endif #define JOIN(a, b) a##b - -// first loop: -// declare flag 'guard' (initially true) -// declare flag 'broken' (initially false) -// condition is 'guard' must be true, which is the case only for the first iteration -// post checks 'broken' and if set, break the loop -// second loop: -// declare public 'var' variable -// condition is that 'guard' must be true -// post sets 'guard' to false to make this loop run only once -// third loop: -// enable broken flag; it will remain set if 'break' is in the loop -// condition is that 'broken' must be true -// post sets 'broken' to false, which then fails the condition -// if user has a 'break' inside, then 'broken' will be true -// in either case, go back to the second loop's post -#define WITH_VAR_INLOOP(ty, var, expr) \ - for (bool JOIN(var, _guard) = true, JOIN(var, _broken) = false; JOIN(var, _guard); ({if (JOIN(var, _broken)) { break; } })) \ - for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) \ - for (JOIN(var, _broken) = true; JOIN(var, _broken); JOIN(var, _broken) = false) -#define WITH_VAR_NOLOOP(ty, var, expr) \ - for (bool JOIN(var, _guard) = true, JOIN(var, _broken) = false; JOIN(var, _guard); ({if (JOIN(var, _broken)) {abort();} })) \ - for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) \ - for (JOIN(var, _broken) = true; JOIN(var, _broken); JOIN(var, _broken) = false) } // namespace tmwa diff --git a/src/compat/attr_test.cpp b/src/compat/attr_test.cpp deleted file mode 100644 index eb9042d..0000000 --- a/src/compat/attr_test.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "attr.hpp" -// attr_test.cpp - Tests for attributes -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include <gtest/gtest.h> - -#include "../poison.hpp" - - -namespace tmwa -{ -TEST(attr, withvar) -{ - int x = 41; - for (int i = 0; i < 2; ++i) - { - WITH_VAR_NOLOOP(auto, y, x + 1) - { - x = y; - } - } - EXPECT_EQ(x, 43); - for (int i = 0; i < 2; ++i) - { - if (i == 1) - WITH_VAR_INLOOP(auto, y, i) - { - x = y; - break; - } - } - EXPECT_EQ(x, 1); -} -} // namespace tmwa diff --git a/src/compat/option.hpp b/src/compat/option.hpp index 7beef6f..b6e7655 100644 --- a/src/compat/option.hpp +++ b/src/compat/option.hpp @@ -24,8 +24,6 @@ #include <utility> -#include "attr.hpp" - namespace tmwa { @@ -423,13 +421,46 @@ namespace option if (o.maybe_ref.is_none()) falsy; \ tmwa::option::option_unwrap(std::move(o)); \ }).maybe_ref_fun() -// immediately preceded by 'if'; not double-eval-safe -#define OPTION_IS_SOME_INLOOP(var, expr) \ - ((expr).is_some()) \ - WITH_VAR_INLOOP(auto&, var, *(expr).ptr_or(nullptr)) -#define OPTION_IS_SOME_NOLOOP(var, expr) \ - ((expr).is_some()) \ - WITH_VAR_NOLOOP(auto&, var, *(expr).ptr_or(nullptr)) + +#define OMATCH_BEGIN(expr) \ + { \ + auto&& _omatch_var = (expr); \ + switch (_omatch_var.is_some()) \ + { \ + { \ + { \ + /*}}}}*/ +#define OMATCH_END() \ + /*{{{{*/ \ + } \ + } \ + } \ + (void) _omatch_var; \ + } + +#define OMATCH_BEGIN_SOME(var, expr) \ + OMATCH_BEGIN (expr) \ + OMATCH_CASE_SOME (var) + +#define OMATCH_CASE_SOME(var) \ + /*{{{{*/ \ + } \ + break; \ + } \ + { \ + case true: \ + { \ + auto&& var = *_omatch_var.ptr_or(nullptr); \ + /*}}}}*/ +#define OMATCH_CASE_NONE() \ + /*{{{{*/ \ + } \ + break; \ + } \ + { \ + case false: \ + { \ + /*}}}}*/ } // namespace option //using option::Option; diff --git a/src/compat/option_test.cpp b/src/compat/option_test.cpp index f9cec0e..69f3a60 100644 --- a/src/compat/option_test.cpp +++ b/src/compat/option_test.cpp @@ -398,24 +398,32 @@ TEST(Option, unwrap) v = None; TRY_UNWRAP(fcr(), v = Some(1)); v = None; - if OPTION_IS_SOME_NOLOOP(o, v) + OMATCH_BEGIN (v) { - EXPECT_NE(o, o); - } - else - { - SUCCEED(); + OMATCH_CASE_SOME (o) + { + EXPECT_NE(o, o); + } + OMATCH_CASE_NONE () + { + SUCCEED(); + } } + OMATCH_END (); v = Some(1); - if OPTION_IS_SOME_NOLOOP(o, v) + OMATCH_BEGIN (v) { - EXPECT_EQ(o, 1); - } - else - { - FAIL(); + OMATCH_CASE_SOME (o) + { + EXPECT_EQ(o, 1); + } + OMATCH_CASE_NONE () + { + FAIL(); + } } + OMATCH_END (); } TEST(Option, flatten) diff --git a/src/generic/db.hpp b/src/generic/db.hpp index b0dcf0c..04ead79 100644 --- a/src/generic/db.hpp +++ b/src/generic/db.hpp @@ -115,10 +115,11 @@ public: V get(const K& k) { Option<Borrowed<V>> vp = impl.search(k); - if OPTION_IS_SOME_NOLOOP(v, vp) + OMATCH_BEGIN_SOME (v, vp) { return *v; } + OMATCH_END (); return V(); } void put(const K& k, V v) @@ -162,10 +163,11 @@ public: Option<Borrowed<V>> get(const K& k) { Option<Borrowed<U>> up = impl.search(k); - if OPTION_IS_SOME_NOLOOP(u, up) + OMATCH_BEGIN_SOME (u, up) { return Some(borrow(*u->get())); } + OMATCH_END (); return None; } void put(const K& k, U v) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index bd1690d..f08d561 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -375,17 +375,24 @@ bool atcommand_config_read(ZString cfgName) continue; } Option<P<AtCommandInfo>> p_ = get_atcommandinfo_byname(w1); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); - } - else if (w1 == "import"_s) - rv &= atcommand_config_read(w2); - else - { - PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); - rv = false; + OMATCH_CASE_SOME (p) + { + p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); + } + OMATCH_CASE_NONE () + { + if (w1 == "import"_s) + rv &= atcommand_config_read(w2); + else + { + PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); + rv = false; + } + } } + OMATCH_END (); } return rv; @@ -3406,41 +3413,45 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, Option<PartyPair> p_ = party_searchname(party_name); if (p_.is_none()) p_ = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - count = 0; - for (io::FD i : iter_fds()) + OMATCH_CASE_SOME (p) { - Session *s2 = get_session(i); - if (!s2) - continue; - dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); - if (pl_sd && pl_sd->state.auth - && sd->status_key.account_id != pl_sd->status_key.account_id - && pl_sd->status.party_id == p.party_id) + count = 0; + for (io::FD i : iter_fds()) { - if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) - count++; - else - pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); + Session *s2 = get_session(i); + if (!s2) + continue; + dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); + if (pl_sd && pl_sd->state.auth + && sd->status_key.account_id != pl_sd->status_key.account_id + && pl_sd->status.party_id == p.party_id) + { + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + count++; + else + pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); + } + } + AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); + clif_displaymessage(s, output); + if (count) + { + output = STRPRINTF( + "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, + count); + clif_displaymessage(s, output); } } - AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); - clif_displaymessage(s, output); - if (count) + OMATCH_CASE_NONE () { - output = STRPRINTF( - "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, - count); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3588,26 +3599,30 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd, Option<PartyPair> p_ = party_searchname(party_name); if (p_.is_none()) p_ = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - if (sd->partyspy == p.party_id) + OMATCH_CASE_SOME (p) { - sd->partyspy = PartyId(); - AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + if (sd->partyspy == p.party_id) + { + sd->partyspy = PartyId(); + AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } + else + { + sd->partyspy = p.party_id; + AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } } - else + OMATCH_CASE_NONE () { - sd->partyspy = p.party_id; - AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3962,51 +3977,55 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, { // you can look items only lower or same level Option<P<Storage>> stor_ = account2storage2(pl_sd->status_key.account_id); - if OPTION_IS_SOME_NOLOOP(stor, stor_) + OMATCH_BEGIN (stor_) { - counter = 0; - count = 0; - for (SOff0 i : SOff0::iter()) + OMATCH_CASE_SOME (stor) { - if (!stor->storage_[i].nameid) - continue; - P<struct item_data> item_data = TRY_UNWRAP(itemdb_exists(stor->storage_[i].nameid), continue); - + counter = 0; + count = 0; + for (SOff0 i : SOff0::iter()) { - counter = counter + stor->storage_[i].amount; - count++; - if (count == 1) + if (!stor->storage_[i].nameid) + continue; + P<struct item_data> item_data = TRY_UNWRAP(itemdb_exists(stor->storage_[i].nameid), continue); + { - AString output = STRPRINTF( - "------ Storage items list of '%s' ------"_fmt, - pl_sd->status_key.name); + counter = counter + stor->storage_[i].amount; + count++; + if (count == 1) + { + AString output = STRPRINTF( + "------ Storage items list of '%s' ------"_fmt, + pl_sd->status_key.name); + clif_displaymessage(s, output); + } + AString output; + if (true) + output = STRPRINTF("%d %s (%s, id: %d)"_fmt, + stor->storage_[i].amount, + item_data->name, item_data->jname, + stor->storage_[i].nameid); clif_displaymessage(s, output); } - AString output; - if (true) - output = STRPRINTF("%d %s (%s, id: %d)"_fmt, - stor->storage_[i].amount, - item_data->name, item_data->jname, - stor->storage_[i].nameid); + } + if (count == 0) + clif_displaymessage(s, + "No item found in the storage of this player."_s); + else + { + AString output = STRPRINTF( + "%d item(s) found in %d kind(s) of items."_fmt, + counter, count); clif_displaymessage(s, output); } } - if (count == 0) - clif_displaymessage(s, - "No item found in the storage of this player."_s); - else + OMATCH_CASE_NONE () { - AString output = STRPRINTF( - "%d item(s) found in %d kind(s) of items."_fmt, - counter, count); - clif_displaymessage(s, output); + clif_displaymessage(s, "This player has no storage."_s); + return ATCE::OKAY; } } - else - { - clif_displaymessage(s, "This player has no storage."_s); - return ATCE::OKAY; - } + OMATCH_END (); } else { @@ -4426,12 +4445,13 @@ ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>, Option<P<AtCommandInfo>> it_ = atcommand_info.search(cmd); { - if OPTION_IS_SOME_NOLOOP(it, it_) + OMATCH_BEGIN_SOME (it, it_) { it->level = newlev; clif_displaymessage(s, "@command level changed."_s); return ATCE::OKAY; } + OMATCH_END (); } clif_displaymessage(s, "@command not found."_s); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 0a6ffa7..96945a4 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1400,8 +1400,11 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, if (widx.ok()) { - if OPTION_IS_SOME_NOLOOP(sdidw, sd->inventory_data[widx]) + OMATCH_BEGIN_SOME (sdidw, sd->inventory_data[widx]) + { atkmin = atkmin * (80 + sdidw->wlv * 20) / 100; + } + OMATCH_END (); } if (sd->status.weapon == ItemLook::BOW) { //武器が弓矢の場合 @@ -1921,13 +1924,14 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, ItemNameId weapon; if (weapon_index.ok()) { - if OPTION_IS_SOME_NOLOOP(sdidw, sd->inventory_data[weapon_index]) + OMATCH_BEGIN_SOME (sdidw, sd->inventory_data[weapon_index]) { if (bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON)) { weapon = sdidw->nameid; } } + OMATCH_END (); } MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d"_fmt, diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 61fa8c5..5329eff 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -401,7 +401,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type) p_ = party_search(sd->status.party_id); } } - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { for (int i = 0; i < MAX_PARTY; i++) { @@ -440,6 +440,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type) } } } + OMATCH_END (); } break; case SendWho::SELF: @@ -1231,19 +1232,18 @@ int clif_selllist(dumb_ptr<map_session_data> sd) { if (!sd->status.inventory[i].nameid) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[i]) { int val = sdidi->value_sell; if (val < 0) - goto continue_outer; + continue; Packet_Repeat<0x00c7> info; info.ioff2 = i.shift(); info.base_price = val; info.actual_price = val; repeat_c7.push_back(info); } - continue_outer: - ; + OMATCH_END (); } send_packet_repeatonly<0x00c7, 4, 10>(s, repeat_c7); @@ -3555,11 +3555,12 @@ RecvResult clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> { Option<PartyPair> p_ = party_search(ssd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { party_name = p->name; send = 1; } + OMATCH_END (); } if (send) @@ -4088,7 +4089,7 @@ RecvResult clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd) if (sd->npc_id) return rv; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { EPOS epos = fixed.epos_ignored; if (sdidi->type == ItemType::ARROW) @@ -4097,6 +4098,7 @@ RecvResult clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd) // Note: the EPOS argument to pc_equipitem is actually ignored pc_equipitem(sd, index, epos); } + OMATCH_END (); return rv; } diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index dbe2dd6..c2fd0e2 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -92,8 +92,11 @@ Option<Borrowed<struct item_data>> itemdb_exists(ItemNameId nameid) Borrowed<struct item_data> itemdb_search(ItemNameId nameid) { Option<P<struct item_data>> id_ = item_db.search(nameid); - if OPTION_IS_SOME_NOLOOP(id, id_) + OMATCH_BEGIN_SOME (id, id_) + { return id; + } + OMATCH_END (); P<struct item_data> id = item_db.init(nameid); @@ -172,13 +175,13 @@ bool itemdb_readdb(ZString filename) PRINTF("%s\n"_fmt, res.get_failure()); ast::item::ItemOrComment ioc = TRY_UNWRAP(std::move(res.get_success()), return false); - MATCH (ioc) + MATCH_BEGIN (ioc) { - CASE(const ast::item::Comment&, c) + MATCH_CASE (const ast::item::Comment&, c) { (void)c; } - CASE(const ast::item::Item&, item) + MATCH_CASE (const ast::item::Item&, item) { ln++; @@ -207,6 +210,7 @@ bool itemdb_readdb(ZString filename) *id = std::move(idv); } } + MATCH_END (); } } diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 9cc4e33..f1f137d 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -58,14 +58,15 @@ void free_area(dumb_ptr<area_t> area) if (!area) return; - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { free_area(a.a_union[0]); free_area(a.a_union[1]); } } + MATCH_END (); area.delete_(); } @@ -73,109 +74,111 @@ void free_area(dumb_ptr<area_t> area) static dumb_ptr<area_t> dup_area(dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const location_t&, loc) + MATCH_CASE (const location_t&, loc) { return dumb_ptr<area_t>::make(loc); } - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { AreaUnion u; u.a_union[0] = dup_area(a.a_union[0]); u.a_union[1] = dup_area(a.a_union[1]); return dumb_ptr<area_t>::make(u); } - CASE (const AreaRect&, rect) + MATCH_CASE (const AreaRect&, rect) { return dumb_ptr<area_t>::make(rect); } - CASE (const AreaBar&, bar) + MATCH_CASE (const AreaBar&, bar) { return dumb_ptr<area_t>::make(bar); } } + MATCH_END (); abort(); } void magic_copy_var(val_t *dest, const val_t *src) { - MATCH (*src) + MATCH_BEGIN (*src) { - // mumble mumble not a public API ... - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, s) + MATCH_CASE (const ValUndef&, s) { *dest = s; } - CASE (const ValInt&, s) + MATCH_CASE (const ValInt&, s) { *dest = s; } - CASE (const ValDir&, s) + MATCH_CASE (const ValDir&, s) { *dest = s; } - CASE (const ValString&, s) + MATCH_CASE (const ValString&, s) { *dest = ValString{s.v_string}; } - CASE (const ValEntityInt&, s) + MATCH_CASE (const ValEntityInt&, s) { *dest = s; } - CASE (const ValEntityPtr&, s) + MATCH_CASE (const ValEntityPtr&, s) { *dest = s; } - CASE (const ValLocation&, s) + MATCH_CASE (const ValLocation&, s) { *dest = s; } - CASE (const ValArea&, s) + MATCH_CASE (const ValArea&, s) { *dest = ValArea{dup_area(s.v_area)}; } - CASE (const ValSpell&, s) + MATCH_CASE (const ValSpell&, s) { *dest = s; } - CASE (const ValInvocationInt&, s) + MATCH_CASE (const ValInvocationInt&, s) { *dest = s; } - CASE (const ValInvocationPtr&, s) + MATCH_CASE (const ValInvocationPtr&, s) { *dest = s; } - CASE (const ValFail&, s) + MATCH_CASE (const ValFail&, s) { *dest = s; } - CASE (const ValNegative1&, s) + MATCH_CASE (const ValNegative1&, s) { *dest = s; } } + MATCH_END (); } void magic_clear_var(val_t *v) { - MATCH (*v) + MATCH_BEGIN (*v) { - CASE (ValString&, s) + MATCH_CASE (ValString&, s) { (void)s; } - CASE (const ValArea&, a) + MATCH_CASE (const ValArea&, a) { free_area(a.v_area); } } + MATCH_END (); } static @@ -214,63 +217,64 @@ void stringify(val_t *v) }}; AString buf; - MATCH (*v) + MATCH_BEGIN (*v) { - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, x) + MATCH_CASE (const ValUndef&, x) { (void)x; buf = "UNDEF"_s; } - CASE (const ValInt&, x) + MATCH_CASE (const ValInt&, x) { buf = STRPRINTF("%i"_fmt, x.v_int); } - CASE (const ValString&, x) + MATCH_CASE (const ValString&, x) { (void)x; return; } - CASE (const ValDir&, x) + MATCH_CASE (const ValDir&, x) { buf = dirs[x.v_dir]; } - CASE (const ValEntityPtr&, x) + MATCH_CASE (const ValEntityPtr&, x) { buf = show_entity(x.v_entity); } - CASE (const ValLocation&, x) + MATCH_CASE (const ValLocation&, x) { buf = STRPRINTF("<\"%s\", %d, %d>"_fmt, x.v_location.m->name_, x.v_location.x, x.v_location.y); } - CASE (const ValArea&, x) + MATCH_CASE (const ValArea&, x) { buf = "%area"_s; free_area(x.v_area); } - CASE (const ValSpell&, x) + MATCH_CASE (const ValSpell&, x) { buf = x.v_spell->name; } - CASE (const ValInvocationInt&, x) + MATCH_CASE (const ValInvocationInt&, x) { dumb_ptr<invocation> invocation_ = map_id2bl(x.v_iid)->is_spell(); buf = invocation_->spell->name; } - CASE (const ValInvocationPtr&, x) + MATCH_CASE (const ValInvocationPtr&, x) { dumb_ptr<invocation> invocation_ = x.v_invocation; buf = invocation_->spell->name; } } + MATCH_END (); *v = ValString{buf}; } @@ -312,14 +316,15 @@ void make_location(val_t *v) { if (ValArea *a = v->get_if<ValArea>()) { - MATCH (*a->v_area) + MATCH_BEGIN (*a->v_area) { - CASE (const location_t&, location) + MATCH_CASE (const location_t&, location) { free_area(a->v_area); *v = ValLocation{location}; } } + MATCH_END (); } } @@ -587,14 +592,14 @@ int fun_if_then_else(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) Borrowed<map_local> magic_area_rect(int *x, int *y, int *width, int *height, area_t& area_) { - MATCH (area_) + MATCH_BEGIN (area_) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { (void)a; abort(); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { P<map_local> m = a_loc.m; *x = a_loc.x; @@ -603,7 +608,7 @@ Borrowed<map_local> magic_area_rect(int *x, int *y, int *width, int *height, *height = 1; return m; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { P<map_local> m = a_rect.loc.m; *x = a_rect.loc.x; @@ -612,7 +617,7 @@ Borrowed<map_local> magic_area_rect(int *x, int *y, int *width, int *height, *height = a_rect.height; return m; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { int tx = a_bar.loc.x; int ty = a_bar.loc.y; @@ -660,19 +665,20 @@ Borrowed<map_local> magic_area_rect(int *x, int *y, int *width, int *height, return m; } } + MATCH_END (); abort(); } int magic_location_in_area(Borrowed<map_local> m, int x, int y, dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { return magic_location_in_area(m, x, y, a.a_union[0]) || magic_location_in_area(m, x, y, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -682,7 +688,7 @@ int magic_location_in_area(Borrowed<map_local> m, int x, int y, dumb_ptr<area_t> && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this is too complicated @@ -692,7 +698,7 @@ int magic_location_in_area(Borrowed<map_local> m, int x, int y, dumb_ptr<area_t> && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -703,6 +709,7 @@ int magic_location_in_area(Borrowed<map_local> m, int x, int y, dumb_ptr<area_t> && (x < ax + awidth) && (y < ay + aheight)); } } + MATCH_END (); abort(); } @@ -1084,16 +1091,16 @@ int fun_line_of_sight(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) void magic_random_location(location_t *dest, dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { if (random_::chance({a.a_union[0]->size, area->size})) magic_random_location(dest, a.a_union[0]); else magic_random_location(dest, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -1114,7 +1121,7 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this can be simplified @@ -1135,7 +1142,7 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -1157,6 +1164,7 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->y = pair.second; } } + MATCH_END (); } static @@ -1529,9 +1537,9 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, const e_location_t *exp static dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) { - MATCH (expr_) + MATCH_BEGIN (expr_) { - CASE (const e_location_t&, a_loc) + MATCH_CASE (const e_location_t&, a_loc) { location_t loc; if (eval_location(env, &loc, &a_loc)) @@ -1543,7 +1551,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) return dumb_ptr<area_t>::make(loc); } } - CASE (const ExprAreaUnion&, a) + MATCH_CASE (const ExprAreaUnion&, a) { AreaUnion u; bool fail = false; @@ -1565,7 +1573,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) } return dumb_ptr<area_t>::make(u); } - CASE (const ExprAreaRect&, a_rect) + MATCH_CASE (const ExprAreaRect&, a_rect) { val_t width, height; magic_eval(env, &width, a_rect.width); @@ -1591,7 +1599,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) return nullptr; } } - CASE (const ExprAreaBar&, a_bar) + MATCH_CASE (const ExprAreaBar&, a_bar) { val_t width, depth, dir; magic_eval(env, &width, a_bar.width); @@ -1623,6 +1631,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) } } } + MATCH_END (); abort(); } @@ -1741,14 +1750,14 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) { - MATCH (*expr) + MATCH_BEGIN (*expr) { - CASE (const val_t&, e_val) + MATCH_CASE (const val_t&, e_val) { magic_copy_var(dest, &e_val); } - CASE (const e_location_t&, e_location) + MATCH_CASE (const e_location_t&, e_location) { location_t loc; if (eval_location(env, &loc, &e_location)) @@ -1756,14 +1765,14 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) else *dest = ValLocation{loc}; } - CASE (const e_area_t&, e_area) + MATCH_CASE (const e_area_t&, e_area) { if (dumb_ptr<area_t> area = eval_area(env, e_area)) *dest = ValArea{area}; else *dest = ValFail(); } - CASE (const ExprFunApp&, e_funapp) + MATCH_CASE (const ExprFunApp&, e_funapp) { val_t arguments[MAX_ARGS]; int args_nr = e_funapp.args_nr; @@ -1797,12 +1806,12 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) for (i = 0; i < args_nr; ++i) magic_clear_var(&arguments[i]); } - CASE (const ExprId&, e) + MATCH_CASE (const ExprId&, e) { val_t& v = env->VAR(e.e_id); magic_copy_var(dest, &v); } - CASE (const ExprField&, e_field) + MATCH_CASE (const ExprField&, e_field) { val_t v; int id = e_field.id; @@ -1830,6 +1839,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) } } } + MATCH_END (); } int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp index 7fde979..e0392e4 100644 --- a/src/map/magic-interpreter-base.cpp +++ b/src/map/magic-interpreter-base.cpp @@ -314,22 +314,22 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, if (guard == nullptr) return nullptr; - MATCH (*guard) + MATCH_BEGIN (*guard) { - CASE (const GuardCondition&, s) + MATCH_CASE (const GuardCondition&, s) { if (!magic_eval_int(env, s.s_condition)) return nullptr; } - CASE (const GuardComponents&, s) + MATCH_CASE (const GuardComponents&, s) { copy_components(&check->components, s.s_components); } - CASE (const GuardCatalysts&, s) + MATCH_CASE (const GuardCatalysts&, s) { copy_components(&check->catalysts, s.s_catalysts); } - CASE (const GuardChoice&, s) + MATCH_CASE (const GuardChoice&, s) { spellguard_check_t altcheck = *check; const effect_set_t *retval; @@ -351,15 +351,15 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, return spellguard_check_sub(check, s.s_alt, caster, env, near_miss); } - CASE (const GuardMana&, s) + MATCH_CASE (const GuardMana&, s) { check->mana += magic_eval_int(env, s.s_mana); } - CASE (const GuardCastTime&, s) + MATCH_CASE (const GuardCastTime&, s) { check->casttime += static_cast<interval_t>(magic_eval_int(env, s.s_casttime)); } - CASE (const effect_set_t&, s_effect) + MATCH_CASE (const effect_set_t&, s_effect) { if (spellguard_can_satisfy(check, caster, env, near_miss)) return &s_effect; @@ -367,6 +367,7 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, return nullptr; } } + MATCH_END (); return spellguard_check_sub(check, guard->next, caster, env, near_miss); } diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index d5e1a15..39b47fc 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -61,17 +61,18 @@ constexpr Species INVISIBLE_NPC = wrap<Species>(127); static void clear_activation_record(cont_activation_record_t *ar) { - MATCH (*ar) + MATCH_BEGIN (*ar) { - CASE (CarForEach&, c_foreach) + MATCH_CASE (CarForEach&, c_foreach) { c_foreach.entities_vp.delete_(); } - CASE (CarProc&, c_proc) + MATCH_CASE (CarProc&, c_proc) { c_proc.old_actualpa.delete_(); } } + MATCH_END (); } static @@ -998,9 +999,9 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) { cont_activation_record_t *ar = &invocation_->stack.back(); - MATCH (*ar) + MATCH_BEGIN (*ar) { - CASE (const CarProc&, c_proc) + MATCH_CASE (const CarProc&, c_proc) { dumb_ptr<effect_t> ret = ar->return_location; for (int i = 0; i < c_proc.args_nr; i++) @@ -1017,7 +1018,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) return ret; } - CASE (CarForEach&, c_foreach) + MATCH_CASE (CarForEach&, c_foreach) { BlockId entity_id; val_t *var = &invocation_->env->varu[c_foreach.id]; @@ -1048,7 +1049,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) return c_foreach.body; } - CASE (CarFor&, c_for) + MATCH_CASE (CarFor&, c_for) { if (c_for.current > c_for.stop) { @@ -1065,6 +1066,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) return c_for.body; } } + MATCH_END (); abort(); } } @@ -1136,14 +1138,14 @@ void find_entities_in_area(area_t& area_, std::vector<BlockId> *entities_vp, FOREACH_FILTER filter) { - MATCH (area_) + MATCH_BEGIN (area_) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { find_entities_in_area(*a.a_union[0], entities_vp, filter); find_entities_in_area(*a.a_union[1], entities_vp, filter); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -1155,7 +1157,7 @@ void find_entities_in_area(area_t& area_, x + width, y + height, BL::NUL /* filter elsewhere */); } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this can be simplified @@ -1167,7 +1169,7 @@ void find_entities_in_area(area_t& area_, x + width, y + height, BL::NUL /* filter elsewhere */); } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -1180,6 +1182,7 @@ void find_entities_in_area(area_t& area_, BL::NUL /* filter elsewhere */); } } + MATCH_END (); } static @@ -1312,13 +1315,13 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) dumb_ptr<effect_t> next = e->next; int i; - MATCH (*e) + MATCH_BEGIN (*e) { - CASE (const EffectSkip&, e_) + MATCH_CASE (const EffectSkip&, e_) { (void)e_; } - CASE (const EffectAbort&, e_) + MATCH_CASE (const EffectAbort&, e_) { (void)e_; invocation_->flags |= INVOCATION_FLAG::ABORTED; @@ -1326,34 +1329,34 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) clear_stack(invocation_); next = nullptr; } - CASE (const EffectEnd&, e_) + MATCH_CASE (const EffectEnd&, e_) { (void)e_; clear_stack(invocation_); next = nullptr; } - CASE (const EffectAssign&, e_assign) + MATCH_CASE (const EffectAssign&, e_assign) { magic_eval(invocation_->env, &invocation_->env->varu[e_assign.id], e_assign.expr); } - CASE (const EffectForEach&, e_foreach) + MATCH_CASE (const EffectForEach&, e_foreach) { next = run_foreach(invocation_, &e_foreach, next); } - CASE (const EffectFor&, e_for) + MATCH_CASE (const EffectFor&, e_for) { next = run_for (invocation_, &e_for, next); } - CASE (const EffectIf&, e_if) + MATCH_CASE (const EffectIf&, e_if) { if (magic_eval_int(invocation_->env, e_if.cond)) next = e_if.true_branch; else next = e_if.false_branch; } - CASE (const EffectSleep&, e_) + MATCH_CASE (const EffectSleep&, e_) { interval_t sleeptime = static_cast<interval_t>( magic_eval_int(invocation_->env, e_.e_sleep)); @@ -1361,7 +1364,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) if (sleeptime > interval_t::zero()) return sleeptime; } - CASE (const EffectScript&, e_) + MATCH_CASE (const EffectScript&, e_) { dumb_ptr<map_session_data> caster = map_id_is_player(invocation_->caster); if (caster) @@ -1408,12 +1411,12 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) } REFRESH_INVOCATION; // Script may have killed the caster } - CASE (const EffectBreak&, e_) + MATCH_CASE (const EffectBreak&, e_) { (void)e_; next = return_to_stack(invocation_); } - CASE (const EffectOp&, e_op) + MATCH_CASE (const EffectOp&, e_op) { op_t *op = e_op.opp; val_t args[MAX_ARGS]; @@ -1432,11 +1435,12 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) REFRESH_INVOCATION; // Effect may have killed the caster } - CASE (const EffectCall&, e_call) + MATCH_CASE (const EffectCall&, e_call) { next = run_call(invocation_, &e_call, next); } } + MATCH_END (); break_match: if (!next) diff --git a/src/map/magic-v2.cpp b/src/map/magic-v2.cpp index 204c774..7dfae08 100644 --- a/src/map/magic-v2.cpp +++ b/src/map/magic-v2.cpp @@ -139,14 +139,15 @@ namespace magic_v2 /* For FOR and FOREACH, we use special stack handlers and thus don't have to set * the continuation. It's only IF that we need to handle in this fashion. */ - MATCH (*src) + MATCH_BEGIN (*src) { - CASE (EffectIf&, e_if) + MATCH_CASE (EffectIf&, e_if) { set_effect_continuation(e_if.true_branch, continuation); set_effect_continuation(e_if.false_branch, continuation); } } + MATCH_END (); if (src->next) set_effect_continuation(src->next, continuation); @@ -177,13 +178,14 @@ namespace magic_v2 } /* If the premise is a disjunction, b is the continuation of _all_ branches */ - MATCH (*a) + MATCH_BEGIN (*a) { - CASE(const GuardChoice&, s) + MATCH_CASE (const GuardChoice&, s) { spellguard_implication(s.s_alt, b); } } + MATCH_END (); if (a->next) spellguard_implication(a->next, b); diff --git a/src/map/map.cpp b/src/map/map.cpp index 784319f..e2c38a7 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1247,36 +1247,40 @@ void map_setcell(Borrowed<map_local> m, int x, int y, MapCell t) int map_setipport(MapName name, IP4Address ip, int port) { Option<P<map_abstract>> md_ = maps_db.get(name); - if OPTION_IS_SOME_NOLOOP(md, md_) + OMATCH_BEGIN (md_) { - if (md->gat) + OMATCH_CASE_SOME (md) { - // local -> check data - if (ip != clif_getip() || port != clif_getport()) + if (md->gat) { - PRINTF("from char server : %s -> %s:%d\n"_fmt, - name, ip, port); - return 1; + // local -> check data + if (ip != clif_getip() || port != clif_getport()) + { + PRINTF("from char server : %s -> %s:%d\n"_fmt, + name, ip, port); + return 1; + } + } + else + { + // update + P<map_remote> mdos = md.downcast_to<map_remote>(); + mdos->ip = ip; + mdos->port = port; } } - else + OMATCH_CASE_NONE () { - // update - P<map_remote> mdos = md.downcast_to<map_remote>(); + // not exist -> add new data + auto mdos = make_unique<map_remote>(); + mdos->name_ = name; + mdos->gat = nullptr; mdos->ip = ip; mdos->port = port; + maps_db.put(mdos->name_, std::move(mdos)); } } - else - { - // not exist -> add new data - auto mdos = make_unique<map_remote>(); - mdos->name_ = name; - mdos->gat = nullptr; - mdos->ip = ip; - mdos->port = port; - maps_db.put(mdos->name_, std::move(mdos)); - } + OMATCH_END (); return 0; } diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 63db442..b01a4ff 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -2591,7 +2591,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (it == ptv.end()) { Option<PartyPair> p_ = party_search(pid); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { if (p->exp != 0) { @@ -2600,6 +2600,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, flag = 0; } } + OMATCH_END (); } else { diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index 8b47502..3df54c7 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -756,17 +756,17 @@ bool npc_load_script_map(ast::script::ScriptBody& body, ast::npc::ScriptMap& scr static bool npc_load_script_any(ast::npc::Script *script) { - MATCH (*script) + MATCH_BEGIN (*script) { - CASE (ast::npc::ScriptFunction&, script_function) + MATCH_CASE (ast::npc::ScriptFunction&, script_function) { return npc_load_script_function(script->body, script_function); } - CASE (ast::npc::ScriptNone&, script_none) + MATCH_CASE (ast::npc::ScriptNone&, script_none) { return npc_load_script_none(script->body, script_none); } - CASE (ast::npc::ScriptMapNone&, script_map_none) + MATCH_CASE (ast::npc::ScriptMapNone&, script_map_none) { auto& mapname = script_map_none.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -777,7 +777,7 @@ bool npc_load_script_any(ast::npc::Script *script) } return npc_load_script_map_none(script->body, script_map_none); } - CASE (ast::npc::ScriptMap&, script_map) + MATCH_CASE (ast::npc::ScriptMap&, script_map) { auto& mapname = script_map.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -789,6 +789,7 @@ bool npc_load_script_any(ast::npc::Script *script) return npc_load_script_map(script->body, script_map); } } + MATCH_END (); abort(); } @@ -827,14 +828,14 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) PRINTF("%s\n"_fmt, res.get_failure()); ast::npc::TopLevel tl = TRY_UNWRAP(std::move(res.get_success()), return false); - MATCH (tl) + MATCH_BEGIN (tl) { - CASE (ast::npc::Comment&, c) + MATCH_CASE (ast::npc::Comment&, c) { (void)c; return true; } - CASE (ast::npc::Warp&, warp) + MATCH_CASE (ast::npc::Warp&, warp) { auto& mapname = warp.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -845,7 +846,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_warp(warp); } - CASE (ast::npc::Shop&, shop) + MATCH_CASE (ast::npc::Shop&, shop) { auto& mapname = shop.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -856,7 +857,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_shop(shop); } - CASE (ast::npc::Monster&, monster) + MATCH_CASE (ast::npc::Monster&, monster) { auto& mapname = monster.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -867,7 +868,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_monster(monster); } - CASE (ast::npc::MapFlag&, mapflag) + MATCH_CASE (ast::npc::MapFlag&, mapflag) { auto& mapname = mapflag.m; Option<P<map_local>> m = map_mapname2mapid(mapname.data); @@ -878,11 +879,12 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_mapflag(mapflag); } - CASE (ast::npc::Script&, script) + MATCH_CASE (ast::npc::Script&, script) { return npc_load_script_any(&script); } } + MATCH_END (); abort(); } diff --git a/src/map/party.cpp b/src/map/party.cpp index 0a9d2c5..b05f4f1 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -213,11 +213,12 @@ static PartyPair handle_info(const PartyPair sp) { Option<PartyPair> p_ = party_search(sp.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { *p.party_most = *sp.party_most; return p; } + OMATCH_END (); { PartyPair p{sp.party_id, party_db.init(sp.party_id)}; @@ -459,7 +460,7 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) { dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)); Option<PartyPair> p_ = party_search(party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { int i; for (i = 0; i < MAX_PARTY; i++) @@ -470,6 +471,7 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) p->member[i].sd = nullptr; } } + OMATCH_END (); if (sd != nullptr && sd->status.party_id == party_id) { sd->status.party_id = PartyId(); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a38c05f..33d77fd 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -555,14 +555,22 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd) sd->equip_index_maybe[j] = i; if (bool(sd->status.inventory[i].equip & EPOS::WEAPON)) { - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) - sd->weapontype1 = sdidi->look; - else - sd->weapontype1 = ItemLook::NONE; + OMATCH_BEGIN (sd->inventory_data[i]) + { + OMATCH_CASE_SOME (sdidi) + { + sd->weapontype1 = sdidi->look; + } + OMATCH_CASE_NONE () + { + sd->weapontype1 = ItemLook::NONE; + } + } + OMATCH_END (); } if (bool(sd->status.inventory[i].equip & EPOS::SHIELD)) { - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[i]) { if (sdidi->type == ItemType::WEAPON) { @@ -570,6 +578,7 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd) assert(0 && "unreachable - offhand weapons are not supported"); } } + OMATCH_END (); } } } @@ -998,13 +1007,14 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) || sd->equip_index_maybe[EQUIP::LEGS] == index)) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { sd->spellpower_bonus_target += sdidi->magic_bonus; // used to apply cards } + OMATCH_END (); } #ifdef USE_ASTRAL_SOUL_SKILL @@ -1033,7 +1043,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) && (sd->equip_index_maybe[EQUIP::TORSO] == index || sd->equip_index_maybe[EQUIP::LEGS] == index)) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { sd->def += sdidi->def; if (sdidi->type == ItemType::WEAPON) @@ -1072,6 +1082,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) arg); } } + OMATCH_END (); } if (battle_is_unarmed(sd)) @@ -1084,7 +1095,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) if (aidx.ok()) { IOff0 index = aidx; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { //まだ属性が入っていない argrec_t arg[2] = { @@ -1098,6 +1109,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->state.lr_flag_is_arrow_2 = 0; sd->arrow_atk += sdidi->atk; } + OMATCH_END (); } sd->def += (refinedef + 50) / 100; @@ -2111,7 +2123,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n) if (!n.ok()) return 0; - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[n]) { amount = sd->status.inventory[n].amount; if (!sd->status.inventory[n].nameid @@ -2128,6 +2140,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n) run_script(ScriptPointer(script, 0), sd->bl_id, BlockId()); } + OMATCH_END (); return 0; } @@ -3172,8 +3185,11 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] Option<PartyPair> p_ = party_search(sd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) + { clif_party_hp(p, sd); + } + OMATCH_END (); } // end addition [Valaris] return 0; @@ -3540,8 +3556,11 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp) if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] Option<PartyPair> p_ = party_search(sd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) + { clif_party_hp(p, sd); + } + OMATCH_END (); } // end addition [Valaris] return hp + sp; @@ -4191,7 +4210,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS) ItemNameId view_i; ItemLook view_l = ItemLook::NONE; // TODO: This is ugly. - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[n]) { bool look_not_weapon = sdidn->look == ItemLook::NONE; bool equip_is_weapon = bool(sd->status.inventory[n].equip & EPOS::WEAPON); @@ -4202,6 +4221,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS) else view_l = sdidn->look; } + OMATCH_END (); if (bool(sd->status.inventory[n].equip & EPOS::WEAPON)) { @@ -4211,23 +4231,27 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS) } if (bool(sd->status.inventory[n].equip & EPOS::SHIELD)) { - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN (sd->inventory_data[n]) { - if (sdidn->type == ItemType::WEAPON) + OMATCH_CASE_SOME (sdidn) { - sd->status.shield = ItemNameId(); - if (sd->status.inventory[n].equip == EPOS::SHIELD) - assert(0 && "unreachable - offhand weapons are not supported"); + if (sdidn->type == ItemType::WEAPON) + { + sd->status.shield = ItemNameId(); + if (sd->status.inventory[n].equip == EPOS::SHIELD) + assert(0 && "unreachable - offhand weapons are not supported"); + } + else if (sdidn->type == ItemType::ARMOR) + { + sd->status.shield = view_i; + } } - else if (sdidn->type == ItemType::ARMOR) + OMATCH_CASE_NONE () { - sd->status.shield = view_i; + sd->status.shield = ItemNameId(); } } - else - { - sd->status.shield = ItemNameId(); - } + OMATCH_END (); pc_calcweapontype(sd); clif_changelook(sd, LOOK::SHIELD, unwrap<ItemNameId>(sd->status.shield)); } diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp index abab24d..5ac45e5 100644 --- a/src/map/script-call.cpp +++ b/src/map/script-call.cpp @@ -74,9 +74,9 @@ dumb_ptr<map_session_data> script_rid2sd(ScriptState *st) */ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) { - MATCH (*data) + MATCH_BEGIN (*data) { - CASE (const ScriptDataParam&, u) + MATCH_CASE (const ScriptDataParam&, u) { if (sd == nullptr) PRINTF("get_val error param SP::%d\n"_fmt, u.reg.sp()); @@ -85,7 +85,7 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) numi = pc_readparam(sd, u.reg.sp()); *data = ScriptDataInt{numi}; } - CASE (const ScriptDataVariable&, u) + MATCH_CASE (const ScriptDataVariable&, u) { ZString name_ = variable_names.outtern(u.reg.base()); VarName name = stringish<VarName>(name_); @@ -108,8 +108,11 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) else if (prefix == '$') { Option<P<RString>> s_ = mapregstr_db.search(u.reg); - if OPTION_IS_SOME_NOLOOP(s, s_) + OMATCH_BEGIN_SOME (s, s_) + { str = *s; + } + OMATCH_END (); } else { @@ -152,6 +155,7 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) } } } + MATCH_END (); } void get_val(ScriptState *st, struct script_data *data) @@ -268,24 +272,27 @@ int conv_num(ScriptState *st, struct script_data *data) int rv = 0; get_val(st, data); assert (!data->is<ScriptDataRetInfo>()); - MATCH (*data) + MATCH_BEGIN (*data) { - default: + MATCH_DEFAULT () + { abort(); - CASE (const ScriptDataStr&, u) + } + MATCH_CASE (const ScriptDataStr&, u) { RString p = u.str; rv = atoi(p.c_str()); } - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { return u.numi; } - CASE (const ScriptDataPos&, u) + MATCH_CASE (const ScriptDataPos&, u) { return u.numi; } } + MATCH_END () *data = ScriptDataInt{rv}; return rv; } @@ -596,45 +603,46 @@ void run_func(ScriptState *st) PRINTF("stack dump :"_fmt); for (script_data& d : st->stack->stack_datav) { - MATCH (d) + MATCH_BEGIN (d) { - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { PRINTF(" int(%d)"_fmt, u.numi); } - CASE (const ScriptDataRetInfo&, u) + MATCH_CASE (const ScriptDataRetInfo&, u) { PRINTF(" retinfo(%p)"_fmt, static_cast<const void *>(&*u.script)); } - CASE (const ScriptDataParam&, u) + MATCH_CASE (const ScriptDataParam&, u) { PRINTF(" param(%d)"_fmt, u.reg.sp()); } - CASE (const ScriptDataVariable&, u) + MATCH_CASE (const ScriptDataVariable&, u) { PRINTF(" name(%s)[%d]"_fmt, variable_names.outtern(u.reg.base()), u.reg.index()); } - CASE (const ScriptDataArg&, u) + MATCH_CASE (const ScriptDataArg&, u) { (void)u; PRINTF(" arg"_fmt); } - CASE (const ScriptDataPos&, u) + MATCH_CASE (const ScriptDataPos&, u) { (void)u; PRINTF(" pos(%d)"_fmt, u.numi); } - CASE (const ScriptDataStr&, u) + MATCH_CASE (const ScriptDataStr&, u) { (void)u; PRINTF(" str(%s)"_fmt, u.str); } - CASE (const ScriptDataFuncRef&, u) + MATCH_CASE (const ScriptDataFuncRef&, u) { (void)u; PRINTF(" func(%s)"_fmt, builtin_functions[u.numi].name); } } + MATCH_END (); } PRINTF("\n"_fmt); } 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<P<const ScriptBuffer>> 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<ScriptDataInt>(st->stack, j); // 引数の数をプッシュ - push_int<ScriptDataInt>(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ - push_int<ScriptDataInt>(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ - push_script<ScriptDataRetInfo>(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ + push_int<ScriptDataInt>(st->stack, j); // 引数の数をプッシュ + push_int<ScriptDataInt>(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ + push_int<ScriptDataInt>(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ + push_script<ScriptDataRetInfo>(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<P<struct item_data>> 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<ItemNameId>(conv_num(st, data)); @@ -763,8 +769,11 @@ void builtin_checkweight(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option<P<struct item_data>> 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<ItemNameId>(conv_num(st, data)); @@ -808,8 +817,11 @@ void builtin_getitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option<P<struct item_data>> 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<ItemNameId>(conv_num(st, data)); @@ -861,8 +873,11 @@ void builtin_makeitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option<P<struct item_data>> 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<ItemNameId>(conv_num(st, data)); @@ -905,8 +920,11 @@ void builtin_delitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option<P<struct item_data>> 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<ItemNameId>(conv_num(st, data)); @@ -1080,10 +1098,18 @@ void builtin_getequipid(ScriptState *st) if (i.ok()) { Option<P<struct item_data>> item_ = sd->inventory_data[i]; - if OPTION_IS_SOME_NOLOOP(item, item_) - push_int<ScriptDataInt>(st->stack, unwrap<ItemNameId>(item->nameid)); - else - push_int<ScriptDataInt>(st->stack, 0); + OMATCH_BEGIN (item_) + { + OMATCH_CASE_SOME (item) + { + push_int<ScriptDataInt>(st->stack, unwrap<ItemNameId>(item->nameid)); + } + OMATCH_CASE_NONE () + { + push_int<ScriptDataInt>(st->stack, 0); + } + } + OMATCH_END (); } else { @@ -1109,10 +1135,18 @@ void builtin_getequipname(ScriptState *st) if (i.ok()) { Option<P<struct item_data>> 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<P<struct item_data>> 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<ItemNameId>(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<P<map_local>> 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<P<map_local>> 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<P<map_local>> 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<ScriptDataInt>(st->stack, r); } diff --git a/src/map/script-parse.cpp b/src/map/script-parse.cpp index 47e0def..6b41225 100644 --- a/src/map/script-parse.cpp +++ b/src/map/script-parse.cpp @@ -134,8 +134,11 @@ Option<Borrowed<str_data_t>> search_strp(XString p) Borrowed<str_data_t> add_strp(XString p) { Option<P<str_data_t>> rv_ = search_strp(p); - if OPTION_IS_SOME_NOLOOP(rv, rv_) + OMATCH_BEGIN_SOME (rv, rv_) + { return rv; + } + OMATCH_END (); RString p2 = p; P<str_data_t> datum = str_datam.init(p2); diff --git a/src/map/trade.cpp b/src/map/trade.cpp index 5ec63c9..bc6e98f 100644 --- a/src/map/trade.cpp +++ b/src/map/trade.cpp @@ -174,7 +174,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount) sd->status.inventory[index.unshift()].nameid) continue; - if OPTION_IS_SOME_INLOOP(id, target_sd->inventory_data[i]) + OMATCH_BEGIN_SOME (id, target_sd->inventory_data[i]) { if (id->type != ItemType::WEAPON && id->type != ItemType::ARMOR @@ -182,9 +182,12 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount) && id->type != ItemType::_8) { free_++; - break; + goto break_outer1; } } + OMATCH_END (); + break_outer1: + break; } if (target_sd->weight + trade_weight > @@ -231,7 +234,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount) sd->status. inventory[sd->deal_item_index[trade_i].unshift()].nameid) continue; - if OPTION_IS_SOME_INLOOP(id, target_sd->inventory_data[i]) + OMATCH_BEGIN_SOME (id, target_sd->inventory_data[i]) { if (id->type != ItemType::WEAPON && id->type != ItemType::ARMOR @@ -239,9 +242,12 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount) && id->type != ItemType::_8) { free_++; - break; + goto break_outer2; } } + OMATCH_END (); + break_outer2: + break; } } // used a slot, but might be cancelled out by stackable checks above diff --git a/src/sexpr/fwd.hpp b/src/sexpr/fwd.hpp index 41e21a1..b86d9fb 100644 --- a/src/sexpr/fwd.hpp +++ b/src/sexpr/fwd.hpp @@ -21,7 +21,6 @@ #include "../sanity.hpp" #include "../strings/fwd.hpp" // rank 1 -#include "../compat/fwd.hpp" // rank 2 #include "../io/fwd.hpp" // rank 4 // sexpr/fwd.hpp is rank 5 diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp index 287a5f0..0eccc5a 100644 --- a/src/sexpr/variant.hpp +++ b/src/sexpr/variant.hpp @@ -23,8 +23,6 @@ #include <cstddef> #include <utility> -#include "../compat/attr.hpp" - #include "union.hpp" #include "void.hpp" @@ -35,14 +33,42 @@ namespace tmwa { namespace sexpr { -#define MATCH(expr) \ - WITH_VAR_NOLOOP(auto&&, _match_var, expr) \ - switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) -#define TYPED_CASE(ty, var, look) \ - break; \ - case tmwa::sexpr::VariantFriend::get_state_for<look, decltype(_match_var)>(): \ - WITH_VAR_INLOOP(ty, var, tmwa::sexpr::VariantFriend::unchecked_get<look>(_match_var)) -#define CASE(ty, var) TYPED_CASE(ty, var, std::remove_const<std::remove_reference<ty>::type>::type) +#define MATCH_BEGIN(expr) \ + { \ + auto&& _match_var = (expr); \ + switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) \ + { \ + { \ + { \ + /* }}}} */ +#define MATCH_END() \ + /* {{{{ */ \ + } \ + } \ + } \ + (void) _match_var; \ + } + +#define MATCH_CASE(ty, v) \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + using _match_case_type = std::remove_const<std::remove_reference<ty>::type>::type; \ + case tmwa::sexpr::VariantFriend::get_state_for<_match_case_type, decltype(_match_var)>(): \ + { \ + ty v = tmwa::sexpr::VariantFriend::unchecked_get<_match_case_type>(_match_var); + /* }}}} */ +#define MATCH_DEFAULT() \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + default: \ + { \ + /* }}}} */ template<class... T> class Variant diff --git a/src/sexpr/variant_test.cpp b/src/sexpr/variant_test.cpp index bc378aa..c671264 100644 --- a/src/sexpr/variant_test.cpp +++ b/src/sexpr/variant_test.cpp @@ -77,42 +77,46 @@ TEST(variant, match) : sexpr::Variant<Foo, Bar>(Foo(1)) {} }; + Sub v1; - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; SUCCEED(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; FAIL(); } } + MATCH_END (); + v1.emplace<Bar>(2); - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; FAIL(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; SUCCEED(); } } + MATCH_END (); } TEST(variant, copymove1) |