From 730e5dde39333cb2f63c72a7d7152bee5c4dbb05 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 8 Feb 2014 15:09:25 -0800 Subject: Implement AString --- src/admin/ladmin.cpp | 26 ++-- src/char/char.cpp | 20 +-- src/char/int_party.cpp | 14 +-- src/char/int_party.hpp | 2 +- src/char/int_storage.cpp | 14 +-- src/char/int_storage.hpp | 2 +- src/char/inter.cpp | 16 +-- src/common/dumb_ptr.hpp | 4 +- src/common/extract.cpp | 4 +- src/common/extract.hpp | 2 +- src/common/intern-pool.hpp | 9 +- src/common/mmo.hpp | 3 +- src/common/socket.hpp | 6 +- src/common/utils.cpp | 2 +- src/io/cxxstdio.hpp | 6 +- src/io/line.cpp | 10 +- src/io/line.hpp | 14 ++- src/io/lock.cpp | 10 +- src/io/lock.hpp | 6 +- src/io/read.cpp | 6 +- src/io/read.hpp | 2 +- src/io/read_test.cpp | 10 +- src/io/write_test.cpp | 12 +- src/login/login.cpp | 34 +++--- src/map/atcommand.cpp | 148 +++++++++++----------- src/map/atcommand.hpp | 2 +- src/map/battle.cpp | 6 +- src/map/chrif.cpp | 4 +- src/map/clif.cpp | 28 ++--- src/map/grfio.cpp | 17 ++- src/map/intif.cpp | 10 +- src/map/itemdb.cpp | 4 +- src/map/magic-expr.cpp | 10 +- src/map/magic-expr.hpp | 2 +- src/map/magic-interpreter-base.cpp | 10 +- src/map/magic-interpreter-parser.ypp | 29 ++--- src/map/magic-interpreter.hpp | 18 +-- src/map/magic.hpp | 4 +- src/map/map.cpp | 16 +-- src/map/map.hpp | 17 +-- src/map/mob.cpp | 6 +- src/map/npc.cpp | 24 ++-- src/map/npc.hpp | 6 +- src/map/pc.cpp | 13 +- src/map/pc.hpp | 2 +- src/map/script.cpp | 37 +++--- src/map/script.hpp | 7 +- src/map/skill.cpp | 8 +- src/map/skill.hpp | 11 +- src/map/tmw.cpp | 8 +- src/monitor/main.cpp | 21 ++-- src/strings/all.hpp | 3 +- src/strings/astring.cpp | 229 +++++++++++++++++++++++++++++++++++ src/strings/astring.hpp | 98 +++++++++++++++ src/strings/astring.py | 24 ++++ src/strings/astring.tcc | 76 ++++++++++++ src/strings/base.hpp | 2 +- src/strings/base.tcc | 2 +- src/strings/base_test.cpp | 4 +- src/strings/fstring.cpp | 173 -------------------------- src/strings/fstring.hpp | 104 ---------------- src/strings/fstring.py | 19 --- src/strings/fstring.tcc | 67 ---------- src/strings/fwd.hpp | 6 +- src/strings/rstring.cpp | 164 +++++++++++++++++++++++++ src/strings/rstring.hpp | 93 ++++++++++++++ src/strings/rstring.py | 19 +++ src/strings/rstring.tcc | 67 ++++++++++ src/strings/sstring.cpp | 45 +++++-- src/strings/sstring.hpp | 16 +-- src/strings/strings2_test.cpp | 106 ++++++++++++++-- src/strings/strings_test.cpp | 29 +++-- src/strings/tstring.cpp | 31 +++-- src/strings/tstring.hpp | 11 +- src/strings/vstring.hpp | 5 +- src/strings/vstring.tcc | 12 +- src/strings/xstring.cpp | 11 +- src/strings/xstring.hpp | 13 +- src/strings/zstring.cpp | 11 +- src/strings/zstring.hpp | 15 +-- src/strings/zstring.tcc | 2 +- 81 files changed, 1367 insertions(+), 792 deletions(-) create mode 100644 src/strings/astring.cpp create mode 100644 src/strings/astring.hpp create mode 100644 src/strings/astring.py create mode 100644 src/strings/astring.tcc delete mode 100644 src/strings/fstring.cpp delete mode 100644 src/strings/fstring.hpp delete mode 100644 src/strings/fstring.py delete mode 100644 src/strings/fstring.tcc create mode 100644 src/strings/rstring.cpp create mode 100644 src/strings/rstring.hpp create mode 100644 src/strings/rstring.py create mode 100644 src/strings/rstring.tcc (limited to 'src') diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp index d875205..38f0c4b 100644 --- a/src/admin/ladmin.cpp +++ b/src/admin/ladmin.cpp @@ -6,7 +6,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" @@ -48,7 +48,7 @@ int login_port = 6900; // Port of login-server static AccountPass admin_pass = stringish("admin"); // Administration password static -FString ladmin_log_filename = "log/ladmin.log"; +AString ladmin_log_filename = "log/ladmin.log"; //------------------------------------------------------------------------- // LIST of COMMANDs that you can type at the prompt: // To use these commands you can only type only the first letters. @@ -582,7 +582,7 @@ void display_help(ZString param) { if (command) PRINTF("Unknown command [%s] for help. Displaying of all commands.\n", - FString(command)); + AString(command)); PRINTF(" help/? -- Display this help\n"); PRINTF(" help/? [command] -- Display the help of the command\n"); PRINTF(" add -- Create an account with default email\n"); @@ -678,9 +678,9 @@ void addaccount(ZString param, int emailflag) if (!e_mail_check(email_)) { PRINTF("Invalid email [%s]. Please input a valid e-mail.\n", - FString(email_)); + AString(email_)); LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n", - FString(email_)); + AString(email_)); return; } AccountEmail email = stringish(email_); @@ -1040,9 +1040,9 @@ void changeemail(ZString param) if (!e_mail_check(email_)) { PRINTF("Invalid email [%s]. Please input a valid e-mail.\n", - FString(email_)); + AString(email_)); LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n", - FString(email_)); + AString(email_)); return; } AccountEmail email = stringish(email_); @@ -1773,7 +1773,7 @@ void prompt(void) // get command and parameter // TODO figure out a better way to do stdio static auto cin = make_unique(io::FD::stdin().dup()); - FString buf; + AString buf; cin->getline(buf); Iprintf(SGR_RESET); @@ -1791,7 +1791,7 @@ void prompt(void) // extract command name and parameters auto space = std::find(buf.begin(), buf.end(), ' '); - FString command = buf.xislice_h(space); + AString command = buf.xislice_h(space); while (*space == ' ') ++space; @@ -1809,7 +1809,7 @@ void prompt(void) { // We don't want passwords in the log - Camel if (command == "create" || command == "add" || command == "password") { - FString name, email_, password; + AString name, email_, password; VString<1> sex_; if (qsplit(parameters, &name, &sex_, &email_, &password)) @@ -2218,7 +2218,7 @@ void parse_fromlogin(Session *s) break; } tmpstr += ']'; - FString tmpstr_ = FString(tmpstr); + AString tmpstr_ = AString(tmpstr); PRINTF("%s\n", tmpstr_); LADMIN_LOG("%s\n", tmpstr_); } @@ -2630,7 +2630,7 @@ void parse_fromlogin(Session *s) AccountEmail email = stringish(RFIFO_STRING<40>(s, 100)); TimeT connect_until_time = static_cast(RFIFOL(s, 140)); TimeT ban_until_time = static_cast(RFIFOL(s, 144)); - FString memo = RFIFO_STRING(s, 150, RFIFOW(s, 148)); + AString memo = RFIFO_STRING(s, 150, RFIFOW(s, 148)); if (account_id == -1) { PRINTF("Unabled to find the account [%s]. Account doesn't exist.\n", @@ -2812,7 +2812,7 @@ bool admin_confs(XString w1, ZString w2) } else { - PRINTF("WARNING: unknown ladmin config key: %s\n", FString(w1)); + PRINTF("WARNING: unknown ladmin config key: %s\n", AString(w1)); return false; } } diff --git a/src/char/char.cpp b/src/char/char.cpp index 15ea46b..55dca81 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -16,7 +16,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -74,11 +74,11 @@ IP4Address char_ip; static int char_port = 6121; static -FString char_txt; +AString char_txt; static CharName unknown_char_name = stringish("Unknown"); static -FString char_log_filename = "log/char.log"; +AString char_log_filename = "log/char.log"; //Added for lan support static IP4Address lan_map_ip = IP4_LOCALHOST; @@ -140,9 +140,9 @@ std::vector gm_accounts; // online players by [Yor] static -FString online_txt_filename = "online.txt"; +AString online_txt_filename = "online.txt"; static -FString online_html_filename = "online.html"; +AString online_html_filename = "online.html"; static int online_sorting_option = 0; // sorting option to display online players in online files static @@ -232,7 +232,7 @@ Session *& server_for_m(const mmo_charstatus *mcs) // Function to create the character line (for save) //------------------------------------------------- static -FString mmo_char_tostr(struct mmo_charstatus *p) +AString mmo_char_tostr(struct mmo_charstatus *p) { // on multi-map server, sometimes it's posssible that last_point become void. (reason???) We check that to not lost character at restart. if (!p->last_point.map_) @@ -333,7 +333,7 @@ FString mmo_char_tostr(struct mmo_charstatus *p) p->global_reg[i].value); str_p += '\t'; - return FString(str_p); + return AString(str_p); } static @@ -470,7 +470,7 @@ int mmo_char_init(void) } int line_count = 0; - FString line; + AString line; while (in.getline(line)) { line_count++; @@ -528,7 +528,7 @@ void mmo_char_sync(void) // yes, we need a mutable reference to do the saves ... for (mmo_charstatus& cd : char_data) { - FString line = mmo_char_tostr(&cd); + AString line = mmo_char_tostr(&cd); fp.put_line(line); } FPRINTF(fp, "%d\t%%newid%%\n", char_id_count); @@ -1282,7 +1282,7 @@ void parse_tologin(Session *ls) else { size_t len = RFIFOL(ls, 4); - FString message = RFIFO_STRING(ls, 8, len).to_print().lstrip(); + AString message = RFIFO_STRING(ls, 8, len).to_print().lstrip(); // if message is only composed of spaces if (!message) CHAR_LOG("Receiving a message for broadcast, but message is only a lot of spaces.\n"); diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 79f24cb..cf9b3e5 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -4,7 +4,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" @@ -21,7 +21,7 @@ #include "../poison.hpp" -FString party_txt = "save/party.txt"; +AString party_txt = "save/party.txt"; static Map party_db; @@ -37,7 +37,7 @@ void mapif_parse_PartyLeave(Session *s, int party_id, int account_id); // パーティデータの文字列への変換 static -FString inter_party_tostr(struct party *p) +AString inter_party_tostr(struct party *p) { MString str; str += STRPRINTF( @@ -59,7 +59,7 @@ FString inter_party_tostr(struct party *p) m->name); } - return FString(str); + return AString(str); } static @@ -130,7 +130,7 @@ void inter_party_init(void) return; // TODO: convert to use char_id, and change to extract() - FString line; + AString line; int c = 0; while (in.getline(line)) { @@ -164,7 +164,7 @@ void inter_party_init(void) static void inter_party_save_sub(struct party *data, io::WriteFile& fp) { - FString line = inter_party_tostr(data); + AString line = inter_party_tostr(data); fp.put_line(line); } @@ -701,7 +701,7 @@ int inter_party_parse_frommap(Session *ms) size_t len = RFIFOW(ms, 2) - 12; int party_id = RFIFOL(ms, 4); int account_id = RFIFOL(ms, 8); - FString mes = RFIFO_STRING(ms, 12, len); + AString mes = RFIFO_STRING(ms, 12, len); mapif_parse_PartyMessage(ms, party_id, account_id, diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index a5b6e8b..e4dedd1 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -12,6 +12,6 @@ int inter_party_parse_frommap(Session *ms); void inter_party_leave(int party_id, int account_id); -extern FString party_txt; +extern AString party_txt; #endif // INT_PARTY_HPP diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index c21da81..cdc6e05 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -6,7 +6,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" @@ -22,14 +22,14 @@ // ファイル名のデフォルト // inter_config_read()で再設定される -FString storage_txt = "save/storage.txt"; +AString storage_txt = "save/storage.txt"; static Map storage_db; // 倉庫データを文字列に変換 static -FString storage_tostr(struct storage *p) +AString storage_tostr(struct storage *p) { MString str; str += STRPRINTF( @@ -59,8 +59,8 @@ FString storage_tostr(struct storage *p) str += '\t'; if (!f) - return FString(); - return FString(str); + return AString(); + return AString(str); } // 文字列を倉庫データに変換 @@ -111,7 +111,7 @@ void inter_storage_init(void) return; } - FString line; + AString line; while (in.getline(line)) { struct storage s {}; @@ -131,7 +131,7 @@ void inter_storage_init(void) static void inter_storage_save_sub(struct storage *data, io::WriteFile& fp) { - FString line = storage_tostr(data); + AString line = storage_tostr(data); if (line) fp.put_line(line); } diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 0790b6e..7081f30 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -12,6 +12,6 @@ struct storage *account2storage(int account_id); int inter_storage_parse_frommap(Session *ms); -extern FString storage_txt; +extern AString storage_txt; #endif // INT_STORAGE_HPP diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 19ba254..192ffd5 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -7,7 +7,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -29,7 +29,7 @@ #include "../poison.hpp" static -FString accreg_txt = "save/accreg.txt"; +AString accreg_txt = "save/accreg.txt"; struct accreg { @@ -60,13 +60,13 @@ int inter_recv_packet_length[] = // アカウント変数を文字列へ変換 static -FString inter_accreg_tostr(struct accreg *reg) +AString inter_accreg_tostr(struct accreg *reg) { MString str; str += STRPRINTF("%d\t", reg->account_id); for (int j = 0; j < reg->reg_num; j++) str += STRPRINTF("%s,%d ", reg->reg[j].str, reg->reg[j].value); - return FString(str); + return AString(str); } // アカウント変数を文字列から変換 @@ -98,7 +98,7 @@ void inter_accreg_init(void) io::ReadFile in(accreg_txt); if (!in.is_open()) return; - FString line; + AString line; while (in.getline(line)) { struct accreg reg {}; @@ -121,7 +121,7 @@ void inter_accreg_save_sub(struct accreg *reg, io::WriteFile& fp) { if (reg->reg_num > 0) { - FString line = inter_accreg_tostr(reg); + AString line = inter_accreg_tostr(reg); fp.put_line(line); } } @@ -282,7 +282,7 @@ void mapif_parse_GMmessage(Session *s) { size_t msg_len = RFIFOW(s, 2); size_t str_len = msg_len - 4; - FString buf = RFIFO_STRING(s, 4, str_len); + AString buf = RFIFO_STRING(s, 4, str_len); mapif_GMmessage(buf); } @@ -328,7 +328,7 @@ void mapif_parse_WisRequest(Session *sms) { size_t len = RFIFOW(sms, 2) - 52; Session *tms = server_for(mcs); // for to - FString msg = RFIFO_STRING(sms, 52, len); + AString msg = RFIFO_STRING(sms, 52, len); if (tms) { mapif_wis_message(tms, from, to, msg); diff --git a/src/common/dumb_ptr.hpp b/src/common/dumb_ptr.hpp index 1ac237a..bf97f22 100644 --- a/src/common/dumb_ptr.hpp +++ b/src/common/dumb_ptr.hpp @@ -25,7 +25,7 @@ # include -# include "../strings/fstring.hpp" +# include "../strings/astring.hpp" # include "../strings/zstring.hpp" # include "../strings/xstring.hpp" @@ -246,7 +246,7 @@ struct dumb_string return ZString(strings::really_construct_from_a_pointer, c_str(), nullptr); } - FString str() const + AString str() const { return ZString(*this); } diff --git a/src/common/extract.cpp b/src/common/extract.cpp index bac7b38..5c07e24 100644 --- a/src/common/extract.cpp +++ b/src/common/extract.cpp @@ -18,7 +18,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" @@ -30,7 +30,7 @@ bool extract(XString str, XString *rv) return true; } -bool extract(XString str, FString *rv) +bool extract(XString str, AString *rv) { *rv = str; return true; diff --git a/src/common/extract.hpp b/src/common/extract.hpp index e798204..31cf111 100644 --- a/src/common/extract.hpp +++ b/src/common/extract.hpp @@ -84,7 +84,7 @@ bool extract(XString str, T *iv) bool extract(XString str, XString *rv); -bool extract(XString str, FString *rv); +bool extract(XString str, AString *rv); template bool extract(XString str, VString *out) diff --git a/src/common/intern-pool.hpp b/src/common/intern-pool.hpp index 163e5cc..e75a359 100644 --- a/src/common/intern-pool.hpp +++ b/src/common/intern-pool.hpp @@ -6,18 +6,19 @@ # include # include -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" # include "../strings/zstring.hpp" # include "../strings/xstring.hpp" class InternPool { - std::map known; - std::vector names; + std::map known; + std::vector names; public: size_t intern(XString name_) { - FString name = name_; + // TODO just look up the XString, the memory should not move by now + RString name = name_; // hm, I could change this to do aliases auto pair = known.insert({name, known.size()}); if (pair.second) diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index 8b18181..b2f36b6 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -69,7 +69,8 @@ public: iterator end() const { return &*_impl.end(); } const char *c_str() const { return _impl.c_str(); } - operator FString() const { return _impl; } + operator RString() const { return _impl; } + operator AString() const { return _impl; } operator TString() const { return _impl; } operator SString() const { return _impl; } operator ZString() const { return _impl; } diff --git a/src/common/socket.hpp b/src/common/socket.hpp index 6d0ca01..e0847ac 100644 --- a/src/common/socket.hpp +++ b/src/common/socket.hpp @@ -9,7 +9,7 @@ # include -# include "../strings/fstring.hpp" +# include "../strings/astring.hpp" # include "../strings/vstring.hpp" # include "../strings/xstring.hpp" @@ -183,7 +183,7 @@ VString RFIFO_STRING(Session *s, size_t pos) return XString(begin, mid, nullptr); } inline -FString RFIFO_STRING(Session *s, size_t pos, size_t len) +AString RFIFO_STRING(Session *s, size_t pos, size_t len) { const char *const begin = static_cast(RFIFOP(s, pos)); const char *const end = begin + len; @@ -242,7 +242,7 @@ VString RBUF_STRING(const uint8_t *p, size_t pos) return XString(begin, mid, nullptr); } inline -FString RBUF_STRING(const uint8_t *p, size_t pos, size_t len) +AString RBUF_STRING(const uint8_t *p, size_t pos, size_t len) { const char *const begin = static_cast(RBUFP(p, pos)); const char *const end = begin + len; diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 3a26e6d..0dbf145 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -5,7 +5,7 @@ #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" diff --git a/src/io/cxxstdio.hpp b/src/io/cxxstdio.hpp index b4b4c79..753a1fc 100644 --- a/src/io/cxxstdio.hpp +++ b/src/io/cxxstdio.hpp @@ -238,15 +238,15 @@ namespace cxxstdio # define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast*/(file), fmt, ## __VA_ARGS__) # define FSCANF(file, fmt, ...) XSCANF(no_cast(file), fmt, ## __VA_ARGS__) # define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__) -# define SPRINTF(str, fmt, ...) XPRINTF(base_cast(str), fmt, ## __VA_ARGS__) +# define SPRINTF(str, fmt, ...) XPRINTF(base_cast(str), fmt, ## __VA_ARGS__) # define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast&>(str), fmt, ## __VA_ARGS__) # define SCANF(fmt, ...) FSCANF(stdin, fmt, ## __VA_ARGS__) # define SSCANF(str, fmt, ...) XSCANF(/*ZString or compatible*/str, fmt, ## __VA_ARGS__) # define STRPRINTF(fmt, ...) \ - (/*[&]() -> FString*/ \ + (/*[&]() -> AString*/ \ { \ - FString _out_impl; \ + AString _out_impl; \ SPRINTF(_out_impl, fmt, ## __VA_ARGS__); \ /*return*/ _out_impl; \ }/*()*/) diff --git a/src/io/line.cpp b/src/io/line.cpp index 83f439d..fb73f45 100644 --- a/src/io/line.cpp +++ b/src/io/line.cpp @@ -21,7 +21,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/zstring.hpp" @@ -32,7 +32,7 @@ namespace io { - FString Line::message_str(ZString cat, ZString msg) + AString Line::message_str(ZString cat, ZString msg) { MString out; if (column) @@ -43,7 +43,7 @@ namespace io filename, line, cat, msg); out += STRPRINTF("%s\n", text); out += STRPRINTF("%*c\n", column, '^'); - return FString(out); + return AString(out); } void Line::message(ZString cat, ZString msg) @@ -68,8 +68,10 @@ namespace io bool LineReader::read_line(Line& l) { - if (rf.getline(l.text)) + AString text; + if (rf.getline(text)) { + l.text = text; l.filename = filename; l.line = ++line; l.column = 0; // whole line diff --git a/src/io/line.hpp b/src/io/line.hpp index 00f0a11..bdff1bb 100644 --- a/src/io/line.hpp +++ b/src/io/line.hpp @@ -21,7 +21,8 @@ # include "../sanity.hpp" -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" +# include "../strings/astring.hpp" # include "../strings/zstring.hpp" # include "fd.hpp" @@ -30,15 +31,16 @@ namespace io { + // TODO split this out struct Line { - FString text; + RString text; - FString filename; + RString filename; // 1-based uint16_t line, column; - FString message_str(ZString cat, ZString msg); + AString message_str(ZString cat, ZString msg); void message(ZString cat, ZString msg); void note(ZString msg) { message("note", msg); } void warning(ZString msg) { message("warning", msg); } @@ -60,7 +62,7 @@ namespace io class LineReader { protected: - FString filename; + RString filename; uint16_t line, column; ReadFile rf; public: @@ -77,7 +79,7 @@ namespace io class LineCharReader : private LineReader { - FString line_text; + RString line_text; public: explicit LineCharReader(ZString name); diff --git a/src/io/lock.cpp b/src/io/lock.cpp index c7cbda8..96c3649 100644 --- a/src/io/lock.cpp +++ b/src/io/lock.cpp @@ -46,7 +46,7 @@ namespace io int no = getpid(); // Get a filename that doesn't already exist - FString newfile; + AString newfile; do { newfile = STRPRINTF("%s_%d.tmp", filename, no++); @@ -59,7 +59,7 @@ namespace io return fd; } - WriteLock::WriteLock(FString fn, bool linebuffered) + WriteLock::WriteLock(RString fn, bool linebuffered) : WriteFile(get_lock_open(fn, &tmp_suffix), linebuffered), filename(fn) {} WriteLock::~WriteLock() @@ -72,16 +72,16 @@ namespace io } int n = backup_count; - FString old_filename = STRPRINTF("%s.%d", filename, n); + AString old_filename = STRPRINTF("%s.%d", filename, n); while (--n) { - FString newer_filename = STRPRINTF("%s.%d", filename, n); + AString newer_filename = STRPRINTF("%s.%d", filename, n); rename(newer_filename.c_str(), old_filename.c_str()); old_filename = std::move(newer_filename); } rename(filename.c_str(), old_filename.c_str()); - FString tmpfile = STRPRINTF("%s_%d.tmp", filename, tmp_suffix); + AString tmpfile = STRPRINTF("%s_%d.tmp", filename, tmp_suffix); rename(tmpfile.c_str(), filename.c_str()); } } // namespace io diff --git a/src/io/lock.hpp b/src/io/lock.hpp index a19acdb..b5052cf 100644 --- a/src/io/lock.hpp +++ b/src/io/lock.hpp @@ -21,17 +21,17 @@ # include "write.hpp" -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" namespace io { class WriteLock : public WriteFile { - FString filename; + RString filename; int tmp_suffix; public: - WriteLock(FString filename, bool linebuffered=false); + WriteLock(RString filename, bool linebuffered=false); ~WriteLock(); bool close() = delete; }; diff --git a/src/io/read.cpp b/src/io/read.cpp index fe2c765..2ef35cc 100644 --- a/src/io/read.cpp +++ b/src/io/read.cpp @@ -21,7 +21,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/zstring.hpp" @@ -74,7 +74,7 @@ namespace io } return len; } - bool ReadFile::getline(FString& line) + bool ReadFile::getline(AString& line) { MString tmp; char c; @@ -111,7 +111,7 @@ namespace io } else if (!happy && anything) PRINTF("warning: file does not contain a trailing newline\n"); - line = FString(tmp); + line = AString(tmp); return anything; } diff --git a/src/io/read.hpp b/src/io/read.hpp index 4830fa4..2355e46 100644 --- a/src/io/read.hpp +++ b/src/io/read.hpp @@ -44,7 +44,7 @@ namespace io bool get(char&); size_t get(char *buf, size_t len); - bool getline(FString&); + bool getline(AString&); bool is_open(); }; diff --git a/src/io/read_test.cpp b/src/io/read_test.cpp index ebb20ca..5d287dd 100644 --- a/src/io/read_test.cpp +++ b/src/io/read_test.cpp @@ -23,7 +23,7 @@ io::FD string_pipe(ZString sz) TEST(io, read1) { io::ReadFile rf(string_pipe("Hello")); - FString hi; + AString hi; EXPECT_TRUE(rf.getline(hi)); EXPECT_EQ(hi, "Hello"); EXPECT_FALSE(rf.getline(hi)); @@ -31,7 +31,7 @@ TEST(io, read1) TEST(io, read2) { io::ReadFile rf(string_pipe("Hello\n")); - FString hi; + AString hi; EXPECT_TRUE(rf.getline(hi)); EXPECT_EQ(hi, "Hello"); EXPECT_FALSE(rf.getline(hi)); @@ -39,7 +39,7 @@ TEST(io, read2) TEST(io, read3) { io::ReadFile rf(string_pipe("Hello\r")); - FString hi; + AString hi; EXPECT_TRUE(rf.getline(hi)); EXPECT_EQ(hi, "Hello"); EXPECT_FALSE(rf.getline(hi)); @@ -47,7 +47,7 @@ TEST(io, read3) TEST(io, read4) { io::ReadFile rf(string_pipe("Hello\r\n")); - FString hi; + AString hi; EXPECT_TRUE(rf.getline(hi)); EXPECT_EQ(hi, "Hello"); EXPECT_FALSE(rf.getline(hi)); @@ -55,7 +55,7 @@ TEST(io, read4) TEST(io, read5) { io::ReadFile rf(string_pipe("Hello\n\r")); - FString hi; + AString hi; EXPECT_TRUE(rf.getline(hi)); EXPECT_EQ(hi, "Hello"); EXPECT_TRUE(rf.getline(hi)); diff --git a/src/io/write_test.cpp b/src/io/write_test.cpp index a9736b8..f703850 100644 --- a/src/io/write_test.cpp +++ b/src/io/write_test.cpp @@ -5,7 +5,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/xstring.hpp" @@ -35,7 +35,7 @@ public: { rfd.close(); } - FString slurp() + AString slurp() { MString tmp; char buf[4096]; @@ -52,7 +52,7 @@ public: break; tmp += XString(buf + 0, buf + rv, nullptr); } - return FString(tmp); + return AString(tmp); } }; @@ -73,10 +73,10 @@ TEST(io, write2) PipeWriter pw(true); io::WriteFile& wf = pw.wf; wf.really_put("Hello, ", 7); - EXPECT_EQ("", std::string(pw.slurp().c_str())); + EXPECT_EQ("", pw.slurp()); wf.put_line("World!"); wf.really_put("XXX", 3); - EXPECT_EQ("Hello, World!\n", std::string(pw.slurp().c_str())); + EXPECT_EQ("Hello, World!\n", pw.slurp()); EXPECT_TRUE(wf.close()); - EXPECT_EQ("XXX", std::string(pw.slurp().c_str())); + EXPECT_EQ("XXX", pw.slurp()); } diff --git a/src/login/login.cpp b/src/login/login.cpp index b1d37dc..ea58669 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -15,7 +15,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" @@ -80,7 +80,7 @@ IP4Address lan_char_ip = IP4_LOCALHOST; static IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); static -FString update_host; +AString update_host; static AccountName userid; static @@ -89,13 +89,13 @@ static ServerName main_server; static -FString account_filename = "save/account.txt"; +AString account_filename = "save/account.txt"; static -FString gm_account_filename = "save/gm_account.txt"; +AString gm_account_filename = "save/gm_account.txt"; static -FString login_log_filename = "log/login.log"; +AString login_log_filename = "log/login.log"; static -FString login_log_unknown_packets_filename = "log/login_unknown_packets.log"; +AString login_log_unknown_packets_filename = "log/login_unknown_packets.log"; static int save_unknown_packets = 0; static @@ -191,7 +191,7 @@ int admin_state = 0; static AccountPass admin_pass; static -FString gm_pass; +AString gm_pass; static int level_new_gm = 60; @@ -268,7 +268,7 @@ int read_gm_account(void) } // limited to 4000, because we send information to char-servers (more than 4000 GM accounts???) // int (id) + int (level) = 8 bytes * 4000 = 32k (limit of packets in windows) - FString line; + AString line; while (fp.getline(line) && c < 4000) { if (is_comment(line)) @@ -413,7 +413,7 @@ AuthData *search_account(AccountName account_name) // Create a string to save the account in the account file //-------------------------------------------------------- static -FString mmo_auth_tostr(const AuthData *p) +AString mmo_auth_tostr(const AuthData *p) { MString str; str += STRPRINTF( @@ -449,7 +449,7 @@ FString mmo_auth_tostr(const AuthData *p) str += STRPRINTF("%s,%d ", p->account_reg2[i].str, p->account_reg2[i].value); - return FString(str); + return AString(str); } static @@ -543,7 +543,7 @@ int mmo_auth_init(void) return 0; } - FString line; + AString line; while (in.getline(line)) { if (is_comment(line)) @@ -574,7 +574,7 @@ int mmo_auth_init(void) account_id_count = ad.account_id + 1; } - FString str = STRPRINTF("%s has %zu accounts (%d GMs)\n", + AString str = STRPRINTF("%s has %zu accounts (%d GMs)\n", account_filename, auth_data.size(), gm_count); PRINTF("%s: %s\n", __PRETTY_FUNCTION__, str); LOGIN_LOG("%s\n", line); @@ -621,7 +621,7 @@ void mmo_auth_sync(void) if (ad.account_id < 0) continue; - FString line = mmo_auth_tostr(&ad); + AString line = mmo_auth_tostr(&ad); fp.put_line(line); } FPRINTF(fp, "%d\t%%newid%%\n", account_id_count); @@ -1112,7 +1112,7 @@ void parse_fromchar(Session *s) WBUFL(buf, 2) = acc; WBUFL(buf, 6) = 0; size_t len = RFIFOW(s, 2) - 8; - FString pass = RFIFO_STRING(s, 8, len); + AString pass = RFIFO_STRING(s, 8, len); if (pass == gm_pass) { @@ -1740,7 +1740,7 @@ void parse_admin(Session *s) ad->userid, ad->account_id, ip); { - FString buf2 = mmo_auth_tostr(ad); + AString buf2 = mmo_auth_tostr(ad); LOGIN_LOG("%s\n", buf2); } // delete account @@ -2000,7 +2000,7 @@ void parse_admin(Session *s) stamp_time(tmpstr); modify_flag = 0; // read/write GM file - FString line; + AString line; while (fp.getline(line)) { if (is_comment(line)) @@ -2426,7 +2426,7 @@ void parse_admin(Session *s) WFIFOW(s, 2) = 0; size_t len = RFIFOL(s, 4); - FString message = RFIFO_STRING(s, 8, len).to_print(); + AString message = RFIFO_STRING(s, 8, len).to_print(); LOGIN_LOG("'ladmin': Receiving a message for broadcast (message: %s, ip: %s)\n", message, ip); // send same message to all char-servers (no answer) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index f5deab8..dca9b4e 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -5,7 +5,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" @@ -182,7 +182,7 @@ void log_atcommand(dumb_ptr sd, ZString cmd) cmd); } -FString gm_log; +AString gm_log; io::AppendFile *get_gm_log() { @@ -201,7 +201,7 @@ io::AppendFile *get_gm_log() return gm_logfile.get(); last_logfile_nr = logfile_nr; - FString fullname = STRPRINTF("%s.%04d-%02d", + AString fullname = STRPRINTF("%s.%04d-%02d", gm_log, year, month); if (gm_logfile) @@ -212,7 +212,7 @@ io::AppendFile *get_gm_log() if (!gm_logfile) { perror("GM log file"); - gm_log = FString(); + gm_log = AString(); } return gm_logfile.get(); } @@ -235,24 +235,24 @@ bool is_atcommand(Session *s, dumb_ptr sd, gmlvl = pc_isGM(sd); if (battle_config.atcommand_gm_only != 0 && !gmlvl) { - FString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s", - FString(command)); + AString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s", + AString(command)); clif_displaymessage(s, output); return true; } if (!info) { - FString output = STRPRINTF("GM command not found: %s", - FString(command)); + AString output = STRPRINTF("GM command not found: %s", + AString(command)); clif_displaymessage(s, output); return true; // don't show in chat } if (info->level > gmlvl) { - FString output = STRPRINTF("GM command is level %d, but you are level %d: %s", + AString output = STRPRINTF("GM command is level %d, but you are level %d: %s", info->level, gmlvl, - FString(command)); + AString(command)); clif_displaymessage(s, output); return true; } @@ -269,7 +269,7 @@ bool is_atcommand(Session *s, dumb_ptr sd, break; case ATCE::USAGE: clif_displaymessage(s, "Command failed: usage error"); - clif_displaymessage(s, STRPRINTF("Usage: %s %s", FString(command), info->args)); + clif_displaymessage(s, STRPRINTF("Usage: %s %s", AString(command), info->args)); break; case ATCE::EXIST: clif_displaymessage(s, "Command failed: something does not exist (or already exists)"); @@ -328,7 +328,7 @@ bool atcommand_config_read(ZString cfgName) } bool rv = true; - FString line; + AString line; while (in.getline(line)) { if (is_comment(line)) @@ -442,7 +442,7 @@ ATCE atcommand_setup(Session *s, dumb_ptr sd, return ATCE::USAGE; level--; - FString buf; + AString buf; buf = STRPRINTF("-255 %s", character); atcommand_character_baselevel(s, sd, buf); @@ -606,7 +606,7 @@ ATCE atcommand_where(Session *s, dumb_ptr sd, && (pc_isGM(pl_sd) > pc_isGM(sd)))) { // you can look only lower or same level - FString output = STRPRINTF("%s: %s (%d,%d)", + AString output = STRPRINTF("%s: %s (%d,%d)", pl_sd->status.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); @@ -651,7 +651,7 @@ ATCE atcommand_goto(Session *s, dumb_ptr sd, return ATCE::PERM; } pc_setpos(sd, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - FString output = STRPRINTF("Jump to %s", character); + AString output = STRPRINTF("Jump to %s", character); clif_displaymessage(s, output); } else @@ -692,7 +692,7 @@ ATCE atcommand_jump(Session *s, dumb_ptr sd, return ATCE::PERM; } pc_setpos(sd, sd->mapname_, x, y, BeingRemoveWhy::WARPED); - FString output = STRPRINTF("Jump to %d %d", x, y); + AString output = STRPRINTF("Jump to %d %d", x, y); clif_displaymessage(s, output); } else @@ -734,7 +734,7 @@ ATCE atcommand_who(Session *s, dumb_ptr sd, if (player_name.contains_seq(match_text)) { // search with no case sensitive - FString output; + AString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", @@ -758,7 +758,7 @@ ATCE atcommand_who(Session *s, dumb_ptr sd, clif_displaymessage(s, "1 player found."); else { - FString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found.", count); clif_displaymessage(s, output); } @@ -799,7 +799,7 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr sd, // search with no case sensitive p = party_search(pl_sd->status.party_id); PartyName temp0 = p ? p->name : stringish("None"); - FString output; + AString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Party: '%s'", @@ -817,7 +817,7 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr sd, clif_displaymessage(s, "1 player found."); else { - FString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found.", count); clif_displaymessage(s, output); } @@ -859,7 +859,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr sd, // you can look only lower or same level if (pl_sd->bl_m == map_id) { - FString output; + AString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", @@ -877,7 +877,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr sd, } } - FString output = STRPRINTF("%d players found in map '%s'.", + AString output = STRPRINTF("%d players found in map '%s'.", count, map_id->name_); clif_displaymessage(s, output); @@ -922,7 +922,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr sd, { p = party_search(pl_sd->status.party_id); PartyName temp0 = p ? p->name : stringish("None"); - FString output; + AString output; if (pl_GM_level > 0) output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'", pl_sd->status.name, pl_GM_level, temp0); @@ -936,7 +936,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr sd, } } - FString output; + AString output; if (count == 0) output = STRPRINTF("No player found in map '%s'.", map_id->name_); else if (count == 1) @@ -984,7 +984,7 @@ ATCE atcommand_whogm(Session *s, dumb_ptr sd, if (player_name.contains_seq(match_text)) { // search with no case sensitive - FString output; + AString output; output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, @@ -1015,7 +1015,7 @@ ATCE atcommand_whogm(Session *s, dumb_ptr sd, clif_displaymessage(s, "1 GM found."); else { - FString output = STRPRINTF("%d GMs found.", count); + AString output = STRPRINTF("%d GMs found.", count); clif_displaymessage(s, output); } @@ -1067,7 +1067,7 @@ ATCE atcommand_speed(Session *s, dumb_ptr sd, { if (!message) { - FString output = STRPRINTF( + AString output = STRPRINTF( "Please, enter a speed value (usage: @speed <%d-%d>).", static_cast(MIN_WALK_SPEED.count()), static_cast(MAX_WALK_SPEED.count())); @@ -1086,7 +1086,7 @@ ATCE atcommand_speed(Session *s, dumb_ptr sd, } else { - FString output = STRPRINTF( + AString output = STRPRINTF( "Please, enter a valid speed value (usage: @speed <%d-%d>).", static_cast(MIN_WALK_SPEED.count()), static_cast(MAX_WALK_SPEED.count())); @@ -1746,7 +1746,7 @@ ATCE atcommand_spawn(Session *s, dumb_ptr sd, clif_displaymessage(s, "All monster summoned!"); else { - FString output = STRPRINTF("%d monster(s) summoned!", + AString output = STRPRINTF("%d monster(s) summoned!", count); clif_displaymessage(s, output); } @@ -1795,7 +1795,7 @@ void atlist_nearby_sub(dumb_ptr bl, Session *s) { nullpo_retv(bl); - FString buf = STRPRINTF(" - \"%s\"", + AString buf = STRPRINTF(" - \"%s\"", bl->is_player()->status.name); clif_displaymessage(s, buf); } @@ -1831,7 +1831,7 @@ ATCE atcommand_gat(Session *s, dumb_ptr sd, for (y = 2; y >= -2; y--) { - FString output = STRPRINTF( + AString output = STRPRINTF( "%s (x= %d, y= %d) %02X %02X %02X %02X %02X", sd->bl_m->name_, sd->bl_x - 2, sd->bl_y + y, map_getcell(sd->bl_m, sd->bl_x - 2, sd->bl_y + y), @@ -2049,7 +2049,7 @@ ATCE atcommand_recall(Session *s, dumb_ptr sd, return ATCE::PERM; } pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); - FString output = STRPRINTF("%s recalled!", character); + AString output = STRPRINTF("%s recalled!", character); clif_displaymessage(s, output); } else @@ -2109,7 +2109,7 @@ ATCE atcommand_character_stats(Session *s, dumb_ptr, dumb_ptr pl_sd = map_nick2sd(character); if (pl_sd != NULL) { - FString output; + AString output; output = STRPRINTF("'%s' stats:", pl_sd->status.name); clif_displaymessage(s, output); output = STRPRINTF("Base Level - %d", pl_sd->status.base_level), @@ -2163,13 +2163,13 @@ ATCE atcommand_character_stats_all(Session *s, dumb_ptr, dumb_ptr pl_sd = dumb_ptr(static_cast(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - FString gmlevel; + AString gmlevel; if (pc_isGM(pl_sd) > 0) gmlevel = STRPRINTF("| GM Lvl: %d", pc_isGM(pl_sd)); else gmlevel = " "; - FString output; + AString output; output = STRPRINTF( "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, @@ -2198,7 +2198,7 @@ ATCE atcommand_character_stats_all(Session *s, dumb_ptr, clif_displaymessage(s, "1 player found."); else { - FString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found.", count); clif_displaymessage(s, output); } @@ -2935,7 +2935,7 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr, if (!extract(message, &item_name) || !item_name) return ATCE::USAGE; - FString output = STRPRINTF("The reference result of '%s' (name: id):", item_name); + AString output = STRPRINTF("The reference result of '%s' (name: id):", item_name); clif_displaymessage(s, output); match = 0; for (i = 0; i < 20000; i++) @@ -2970,7 +2970,7 @@ ATCE atcommand_charskreset(Session *s, dumb_ptr sd, { // you can reset skill points only lower or same gm level pc_resetskill(pl_sd); - FString output = STRPRINTF( + AString output = STRPRINTF( "'%s' skill points reseted!", character); clif_displaymessage(s, output); } @@ -3005,7 +3005,7 @@ ATCE atcommand_charstreset(Session *s, dumb_ptr sd, { // you can reset stats points only lower or same gm level pc_resetstate(pl_sd); - FString output = STRPRINTF( + AString output = STRPRINTF( "'%s' stats points reseted!", character); clif_displaymessage(s, output); @@ -3046,7 +3046,7 @@ ATCE atcommand_charreset(Session *s, dumb_ptr sd, // [Fate] Reset magic quest variables pc_setglobalreg(pl_sd, stringish("MAGIC_EXP"), 0); // [Fate] Reset magic experience - FString output = STRPRINTF( + AString output = STRPRINTF( "'%s' skill and stats points reseted!", character); clif_displaymessage(s, output); } @@ -3131,7 +3131,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr sd, pc_setglobalreg(pl_sd, stringish("MAGIC_EXP"), 0); // [Fate] Reset magic experience - FString output = STRPRINTF("%s: wiped.", character); + AString output = STRPRINTF("%s: wiped.", character); clif_displaymessage(s, output); } else @@ -3341,7 +3341,7 @@ ATCE atcommand_recallall(Session *s, dumb_ptr sd, clif_displaymessage(s, "All characters recalled!"); if (count) { - FString output = STRPRINTF( + AString output = STRPRINTF( "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count); clif_displaymessage(s, output); @@ -3391,7 +3391,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr sd, pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); } } - FString output = STRPRINTF("All online characters of the %s party are near you.", p->name); + AString output = STRPRINTF("All online characters of the %s party are near you.", p->name); clif_displaymessage(s, output); if (count) { @@ -3432,7 +3432,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr sd, return ATCE::EXIST; clif_displaymessage(s, "------ Map Info ------"); - FString output = STRPRINTF("Map Name: %s", map_name); + AString output = STRPRINTF("Map Name: %s", map_name); clif_displaymessage(s, output); output = STRPRINTF("Players In Map: %d", m_id->users); clif_displaymessage(s, output); @@ -3565,13 +3565,13 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr sd, if (sd->partyspy == p->party_id) { sd->partyspy = 0; - FString output = STRPRINTF("No longer spying on the %s party.", p->name); + AString output = STRPRINTF("No longer spying on the %s party.", p->name); clif_displaymessage(s, output); } else { sd->partyspy = p->party_id; - FString output = STRPRINTF("Spying on the %s party.", p->name); + AString output = STRPRINTF("Spying on the %s party.", p->name); clif_displaymessage(s, output); } } @@ -3636,7 +3636,7 @@ ATCE atcommand_servertime(Session *s, dumb_ptr, { timestamp_seconds_buffer tsbuf; stamp_time(tsbuf); - FString temp = STRPRINTF("Server time: %s", tsbuf); + AString temp = STRPRINTF("Server time: %s", tsbuf); clif_displaymessage(s, temp); return ATCE::OKAY; @@ -3678,7 +3678,7 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr sd, item_position = pc_search_inventory(pl_sd, item_id); // for next loop } - FString output = STRPRINTF( + AString output = STRPRINTF( "%d item(s) removed by a GM.", count); clif_displaymessage(pl_sd->sess, output); @@ -3723,7 +3723,7 @@ ATCE atcommand_broadcast(Session *, dumb_ptr sd, if (!message) return ATCE::USAGE; - FString output = STRPRINTF("%s : %s", sd->status.name, message); + AString output = STRPRINTF("%s : %s", sd->status.name, message); intif_GMmessage(output); return ATCE::OKAY; @@ -3736,7 +3736,7 @@ ATCE atcommand_localbroadcast(Session *, dumb_ptr sd, if (!message) return ATCE::USAGE; - FString output = STRPRINTF("%s : %s", sd->status.name, message); + AString output = STRPRINTF("%s : %s", sd->status.name, message); clif_GMmessage(sd, output, 1); @@ -3844,7 +3844,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr sd, count++; if (count == 1) { - FString output = STRPRINTF( + AString output = STRPRINTF( "------ Items list of '%s' ------", pl_sd->status.name); clif_displaymessage(s, output); @@ -3888,7 +3888,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr sd, else equipstr = MString(); - FString output; + AString output; if (sd->status.inventory[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d) %s", pl_sd->status.inventory[i].amount, @@ -3897,13 +3897,13 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr sd, item_data->jname, pl_sd->status.inventory[i].refine, pl_sd->status.inventory[i].nameid, - FString(equipstr)); + AString(equipstr)); else output = STRPRINTF("%d %s (%s, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, item_data->jname, pl_sd->status.inventory[i].nameid, - FString(equipstr)); + AString(equipstr)); clif_displaymessage(s, output); MString voutput; @@ -3938,7 +3938,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr sd, // replace trailing ", " voutput.pop_back(); voutput.back() = ')'; - clif_displaymessage(s, FString(voutput)); + clif_displaymessage(s, AString(voutput)); } } } @@ -3946,7 +3946,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr sd, clif_displaymessage(s, "No item found on this player."); else { - FString output = STRPRINTF( + AString output = STRPRINTF( "%d item(s) found in %d kind(s) of items.", counter, count); clif_displaymessage(s, output); @@ -3999,12 +3999,12 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr sd, count++; if (count == 1) { - FString output = STRPRINTF( + AString output = STRPRINTF( "------ Storage items list of '%s' ------", pl_sd->status.name); clif_displaymessage(s, output); } - FString output; + AString output; if (stor->storage_[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d)", stor->storage_[i].amount, @@ -4052,7 +4052,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr sd, // replace last ", " voutput.pop_back(); voutput.back() = ')'; - clif_displaymessage(s, FString(voutput)); + clif_displaymessage(s, AString(voutput)); } } } @@ -4061,7 +4061,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr sd, "No item found in the storage of this player."); else { - FString output = STRPRINTF( + AString output = STRPRINTF( "%d item(s) found in %d kind(s) of items.", counter, count); clif_displaymessage(s, output); @@ -4117,13 +4117,13 @@ ATCE atcommand_character_cart_list(Session *s, dumb_ptr sd, count++; if (count == 1) { - FString output = STRPRINTF( + AString output = STRPRINTF( "------ Cart items list of '%s' ------", pl_sd->status.name); clif_displaymessage(s, output); } - FString output; + AString output; if (pl_sd->status.cart[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d)", pl_sd->status.cart[i].amount, @@ -4170,7 +4170,7 @@ ATCE atcommand_character_cart_list(Session *s, dumb_ptr sd, { voutput.pop_back(); voutput.back() = '0'; - clif_displaymessage(s, FString(voutput)); + clif_displaymessage(s, AString(voutput)); } } } @@ -4179,7 +4179,7 @@ ATCE atcommand_character_cart_list(Session *s, dumb_ptr sd, "No item found in the cart of this player."); else { - FString output = STRPRINTF("%d item(s) found in %d kind(s) of items.", + AString output = STRPRINTF("%d item(s) found in %d kind(s) of items.", counter, count); clif_displaymessage(s, output); } @@ -4312,9 +4312,9 @@ ATCE atcommand_addwarp(Session *s, dumb_ptr sd, if (!extract(message, record<' '>(&mapname, &x, &y))) return ATCE::USAGE; - FString w1 = STRPRINTF("%s,%d,%d", sd->mapname_, sd->bl_x, sd->bl_y); - FString w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y); - FString w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y); + AString w1 = STRPRINTF("%s,%d,%d", sd->mapname_, sd->bl_x, sd->bl_y); + AString w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y); + AString w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y); NpcName w3name = stringish(w3); int ret = npc_parse_warp(w1, ZString("warp"), w3name, w4); @@ -4322,7 +4322,7 @@ ATCE atcommand_addwarp(Session *s, dumb_ptr sd, // warp failed return ATCE::RANGE; - FString output = STRPRINTF("New warp NPC => %s", w3); + AString output = STRPRINTF("New warp NPC => %s", w3); clif_displaymessage(s, output); return ATCE::OKAY; @@ -4689,7 +4689,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr, dumb_ptr pl_sd = map_nick2sd(character); if (pl_sd) { - FString buf = STRPRINTF( + AString buf = STRPRINTF( "`%s' has the following magic skills:", character); clif_displaymessage(s, buf); @@ -4788,7 +4788,7 @@ ATCE atcommand_tee(Session *, dumb_ptr sd, data += sd->status.name.to__actual(); data += " : "; data += message; - clif_message(sd, FString(data)); + clif_message(sd, AString(data)); return ATCE::OKAY; } @@ -4845,7 +4845,7 @@ ATCE atcommand_jump_iterate(Session *s, dumb_ptr sd, return ATCE::PERM; } pc_setpos(sd, pl_sd->bl_m->name_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - FString output = STRPRINTF("Jump to %s", pl_sd->status.name); + AString output = STRPRINTF("Jump to %s", pl_sd->status.name); clif_displaymessage(s, output); sd->followtarget = pl_sd->bl_id; @@ -4896,7 +4896,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr, int pool_skills_nr = skill_pool(pl_sd, pool_skills); int i; - FString buf = STRPRINTF( + AString buf = STRPRINTF( "Active skills %d out of %d for %s:", pool_skills_nr, skill_pool_max(pl_sd), character); clif_displaymessage(s, buf); @@ -4915,7 +4915,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr, for (i = 0; i < skill_pool_skills_size; ++i) { - const FString& name = skill_name(skill_pool_skills[i]); + const RString& name = skill_name(skill_pool_skills[i]); int lvl = pl_sd->status.skill[skill_pool_skills[i]].lv; if (lvl) @@ -5042,7 +5042,7 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr, // Is checking GM levels really needed here? if (ip == pl_sd->get_ip()) { - FString output = STRPRINTF( + AString output = STRPRINTF( "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp index a18b035..c825976 100644 --- a/src/map/atcommand.hpp +++ b/src/map/atcommand.hpp @@ -15,7 +15,7 @@ bool atcommand_config_read(ZString cfgName); void log_atcommand(dumb_ptr sd, ZString cmd); // only used by map.cpp -extern FString gm_log; +extern AString gm_log; void atcommand_config_write(ZString cfgName); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 35cef79..d1e79ef 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -2,7 +2,7 @@ #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../io/cxxstdio.hpp" @@ -2420,7 +2420,7 @@ bool battle_config_read(ZString cfgName) return false; } - FString line; + AString line; while (in.getline(line)) { #define BATTLE_CONFIG_VAR(name) {{#name}, &battle_config.name} @@ -2555,7 +2555,7 @@ bool battle_config_read(ZString cfgName) goto continue_outer; } - PRINTF("WARNING: unknown battle conf key: %s\n", FString(w1)); + PRINTF("WARNING: unknown battle conf key: %s\n", AString(w1)); rv = false; continue_outer: diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index ab67b5c..c49a101 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -4,7 +4,7 @@ #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../io/cxxstdio.hpp" @@ -462,7 +462,7 @@ int chrif_char_ask_name_answer(Session *s) dumb_ptr sd = map_id2sd(acc); if (acc >= 0 && sd != NULL) { - FString output; + AString output; if (RFIFOW(s, 32) == 1) // player not found output = STRPRINTF("The player '%s' doesn't exist.", player_name); diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 61c47d9..3fc716d 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -6,7 +6,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -217,7 +217,7 @@ enum class ChatType }; static -FString clif_validate_chat(dumb_ptr sd, ChatType type); +AString clif_validate_chat(dumb_ptr sd, ChatType type); /*========================================== * clif_sendでSendWho::AREA*指定時用 @@ -3761,7 +3761,7 @@ void clif_parse_GlobalMessage(Session *s, dumb_ptr sd) { nullpo_retv(sd); - FString mbuf = clif_validate_chat(sd, ChatType::Global); + AString mbuf = clif_validate_chat(sd, ChatType::Global); if (!mbuf) { clif_displaymessage(s, "Your message could not be sent."); @@ -4017,7 +4017,7 @@ void clif_parse_Wis(Session *s, dumb_ptr sd) nullpo_retv(sd); - FString mbuf = clif_validate_chat(sd, ChatType::Whisper); + AString mbuf = clif_validate_chat(sd, ChatType::Whisper); if (!mbuf) { clif_displaymessage(s, "Your message could not be sent."); @@ -4628,7 +4628,7 @@ void clif_parse_PartyMessage(Session *s, dumb_ptr sd) { nullpo_retv(sd); - FString mbuf = clif_validate_chat(sd, ChatType::Party); + AString mbuf = clif_validate_chat(sd, ChatType::Party); if (!mbuf) { clif_displaymessage(s, "Your message could not be sent."); @@ -5294,15 +5294,15 @@ void WARN_MALFORMED_MSG(dumb_ptr sd, const char *msg) * @return a dynamically allocated copy of the message, or empty string upon failure */ static -FString clif_validate_chat(dumb_ptr sd, ChatType type) +AString clif_validate_chat(dumb_ptr sd, ChatType type) { - nullpo_retr(FString(), sd); + nullpo_retr(AString(), sd); /* * Don't send chat in the period between the ban and the connection's * closure. */ if (sd->auto_ban_info.in_progress) - return FString(); + return AString(); Session *s = sd->sess; size_t msg_len = RFIFOW(s, 2) - 4; @@ -5326,14 +5326,14 @@ FString clif_validate_chat(dumb_ptr sd, ChatType type) if (!msg_len) { WARN_MALFORMED_MSG(sd, "no message sent"); - return FString(); + return AString(); } /* The client sent (or claims to have sent) an empty message. */ if (msg_len == min_len) { WARN_MALFORMED_MSG(sd, "empty message"); - return FString(); + return AString(); } /* The protocol specifies that the target must be 24 bytes long. */ @@ -5342,7 +5342,7 @@ FString clif_validate_chat(dumb_ptr sd, ChatType type) /* Disallow malformed messages. */ clif_setwaitclose(s); WARN_MALFORMED_MSG(sd, "illegal target name"); - return FString(); + return AString(); } size_t pstart = 4; @@ -5352,7 +5352,7 @@ FString clif_validate_chat(dumb_ptr sd, ChatType type) pstart += 24; buf_len -= 24; } - FString pbuf = RFIFO_STRING(s, pstart, buf_len); + AString pbuf = RFIFO_STRING(s, pstart, buf_len); /* * The client attempted to exceed the maximum message length. @@ -5364,7 +5364,7 @@ FString clif_validate_chat(dumb_ptr sd, ChatType type) if (buf_len >= battle_config.chat_maxline) { WARN_MALFORMED_MSG(sd, "exceeded maximum message length"); - return FString(); + return AString(); } if (type == ChatType::Global) @@ -5375,7 +5375,7 @@ FString clif_validate_chat(dumb_ptr sd, ChatType type) /* Disallow malformed/spoofed messages. */ clif_setwaitclose(s); WARN_MALFORMED_MSG(sd, "spoofed name/invalid format"); - return FString(); + return AString(); } /* Step beyond the separator. */ XString xs = p.xslice_t(name_len + 3); diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp index ff73c90..d89fe21 100644 --- a/src/map/grfio.cpp +++ b/src/map/grfio.cpp @@ -13,7 +13,8 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/astring.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" @@ -23,7 +24,7 @@ #include "../poison.hpp" static -std::map resnametable; +std::map resnametable; bool load_resnametable(ZString filename) { @@ -35,11 +36,11 @@ bool load_resnametable(ZString filename) } bool rv = true; - FString line; + AString line; while (in.getline(line)) { MapName key; - FString value; + AString value; if (!extract(line, record<'#'>(&key, &value))) { @@ -47,6 +48,7 @@ bool load_resnametable(ZString filename) rv = false; continue; } + // TODO add "data/" here ... resnametable[key] = value; } return rv; @@ -54,18 +56,21 @@ bool load_resnametable(ZString filename) /// Change *.gat to *.wlk static -FString grfio_resnametable(MapName rname) +RString grfio_resnametable(MapName rname) { + // TODO return an error instead of throwing an exception return resnametable.at(rname); } std::vector grfio_reads(MapName rname) { MString lfname_; + // TODO ... instead of here lfname_ += "data/"; lfname_ += grfio_resnametable(rname); - FString lfname = FString(lfname_); + AString lfname = AString(lfname_); + // TODO wrap this immediately int fd = open(lfname.c_str(), O_RDONLY); if (fd == -1) { diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 7d699dd..e994bdb 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -3,7 +3,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -254,7 +254,7 @@ int intif_parse_WisMessage(Session *s) CharName to = stringish(RFIFO_STRING<24>(s, 32)); size_t len = RFIFOW(s, 2) - 56; - FString buf = RFIFO_STRING(s, 56, len); + AString buf = RFIFO_STRING(s, 56, len); if (battle_config.etc_log) { @@ -313,7 +313,7 @@ void mapif_parse_WisToGM(Session *s) min_gm_level = RFIFOW(s, 28); CharName Wisp_name = stringish(RFIFO_STRING<24>(s, 4)); - FString message = RFIFO_STRING(s, 30, len); + AString message = RFIFO_STRING(s, 30, len); // information is sended to all online GM for (io::FD i : iter_fds()) { @@ -503,7 +503,7 @@ static void intif_parse_PartyMessage(Session *s) { size_t len = RFIFOW(s, 2) - 12; - FString buf = RFIFO_STRING(s, 12, len); + AString buf = RFIFO_STRING(s, 12, len); party_recv_message(RFIFOL(s, 4), RFIFOL(s, 8), buf); } @@ -542,7 +542,7 @@ int intif_parse(Session *s) { case 0x3800: { - FString mes = RFIFO_STRING(s, 4, packet_len - 4); + AString mes = RFIFO_STRING(s, 4, packet_len - 4); clif_GMmessage(NULL, mes, 0); } break; diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index bcef583..ba225bd 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -3,7 +3,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -161,7 +161,7 @@ bool itemdb_readdb(ZString filename) lines = 0; - FString line; + AString line; while (in.getline(line)) { lines++; diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 655da1b..7343e50 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -6,7 +6,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/vstring.hpp" @@ -93,7 +93,7 @@ void magic_clear_var(val_t *v) } static -FString show_entity(dumb_ptr entity) +AString show_entity(dumb_ptr entity) { switch (entity->bl_type) { @@ -126,7 +126,7 @@ void stringify(val_t *v, int within_op) {"north"}, {"north-east"}, {"east"}, {"south-east"}, }}; - FString buf; + AString buf; switch (v->ty) { @@ -287,7 +287,7 @@ int fun_add(dumb_ptr, val_t *result, const_array args) MString m; m += ARGSTR(0); m += ARGSTR(1); - RESULTSTR = dumb_string::copys(FString(m)); + RESULTSTR = dumb_string::copys(AString(m)); result->ty = TYPE::STRING; } return 0; @@ -1677,7 +1677,7 @@ int magic_eval_int(dumb_ptr env, dumb_ptr expr) return result.v.v_int; } -FString magic_eval_str(dumb_ptr env, dumb_ptr expr) +AString magic_eval_str(dumb_ptr env, dumb_ptr expr) { val_t result; magic_eval(env, &result, expr); diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp index 7601bef..0fdc435 100644 --- a/src/map/magic-expr.hpp +++ b/src/map/magic-expr.hpp @@ -61,7 +61,7 @@ int magic_eval_int(dumb_ptr env, dumb_ptr expr); /** * Evaluates an expression and coerces the result into a string */ -FString magic_eval_str(dumb_ptr env, dumb_ptr expr); +AString magic_eval_str(dumb_ptr env, dumb_ptr expr); dumb_ptr magic_new_expr(EXPR ty); diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp index 0ba145a..f1878a0 100644 --- a/src/map/magic-interpreter-base.cpp +++ b/src/map/magic-interpreter-base.cpp @@ -3,7 +3,7 @@ #include "magic-interpreter-aux.hpp" #include "magic-interpreter.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" @@ -68,13 +68,13 @@ void set_spell SETTER(dumb_ptr, TYPE::SPELL, v_spell) magic_conf_t magic_conf; /* Global magic conf */ env_t magic_default_env = { &magic_conf, NULL }; -FString magic_find_invocation(XString spellname) +AString magic_find_invocation(XString spellname) { auto it = magic_conf.spells_by_name.find(spellname); if (it != magic_conf.spells_by_name.end()) return it->second->invocation; - return FString(); + return AString(); } dumb_ptr magic_find_spell(XString invocation) @@ -90,14 +90,14 @@ dumb_ptr magic_find_spell(XString invocation) /* Spell anchors */ /* -------------------------------------------------------------------------------- */ -FString magic_find_anchor_invocation(XString anchor_name) +AString magic_find_anchor_invocation(XString anchor_name) { auto it = magic_conf.anchors_by_name.find(anchor_name); if (it != magic_conf.anchors_by_name.end()) return it->second->invocation; - return FString(); + return AString(); } dumb_ptr magic_find_anchor(XString name) diff --git a/src/map/magic-interpreter-parser.ypp b/src/map/magic-interpreter-parser.ypp index a86f1c8..3ec1bdd 100644 --- a/src/map/magic-interpreter-parser.ypp +++ b/src/map/magic-interpreter-parser.ypp @@ -3,7 +3,7 @@ #include "magic-interpreter.hpp" extern -FString current_magic_filename; +AString current_magic_filename; } // %code requires %code @@ -13,7 +13,8 @@ FString current_magic_filename; #include #include // exception to "no va_list" rule, even after cxxstdio -#include "../strings/fstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../io/cxxstdio.hpp" @@ -23,7 +24,7 @@ FString current_magic_filename; #include "itemdb.hpp" #include "magic-expr.hpp" -FString current_magic_filename; +AString current_magic_filename; // can't use src/warnings.hpp in generated code #pragma GCC diagnostic warning "-Wall" @@ -37,13 +38,13 @@ static size_t intern_id(ZString id_name); static -dumb_ptr fun_expr(FString name, const_array> argv, int line, int column); +dumb_ptr fun_expr(AString name, const_array> argv, int line, int column); static dumb_ptr dot_expr(dumb_ptr lhs, int id); static -void BIN_EXPR(dumb_ptr& x, FString name, dumb_ptr arg1, dumb_ptr arg2, int line, int column) +void BIN_EXPR(dumb_ptr& x, AString name, dumb_ptr arg1, dumb_ptr arg2, int line, int column) { dumb_ptr e[2]; e[0] = arg1; @@ -82,7 +83,7 @@ static void add_teleport_anchor(dumb_ptr anchor, int line_nr); static -dumb_ptr op_effect(FString name, const_array> argv, int line, int column); +dumb_ptr op_effect(AString name, const_array> argv, int line, int column); // in magic-interpreter-lexer.cpp int magic_frontend_lex(void); @@ -94,10 +95,10 @@ static dumb_ptr call_proc(ZString name, dumb_ptr>> argvp, int line_nr, int column); static -void bind_constant(FString name, val_t *val, int line_nr); +void bind_constant(RString name, val_t *val, int line_nr); static -val_t *find_constant(FString name); +val_t *find_constant(RString name); } // %code @@ -1182,7 +1183,7 @@ dumb_ptr dot_expr(dumb_ptr expr, int id) return retval; } -dumb_ptr fun_expr(FString name, const_array> argv, int line, int column) +dumb_ptr fun_expr(AString name, const_array> argv, int line, int column) { dumb_ptr expr; fun_t *fun = magic_get_fun(name); @@ -1293,7 +1294,7 @@ dumb_ptr set_effect_continuation(dumb_ptr src, dumb_ptr op_effect(FString name, const_array> argv, int line, int column) +dumb_ptr op_effect(AString name, const_array> argv, int line, int column) { dumb_ptr effect; op_t *op = magic_get_op(name); @@ -1325,7 +1326,7 @@ dumb_ptr op_effect(FString name, const_array> argv, i } -std::map procs; +std::map procs; // I think this was a memory leak (or undefined behavior) void install_proc(dumb_ptr proc) @@ -1358,9 +1359,9 @@ dumb_ptr call_proc(ZString name, dumb_ptr return retval; } -std::map const_defm; +std::map const_defm; -void bind_constant(FString name, val_t *val, int line_nr) +void bind_constant(RString name, val_t *val, int line_nr) { if (!const_defm.insert({name, *val}).second) { @@ -1368,7 +1369,7 @@ void bind_constant(FString name, val_t *val, int line_nr) } } -val_t *find_constant(FString name) +val_t *find_constant(RString name) { auto it = const_defm.find(name); if (it != const_defm.end()) diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp index 19f8574..7e42499 100644 --- a/src/map/magic-interpreter.hpp +++ b/src/map/magic-interpreter.hpp @@ -6,7 +6,7 @@ # include # include "../strings/fwd.hpp" -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" # include "magic.hpp" # include "map.hpp" @@ -244,8 +244,8 @@ struct letdef_t struct spell_t { - FString name; - FString invocation; + RString name; + RString invocation; SPELL_FLAG flags; int arg; SPELLARG spellarg_ty; @@ -261,8 +261,8 @@ struct spell_t struct teleport_anchor_t { - FString name; - FString invocation; + RString name; + RString invocation; dumb_ptr location; }; @@ -274,15 +274,15 @@ struct magic_conf_t { struct mcvar { - FString name; + RString name; val_t val; }; // This should probably be done by a dedicated "intern pool" class std::vector varv; - std::map> spells_by_name, spells_by_invocation; + std::map> spells_by_name, spells_by_invocation; - std::map> anchors_by_name, anchors_by_invocation; + std::map> anchors_by_name, anchors_by_invocation; }; /* Execution environment */ @@ -434,7 +434,7 @@ struct args_rec_t struct proc_t { - FString name; + RString name; std::vector argv; dumb_ptr body; diff --git a/src/map/magic.hpp b/src/map/magic.hpp index 5d4e517..1fabd6f 100644 --- a/src/map/magic.hpp +++ b/src/map/magic.hpp @@ -46,14 +46,14 @@ void spell_effect_report_termination(int invocation, int bl_id, * * Returns empty string if not found */ -FString magic_find_invocation(XString spellname); +AString magic_find_invocation(XString spellname); /** * Identifies the invocation used to denote a teleport location * * Returns empty string if not found */ -FString magic_find_anchor_invocation(XString teleport_location); +AString magic_find_anchor_invocation(XString teleport_location); /** * Execute a spell invocation and sets up timers to finish diff --git a/src/map/map.cpp b/src/map/map.cpp index 8a1d8eb..caab5b4 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -10,7 +10,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" @@ -75,7 +75,7 @@ int first_free_object_id = 0, last_object_id = 0; interval_t autosave_time = DEFAULT_AUTOSAVE_INTERVAL; int save_settings = 0xFFFF; -FString motd_txt = "conf/motd.txt"; +AString motd_txt = "conf/motd.txt"; CharName wisp_server_name = stringish("Server"); // can be modified in char-server configuration file @@ -1351,7 +1351,7 @@ constexpr int LOGFILE_SECONDS_PER_CHUNK_SHIFT = 10; static std::unique_ptr map_logfile; static -FString map_logfile_name; +AString map_logfile_name; static long map_logfile_index; @@ -1360,7 +1360,7 @@ void map_close_logfile(void) { if (map_logfile) { - FString filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index); + AString filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index); const char *args[] = { "gzip", @@ -1386,7 +1386,7 @@ void map_start_logfile(long index) { map_logfile_index = index; - FString filename_buf = STRPRINTF( + AString filename_buf = STRPRINTF( "%s.%ld", map_logfile_name, map_logfile_index); @@ -1399,7 +1399,7 @@ void map_start_logfile(long index) } static -void map_set_logfile(FString filename) +void map_set_logfile(AString filename) { struct timeval tv; @@ -1445,7 +1445,7 @@ bool map_config_read(ZString cfgName) } bool rv = true; - FString line; + AString line; while (in.getline(line)) { if (is_comment(line)) @@ -1663,7 +1663,7 @@ bool map_confs(XString key, ZString value) return load_resnametable(value); if (key == "const_db") return read_constdb(value); - PRINTF("unknown map conf key: %s\n", FString(key)); + PRINTF("unknown map conf key: %s\n", AString(key)); return false; } diff --git a/src/map/map.hpp b/src/map/map.hpp index 897c619..092fd80 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -9,7 +9,8 @@ # include # include "../strings/fwd.hpp" -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" +# include "../strings/astring.hpp" # include "../strings/vstring.hpp" # include "../io/cxxstdio.hpp" @@ -193,7 +194,7 @@ struct map_session_data : block_list, SessionData // but one should probably be replaced with a ScriptPointer ??? const ScriptBuffer *npc_script, *npc_scriptroot; std::vector npc_stackbuf; - FString npc_str; + RString npc_str; struct { unsigned storage:1; @@ -267,8 +268,8 @@ struct map_session_data : block_list, SessionData // Not anymore! Well, sort of. DMap regm; // can't be DMap because we want predictable .c_str()s - // This could change once FString ensures CoW. - Map regstrm; + // TODO this can change now + Map regstrm; earray sc_data; short sc_count; @@ -302,7 +303,7 @@ struct map_session_data : block_list, SessionData TimeT chat_repeat_reset_due; int chat_lines_in; int chat_total_repeats; - FString chat_lastmsg; + RString chat_lastmsg; tick_t flood_rates[0x220]; TimeT packet_flood_reset_due; @@ -347,7 +348,7 @@ struct npc_data : block_list Option option; short flag; - std::list eventqueuel; + std::list eventqueuel; Timer eventtimer[MAX_EVENTTIMER]; short arenaflag; @@ -414,7 +415,7 @@ public: class npc_data_message : public npc_data { public: - FString message; + RString message; }; constexpr int MOB_XP_BONUS_BASE = 1024; @@ -574,7 +575,7 @@ struct flooritem_data : block_list extern interval_t autosave_time; extern int save_settings; -extern FString motd_txt; +extern AString motd_txt; extern CharName wisp_server_name; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 7a73df5..2a06cf7 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -8,7 +8,7 @@ #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" @@ -3420,7 +3420,7 @@ bool mob_readdb(ZString filename) PRINTF("Unable to read mob db: %s\n", filename); return false; } - FString line; + AString line; while (in.getline(line)) { int mob_class; @@ -3631,7 +3631,7 @@ bool mob_readskilldb(ZString filename) PRINTF("can't read %s\n", filename); return false; } - FString line; + AString line; while (in.getline(line)) { int mob_id; diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 4a116b2..788d785 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -8,7 +8,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -34,7 +34,7 @@ #include "../poison.hpp" static -std::list npc_srcs; +std::list npc_srcs; static int npc_id = START_NPC_NUM; @@ -903,7 +903,7 @@ void npc_clearsrcfile(void) * 読み込むnpcファイルの追加 *------------------------------------------ */ -void npc_addsrcfile(FString name) +void npc_addsrcfile(AString name) { if (name == "clear") { @@ -918,7 +918,7 @@ void npc_addsrcfile(FString name) * 読み込むnpcファイルの削除 *------------------------------------------ */ -void npc_delsrcfile(FString name) +void npc_delsrcfile(XString name) { if (name == "all") { @@ -1209,7 +1209,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, if (it != srcbuf.rend() && *it == '}') break; - FString line; + AString line; if (!fp.getline(line)) // eof break; @@ -1226,7 +1226,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, srcbuf += line; srcbuf += '\n'; } - script = parse_script(FString(srcbuf), startline); + script = parse_script(AString(srcbuf), startline); if (script == NULL) // script parse error? return 1; @@ -1404,7 +1404,7 @@ int npc_parse_function(XString, XString, XString w3, ZString, if (it != srcbuf.rend() && *it == '}') break; - FString line; + AString line; if (!fp.getline(line)) break; (*lines)++; @@ -1417,7 +1417,7 @@ int npc_parse_function(XString, XString, XString w3, ZString, srcbuf += line; srcbuf += '\n'; } - std::unique_ptr script = parse_script(FString(srcbuf), startline); + std::unique_ptr script = parse_script(AString(srcbuf), startline); if (script == NULL) { // script parse error? @@ -1636,7 +1636,7 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4) } dumb_ptr npc_spawn_text(map_local *m, int x, int y, - int npc_class, NpcName name, FString message) + int npc_class, NpcName name, AString message) { dumb_ptr retval; retval.new_(); @@ -1678,7 +1678,7 @@ void npc_free_internal(dumb_ptr nd_) else if (nd_->npc_subtype == NpcSubtype::MESSAGE) { dumb_ptr nd = nd_->is_message(); - nd->message = FString(); + nd->message = AString(); } nd_.delete_(); } @@ -1722,7 +1722,7 @@ bool do_init_npc(void) for (; !npc_srcs.empty(); npc_srcs.pop_front()) { - FString nsl = npc_srcs.front(); + AString nsl = npc_srcs.front(); io::ReadFile fp(nsl); if (!fp.is_open()) { @@ -1733,7 +1733,7 @@ bool do_init_npc(void) PRINTF("\rLoading NPCs [%d]: %-54s", npc_id - START_NPC_NUM, nsl); int lines = 0; - FString zline; + AString zline; while (fp.getline(zline)) { XString w1, w2, w3, w4x; diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 17eea04..4d4cef1 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -39,15 +39,15 @@ int npc_get_new_npc_id(void); * \param message The message to speak. If message is NULL, the NPC will not do anything at all. */ dumb_ptr npc_spawn_text(map_local *m, int x, int y, - int class_, NpcName name, FString message); + int class_, NpcName name, AString message); /** * Uninstalls and frees an NPC */ void npc_free(dumb_ptr npc); -void npc_addsrcfile(FString); -void npc_delsrcfile(FString); +void npc_addsrcfile(AString); +void npc_delsrcfile(XString); bool do_init_npc(void); int npc_event_do_oninit(void); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 8d242ae..c9588bb 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -4,7 +4,8 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../io/cxxstdio.hpp" @@ -751,7 +752,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, sd->chat_reset_due = TimeT(); sd->chat_lines_in = sd->chat_total_repeats = 0; sd->chat_repeat_reset_due = TimeT(); - sd->chat_lastmsg = FString(); + sd->chat_lastmsg = RString(); for (tick_t& t : sd->flood_rates) t = tick_t(); @@ -780,7 +781,7 @@ void pc_show_motd(dumb_ptr sd) io::ReadFile in(motd_txt); if (in.is_open()) { - FString buf; + AString buf; while (in.getline(buf)) { clif_displaymessage(sd->sess, buf); @@ -3094,7 +3095,7 @@ int pc_gainexp_reason(dumb_ptr sd, int base_exp, int job_exp, if (battle_config.disp_experience) { - FString output = STRPRINTF( + AString output = STRPRINTF( "Experienced Gained Base:%d Job:%d", base_exp, job_exp); clif_displaymessage(sd->sess, output); @@ -4123,7 +4124,7 @@ ZString pc_readregstr(dumb_ptr sd, SIR reg) { nullpo_retr(ZString(), sd); - FString *s = sd->regstrm.search(reg); + RString *s = sd->regstrm.search(reg); if (s) return *s; @@ -4134,7 +4135,7 @@ ZString pc_readregstr(dumb_ptr sd, SIR reg) * script用文字列変数の値を設定 *------------------------------------------ */ -void pc_setregstr(dumb_ptr sd, SIR reg, FString str) +void pc_setregstr(dumb_ptr sd, SIR reg, RString str) { nullpo_retv(sd); diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 48ba8f3..be66cc4 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -123,7 +123,7 @@ int pc_setparam(dumb_ptr, SP, int); int pc_readreg(dumb_ptr, SIR); void pc_setreg(dumb_ptr, SIR, int); ZString pc_readregstr(dumb_ptr sd, SIR reg); -void pc_setregstr(dumb_ptr sd, SIR reg, FString str); +void pc_setregstr(dumb_ptr sd, SIR reg, RString str); int pc_readglobalreg(dumb_ptr, VarName ); int pc_setglobalreg(dumb_ptr, VarName , int); int pc_readaccountreg(dumb_ptr, VarName ); diff --git a/src/map/script.cpp b/src/map/script.cpp index c154182..36ceb8c 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -8,7 +8,8 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -49,27 +50,27 @@ constexpr bool DEBUG_RUN = false; struct str_data_t { ByteCode type; - FString strs; + RString strs; int backpatch; int label_; int val; }; static -Map str_datam; +Map str_datam; static str_data_t LABEL_NEXTLINE_; static DMap mapreg_db; static -Map mapregstr_db; +Map mapregstr_db; static int mapreg_dirty = -1; -FString mapreg_txt = "save/mapreg.txt"; +AString mapreg_txt = "save/mapreg.txt"; constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10); Map scriptlabel_db; -UPMap userfunc_db; +UPMap userfunc_db; static const char *pos_str[11] = @@ -157,7 +158,7 @@ str_data_t *add_strp(XString p) if (str_data_t *rv = search_strp(p)) return rv; - FString p2 = p; + RString p2 = p; str_data_t *datum = str_datam.init(p2); datum->type = ByteCode::NOP; datum->strs = p2; @@ -699,13 +700,13 @@ bool read_constdb(ZString filename) } bool rv = true; - FString line; + AString line; while (in.getline(line)) { if (is_comment(line)) continue; - FString name; + AString name; int val; int type = 0; // if not provided // TODO get rid of SSCANF - this is the last serious use @@ -908,7 +909,7 @@ void get_val(ScriptState *st, struct script_data *data) } else if (prefix == '$') { - FString *s = mapregstr_db.search(data->u.reg); + RString *s = mapregstr_db.search(data->u.reg); data->u.str = s ? dumb_string::fake(*s) : dumb_string(); } else @@ -1059,7 +1060,7 @@ dumb_string conv_str(ScriptState *st, struct script_data *data) assert (data->type != ByteCode::RETINFO); if (data->type == ByteCode::INT) { - FString buf = STRPRINTF("%d", data->u.numi); + AString buf = STRPRINTF("%d", data->u.numi); data->type = ByteCode::STR; data->u.str = dumb_string::copys(buf); } @@ -1340,7 +1341,7 @@ void builtin_menu(ScriptState *st) buf += ':'; } - clif_scriptmenu(script_rid2sd(st), st->oid, FString(buf)); + clif_scriptmenu(script_rid2sd(st), st->oid, AString(buf)); } else { @@ -2233,7 +2234,7 @@ void builtin_getequipname(ScriptState *st) dumb_ptr sd; struct item_data *item; - FString buf; + AString buf; sd = script_rid2sd(st); num = conv_num(st, &AARGO2(2)); @@ -3572,7 +3573,7 @@ void builtin_getspellinvocation(ScriptState *st) { dumb_string name = conv_str(st, &AARGO2(2)); - FString invocation = magic_find_invocation(name.str()); + AString invocation = magic_find_invocation(name.str()); if (!invocation) invocation = "..."; @@ -3938,7 +3939,7 @@ void builtin_npctalk(ScriptState *st) message += nd->name; message += " : "; message += ZString(str); - clif_message(nd, FString(message)); + clif_message(nd, AString(message)); } } @@ -4275,7 +4276,7 @@ void op_add(ScriptState *st) if (back.type == ByteCode::STR) back.u.str.delete_(); back1.type = ByteCode::STR; - back1.u.str = dumb_string::copys(FString(buf)); + back1.u.str = dumb_string::copys(AString(buf)); } } @@ -4921,7 +4922,7 @@ void script_load_mapreg(void) if (!in.is_open()) return; - FString line; + AString line; while (in.getline(line)) { XString buf1, buf2; @@ -4952,7 +4953,7 @@ void script_load_mapreg(void) else { borken: - PRINTF("%s: %s broken data !\n", mapreg_txt, FString(buf1)); + PRINTF("%s: %s broken data !\n", mapreg_txt, AString(buf1)); continue; } } diff --git a/src/map/script.hpp b/src/map/script.hpp index ec52f65..22a079b 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -6,7 +6,8 @@ # include -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" +# include "../strings/astring.hpp" # include "../strings/zstring.hpp" # include "../common/db.hpp" @@ -157,12 +158,12 @@ struct ScriptLabel; extern Map scriptlabel_db; extern -UPMap userfunc_db; +UPMap userfunc_db; void do_init_script(void); void do_final_script(void); -extern FString mapreg_txt; +extern AString mapreg_txt; extern int script_errors; diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 2253d9d..0222202 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -6,7 +6,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/rstring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" @@ -1169,7 +1169,7 @@ SP scan_stat(XString statname) if (statname == "none") return SP::ZERO; - FPRINTF(stderr, "Unknown stat `%s'\n", FString(statname)); + FPRINTF(stderr, "Unknown stat `%s'\n", AString(statname)); return SP::ZERO; } @@ -1183,7 +1183,7 @@ bool skill_readdb(ZString filename) } bool rv = true; - FString line_; + AString line_; while (in.getline(line_)) { // is_comment only works for whole-line comments @@ -1267,7 +1267,7 @@ bool skill_readdb(ZString filename) c = ' '; skill_db[i] = skdb; - skill_lookup_by_id(i).desc = FString(tmp); + skill_lookup_by_id(i).desc = RString(tmp); } PRINTF("read %s done\n", filename); diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 5f29443..e8f36ab 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -5,7 +5,8 @@ # include "skill-pools.hpp" # include "../strings/fwd.hpp" -# include "../strings/fstring.hpp" +# include "../strings/rstring.hpp" +# include "../strings/astring.hpp" # include "map.hpp" @@ -39,11 +40,11 @@ earray skill_db; struct skill_name_db { SkillID id; // skill id - FString name; // search strings - FString desc; // description that shows up for searches + RString name; // search strings + RString desc; // description that shows up for searches // this makes const char(&)[] not decay into const char * in {} - skill_name_db(SkillID i, FString n, FString d) + skill_name_db(SkillID i, RString n, RString d) : id(i), name(n), desc(d) {} }; @@ -129,7 +130,7 @@ bool skill_pool_is_activated(dumb_ptr sd, SkillID skill); int skill_pool_deactivate(dumb_ptr sd, SkillID skill); // Yield configurable skill name inline -const FString& skill_name(SkillID skill) +const RString& skill_name(SkillID skill) { return skill_lookup_by_id(skill).desc; } diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp index 7e661bb..72cfa2b 100644 --- a/src/map/tmw.cpp +++ b/src/map/tmw.cpp @@ -3,7 +3,7 @@ #include #include -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -95,16 +95,16 @@ void tmw_AutoBan(dumb_ptr sd, ZString reason, int length) sd->auto_ban_info.in_progress = 1; - FString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam", + AString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam", sd->status.name, reason); tmw_GmHackMsg(hack_msg); - FString fake_command = STRPRINTF("@autoban %s %dh (%s spam)", + AString fake_command = STRPRINTF("@autoban %s %dh (%s spam)", sd->status.name, length, reason); log_atcommand(sd, fake_command); - FString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.", + AString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.", reason); clif_displaymessage(sd->sess, anotherbuf); diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp index 352b375..e59be71 100644 --- a/src/monitor/main.cpp +++ b/src/monitor/main.cpp @@ -15,7 +15,7 @@ #include #include "../strings/mstring.hpp" -#include "../strings/fstring.hpp" +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -36,26 +36,26 @@ // initialiized to $HOME/tmwserver static -FString workdir; +AString workdir; //the rest are relative to workdir static -FString login_server = LOGIN_SERVER; +AString login_server = LOGIN_SERVER; static -FString map_server = MAP_SERVER; +AString map_server = MAP_SERVER; static -FString char_server = CHAR_SERVER; +AString char_server = CHAR_SERVER; static pid_t pid_login, pid_map, pid_char; static -FString make_path(XString base, XString path) +AString make_path(XString base, XString path) { MString m; m += base; m += '/'; m += path; - return FString(m); + return AString(m); } static @@ -71,9 +71,8 @@ bool parse_option(XString name, ZString value) workdir = value; else { - FString name_ = name; FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' : '%s'\n", - name_, value); + AString(name), value); return false; } return true; @@ -90,7 +89,7 @@ bool read_config(ZString filename) exit(1); } - FString line; + AString line; while (in.getline(line)) { if (is_comment(line)) @@ -179,8 +178,8 @@ int main(int argc, char *argv[]) PRINTF("Starting:\n"); PRINTF("* workdir: %s\n", workdir); PRINTF("* login_server: %s\n", login_server); - PRINTF("* map_server: %s\n", map_server); PRINTF("* char_server: %s\n", char_server); + PRINTF("* map_server: %s\n", map_server); { //make sure all possible file descriptors are free for use by the servers //if there are file descriptors higher than the max open from before the limit dropped, that's not our problem diff --git a/src/strings/all.hpp b/src/strings/all.hpp index 7fd543f..46d5366 100644 --- a/src/strings/all.hpp +++ b/src/strings/all.hpp @@ -21,7 +21,8 @@ # include "base.hpp" # include "mstring.hpp" -# include "fstring.hpp" +# include "rstring.hpp" +# include "astring.hpp" # include "tstring.hpp" # include "sstring.hpp" # include "zstring.hpp" diff --git a/src/strings/astring.cpp b/src/strings/astring.cpp new file mode 100644 index 0000000..f7cfa2e --- /dev/null +++ b/src/strings/astring.cpp @@ -0,0 +1,229 @@ +#include "astring.hpp" +// strings/astring.cpp - Functions for astring.hpp +// +// Copyright © 2013-2014 Ben Longbons +// +// 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 . + +#include "mstring.hpp" +#include "tstring.hpp" +#include "sstring.hpp" +#include "zstring.hpp" +#include "xstring.hpp" +#include "vstring.hpp" + +namespace strings +{ + static_assert(sizeof(AString) == 256, "AString"); + + static + void acpy(char (&dst)[255], const char (&src)[255]) + { + std::copy(src + 0, src + 255, dst); + } + + // TODO dedup all this code once I drop gcc 4.6 support + AString::AString() + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + } + + AString::AString(const AString& a) + : data(), special(a.special) + { + acpy(data, a.data); + if (special == 255) + new(r_ptr()) RString(*a.r_ptr()); + } + AString::AString(AString&& a) + : data(), special(a.special) + { + acpy(data, a.data); + if (special == 255) + new(r_ptr()) RString(std::move(*a.r_ptr())); + } + AString& AString::operator = (const AString& a) + { + if (this == &a) + return *this; + if (special == 255) + r_ptr()->~RString(); + acpy(data, a.data); + special = a.special; + if (special == 255) + new(r_ptr()) RString(*a.r_ptr()); + return *this; + } + AString& AString::operator = (AString&& a) + { + std::swap(data, a.data); + std::swap(special, a.special); + return *this; + } + AString::AString(RString r) + : data{}, special() + { + new(r_ptr()) RString(std::move(r)); + special = 255; + } + AString::~AString() + { + if (special == 255) + r_ptr()->~RString(); + } + + AString::AString(const MString& s) + : data{}, special() + { + if (s.size() > 255 || s.size() == 0) + { + new(r_ptr()) RString(s); + special = 255; + } + else + { + *std::copy(s.begin(), s.end(), data) = '\0'; + special = 255 - s.size(); + } + } + + AString::AString(XPair p) + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + *this = XString(p); + } + + AString::AString(const TString& t) + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + *this = XString(t); + } + AString::AString(const SString& s) + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + *this = XString(s); + } + AString::AString(ZString z) + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + *this = XString(z); + } + AString::AString(XString x) + : data{}, special() + { + if (const RString *r = x.base()) + { + if (&*r->begin() == &*x.begin() && &*r->end() == &*x.end()) + { + new(r_ptr()) RString(*r); + special = 255; + return; + } + } + if (x.size() > 255 || x.size() == 0) + { + new(r_ptr()) RString(x); + special = 255; + } + else + { + *std::copy(x.begin(), x.end(), data) = '\0'; + special = 255 - x.size(); + } + } + + AString::iterator AString::begin() const + { + if (special == 255) + return &*r_ptr()->begin(); + else + return data + 0; + } + AString::iterator AString::end() const + { + if (special == 255) + return &*r_ptr()->end(); + else + return data + (255 - special); + } + const RString *AString::base() const + { + if (special == 255) + return r_ptr(); + else + return nullptr; + } + const char *AString::c_str() const + { + return &*begin(); + } + + const char *decay_for_printf(const AString& as) + { + return as.c_str(); + } + + int do_vprint(AString& out, const char *fmt, va_list ap) + { + // TODO try with a fixed-size buffer first, then write + // directory into the allocated output? + int len; + { + va_list ap2; + va_copy(ap2, ap); + len = vsnprintf(nullptr, 0, fmt, ap2); + va_end(ap2); + } + char buffer[len + 1]; + vsnprintf(buffer, len + 1, fmt, ap); + + out = AString(buffer, buffer + len); + return len; + } + + AStringConverter::AStringConverter(AString& s) + : out(s), mid(nullptr) + {} + + AStringConverter::~AStringConverter() + { + if (mid) + { + out = ZString(really_construct_from_a_pointer, mid, nullptr); + free(mid); + } + } + + char **AStringConverter::operator &() + { + return ∣ + } + + AStringConverter convert_for_scanf(AString& s) + { + return AStringConverter(s); + } +} // namespace strings diff --git a/src/strings/astring.hpp b/src/strings/astring.hpp new file mode 100644 index 0000000..e682ef0 --- /dev/null +++ b/src/strings/astring.hpp @@ -0,0 +1,98 @@ +#ifndef TMWA_STRINGS_ASTRING_HPP +#define TMWA_STRINGS_ASTRING_HPP +// strings/astring.hpp - An owned, reference-counted immutable string. +// +// Copyright © 2013-2014 Ben Longbons +// +// 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 . + +# include +# include + +# include "base.hpp" +# include "rstring.hpp" + +namespace strings +{ + /// An owning string that has reached its final contents. + /// The storage is NUL-terminated + class AString : public _crtp_string + { + RString *align[0]; + char data[255]; + unsigned char special; + RString *r_ptr() { return reinterpret_cast(data); } + const RString *r_ptr() const { return reinterpret_cast(data); } + public: + AString(); + AString(const AString&); + AString(AString&&); + AString& operator = (const AString&); + AString& operator = (AString&&); + AString(RString); + ~AString(); + + explicit AString(const MString& s); + + template + AString(char (&s)[n]) = delete; + + template + AString(const char (&s)[n]); + + template + AString(It b, It e); + + AString(XPair p); + //AString(const AString&) + AString(const TString&); + AString(const SString&); + AString(ZString); + AString(XString); + template + AString(const VString& v); + + iterator begin() const; + iterator end() const; + const RString *base() const; + const char *c_str() const; + }; + + // cxxstdio helpers + // I think the conversion will happen automatically. TODO test this. + // Nope, it doesn't, since there's a template + // Actually, it might now. + const char *decay_for_printf(const AString& fs); + + __attribute__((format(printf, 2, 0))) + int do_vprint(AString& out, const char *fmt, va_list ap); + + class AStringConverter + { + AString& out; + char *mid; + public: + AStringConverter(AString& s); + ~AStringConverter(); + char **operator &(); + }; + + AStringConverter convert_for_scanf(AString& s); +} // namespace strings + +# include "astring.tcc" + +#endif // TMWA_STRINGS_ASTRING_HPP diff --git a/src/strings/astring.py b/src/strings/astring.py new file mode 100644 index 0000000..ec1dafe --- /dev/null +++ b/src/strings/astring.py @@ -0,0 +1,24 @@ +class AString(object): + ''' print an AString + ''' + __slots__ = ('_value') + name = 'strings::AString' + enabled = True + + def __init__(self, value): + self._value = value + + def to_string(self): + return None + + def children(self): + b = self._value['data'] + s = self._value['special'] + if s == 255: + b = b.cast(gdb.lookup_type('strings::RString').pointer()) + yield 'allocated', b.dereference() + else: + b = b.cast(b.type.target().pointer()) + n = 255 + d = n - s + yield 'contained', b.lazy_string(length=d) diff --git a/src/strings/astring.tcc b/src/strings/astring.tcc new file mode 100644 index 0000000..ed07bd9 --- /dev/null +++ b/src/strings/astring.tcc @@ -0,0 +1,76 @@ +// strings/astring.tcc - Inline functions for astring.hpp +// +// Copyright © 2013 Ben Longbons +// +// 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 . + +#include "mstring.hpp" + +namespace strings +{ + template + AString::AString(const char (&s)[n]) + : data{}, special() + { + XPair x = s; + if (x.size() > 255 || x.size() == 0) + { + new(r_ptr()) RString(x); + special = 255; + } + else + { + *std::copy(x.begin(), x.end(), data) = '\0'; + special = 255 - x.size(); + } + } + + template + AString::AString(It b, It e) + : data{}, special() + { + if (!std::is_base_of::iterator_category>::value) + { + // can't use std::distance + MString m; + for (; b != e; ++b) + m += *b; + *this = AString(m); // will recurse + return; + } + auto d = std::distance(b, e); + if (d > 255 || d == 0) + { + new(r_ptr()) RString(b, e); + special = 255; + } + else + { + *std::copy(b, e, data) = '\0'; + special = 255 - d; + } + } + + template + AString::AString(const VString& v) + : data{}, special() + { + *std::copy(v.begin(), v.end(), data) = '\0'; + special = 255 - v.size(); + if (!v) + new(r_ptr()) RString(); + } +} // namespace strings diff --git a/src/strings/base.hpp b/src/strings/base.hpp index 7461872..c081f70 100644 --- a/src/strings/base.hpp +++ b/src/strings/base.hpp @@ -88,7 +88,7 @@ namespace strings const T& _ref() const; iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; public: size_t size() const; reverse_iterator rbegin() const; diff --git a/src/strings/base.tcc b/src/strings/base.tcc index 491b4ca..a5a57d0 100644 --- a/src/strings/base.tcc +++ b/src/strings/base.tcc @@ -104,7 +104,7 @@ namespace strings return _ref().end(); } template - const FString *_crtp_string::base() const + const RString *_crtp_string::base() const { return _ref().base(); } diff --git a/src/strings/base_test.cpp b/src/strings/base_test.cpp index cb41fa9..3f9900e 100644 --- a/src/strings/base_test.cpp +++ b/src/strings/base_test.cpp @@ -4,7 +4,7 @@ #include "vstring.hpp" #include "xstring.hpp" -#include "fstring.hpp" +#include "rstring.hpp" using namespace strings; @@ -18,7 +18,7 @@ static_assert(!string_comparison_allowed<_test, VString<1>>::value, "tv"); static_assert(!string_comparison_allowed<_test, _test2>::value, "t2"); static_assert(string_comparison_allowed, XString>::value, "vx"); static_assert(string_comparison_allowed::value, "xx"); -static_assert(string_comparison_allowed::value, "xf"); +static_assert(string_comparison_allowed::value, "xf"); TEST(strings, contains) { diff --git a/src/strings/fstring.cpp b/src/strings/fstring.cpp deleted file mode 100644 index 97ef4b0..0000000 --- a/src/strings/fstring.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "fstring.hpp" -// strings/fstring.cpp - Functions for fstring.hpp -// -// Copyright © 2013-2014 Ben Longbons -// -// 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 . - -#include "mstring.hpp" -#include "tstring.hpp" -#include "sstring.hpp" -#include "zstring.hpp" -#include "xstring.hpp" -#include "vstring.hpp" - -namespace strings -{ - uint8_t FString::empty_string_rep[sizeof(Rep) + 1]; - - FString::FString() - : owned(reinterpret_cast(&empty_string_rep)) - { - owned->count++; - } - - FString::FString(const FString& r) - : owned(r.owned) - { - owned->count++; - } - FString::FString(FString&& r) - : owned(reinterpret_cast(&empty_string_rep)) - { - std::swap(owned, r.owned); - r.owned->count++; - } - FString& FString::operator = (const FString& r) - { - // order important for self-assign - r.owned->count++; - // owned can be NULL from ctors - // TODO do ctors *properly* (requires gcc 4.7 to stay sane) - if (owned && !owned->count--) - ::operator delete(owned); - owned = r.owned; - return *this; - } - FString& FString::operator = (FString&& r) - { - std::swap(owned, r.owned); - return *this; - } - FString::~FString() - { - if (owned && !owned->count--) - ::operator delete(owned); - owned = nullptr; - } - - FString::FString(const MString& s) - : owned(nullptr) - { - _assign(s.begin(), s.end()); - } - - FString::FString(XPair p) - : owned(nullptr) - { - _assign(p.begin(), p.end()); - } - - FString::FString(const TString& t) - : owned(nullptr) - { - *this = XString(t); - } - FString::FString(const SString& s) - : owned(nullptr) - { - *this = XString(s); - } - FString::FString(ZString z) - : owned(nullptr) - { - *this = XString(z); - } - FString::FString(XString x) - : owned(nullptr) - { - const FString *f = x.base(); - const char *xb = &*x.begin(); - const char *xe = &*x.end(); - const char *fb = f ? &*f->begin() : nullptr; - const char *fe = f ? &*f->end() : nullptr; - if (f && xb == fb && xe == fe) - *this = *f; - else - _assign(x.begin(), x.end()); - } - - FString::iterator FString::begin() const - { - return owned->body; - } - FString::iterator FString::end() const - { - return owned->body + owned->size; - } - const FString *FString::base() const - { - return this; - } - const char *FString::c_str() const - { - return &*begin(); - } - - const char *decay_for_printf(const FString& fs) - { - return fs.c_str(); - } - - int do_vprint(FString& out, const char *fmt, va_list ap) - { - int len; - { - va_list ap2; - va_copy(ap2, ap); - len = vsnprintf(nullptr, 0, fmt, ap2); - va_end(ap2); - } - char buffer[len + 1]; - vsnprintf(buffer, len + 1, fmt, ap); - - out = FString(buffer, buffer + len); - return len; - } - - StringConverter::StringConverter(FString& s) - : out(s), mid(nullptr) - {} - - StringConverter::~StringConverter() - { - if (mid) - { - out = ZString(really_construct_from_a_pointer, mid, nullptr); - free(mid); - } - } - - char **StringConverter::operator &() - { - return ∣ - } - - StringConverter convert_for_scanf(FString& s) - { - return StringConverter(s); - } -} // namespace strings diff --git a/src/strings/fstring.hpp b/src/strings/fstring.hpp deleted file mode 100644 index 48da326..0000000 --- a/src/strings/fstring.hpp +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef TMWA_STRINGS_FSTRING_HPP -#define TMWA_STRINGS_FSTRING_HPP -// strings/fstring.hpp - An owned, reference-counted immutable string. -// -// Copyright © 2013-2014 Ben Longbons -// -// 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 . - -# include -# include - -# include "base.hpp" - -namespace strings -{ - /// An owning string that has reached its final contents. - /// The storage is NUL-terminated - class FString : public _crtp_string - { - struct Rep - { - size_t count; - size_t size; - char body[]; - }; - static - uint8_t empty_string_rep[sizeof(Rep) + 1]; - - Rep *owned; - - template - void _assign(It b, It e); - public: - FString(); - FString(const FString&); - FString(FString&&); - FString& operator = (const FString&); - FString& operator = (FString&&); - ~FString(); - - explicit FString(const MString& s); - - template - FString(char (&s)[n]) = delete; - - template - FString(const char (&s)[n]); - - template - FString(It b, It e); - - FString(XPair p); - //FString(const FString&) - FString(const TString&); - FString(const SString&); - FString(ZString); - FString(XString); - template - FString(const VString& v); - - iterator begin() const; - iterator end() const; - const FString *base() const; - const char *c_str() const; - }; - - // cxxstdio helpers - // I think the conversion will happen automatically. TODO test this. - // Nope, it doesn't, since there's a template - // Actually, it might now. - const char *decay_for_printf(const FString& fs); - - __attribute__((format(printf, 2, 0))) - int do_vprint(FString& out, const char *fmt, va_list ap); - - class StringConverter - { - FString& out; - char *mid; - public: - StringConverter(FString& s); - ~StringConverter(); - char **operator &(); - }; - - StringConverter convert_for_scanf(FString& s); -} // namespace strings - -# include "fstring.tcc" - -#endif // TMWA_STRINGS_FSTRING_HPP diff --git a/src/strings/fstring.py b/src/strings/fstring.py deleted file mode 100644 index 5418300..0000000 --- a/src/strings/fstring.py +++ /dev/null @@ -1,19 +0,0 @@ -class FString(object): - ''' print a FString - ''' - __slots__ = ('_value') - name = 'strings::FString' - enabled = True - - def __init__(self, value): - self._value = value - - def children(self): - yield 'count', self._value['owned'].dereference()['count'] - - def to_string(self): - r = self._value['owned'].dereference() - b = r['body'] - b = b.cast(b.type.target().pointer()) - d = r['size'] - return b.lazy_string(length=d) diff --git a/src/strings/fstring.tcc b/src/strings/fstring.tcc deleted file mode 100644 index 8072fb0..0000000 --- a/src/strings/fstring.tcc +++ /dev/null @@ -1,67 +0,0 @@ -// strings/fstring.tcc - Inline functions for fstring.hpp -// -// Copyright © 2013 Ben Longbons -// -// 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 . - -#include "mstring.hpp" - -namespace strings -{ - template - void FString::_assign(It b, It e) - { - owned = nullptr; - if (b == e) - { - *this = FString(); - return; - } - if (!std::is_base_of::iterator_category>::value) - { - // can't use std::distance - MString m; - for (; b != e; ++b) - m += *b; - *this = FString(m); // will recurse - return; - } - size_t diff = std::distance(b, e); - owned = static_cast(::operator new(sizeof(Rep) + diff + 1)); - owned->count = 0; - owned->size = diff; - std::copy(b, e, owned->body); - owned->body[diff] = '\0'; - } - - template - FString::FString(const char (&s)[n]) - { - _assign(s, s + strlen(s)); - } - - template - FString::FString(It b, It e) - { - _assign(b, e); - } - - template - FString::FString(const VString& v) - { - _assign(v.begin(), v.end()); - } -} // namespace strings diff --git a/src/strings/fwd.hpp b/src/strings/fwd.hpp index a865fc4..f2b4037 100644 --- a/src/strings/fwd.hpp +++ b/src/strings/fwd.hpp @@ -28,7 +28,8 @@ namespace strings { // owning class MString; - class FString; + class RString; + class AString; class TString; // C legacy version of SString class SString; // is this one really worth it? @@ -46,7 +47,8 @@ namespace strings } // namespace strings using strings::MString; -using strings::FString; +using strings::RString; +using strings::AString; using strings::TString; using strings::SString; diff --git a/src/strings/rstring.cpp b/src/strings/rstring.cpp new file mode 100644 index 0000000..eb9d88a --- /dev/null +++ b/src/strings/rstring.cpp @@ -0,0 +1,164 @@ +#include "rstring.hpp" +// strings/rstring.cpp - Functions for rstring.hpp +// +// Copyright © 2013-2014 Ben Longbons +// +// 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 . + +#include "mstring.hpp" +#include "tstring.hpp" +#include "sstring.hpp" +#include "zstring.hpp" +#include "xstring.hpp" +#include "vstring.hpp" + +namespace strings +{ + static_assert(sizeof(RString) == sizeof(const char *), "RString"); + + uint8_t RString::empty_string_rep[sizeof(Rep) + 1]; + + RString::RString() + : owned(reinterpret_cast(&empty_string_rep)) + { + owned->count++; + } + + RString::RString(const RString& r) + : owned(r.owned) + { + owned->count++; + } + RString::RString(RString&& r) + : owned(reinterpret_cast(&empty_string_rep)) + { + std::swap(owned, r.owned); + r.owned->count++; + } + RString& RString::operator = (const RString& r) + { + // order important for self-assign + r.owned->count++; + // owned can be NULL from ctors + // TODO do ctors *properly* (requires gcc 4.7 to stay sane) + if (owned && !owned->count--) + ::operator delete(owned); + owned = r.owned; + return *this; + } + RString& RString::operator = (RString&& r) + { + std::swap(owned, r.owned); + return *this; + } + RString::RString(AString a) + : owned(nullptr) + { + if (RString *r = const_cast(a.base())) + { + *this = std::move(*r); + } + else + { + *this = XPair(a); + } + } + RString::~RString() + { + if (owned && !owned->count--) + ::operator delete(owned); + owned = nullptr; + } + + RString::RString(const MString& s) + : owned(nullptr) + { + _assign(s.begin(), s.end()); + } + + RString::RString(XPair p) + : owned(nullptr) + { + _assign(p.begin(), p.end()); + } + + RString::RString(const TString& t) + : owned(nullptr) + { + *this = XString(t); + } + RString::RString(const SString& s) + : owned(nullptr) + { + *this = XString(s); + } + RString::RString(ZString z) + : owned(nullptr) + { + *this = XString(z); + } + RString::RString(XString x) + : owned(nullptr) + { + const RString *f = x.base(); + const char *xb = &*x.begin(); + const char *xe = &*x.end(); + const char *fb = f ? &*f->begin() : nullptr; + const char *fe = f ? &*f->end() : nullptr; + if (f && xb == fb && xe == fe) + *this = *f; + else + _assign(x.begin(), x.end()); + } + + RString::iterator RString::begin() const + { + return owned->body; + } + RString::iterator RString::end() const + { + return owned->body + owned->size; + } + const RString *RString::base() const + { + return this; + } + const char *RString::c_str() const + { + return &*begin(); + } + + const char *decay_for_printf(const RString& fs) + { + return fs.c_str(); + } + + int do_vprint(RString& out, const char *fmt, va_list ap) + { + int len; + { + va_list ap2; + va_copy(ap2, ap); + len = vsnprintf(nullptr, 0, fmt, ap2); + va_end(ap2); + } + char buffer[len + 1]; + vsnprintf(buffer, len + 1, fmt, ap); + + out = RString(buffer, buffer + len); + return len; + } +} // namespace strings diff --git a/src/strings/rstring.hpp b/src/strings/rstring.hpp new file mode 100644 index 0000000..b79c7f6 --- /dev/null +++ b/src/strings/rstring.hpp @@ -0,0 +1,93 @@ +#ifndef TMWA_STRINGS_RSTRING_HPP +#define TMWA_STRINGS_RSTRING_HPP +// strings/rstring.hpp - An owned, reference-counted immutable string. +// +// Copyright © 2013-2014 Ben Longbons +// +// 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 . + +# include +# include + +# include "base.hpp" + +namespace strings +{ + /// An owning string that has reached its final contents. + /// The storage is NUL-terminated + class RString : public _crtp_string + { + struct Rep + { + size_t count; + size_t size; + char body[]; + }; + static + uint8_t empty_string_rep[sizeof(Rep) + 1]; + + Rep *owned; + + template + void _assign(It b, It e); + public: + RString(); + RString(const RString&); + RString(RString&&); + RString& operator = (const RString&); + RString& operator = (RString&&); + RString(AString); + ~RString(); + + explicit RString(const MString& s); + + template + RString(char (&s)[n]) = delete; + + template + RString(const char (&s)[n]); + + template + RString(It b, It e); + + RString(XPair p); + //RString(const RString&) + RString(const TString&); + RString(const SString&); + RString(ZString); + RString(XString); + template + RString(const VString& v); + + iterator begin() const; + iterator end() const; + const RString *base() const; + const char *c_str() const; + }; + + // cxxstdio helpers + // I think the conversion will happen automatically. TODO test this. + // Nope, it doesn't, since there's a template + // Actually, it might now. + const char *decay_for_printf(const RString& fs); + + __attribute__((format(printf, 2, 0))) + int do_vprint(RString& out, const char *fmt, va_list ap); +} // namespace strings + +# include "rstring.tcc" + +#endif // TMWA_STRINGS_RSTRING_HPP diff --git a/src/strings/rstring.py b/src/strings/rstring.py new file mode 100644 index 0000000..f0618d6 --- /dev/null +++ b/src/strings/rstring.py @@ -0,0 +1,19 @@ +class RString(object): + ''' print a RString + ''' + __slots__ = ('_value') + name = 'strings::RString' + enabled = True + + def __init__(self, value): + self._value = value + + def children(self): + yield 'count', self._value['owned'].dereference()['count'] + + def to_string(self): + r = self._value['owned'].dereference() + b = r['body'] + b = b.cast(b.type.target().pointer()) + d = r['size'] + return b.lazy_string(length=d) diff --git a/src/strings/rstring.tcc b/src/strings/rstring.tcc new file mode 100644 index 0000000..8b4c0c0 --- /dev/null +++ b/src/strings/rstring.tcc @@ -0,0 +1,67 @@ +// strings/rstring.tcc - Inline functions for rstring.hpp +// +// Copyright © 2013 Ben Longbons +// +// 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 . + +#include "mstring.hpp" + +namespace strings +{ + template + void RString::_assign(It b, It e) + { + owned = nullptr; + if (b == e) + { + *this = RString(); + return; + } + if (!std::is_base_of::iterator_category>::value) + { + // can't use std::distance + MString m; + for (; b != e; ++b) + m += *b; + *this = RString(m); // will recurse + return; + } + size_t diff = std::distance(b, e); + owned = static_cast(::operator new(sizeof(Rep) + diff + 1)); + owned->count = 0; + owned->size = diff; + std::copy(b, e, owned->body); + owned->body[diff] = '\0'; + } + + template + RString::RString(const char (&s)[n]) + { + _assign(s, s + strlen(s)); + } + + template + RString::RString(It b, It e) + { + _assign(b, e); + } + + template + RString::RString(const VString& v) + { + _assign(v.begin(), v.end()); + } +} // namespace strings diff --git a/src/strings/sstring.cpp b/src/strings/sstring.cpp index 99f91ed..fee98f9 100644 --- a/src/strings/sstring.cpp +++ b/src/strings/sstring.cpp @@ -27,8 +27,11 @@ namespace strings SString::SString() : _s(), _b(), _e() {} - SString::SString(FString f) - : _s(std::move(f)), _b(), _e(_s.size()) + SString::SString(RString r) + : _s(std::move(r)), _b(), _e(_s.size()) + {} + SString::SString(AString a) + : _s(std::move(a)), _b(), _e(_s.size()) {} SString::SString(TString t) : _s(t._s), _b(0), _e(_s.size()) @@ -39,19 +42,39 @@ namespace strings } SString::SString(const XString& x) { - const FString *f = x.base(); + const RString *r = x.base(); const char *xb = &*x.begin(); const char *xe = &*x.end(); - const char *fb = f ? &*f->begin() : nullptr; - //const char *fe = f ? &*f->end() : nullptr; - if (f) - *this = SString(*f, xb - fb, xe - fb); + const char *rb = r ? &*r->begin() : nullptr; + //const char *re = r ? &*r->end() : nullptr; + if (r) + *this = SString(*r, xb - rb, xe - rb); else - *this = FString(x); + *this = RString(x); } - SString::SString(FString f, size_t b, size_t e) - : _s(std::move(f)), _b(b), _e(e) + SString::SString(RString r, size_t b, size_t e) + : _s(std::move(r)), _b(b), _e(e) + {} + static + RString get_owned_slice(AString a, size_t *b, size_t *e) + { + if (a.base()) + { + // it's futile + return std::move(a); + } + // have to allocate anyway, so cut first + size_t ob = *b; + size_t oe = *e; + *e -= *b; + *b = 0; + return a.xpslice(ob, oe); + } + SString::SString(AString a, size_t b, size_t e) + : _s(get_owned_slice(std::move(a), &b, &e)) + , _b(b) + , _e(e) {} SString::SString(XPair p) : _s(p), _b(0), _e(p.size()) @@ -65,7 +88,7 @@ namespace strings { return &_s.begin()[_e]; } - const FString *SString::base() const + const RString *SString::base() const { return &_s; } diff --git a/src/strings/sstring.hpp b/src/strings/sstring.hpp index 12fb96d..1836d69 100644 --- a/src/strings/sstring.hpp +++ b/src/strings/sstring.hpp @@ -1,6 +1,6 @@ #ifndef TMWA_STRINGS_SSTRING_HPP #define TMWA_STRINGS_SSTRING_HPP -// strings/sstring.hpp - A full slice of an FString. +// strings/sstring.hpp - A full slice of an RString. // // Copyright © 2013 Ben Longbons // @@ -20,19 +20,20 @@ // along with this program. If not, see . # include "base.hpp" -# include "fstring.hpp" +# include "rstring.hpp" namespace strings { - /// An owning string that represents a arbitrary slice of an FString. + /// An owning string that represents a arbitrary slice of an RString. /// Not guaranteed to be NUL-terminated. class SString : public _crtp_string { - FString _s; + RString _s; size_t _b, _e; public: SString(); - SString(FString f); + SString(RString f); + SString(AString f); SString(TString t); //SString(const SString&); SString(const ZString&); @@ -45,12 +46,13 @@ namespace strings SString(const char (&s)[n]); //template //SString(It b, It e) : _s(b, e), _b(0), _e(_s.size()) {} - SString(FString f, size_t b, size_t e); + SString(RString f, size_t b, size_t e); + SString(AString f, size_t b, size_t e); SString(XPair p); iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; }; } // namespace strings diff --git a/src/strings/strings2_test.cpp b/src/strings/strings2_test.cpp index 3f8662a..24bfc0c 100644 --- a/src/strings/strings2_test.cpp +++ b/src/strings/strings2_test.cpp @@ -6,7 +6,7 @@ TEST(StringTests, traits2) { ZString print_non = "\t\e"; ZString print_mix = "n\t"; - FString print_all = "n "; + RString print_all = "n "; EXPECT_FALSE(print_non.has_print()); EXPECT_TRUE(print_mix.has_print()); EXPECT_TRUE(print_all.has_print()); @@ -20,7 +20,7 @@ TEST(StringTests, traits2) ZString graph_non = " \e"; ZString graph_mix = "n "; - FString graph_all = "n."; + RString graph_all = "n."; EXPECT_FALSE(graph_non.has_graph()); EXPECT_TRUE(graph_mix.has_graph()); EXPECT_TRUE(graph_all.has_graph()); @@ -30,7 +30,7 @@ TEST(StringTests, traits2) ZString lower_non = "0A"; ZString lower_mix = "Oa"; - FString lower_all = "oa"; + RString lower_all = "oa"; EXPECT_FALSE(lower_non.has_lower()); EXPECT_TRUE(lower_mix.has_lower()); EXPECT_TRUE(lower_all.has_lower()); @@ -44,7 +44,7 @@ TEST(StringTests, traits2) ZString upper_non = "0a"; ZString upper_mix = "oA"; - FString upper_all = "OA"; + RString upper_all = "OA"; EXPECT_FALSE(upper_non.has_upper()); EXPECT_TRUE(upper_mix.has_upper()); EXPECT_TRUE(upper_all.has_upper()); @@ -58,7 +58,7 @@ TEST(StringTests, traits2) ZString alpha_non = " 0"; ZString alpha_mix = "n "; - FString alpha_all = "nA"; + RString alpha_all = "nA"; EXPECT_FALSE(alpha_non.has_alpha()); EXPECT_TRUE(alpha_mix.has_alpha()); EXPECT_TRUE(alpha_all.has_alpha()); @@ -68,7 +68,7 @@ TEST(StringTests, traits2) ZString digit2_non = "a9"; ZString digit2_mix = "20"; - FString digit2_all = "01"; + RString digit2_all = "01"; EXPECT_FALSE(digit2_non.has_digit2()); EXPECT_TRUE(digit2_mix.has_digit2()); EXPECT_TRUE(digit2_all.has_digit2()); @@ -78,7 +78,7 @@ TEST(StringTests, traits2) ZString digit8_non = "a9"; ZString digit8_mix = "80"; - FString digit8_all = "37"; + RString digit8_all = "37"; EXPECT_FALSE(digit8_non.has_digit8()); EXPECT_TRUE(digit8_mix.has_digit8()); EXPECT_TRUE(digit8_all.has_digit8()); @@ -88,7 +88,7 @@ TEST(StringTests, traits2) ZString digit10_non = "az"; ZString digit10_mix = "a9"; - FString digit10_all = "42"; + RString digit10_all = "42"; EXPECT_FALSE(digit10_non.has_digit10()); EXPECT_TRUE(digit10_mix.has_digit10()); EXPECT_TRUE(digit10_all.has_digit10()); @@ -98,7 +98,7 @@ TEST(StringTests, traits2) ZString digit16_non = "gz"; ZString digit16_mix = "ao"; - FString digit16_all = "be"; + RString digit16_all = "be"; EXPECT_FALSE(digit16_non.has_digit16()); EXPECT_TRUE(digit16_mix.has_digit16()); EXPECT_TRUE(digit16_all.has_digit16()); @@ -108,7 +108,7 @@ TEST(StringTests, traits2) ZString alnum_non = " ."; ZString alnum_mix = "n "; - FString alnum_all = "n0"; + RString alnum_all = "n0"; EXPECT_FALSE(alnum_non.has_alnum()); EXPECT_TRUE(alnum_mix.has_alnum()); EXPECT_TRUE(alnum_all.has_alnum()); @@ -116,3 +116,89 @@ TEST(StringTests, traits2) EXPECT_FALSE(alnum_mix.is_alnum()); EXPECT_TRUE(alnum_all.is_alnum()); } + +TEST(StringTests, rempty) +{ + const char empty_text[] = ""; + RString r = empty_text; + EXPECT_EQ(r.size(), 0); + AString a = empty_text; + EXPECT_EQ(r, a); + AString r2 = r, r3; + RString a2 = a, a3; + XString r1 = r2; + XString a1 = a2; + r3 = r1; + a3 = a1; + EXPECT_EQ(r, r1); + EXPECT_EQ(a, a1); + EXPECT_EQ(r, r2); + EXPECT_EQ(a, a2); + EXPECT_EQ(r, r3); + EXPECT_EQ(a, a3); + EXPECT_EQ(&*r.begin(), &*r1.begin()); + EXPECT_EQ(&*a.begin(), &*a1.begin()); + EXPECT_EQ(&*r.begin(), &*r2.begin()); + EXPECT_EQ(&*a.begin(), &*a2.begin()); + EXPECT_EQ(&*r.begin(), &*r3.begin()); + EXPECT_EQ(&*a.begin(), &*a3.begin()); +} +TEST(StringTests, rshort) +{ + const char short_text[] = "0123456789"; + RString r = short_text; + EXPECT_EQ(r.size(), 10); + AString a = short_text; + EXPECT_EQ(r, a); + AString r2 = r, r3; + RString a2 = a, a3; + XString r1 = r2; + XString a1 = a2; + r3 = r1; + a3 = a1; + EXPECT_EQ(r, r1); + EXPECT_EQ(a, a1); + EXPECT_EQ(r, r2); + EXPECT_EQ(a, a2); + EXPECT_EQ(r, r3); + EXPECT_EQ(a, a3); + EXPECT_EQ(&*r.begin(), &*r1.begin()); + EXPECT_NE(&*a.begin(), &*a1.begin()); + EXPECT_EQ(&*r.begin(), &*r2.begin()); + EXPECT_NE(&*a.begin(), &*a2.begin()); + EXPECT_EQ(&*r.begin(), &*r3.begin()); + EXPECT_NE(&*a.begin(), &*a3.begin()); +} + +TEST(StringTests, rlong) +{ + const char long_text[] = + "01234567890123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789012345 100" + "01234567890123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789012345 200" + "01234567890123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789012345 300"; + RString r = long_text; + EXPECT_EQ(r.size(), 300); + AString a = long_text; + EXPECT_EQ(r, a); + AString r2 = r, r3; + RString a2 = a, a3; + XString r1 = r2; + XString a1 = a2; + r3 = r1; + a3 = a1; + EXPECT_EQ(r, r1); + EXPECT_EQ(a, a1); + EXPECT_EQ(r, r2); + EXPECT_EQ(a, a2); + EXPECT_EQ(r, r3); + EXPECT_EQ(a, a3); + EXPECT_EQ(&*r.begin(), &*r1.begin()); + EXPECT_EQ(&*a.begin(), &*a1.begin()); + EXPECT_EQ(&*r.begin(), &*r2.begin()); + EXPECT_EQ(&*a.begin(), &*a2.begin()); + EXPECT_EQ(&*r.begin(), &*r3.begin()); + EXPECT_EQ(&*a.begin(), &*a3.begin()); +} diff --git a/src/strings/strings_test.cpp b/src/strings/strings_test.cpp index 82d39d8..55a2ffa 100644 --- a/src/strings/strings_test.cpp +++ b/src/strings/strings_test.cpp @@ -21,7 +21,7 @@ TYPED_TEST_P(StringTest, basic) EXPECT_EQ(0, hi0.size()); __attribute__((unused)) - const FString *base = hi.base(); + const RString *base = hi.base(); } TYPED_TEST_P(StringTest, order) @@ -168,7 +168,8 @@ TYPED_TEST_P(StringTest, convert) constexpr bool is_zstring = std::is_same::value; typedef typename std::conditional::type Sstring; typedef typename std::conditional::type Xstring; - FString f = "f"; + RString r = "r"; + AString a = "a"; TString t = "t"; Sstring s = "s"; ZString z = "z"; @@ -177,7 +178,8 @@ TYPED_TEST_P(StringTest, convert) const char l[] = "l"; VString<5> hi = "hello"; - TypeParam f2 = f; + TypeParam r2 = r; + TypeParam a2 = a; TypeParam t2 = t; TypeParam s2 = s; TypeParam z2 = z; @@ -186,7 +188,8 @@ TYPED_TEST_P(StringTest, convert) TypeParam l2 = l; TypeParam hi2 = hi; - EXPECT_EQ(f, f2); + EXPECT_EQ(r, r2); + EXPECT_EQ(a, a2); EXPECT_EQ(t, t2); EXPECT_EQ(s, s2); EXPECT_EQ(z, z2); @@ -195,8 +198,9 @@ TYPED_TEST_P(StringTest, convert) EXPECT_EQ(l, l2); EXPECT_EQ(hi, hi2); - TypeParam f3, t3, s3, z3, x3, v3, l3, hi3; - f3 = f; + TypeParam r3, a3, t3, s3, z3, x3, v3, l3, hi3; + r3 = r; + a3 = a; t3 = t; s3 = s; z3 = z; @@ -205,7 +209,8 @@ TYPED_TEST_P(StringTest, convert) l3 = l; hi3 = hi; - EXPECT_EQ(f, f3); + EXPECT_EQ(r, r3); + EXPECT_EQ(a, a3); EXPECT_EQ(t, t3); EXPECT_EQ(s, s3); EXPECT_EQ(z, z3); @@ -214,7 +219,8 @@ TYPED_TEST_P(StringTest, convert) EXPECT_EQ(l, l3); EXPECT_EQ(hi, hi3); - TypeParam f4(f); + TypeParam r4(r); + TypeParam a4(a); TypeParam t4(t); TypeParam s4(s); TypeParam z4(z); @@ -223,7 +229,8 @@ TYPED_TEST_P(StringTest, convert) TypeParam l4(l); TypeParam hi4(hi); - EXPECT_EQ(f, f4); + EXPECT_EQ(r, r4); + EXPECT_EQ(a, a4); EXPECT_EQ(t, t4); EXPECT_EQ(s, s4); EXPECT_EQ(z, z4); @@ -237,7 +244,7 @@ REGISTER_TYPED_TEST_CASE_P(StringTest, basic, order, iterators, xslice, convert); typedef ::testing::Types< - FString, TString, SString, ZString, XString, VString<255> + RString, AString, TString, SString, ZString, XString, VString<255> > MostStringTypes; INSTANTIATE_TYPED_TEST_CASE_P(StringStuff, StringTest, MostStringTypes); @@ -274,6 +281,6 @@ REGISTER_TYPED_TEST_CASE_P(NulStringTest, basic); typedef ::testing::Types< - FString, TString, ZString, VString<255> + RString, AString, TString, ZString, VString<255> > NulStringTypes; INSTANTIATE_TYPED_TEST_CASE_P(NulStringStuff, NulStringTest, NulStringTypes); diff --git a/src/strings/tstring.cpp b/src/strings/tstring.cpp index 2d13888..8be7112 100644 --- a/src/strings/tstring.cpp +++ b/src/strings/tstring.cpp @@ -27,9 +27,24 @@ namespace strings TString::TString() : _s(), _o() {} - TString::TString(FString b, size_t i) + TString::TString(RString b, size_t i) : _s(std::move(b)), _o(i) {} + static + RString get_owned_tlice(AString a, size_t *i) + { + if (a.base()) + { + return std::move(a); + } + size_t oi = *i; + *i = 0; + return a.xslice_t(oi); + } + TString::TString(AString b, size_t i) + : _s(get_owned_tlice(std::move(b), &i)) + , _o(i) + {} TString::TString(const SString& s) { *this = XString(s); @@ -40,15 +55,15 @@ namespace strings } TString::TString(const XString& x) { - const FString *f = x.base(); + const RString *r = x.base(); const char *xb = &*x.begin(); const char *xe = &*x.end(); - const char *fb = f ? &*f->begin() : nullptr; - const char *fe = f ? &*f->end() : nullptr; - if (f && xe == fe) - *this = TString(*f, xb - fb); + const char *rb = r ? &*r->begin() : nullptr; + const char *re = r ? &*r->end() : nullptr; + if (r && xe == re) + *this = TString(*r, xb - rb); else - *this = FString(x); + *this = RString(x); } TString::TString(XPair p) @@ -63,7 +78,7 @@ namespace strings { return &*_s.end(); } - const FString *TString::base() const + const RString *TString::base() const { return &_s; } diff --git a/src/strings/tstring.hpp b/src/strings/tstring.hpp index 49ec4ab..700ec3d 100644 --- a/src/strings/tstring.hpp +++ b/src/strings/tstring.hpp @@ -20,20 +20,21 @@ // along with this program. If not, see . # include "base.hpp" -# include "fstring.hpp" +# include "rstring.hpp" namespace strings { - /// An owning string that represents a tail slice of an FString. + /// An owning string that represents a tail slice of an RString. /// Guaranteed to be NUL-terminated. class TString : public _crtp_string { friend class SString; - FString _s; + RString _s; size_t _o; public: TString(); - TString(FString b, size_t i=0); + TString(RString b, size_t i=0); + TString(AString b, size_t i=0); //TString(const TString&) TString(const SString&); TString(const ZString&); @@ -50,7 +51,7 @@ namespace strings iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; const char *c_str() const; }; diff --git a/src/strings/vstring.hpp b/src/strings/vstring.hpp index c07c32a..183e782 100644 --- a/src/strings/vstring.hpp +++ b/src/strings/vstring.hpp @@ -31,7 +31,8 @@ namespace strings public: typedef typename _crtp_string, VString, ZPair>::iterator iterator; VString(XString x); - VString(FString f); + VString(RString f); + VString(AString f); VString(TString t); VString(SString s); VString(ZString z); @@ -48,7 +49,7 @@ namespace strings iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; const char *c_str() const; }; diff --git a/src/strings/vstring.tcc b/src/strings/vstring.tcc index 674b21d..69729d4 100644 --- a/src/strings/vstring.tcc +++ b/src/strings/vstring.tcc @@ -21,7 +21,8 @@ #include "../common/utils2.hpp" -#include "fstring.hpp" +#include "rstring.hpp" +#include "astring.hpp" #include "tstring.hpp" #include "sstring.hpp" #include "zstring.hpp" @@ -43,11 +44,16 @@ namespace strings // poor man's delegated constructors // needed for gcc 4.6 compatibility template - VString::VString(FString f) + VString::VString(RString f) { *this = XString(f); } template + VString::VString(AString a) + { + *this = XString(a); + } + template VString::VString(TString t) { *this = XString(t); @@ -109,7 +115,7 @@ namespace strings return std::end(_data) - _special; } template - const FString *VString::base() const + const RString *VString::base() const { return nullptr; } diff --git a/src/strings/xstring.cpp b/src/strings/xstring.cpp index 107217b..8a604c7 100644 --- a/src/strings/xstring.cpp +++ b/src/strings/xstring.cpp @@ -23,7 +23,10 @@ namespace strings XString::XString() : _b(""), _e(_b), _base() {} - XString::XString(const FString& s) + XString::XString(const RString& s) + : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) + {} + XString::XString(const AString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} XString::XString(const TString& s) @@ -36,10 +39,10 @@ namespace strings : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} - XString::XString(const char *b, const char *e, const FString *base_) + XString::XString(const char *b, const char *e, const RString *base_) : _b(b), _e(e), _base(base_) {} - XString::XString(decltype(really_construct_from_a_pointer) e, const char *s, const FString *base_) + XString::XString(decltype(really_construct_from_a_pointer) e, const char *s, const RString *base_) { *this = ZString(e, s, base_); } @@ -55,7 +58,7 @@ namespace strings { return _e; } - const FString *XString::base() const + const RString *XString::base() const { return _base; } diff --git a/src/strings/xstring.hpp b/src/strings/xstring.hpp index e96ef8a..2766810 100644 --- a/src/strings/xstring.hpp +++ b/src/strings/xstring.hpp @@ -25,17 +25,18 @@ namespace strings { /// A non-owning string that is not guaranteed to be NUL-terminated. /// This should be only used as a parameter. - class XString : public _crtp_string + class XString : public _crtp_string { iterator _b, _e; // optional - const FString *_base; + const RString *_base; public: // do I really want this? XString(); XString(std::nullptr_t) = delete; // no MString - XString(const FString& s); + XString(const RString& s); + XString(const AString& s); XString(const TString& s); XString(const SString& s); XString(const ZString& s); @@ -46,13 +47,13 @@ namespace strings template XString(const char (&s)[n]); // mostly internal - XString(const char *b, const char *e, const FString *base_); - XString(decltype(really_construct_from_a_pointer) e, const char *s, const FString *base_); + XString(const char *b, const char *e, const RString *base_); + XString(decltype(really_construct_from_a_pointer) e, const char *s, const RString *base_); XString(XPair p); iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; }; } // namespace strings diff --git a/src/strings/zstring.cpp b/src/strings/zstring.cpp index 0de836c..bfc0c96 100644 --- a/src/strings/zstring.cpp +++ b/src/strings/zstring.cpp @@ -26,16 +26,19 @@ namespace strings { *this = ZString(""); } - ZString::ZString(const FString& s) + ZString::ZString(const RString& s) + : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) + {} + ZString::ZString(const AString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} ZString::ZString(const TString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} - ZString::ZString(const char *b, const char *e, const FString *base_) + ZString::ZString(const char *b, const char *e, const RString *base_) : _b(b), _e(e), _base(base_) {} - ZString::ZString(decltype(really_construct_from_a_pointer), const char *s, const FString *base_) + ZString::ZString(decltype(really_construct_from_a_pointer), const char *s, const RString *base_) : _b(s), _e(s + strlen(s)), _base(base_) {} @@ -47,7 +50,7 @@ namespace strings { return _e; } - const FString *ZString::base() const + const RString *ZString::base() const { return _base; } diff --git a/src/strings/zstring.hpp b/src/strings/zstring.hpp index 72a227c..96aadc0 100644 --- a/src/strings/zstring.hpp +++ b/src/strings/zstring.hpp @@ -27,15 +27,16 @@ namespace strings { /// A non-owning string that is guaranteed to be NUL-terminated. /// This should be only used as a parameter. - class ZString : public _crtp_string + class ZString : public _crtp_string { iterator _b, _e; // optional - const FString *_base; + const RString *_base; public: ZString(); // no MString - ZString(const FString& s); + ZString(const RString& s); + ZString(const AString& s); ZString(const TString& s); ZString(const SString&) = delete; //ZString(ZString); @@ -43,16 +44,16 @@ namespace strings template ZString(const VString& s); // dangerous - ZString(const char *b, const char *e, const FString *base_); - ZString(decltype(really_construct_from_a_pointer), const char *s, const FString *base_); + ZString(const char *b, const char *e, const RString *base_); + ZString(decltype(really_construct_from_a_pointer), const char *s, const RString *base_); template ZString(char (&s)[n]) = delete; template - ZString(const char (&s)[n], const FString *base_=nullptr); + ZString(const char (&s)[n], const RString *base_=nullptr); iterator begin() const; iterator end() const; - const FString *base() const; + const RString *base() const; const char *c_str() const; }; diff --git a/src/strings/zstring.tcc b/src/strings/zstring.tcc index 1065b7c..fe0e9f3 100644 --- a/src/strings/zstring.tcc +++ b/src/strings/zstring.tcc @@ -29,7 +29,7 @@ namespace strings {} template - ZString::ZString(const char (&s)[n], const FString *base_) + ZString::ZString(const char (&s)[n], const RString *base_) : _b(s), _e(s + strlen(s)), _base(base_) {} } // namespace strings -- cgit v1.2.3-60-g2f50