From: Hourier <66951241+Hourier@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:58:26 +0000 (+0900) Subject: [Refactor] #3513 askfor() の引数からchar* を除去し、戻り値をoptional に変えた X-Git-Tag: 3.0.0.87-Alpha~4^2~1 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8c31d0fdb6002601f23a579c13c6bad675c2861a;p=hengbandforosx%2Fhengbandosx.git [Refactor] #3513 askfor() の引数からchar* を除去し、戻り値をoptional に変えた --- diff --git a/src/cmd-io/cmd-dump.cpp b/src/cmd-io/cmd-dump.cpp index a23bd03d3..f894451e8 100644 --- a/src/cmd-io/cmd-dump.cpp +++ b/src/cmd-io/cmd-dump.cpp @@ -64,9 +64,9 @@ void do_cmd_pref(PlayerType *player_ptr) */ void do_cmd_colors(PlayerType *player_ptr) { - char tmp[160]; FILE *auto_dump_stream; screen_save(); + const auto initial_filename = format("%s.prf", player_ptr->base_name); while (true) { term_clear(); prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0); @@ -83,12 +83,12 @@ void do_cmd_colors(PlayerType *player_ptr) case '1': { prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0); prt(_("ファイル: ", "File: "), 10, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - (void)process_pref_file(player_ptr, tmp, true); + (void)process_pref_file(player_ptr, *ask_result, true); term_xtra(TERM_XTRA_REACT, 0); term_redraw(); break; @@ -97,12 +97,12 @@ void do_cmd_colors(PlayerType *player_ptr) constexpr auto mark = "Colors"; prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0); prt(_("ファイル: ", "File: "), 10, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - const auto &path = path_build(ANGBAND_DIR_USER, tmp); + const auto &path = path_build(ANGBAND_DIR_USER, *ask_result); if (!open_auto_dump(&auto_dump_stream, path, mark)) { continue; } diff --git a/src/cmd-io/cmd-macro.cpp b/src/cmd-io/cmd-macro.cpp index d82b9de60..163cc7a24 100644 --- a/src/cmd-io/cmd-macro.cpp +++ b/src/cmd-io/cmd-macro.cpp @@ -149,7 +149,6 @@ static errr keymap_dump(std::string_view filename) */ void do_cmd_macros(PlayerType *player_ptr) { - char tmp[1024]; char buf[1024]; static char macro_buf[1024]; FILE *auto_dump_stream; @@ -172,6 +171,7 @@ void do_cmd_macros(PlayerType *player_ptr) }; print_macro_menu(); + const auto initial_filename = format("%s.prf", player_ptr->base_name); while (true) { msg_print(_("コマンド: ", "Command: ")); const auto key = inkey(); @@ -185,18 +185,19 @@ void do_cmd_macros(PlayerType *player_ptr) case '1': { prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0); prt(_("ファイル: ", "File: "), 18, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - const auto err = process_pref_file(player_ptr, tmp, true); + const auto err = process_pref_file(player_ptr, *ask_result, true); + const auto *mes = ask_result->data(); if (-2 == err) { - msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp); + msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), mes); } else if (err) { - msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp); + msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), mes); } else { - msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp); + msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), mes); } break; @@ -204,12 +205,12 @@ void do_cmd_macros(PlayerType *player_ptr) case '2': { prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0); prt(_("ファイル: ", "File: "), 18, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - macro_dump(&auto_dump_stream, tmp); + macro_dump(&auto_dump_stream, *ask_result); msg_print(_("マクロを追加しました。", "Appended macros.")); break; } @@ -226,8 +227,8 @@ void do_cmd_macros(PlayerType *player_ptr) // マクロの作成時に参照するためmacro_bufにコピーする strncpy(macro_buf, macro_actions[k].data(), sizeof(macro_buf) - 1); - // too long macro must die - strncpy(tmp, macro_buf, 80); + char tmp[81]{}; + angband_strcpy(tmp, macro_buf, 80); tmp[80] = '\0'; ascii_to_text(buf, tmp, sizeof(buf)); prt(buf, 22, 0); @@ -245,12 +246,14 @@ void do_cmd_macros(PlayerType *player_ptr) prt(_("マクロ行動: ", "Action: "), 20, 0); // 最後に参照したマクロデータを元に作成する(コピーを行えるように) macro_buf[80] = '\0'; + char tmp[81]{}; ascii_to_text(tmp, macro_buf, sizeof(tmp)); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(80, tmp); + if (!ask_result) { break; } - text_to_ascii(macro_buf, tmp, sizeof(macro_buf)); + text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf)); macro_add(buf, macro_buf); msg_print(_("マクロを追加しました。", "Added a macro.")); break; @@ -265,12 +268,12 @@ void do_cmd_macros(PlayerType *player_ptr) case '6': { prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0); prt(_("ファイル: ", "File: "), 18, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(80, initial_filename); + if (!ask_result) { continue; } - (void)keymap_dump(tmp); + (void)keymap_dump(*ask_result); msg_print(_("キー配置を追加しました。", "Appended keymaps.")); break; } @@ -288,6 +291,7 @@ void do_cmd_macros(PlayerType *player_ptr) // マクロの作成時に参照するためmacro_bufにコピーする strncpy(macro_buf, act, sizeof(macro_buf) - 1); // too long macro must die + char tmp[81]{}; strncpy(tmp, macro_buf, 80); tmp[80] = '\0'; ascii_to_text(buf, tmp, sizeof(buf)); @@ -306,12 +310,14 @@ void do_cmd_macros(PlayerType *player_ptr) prt(_("行動: ", "Action: "), 20, 0); // 最後に参照したマクロデータを元に作成する(コピーを行えるように) macro_buf[80] = '\0'; + char tmp[81]{}; ascii_to_text(tmp, macro_buf, sizeof(tmp)); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(80, tmp); + if (!ask_result) { break; } - text_to_ascii(macro_buf, tmp, sizeof(macro_buf)); + text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf)); string_free(keymap_act[mode][(byte)(buf[0])]); keymap_act[mode][(byte)(buf[0])] = string_make(macro_buf); msg_print(_("キー配置を追加しました。", "Added a keymap.")); @@ -332,12 +338,12 @@ void do_cmd_macros(PlayerType *player_ptr) "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0); prt(_("マクロ行動: ", "Action: "), 20, 0); - buf[0] = '\0'; - if (!askfor(buf, 80)) { + const auto ask_result = askfor(80); + if (!ask_result) { continue; } - text_to_ascii(macro_buf, buf, sizeof(macro_buf)); + text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf)); break; } default: diff --git a/src/cmd-visual/cmd-draw.cpp b/src/cmd-visual/cmd-draw.cpp index 5c2d28f75..581a5b362 100644 --- a/src/cmd-visual/cmd-draw.cpp +++ b/src/cmd-visual/cmd-draw.cpp @@ -252,14 +252,10 @@ void do_cmd_messages(int num_now) switch (skey) { case '=': { prt(_("強調: ", "Show: "), hgt - 1, 0); - char ask[81]{}; - angband_strcpy(ask, shower_str, 80); - const auto back_str(shower_str); - if (askfor(ask, 80)) { - shower = ask; - shower_str = ask; - } else { - shower_str = back_str; + const auto ask_result = askfor(80, shower_str); + if (ask_result) { + shower = *ask_result; + shower_str = *ask_result; } continue; @@ -267,15 +263,12 @@ void do_cmd_messages(int num_now) case '/': case KTRL('s'): { prt(_("検索: ", "Find: "), hgt - 1, 0); - char ask[81]{}; - angband_strcpy(ask, finder_str, 80); - const auto back_str(finder_str); - if (!askfor(ask, 80)) { - finder_str = back_str; + const auto ask_result = askfor(80, finder_str); + if (!ask_result) { continue; } - finder_str = ask; + finder_str = *ask_result; if (finder_str.empty()) { shower = ""; continue; diff --git a/src/cmd-visual/cmd-visuals.cpp b/src/cmd-visual/cmd-visuals.cpp index 2696f7f0a..fbc6b6a95 100644 --- a/src/cmd-visual/cmd-visuals.cpp +++ b/src/cmd-visual/cmd-visuals.cpp @@ -82,7 +82,6 @@ static void print_visuals_menu(concptr choice_msg) void do_cmd_visuals(PlayerType *player_ptr) { FILE *auto_dump_stream; - char tmp[160]; bool need_redraw = false; concptr empty_symbol = "<< ? >>"; if (use_bigtile) { @@ -90,6 +89,7 @@ void do_cmd_visuals(PlayerType *player_ptr) } screen_save(); + const auto initial_filename = format("%s.prf", player_ptr->base_name); while (true) { term_clear(); print_visuals_menu(nullptr); @@ -102,24 +102,24 @@ void do_cmd_visuals(PlayerType *player_ptr) case '0': { prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0); prt(_("ファイル: ", "File: "), 17, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - (void)process_pref_file(player_ptr, tmp, true); + (void)process_pref_file(player_ptr, *ask_result, true); need_redraw = true; break; } case '1': { prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0); prt(_("ファイル: ", "File: "), 17, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - const auto &path = path_build(ANGBAND_DIR_USER, tmp); + const auto &path = path_build(ANGBAND_DIR_USER, *ask_result); constexpr auto mark = "Monster attr/chars"; if (!open_auto_dump(&auto_dump_stream, path, mark)) { continue; @@ -138,12 +138,12 @@ void do_cmd_visuals(PlayerType *player_ptr) case '2': { prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0); prt(_("ファイル: ", "File: "), 17, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - const auto &path = path_build(ANGBAND_DIR_USER, tmp); + const auto &path = path_build(ANGBAND_DIR_USER, *ask_result); constexpr auto mark = "Object attr/chars"; if (!open_auto_dump(&auto_dump_stream, path, mark)) { continue; @@ -175,12 +175,12 @@ void do_cmd_visuals(PlayerType *player_ptr) case '3': { prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0); prt(_("ファイル: ", "File: "), 17, 0); - strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name); - if (!askfor(tmp, 70)) { + const auto ask_result = askfor(70, initial_filename); + if (!ask_result) { continue; } - const auto &path = path_build(ANGBAND_DIR_USER, tmp); + const auto &path = path_build(ANGBAND_DIR_USER, *ask_result); constexpr auto mark = "Feature attr/chars"; if (!open_auto_dump(&auto_dump_stream, path, mark)) { continue; diff --git a/src/core/asking-player.cpp b/src/core/asking-player.cpp index 240b1d741..1f9cd1b8e 100644 --- a/src/core/asking-player.cpp +++ b/src/core/asking-player.cpp @@ -24,6 +24,15 @@ #include #include +namespace { +std::vector clear_buffer(int len, std::string_view initial_value) +{ + std::vector buf(len + 1, '\0'); + initial_value.copy(buf.data(), len); + return buf; +} +} + /* * Get some string input at the cursor location. * Assume the buffer is initialized to a default string. @@ -41,7 +50,7 @@ * ESCAPE clears the buffer and the window and returns FALSE. * RETURN accepts the current buffer contents and returns TRUE. */ -bool askfor(char *buf, int len, bool numpad_cursor) +std::optional askfor(int len, std::string_view initial_value, bool numpad_cursor) { /* * Text color @@ -64,11 +73,11 @@ bool askfor(char *buf, int len, bool numpad_cursor) len = MAIN_TERM_MIN_COLS - x; } - buf[len] = '\0'; + auto buf = clear_buffer(len, initial_value); auto pos = 0; while (true) { term_erase(x, y, len); - term_putstr(x, y, -1, color, buf); + term_putstr(x, y, -1, color, buf.data()); term_gotoxy(x + pos, y); const auto skey = inkey_special(numpad_cursor); switch (skey) { @@ -122,14 +131,13 @@ bool askfor(char *buf, int len, bool numpad_cursor) case SKEY_BOTTOM: case KTRL('e'): color = TERM_WHITE; - pos = std::string_view(buf).length(); + pos = std::string_view(buf.data()).length(); break; case ESCAPE: - buf[0] = '\0'; - return false; + return std::nullopt; case '\n': case '\r': - return true; + return buf.data(); case '\010': { auto i = 0; color = TERM_WHITE; @@ -175,18 +183,17 @@ bool askfor(char *buf, int len, bool numpad_cursor) break; } default: { - char tmp[100]; if (skey & SKEY_MASK) { break; } const auto c = static_cast(skey); if (color == TERM_YELLOW) { - buf[0] = '\0'; + buf = clear_buffer(len, ""); color = TERM_WHITE; } - strcpy(tmp, buf + pos); + const auto str_right_cursor = std::string(buf.data()).substr(pos); #ifdef JP if (iskanji(c)) { inkey_base = true; @@ -209,7 +216,7 @@ bool askfor(char *buf, int len, bool numpad_cursor) } buf[pos] = '\0'; - angband_strcat(buf, tmp, len + 1); + angband_strcat(buf.data(), str_right_cursor, buf.size()); break; } } @@ -230,15 +237,9 @@ std::optional input_string(std::string_view prompt, int len, std::s { msg_print(nullptr); prt(prompt, 0, 0); - char buf[1024]{}; - angband_strcpy(buf, initial_value, sizeof(buf)); - const auto res = askfor(buf, len, numpad_cursor); + const auto ask_result = askfor(len, initial_value, numpad_cursor); prt("", 0, 0); - if (!res) { - return std::nullopt; - } - - return buf; + return ask_result; } /* diff --git a/src/core/asking-player.h b/src/core/asking-player.h index 72f1cf820..8ffacdca4 100644 --- a/src/core/asking-player.h +++ b/src/core/asking-player.h @@ -15,7 +15,7 @@ enum class UserCheck { }; class PlayerType; -bool askfor(char *buf, int len, bool numpad_cursor = true); +std::optional askfor(int len, std::string_view initial_value = "", bool numpad_cursor = true); std::optional input_string(std::string_view prompt, int len, std::string_view initial_value = "", bool numpad_cursor = true); bool input_check(std::string_view prompt); bool input_check_strict(PlayerType *player_ptr, std::string_view prompt, UserCheck one_mode); diff --git a/src/core/show-file.cpp b/src/core/show-file.cpp index ee934e305..aab739532 100644 --- a/src/core/show-file.cpp +++ b/src/core/show-file.cpp @@ -142,8 +142,6 @@ bool show_file(PlayerType *player_ptr, bool show_version, std::string_view name_ int wid, hgt; term_get_size(&wid, &hgt); - char finder_str[81] = ""; - char shower_str[81] = ""; char hook[68][32]{}; auto stripped_names = str_split(name_with_tag, '#'); auto &name = stripped_names[0]; @@ -236,7 +234,9 @@ bool show_file(PlayerType *player_ptr, bool show_version, std::string_view name_ term_clear(); std::string find; + std::string finder_str; std::string shower; + std::string shower_str; while (true) { if (line >= size - rows) { line = size - rows; @@ -336,33 +336,31 @@ bool show_file(PlayerType *player_ptr, bool show_version, std::string_view name_ break; case '=': { prt(_("強調: ", "Show: "), hgt - 1, 0); - char back_str[81]; - strcpy(back_str, shower_str); - if (!askfor(shower_str, 80)) { - strcpy(shower_str, back_str); + auto ask_result = askfor(80, shower_str); + if (!ask_result) { break; } - if (!shower_str[0]) { + shower_str = *ask_result; + if (shower_str.empty()) { shower.clear(); break; } - str_tolower(shower_str); + str_tolower(shower_str.data()); shower = shower_str; break; } case '/': case KTRL('s'): { prt(_("検索: ", "Find: "), hgt - 1, 0); - char back_str[81]; - strcpy(back_str, finder_str); - if (!askfor(finder_str, 80)) { - strcpy(finder_str, back_str); + auto ask_result = askfor(80, finder_str); + if (!ask_result) { break; } - if (!finder_str[0]) { + finder_str = *ask_result; + if (finder_str.empty()) { shower.clear(); break; } @@ -370,29 +368,26 @@ bool show_file(PlayerType *player_ptr, bool show_version, std::string_view name_ find = finder_str; back = line; line = line + 1; - str_tolower(finder_str); + str_tolower(finder_str.data()); shower = finder_str; break; } case '#': { - char tmp[81]; prt(_("行: ", "Goto Line: "), hgt - 1, 0); constexpr auto initial_goto = "0"; while (true) { - strcpy(tmp, initial_goto); - if (!askfor(tmp, 10)) { + const auto ask_result = askfor(10, initial_goto); + if (!ask_result) { break; } try { - line = std::stoi(tmp); + line = std::stoi(*ask_result); break; } catch (std::invalid_argument const &) { prt(_("数値を入力して下さい。", "Please input numeric value."), hgt - 1, 0); - continue; } catch (std::out_of_range const &) { prt(_("入力可能な数値の範囲を超えています。", "Input value overflows the maximum number."), hgt - 1, 0); - continue; } } @@ -406,13 +401,12 @@ bool show_file(PlayerType *player_ptr, bool show_version, std::string_view name_ break; case '%': { prt(_("ファイル・ネーム: ", "Goto File: "), hgt - 1, 0); - char tmp[81]; - strcpy(tmp, _("jhelp.hlp", "help.hlp")); - if (!askfor(tmp, 80)) { + const auto ask_result = askfor(80, _("jhelp.hlp", "help.hlp")); + if (!ask_result) { break; } - if (!show_file(player_ptr, true, tmp, 0, mode)) { + if (!show_file(player_ptr, true, *ask_result, 0, mode)) { skey = 'q'; } diff --git a/src/player/process-death.cpp b/src/player/process-death.cpp index ad64bb7f9..c3babc388 100644 --- a/src/player/process-death.cpp +++ b/src/player/process-death.cpp @@ -335,17 +335,14 @@ static void export_player_info(PlayerType *player_ptr) prt(_("キャラクターの記録をファイルに書き出すことができます。", "You may now dump a character record to one or more files."), 21, 0); prt(_("リターンキーでキャラクターを見ます。ESCで中断します。", "Then, hit RETURN to see the character, or ESC to abort."), 22, 0); while (true) { - char out_val[160] = ""; put_str(_("ファイルネーム: ", "Filename: "), 23, 0); - if (!askfor(out_val, 60)) { + const auto ask_result = askfor(60); + if (!ask_result || ask_result->empty()) { return; } - if (!out_val[0]) { - break; - } screen_save(); - file_character(player_ptr, out_val); + file_character(player_ptr, *ask_result); screen_load(); } }