OSDN Git Service

[Refactor] 自動拾いのエディタのヤンクバッファ処理
authorHabu <habu1010+github@gmail.com>
Tue, 13 Jun 2023 12:55:01 +0000 (21:55 +0900)
committerHabu <habu1010+github@gmail.com>
Tue, 13 Jun 2023 13:04:23 +0000 (22:04 +0900)
独自実装のリンクリストをstd::vector<std::string>に置き換えることで、
mallocを使用しないようにする。

src/autopick/autopick-editor-command.cpp
src/autopick/autopick-editor-util.cpp
src/autopick/autopick-util.h
src/cmd-io/cmd-autopick.cpp

index aa2991e..4a6d980 100644 (file)
@@ -26,6 +26,8 @@
 #include "system/player-type-definition.h"
 #include "term/term-color-types.h"
 #include "term/z-form.h"
+#include <string>
+#include <string_view>
 
 /*!
  * @brief
@@ -258,9 +260,8 @@ ape_quittance do_editor_command(PlayerType *player_ptr, text_body_type *tb, int
         break;
     }
     case EC_PASTE: {
-        chain_str_type *chain = tb->yank;
         int len = strlen(tb->lines_list[tb->cy]);
-        if (!chain) {
+        if (tb->yank.empty()) {
             break;
         }
         if (tb->cx > len) {
@@ -272,42 +273,30 @@ ape_quittance do_editor_command(PlayerType *player_ptr, text_body_type *tb, int
             tb->dirty_flags |= DIRTY_ALL;
         }
 
-        while (chain) {
-            concptr yank_str = chain->s;
-            char buf[MAX_LINELEN];
-            int i;
-            char rest[MAX_LINELEN], *rest_ptr = rest;
-            for (i = 0; i < tb->cx; i++) {
-                buf[i] = tb->lines_list[tb->cy][i];
-            }
+        for (auto i = 0U; i < tb->yank.size(); ++i) {
+            const std::string_view line(tb->lines_list[tb->cy]);
+            std::string buf(line.substr(0, tb->cx));
+            buf.append(tb->yank[i], 0, MAX_LINELEN - buf.length() - 1);
 
-            strcpy(rest, &(tb->lines_list[tb->cy][i]));
-            while (*yank_str && i < MAX_LINELEN - 1) {
-                buf[i++] = *yank_str++;
-            }
-
-            buf[i] = '\0';
-            chain = chain->next;
-            if (chain || tb->yank_eol) {
+            const auto is_last_line = i + 1 == tb->yank.size();
+            if (!is_last_line || tb->yank_eol) {
                 if (!insert_return_code(tb)) {
                     break;
                 }
                 string_free(tb->lines_list[tb->cy]);
-                tb->lines_list[tb->cy] = string_make(buf);
+                tb->lines_list[tb->cy] = string_make(buf.data());
                 tb->cx = 0;
                 tb->cy++;
 
                 continue;
             }
 
-            tb->cx = strlen(buf);
-            while (*rest_ptr && i < MAX_LINELEN - 1) {
-                buf[i++] = *rest_ptr++;
-            }
+            const auto rest = line.substr(tb->cx);
+            tb->cx = buf.length();
+            buf.append(rest, 0, MAX_LINELEN - buf.length() - 1);
 
-            buf[i] = '\0';
             string_free(tb->lines_list[tb->cy]);
-            tb->lines_list[tb->cy] = string_make(buf);
+            tb->lines_list[tb->cy] = string_make(buf.data());
             break;
         }
 
@@ -357,7 +346,6 @@ ape_quittance do_editor_command(PlayerType *player_ptr, text_body_type *tb, int
 
         if (tb->old_com_id != com_id) {
             kill_yank_chain(tb);
-            tb->yank = nullptr;
         }
 
         if (tb->cx < len) {
index 072d1a1..4afd258 100644 (file)
@@ -218,54 +218,16 @@ bool add_empty_line(text_body_type *tb)
     return true;
 }
 
-static chain_str_type *new_chain_str(concptr str)
-{
-    size_t len = strlen(str);
-    auto *chain = static_cast<chain_str_type *>(std::malloc(sizeof(chain_str_type) + len * sizeof(char)));
-    if (chain == nullptr) {
-        return nullptr;
-    }
-
-    strcpy(chain->s, str);
-    chain->next = nullptr;
-    return chain;
-}
-
 void kill_yank_chain(text_body_type *tb)
 {
-    chain_str_type *chain = tb->yank;
-    tb->yank = nullptr;
+    tb->yank.clear();
     tb->yank_eol = true;
-
-    while (chain) {
-        chain_str_type *next = chain->next;
-
-        std::free(chain);
-
-        chain = next;
-    }
 }
 
 void add_str_to_yank(text_body_type *tb, concptr str)
 {
     tb->yank_eol = false;
-    if (tb->yank == nullptr) {
-        tb->yank = new_chain_str(str);
-        return;
-    }
-
-    chain_str_type *chain;
-    chain = tb->yank;
-
-    while (true) {
-        if (!chain->next) {
-            chain->next = new_chain_str(str);
-            return;
-        }
-
-        /* Go to next */
-        chain = chain->next;
-    }
+    tb->yank.emplace_back(str);
 }
 
 /*!
index 887343e..dd27a85 100644 (file)
@@ -37,14 +37,6 @@ struct autopick_type {
 };
 
 /*
- * Struct for yank buffer
- */
-struct chain_str_type {
-    struct chain_str_type *next = nullptr;
-    char s[1]{};
-};
-
-/*
  * Data struct for text editor
  */
 class ItemEntity;
@@ -68,7 +60,7 @@ struct text_body_type {
     concptr search_str = "";
     concptr last_destroyed = "";
 
-    chain_str_type *yank = nullptr;
+    std::vector<std::string> yank{};
     bool yank_eol = false;
 
     std::vector<concptr> lines_list{};
index f1e9c9a..3cfdfeb 100644 (file)
@@ -118,7 +118,7 @@ void do_cmd_edit_autopick(PlayerType *player_ptr)
     tb->old_wid = tb->old_hgt = -1;
     tb->old_com_id = 0;
 
-    tb->yank = nullptr;
+    tb->yank.clear();
     tb->search_o_ptr = nullptr;
     tb->search_str = nullptr;
     tb->last_destroyed = nullptr;