OSDN Git Service

[Refactor] #3513 askfor() の引数からchar* を除去し、戻り値をoptional<string> に変えた
authorHourier <66951241+Hourier@users.noreply.github.com>
Thu, 6 Jul 2023 12:58:26 +0000 (21:58 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Sun, 9 Jul 2023 05:33:02 +0000 (14:33 +0900)
src/cmd-io/cmd-dump.cpp
src/cmd-io/cmd-macro.cpp
src/cmd-visual/cmd-draw.cpp
src/cmd-visual/cmd-visuals.cpp
src/core/asking-player.cpp
src/core/asking-player.h
src/core/show-file.cpp
src/player/process-death.cpp

index a23bd03..f894451 100644 (file)
@@ -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;
             }
index d82b9de..163cc7a 100644 (file)
@@ -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:
index 5c2d28f..581a5b3 100644 (file)
@@ -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;
index 2696f7f..fbc6b6a 100644 (file)
@@ -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;
index 240b1d7..1f9cd1b 100644 (file)
 #include <stdexcept>
 #include <string>
 
+namespace {
+std::vector<char> clear_buffer(int len, std::string_view initial_value)
+{
+    std::vector<char> 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<std::string> 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<char>(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<std::string> 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;
 }
 
 /*
index 72f1cf8..8ffacdc 100644 (file)
@@ -15,7 +15,7 @@ enum class UserCheck {
 };
 
 class PlayerType;
-bool askfor(char *buf, int len, bool numpad_cursor = true);
+std::optional<std::string> askfor(int len, std::string_view initial_value = "", bool numpad_cursor = true);
 std::optional<std::string> 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);
index ee934e3..aab7395 100644 (file)
@@ -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';
             }
 
index ad64bb7..c3babc3 100644 (file)
@@ -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();
     }
 }