OSDN Git Service

[Refactor] #3173 path_parse() のシグネチャを、char*の引数からpathの戻り値に変えた
authorHourier <66951241+Hourier@users.noreply.github.com>
Sun, 23 Apr 2023 03:54:03 +0000 (12:54 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Mon, 24 Apr 2023 10:33:40 +0000 (19:33 +0900)
src/main.cpp
src/util/angband-files.cpp
src/util/angband-files.h

index f64a2aa..ec48e89 100644 (file)
@@ -28,6 +28,7 @@
 #include "view/display-scores.h"
 #include "wizard/spoiler-util.h"
 #include "wizard/wizard-spoiler.h"
+#include <filesystem>
 #include <string>
 
 /*
@@ -80,19 +81,11 @@ static void quit_hook(concptr s)
  */
 static void create_user_dir(void)
 {
-    char dirpath[1024];
-    char subdirpath[1024];
+    const auto &dirpath = path_parse(PRIVATE_USER_PATH).string();
+    mkdir(dirpath.data(), 0700);
 
-    /* Get an absolute path from the filename */
-    path_parse(dirpath, 1024, PRIVATE_USER_PATH);
-
-    /* Create the ~/.angband/ directory */
-    mkdir(dirpath, 0700);
-
-    /* Build the path to the variant-specific sub-directory */
-    path_build(subdirpath, sizeof(subdirpath), dirpath, VARIANT_NAME.data());
-
-    /* Create the directory */
+    char subdirpath[1024]{};
+    path_build(subdirpath, sizeof(subdirpath), dirpath.data(), VARIANT_NAME.data());
     mkdir(subdirpath, 0700);
 }
 
index 33e06c8..d6790f4 100644 (file)
@@ -69,39 +69,34 @@ void user_name(char *buf, int id)
 
 #endif /* SET_UID */
 
+std::filesystem::path path_parse(std::string_view file)
 #ifdef SET_UID
-/*
- * Extract a "parsed" path from an initial filename
- * Normally, we simply copy the filename into the buffer
- * But leading tilde symbols must be handled in a special way
- * Replace "~user/" by the home directory of the user named "user"
- * Replace "~/" by the home directory of the current user
- */
-errr path_parse(char *buf, int max, concptr file)
 {
-    buf[0] = '\0';
-    if (!file) {
-        return -1;
-    }
-
-    if (file[0] != '~') {
-        (void)strnfmt(buf, max, "%s", file);
-        return 0;
-    }
-
-    concptr u = file + 1;
-    concptr s = angband_strstr(u, PATH_SEP);
-    char user[128];
-    if (s && (s >= u + sizeof(user))) {
-        return 1;
-    }
-
-    if (s) {
+    /*
+     * Extract a "parsed" path from an initial filename
+     * Normally, we simply copy the filename into the buffer
+     * But leading tilde symbols must be handled in a special way
+     * Replace "~user/" by the home directory of the user named "user"
+     * Replace "~/" by the home directory of the current user
+     */
+    if (file.empty() || (file[0] != '~')) {
+        return file;
+    }
+
+    auto u = file.data() + 1;
+    auto s = angband_strstr(u, PATH_SEP);
+    constexpr auto user_size = 128;
+    char user[user_size]{};
+    if ((s != nullptr) && (s >= u + user_size)) {
+        throw std::runtime_error("User name is too long!");
+    }
+
+    if (s != nullptr) {
         int i;
         for (i = 0; u < s; ++i) {
             user[i] = *u++;
         }
-        user[i] = '\0';
+
         u = user;
     }
 
@@ -110,35 +105,27 @@ errr path_parse(char *buf, int max, concptr file)
     }
 
     struct passwd *pw;
-    if (u) {
+    if (u != nullptr) {
         pw = getpwnam(u);
     } else {
         pw = getpwuid(getuid());
     }
 
-    if (!pw) {
-        return 1;
+    if (pw == nullptr) {
+        throw std::runtime_error("Failed to get User ID!");
     }
 
-    if (s) {
-        strnfmt(buf, max, "%s%s", pw->pw_dir, s);
-    } else {
-        strnfmt(buf, max, "%s", pw->pw_dir);
+    if (s == nullptr) {
+        return pw->pw_dir;
     }
 
-    return 0;
+    std::stringstream ss;
+    ss << pw->pw_dir << s;
+    return ss.str();
 }
-#else /* SET_UID */
-/*
- * Extract a "parsed" path from an initial filename
- *
- * This requires no special processing on simple machines,
- * except for verifying the size of the filename.
- */
-errr path_parse(char *buf, int max, concptr file)
+#else
 {
-    (void)strnfmt(buf, max, "%s", file);
-    return 0;
+    return file;
 }
 #endif /* SET_UID */
 
@@ -223,18 +210,18 @@ static std::string make_file_mode(const FileOpenMode mode, const bool is_binary)
     return ss.str();
 }
 
-/*
- * Hack -- replacement for "fopen()"
+/*!
+ * @brief OSごとの差異を吸収してファイルを開く
+ * @param file ファイルの相対パスまたは絶対パス
+ * @param mode ファイルを開くモード
+ * @param is_binary バイナリモードか否か (無指定の場合false:テキストモード)
+ * @return ファイルポインタ
  */
-FILE *angband_fopen(const std::filesystem::path &path, const FileOpenMode mode, const bool is_binary)
+FILE *angband_fopen(const std::filesystem::path &file, const FileOpenMode mode, const bool is_binary)
 {
-    char buf[1024];
-    if (path_parse(buf, 1024, path.string().data())) {
-        return nullptr;
-    }
-
+    const auto &path = path_parse(file.string());
     const auto &open_mode = make_file_mode(mode, is_binary);
-    return fopen(buf, open_mode.data());
+    return fopen(path.string().data(), open_mode.data());
 }
 
 /*
@@ -367,113 +354,72 @@ errr angband_fputs(FILE *fff, concptr buf, ulong n)
 #define O_BINARY 0
 #endif /* O_BINARY */
 
-/*
- * Hack -- attempt to delete a file
+/*!
+ * @brief OSごとの差異を吸収してファイルを削除する
+ * @param file ファイルの相対パスまたは絶対パス
  */
-errr fd_kill(concptr file)
+void fd_kill(std::string_view file)
 {
-    char buf[1024];
-    if (path_parse(buf, 1024, file)) {
-        return -1;
+    const auto &path = path_parse(file);
+    if (!std::filesystem::exists(path)) {
+        return;
     }
 
-    (void)remove(buf);
-    return 0;
+    std::filesystem::remove(path);
 }
 
-/*
- * Hack -- attempt to move a file
+/*!
+ * @brief OSごとの差異を吸収してファイルを移動する
+ * @param from 移動元のファイルの相対パスまたは絶対パス
+ * @param to 移動先のファイルの相対パスまたは絶対パス
  */
-errr fd_move(concptr file, concptr what)
+void fd_move(std::string_view from, std::string_view to)
 {
-    char buf[1024];
-    char aux[1024];
-    if (path_parse(buf, 1024, file)) {
-        return -1;
-    }
-    if (path_parse(aux, 1024, what)) {
-        return -1;
+    const auto &path_from = path_parse(from);
+    if (!std::filesystem::exists(path_from)) {
+        return;
     }
 
-    (void)rename(buf, aux);
-    return 0;
+    const auto &path_to = path_parse(to);
+    std::filesystem::rename(path_from, path_to);
 }
 
-/*
- * Hack -- attempt to copy a file
+/*!
+ * @brief OSごとの差異を吸収してファイルをコピーする
+ * @param from コピー元のファイルの相対パスまたは絶対パス
+ * @param to コピー先のファイルの相対パスまたは絶対パス
  */
-errr fd_copy(concptr file, concptr what)
+void fd_copy(std::string_view from, std::string_view to)
 {
-    char buf[1024];
-    char aux[1024];
-    int read_num;
-    int src_fd, dst_fd;
-
-    if (path_parse(buf, 1024, file)) {
-        return -1;
-    }
-    if (path_parse(aux, 1024, what)) {
-        return -1;
-    }
-
-    src_fd = fd_open(buf, O_RDONLY);
-    if (src_fd < 0) {
-        return -1;
-    }
-
-    dst_fd = fd_open(aux, O_WRONLY | O_TRUNC | O_CREAT);
-    if (dst_fd < 0) {
-        return -1;
-    }
-
-    while ((read_num = read(src_fd, buf, 1024)) > 0) {
-        int write_num = 0;
-        while (write_num < read_num) {
-            int ret = write(dst_fd, buf + write_num, read_num - write_num);
-            if (ret < 0) {
-                fd_close(src_fd);
-                fd_close(dst_fd);
-
-                return ret;
-            }
-
-            write_num += ret;
-        }
+    const auto &path_from = path_parse(from);
+    if (!std::filesystem::exists(path_from)) {
+        return;
     }
 
-    fd_close(src_fd);
-    fd_close(dst_fd);
-    return 0;
+    const auto &path_to = path_parse(to);
+    std::filesystem::copy(path_from, path_to);
 }
 
-/*
- * Hack -- attempt to open a file descriptor (create file)
- * This function should fail if the file already exists
- * Note that we assume that the file should be "binary"
+/*!
+ * @brief OSごとの差異を吸収してファイルを作成する
+ * @param file 作成先ファイルの相対パスまたは絶対パス
+ * @param mode ファイルのパーミッション (ex. 0644)
  */
-int fd_make(concptr file, BIT_FLAGS mode)
+int fd_make(std::string_view file, BIT_FLAGS mode)
 {
-    char buf[1024];
-    if (path_parse(buf, 1024, file)) {
-        return -1;
-    }
-
-    return open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
+    const auto &path = path_parse(file);
+    return open(path.string().data(), O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
 }
 
 /*
- * Hack -- attempt to open a file descriptor (existing file)
- *
- * Note that we assume that the file should be "binary"
+ * @brief OSごとの差異を吸収してファイルを開く
+ * @param file ファイルの相対パスまたは絶対パス
+ * @param mode ファイルのオープンモード (読み書き、Append/Trunc等)
  */
-int fd_open(concptr file, int flags)
+int fd_open(std::string_view file, int mode)
 {
-    char buf[1024];
-    if (path_parse(buf, 1024, file)) {
-        return -1;
-    }
-
-    return open(buf, flags | O_BINARY, 0);
+    const auto &path = path_parse(file);
+    return open(path.string().data(), mode | O_BINARY, 0);
 }
 
 /*
index 583df76..7f926f2 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "system/angband.h"
 #include <filesystem>
+#include <string_view>
 
 /* Force definitions -- see fd_seek() */
 #ifndef SEEK_SET
@@ -40,18 +41,18 @@ enum class FileOpenMode {
     APPEND,
 };
 
-errr path_parse(char *buf, int max, concptr file);
+std::filesystem::path path_parse(std::string_view file);
 errr path_build(char *buf, int max, concptr path, concptr file);
-FILE *angband_fopen(const std::filesystem::path &path, const FileOpenMode mode, const bool is_binary = false);
+FILE *angband_fopen(const std::filesystem::path &file, const FileOpenMode mode, const bool is_binary = false);
 FILE *angband_fopen_temp(char *buf, int max);
 errr angband_fgets(FILE *fff, char *buf, ulong n);
 errr angband_fputs(FILE *fff, concptr buf, ulong n);
 errr angband_fclose(FILE *fff);
-errr fd_kill(concptr file);
-errr fd_move(concptr file, concptr what);
-errr fd_copy(concptr file, concptr what);
-int fd_make(concptr file, BIT_FLAGS mode);
-int fd_open(concptr file, int flags);
+void fd_kill(std::string_view file);
+void fd_move(std::string_view from, std::string_view to);
+void fd_copy(std::string_view from, std::string_view to);
+int fd_make(std::string_view file, BIT_FLAGS mode);
+int fd_open(std::string_view file, int mode);
 errr fd_lock(int fd, int what);
 errr fd_seek(int fd, ulong n);
 errr fd_chop(int fd, ulong n);