From: Hourier <66951241+Hourier@users.noreply.github.com> Date: Sun, 23 Apr 2023 03:54:03 +0000 (+0900) Subject: [Refactor] #3173 path_parse() のシグネチャを、char*の引数からpathの戻り値に変えた X-Git-Tag: 3.0.0Alpha79^2~15^2~3 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=cbc26cd654db6320e7eaf9e3fed39e9fc63376e6;p=hengbandforosx%2Fhengbandosx.git [Refactor] #3173 path_parse() のシグネチャを、char*の引数からpathの戻り値に変えた --- diff --git a/src/main.cpp b/src/main.cpp index f64a2aa5f..ec48e89e4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ #include "view/display-scores.h" #include "wizard/spoiler-util.h" #include "wizard/wizard-spoiler.h" +#include #include /* @@ -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); } diff --git a/src/util/angband-files.cpp b/src/util/angband-files.cpp index 33e06c885..d6790f4ec 100644 --- a/src/util/angband-files.cpp +++ b/src/util/angband-files.cpp @@ -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); } /* diff --git a/src/util/angband-files.h b/src/util/angband-files.h index 583df7692..7f926f246 100644 --- a/src/util/angband-files.h +++ b/src/util/angband-files.h @@ -2,6 +2,7 @@ #include "system/angband.h" #include +#include /* 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);