OSDN Git Service

Merge branch 'develop' into macos-develop
authorEric Branlund <ebranlund@fastmail.com>
Mon, 1 May 2023 21:46:28 +0000 (15:46 -0600)
committerEric Branlund <ebranlund@fastmail.com>
Mon, 1 May 2023 21:46:28 +0000 (15:46 -0600)
1  2 
src/Makefile.am
src/main.cpp
src/main/angband-initializer.cpp
src/main/angband-initializer.h
src/system/h-config.h

diff --cc src/Makefile.am
Simple merge
diff --cc src/main.cpp
@@@ -67,53 -68,39 +67,16 @@@ static void quit_hook(concptr s
      }
  }
  
--/*
-  * Initialize and verify the file paths, and the score file.
-  *
-  * Use the ANGBAND_PATH environment var if possible, else use
-  * DEFAULT_(LIB|VAR)_PATH, and in either case, branch off
-  * appropriately.
-  *
-  * First, we'll look for the ANGBAND_PATH environment variable,
-  * and then look for the files in there.  If that doesn't work,
-  * we'll try the DEFAULT_(LIB|VAR)_PATH constants.  So be sure
-  * that one of these two things works...
-  *
-  * We must ensure that the path ends with "PATH_SEP" if needed,
-  * since the "init_file_paths()" function will simply append the
-  * relevant "sub-directory names" to the given path.
 - * Set the stack size and overlay buffer (see main-286.c")
 - */
 -#ifdef PRIVATE_USER_PATH
 -
 -/*
 - * Create an ".angband/" directory in the users home directory.
-- *
-  * Make sure that the path doesn't overflow the buffer.  We have
-  * to leave enough space for the path separator, directory, and
-  * filenames.
 - * ToDo: Add error handling.
 - * ToDo: Only create the directories when actually writing files.
-- */
- static void init_stuff(void)
 -static void create_user_dir(void)
 -{
 -    const auto &dirpath = path_parse(PRIVATE_USER_PATH).string();
 -    mkdir(dirpath.data(), 0700);
 -
 -    char subdirpath[1024]{};
 -    path_build(subdirpath, sizeof(subdirpath), dirpath, VARIANT_NAME);
 -    mkdir(subdirpath, 0700);
 -}
 -
 -#endif /* PRIVATE_USER_PATH */
 -
+ static void init_stuff()
  {
-     char libpath[1024], varpath[1024];
-     concptr tail;
-     /* Get the environment variable */
-     tail = getenv("ANGBAND_PATH");
-     /* Use the angband_path, or a default */
+     char libpath[1024]{};
+     const auto tail = getenv("ANGBAND_PATH");
      strncpy(libpath, tail ? tail : DEFAULT_LIB_PATH, 511);
-     strncpy(varpath, tail ? tail : DEFAULT_VAR_PATH, 511);
-     /* Make sure they're terminated */
-     libpath[511] = '\0';
-     varpath[511] = '\0';
-     /* Hack -- Add a path separator (only if needed) */
      if (!suffix(libpath, PATH_SEP)) {
          strcat(libpath, PATH_SEP);
      }
-     if (!suffix(varpath, PATH_SEP)) {
-         strcat(varpath, PATH_SEP);
-     }
  
-     /* Initialize */
-     init_file_paths(libpath, varpath);
 -    init_file_paths(libpath);
++    init_file_paths(libpath, libpath);
  }
  
  /*
  #include "term/term-color-types.h"
  #include "time.h"
  #include "util/angband-files.h"
 +#include "util/string-processor.h"
  #include "world/world.h"
  #ifndef WINDOWS
 -#include "util/string-processor.h"
  #include <dirent.h>
  #endif
--#ifdef PRIVATE_USER_PATH
--#include <string>
--#endif
++#include <vector>
  
  /*!
-  * Find the default paths to all of our important sub-directories.
-  * @param libpath パス保管先の文字列
+  * @brief 各データファイルを読み取るためのパスを取得する.
+  * @param libpath 各PCのインストール環境における"lib/" を表す絶対パス
 + * @param varpath Is the base path for directories that have files which
 + * are not read-only: ANGBAND_DIR_APEX, ANGBAND_DIR_BONE, ANGBAND_DIR_DATA,
-  * and ANGBAND_DIR_SAVE.  If the PRIVATE_USER_PATH preprocessor macro has not
-  * been set, it is also used as the base path for ANGBAND_DIR_USER.
-  * @details
-  * <pre>
-  * The purpose of each sub-directory is described in "io/files-util.c".
-  * The traditional behavior was to put all of the sub-directories within
-  * one directory, "lib".  To get that behavior, pass the same string for
-  * libpath and varpath.  Further customization may be done later in response
-  * to command line options (most importantly for the "info", "user", and
-  * "save" directories), but that is done after this function:  see
-  * "change_path()" in "main.c".  libpath and varpath should end in the
-  * appropriate "PATH_SEP" string.  All of the "sub-directory" paths
-  * (created below or supplied by the user) will NOT end in the "PATH_SEP"
-  * string, see the special "path_build()" function in "util/angband-files.c"
-  * for more information.
-  * Hack -- first we free all the strings, since this is known
-  * to succeed even if the strings have not been allocated yet,
-  * as long as the variables start out as "NULL".  This allows
-  * this function to be called multiple times, for example, to
-  * try several base "path" values until a good one is found.
-  * </pre>
++ * and ANGBAND_DIR_SAVE.  If the PRIVATE_USER_PATH preprocessor macro has
++ * not been set, it is also used as the base path for ANGBAND_DIR_USER.
   */
- void init_file_paths(const char *libpath, const char *varpath)
 -void init_file_paths(const std::filesystem::path &libpath)
++void init_file_paths(const std::filesystem::path &libpath, const std::filesystem::path &varpath)
  {
 -    ANGBAND_DIR_APEX = std::filesystem::path(libpath).append("apex");
 -    ANGBAND_DIR_BONE = std::filesystem::path(libpath).append("bone");
 -    ANGBAND_DIR_DATA = std::filesystem::path(libpath).append("data");
+     ANGBAND_DIR = std::filesystem::path(libpath);
 -    ANGBAND_DIR_SAVE = std::filesystem::path(libpath).append("save");
++    ANGBAND_DIR_APEX = std::filesystem::path(varpath).append("apex");
++    ANGBAND_DIR_BONE = std::filesystem::path(varpath).append("bone");
++    ANGBAND_DIR_DATA = std::filesystem::path(varpath).append("data");
+     ANGBAND_DIR_EDIT = std::filesystem::path(libpath).append("edit");
+     ANGBAND_DIR_SCRIPT = std::filesystem::path(libpath).append("script");
+     ANGBAND_DIR_FILE = std::filesystem::path(libpath).append("file");
+     ANGBAND_DIR_HELP = std::filesystem::path(libpath).append("help");
+     ANGBAND_DIR_INFO = std::filesystem::path(libpath).append("info");
+     ANGBAND_DIR_PREF = std::filesystem::path(libpath).append("pref");
++    ANGBAND_DIR_SAVE = std::filesystem::path(varpath).append("save");
+     ANGBAND_DIR_DEBUG_SAVE = std::filesystem::path(ANGBAND_DIR_SAVE).append("log");
  #ifdef PRIVATE_USER_PATH
-     const auto &base = path_parse(PRIVATE_USER_PATH);
- #endif
-     char buf[1024];
-     string_free(ANGBAND_DIR);
-     string_free(ANGBAND_DIR_APEX);
-     string_free(ANGBAND_DIR_BONE);
-     string_free(ANGBAND_DIR_DATA);
-     string_free(ANGBAND_DIR_EDIT);
-     string_free(ANGBAND_DIR_SCRIPT);
-     string_free(ANGBAND_DIR_FILE);
-     string_free(ANGBAND_DIR_HELP);
-     string_free(ANGBAND_DIR_INFO);
-     string_free(ANGBAND_DIR_SAVE);
-     string_free(ANGBAND_DIR_DEBUG_SAVE);
-     string_free(ANGBAND_DIR_USER);
-     string_free(ANGBAND_DIR_XTRA);
-     ANGBAND_DIR = string_make(libpath);
-     ANGBAND_DIR_APEX = string_make(format("%sapex", varpath).data());
-     ANGBAND_DIR_BONE = string_make(format("%sbone", varpath).data());
-     ANGBAND_DIR_DATA = string_make(format("%sdata", varpath).data());
-     ANGBAND_DIR_EDIT = string_make(format("%sedit", libpath).data());
-     ANGBAND_DIR_SCRIPT = string_make(format("%sscript", libpath).data());
-     ANGBAND_DIR_FILE = string_make(format("%sfile", libpath).data());
-     ANGBAND_DIR_HELP = string_make(format("%shelp", libpath).data());
-     ANGBAND_DIR_INFO = string_make(format("%sinfo", libpath).data());
-     ANGBAND_DIR_PREF = string_make(format("%spref", libpath).data());
-     ANGBAND_DIR_SAVE = string_make(format("%ssave", varpath).data());
-     path_build(buf, sizeof(buf), ANGBAND_DIR_SAVE, "log");
-     ANGBAND_DIR_DEBUG_SAVE = string_make(buf);
- #ifdef PRIVATE_USER_PATH
-     path_build(buf, sizeof(buf), base, VARIANT_NAME);
-     ANGBAND_DIR_USER = string_make(buf);
 -    ANGBAND_DIR_USER = std::filesystem::path(PRIVATE_USER_PATH).append(VARIANT_NAME);
++    ANGBAND_DIR_USER = path_parse(PRIVATE_USER_PATH).append(VARIANT_NAME);
  #else
-     ANGBAND_DIR_USER = string_make(format("%suser", varpath).data());
 -    ANGBAND_DIR_USER = std::filesystem::path(libpath).append("user");
++    ANGBAND_DIR_USER = std::filesystem::path(varpath).append("user");
  #endif
-     ANGBAND_DIR_XTRA = string_make(format("%sxtra", libpath).data());
+     ANGBAND_DIR_XTRA = std::filesystem::path(libpath).append("xtra");
  
      time_t now = time(nullptr);
      struct tm *t = localtime(&now);
  #endif
  }
  
- bool dir_exists(concptr path)
 +/*
 + * Helper function for create_needed_dirs().  Copied over from PosChengband.
 + */
-     if (stat(path, &buf) != 0)
++static bool dir_exists(const std::filesystem::path path)
 +{
 +    struct stat buf;
- bool dir_create(concptr path)
++    if (stat(path.native().data(), &buf) != 0)
 +      return false;
 +#ifdef WIN32
 +    else if (buf.st_mode & S_IFDIR)
 +#else
 +    else if (S_ISDIR(buf.st_mode))
 +#endif
 +      return true;
 +    else
 +      return false;
 +}
 +
 +
 +/*
 + * Helper function for create_needed_dirs().  Copied over from PosChengband
 + * but use the global definition for the path separator rather than a local
 + * one in PosChengband's code and check for paths that end with the path
 + * separator.
 + */
-     const char *ptr;
-     char buf[1024];
++static bool dir_create(const std::filesystem::path path)
 +{
 +#ifdef WIN32
 +    /* If the directory already exists then we're done */
 +    if (dir_exists(path)) return true;
 +    return false;
 +#else
-     /* If the directory already exists then we're done */
-     if (dir_exists(path)) return true;
-     /* Iterate through the path looking for path segements. At each step,
-      * create the path segment if it doesn't already exist. */
-     for (ptr = path; *ptr; ptr++)
-         {
-           if (*ptr == PATH_SEP[0])
-                 {
-                   /* Find the length of the parent path string */
-                   size_t len = (size_t)(ptr - path);
-                   /* Skip the initial slash */
-                   if (len == 0) continue;
-                   /* If this is a duplicate path separator, continue */
-                   if (*(ptr - 1) == PATH_SEP[0]) continue;
-                   /* We can't handle really big filenames */
-                   if (len - 1 > 512) return false;
-                   /* Create the parent path string, plus null-padding */
-                   angband_strcpy(buf, path, len + 1);
-                   /* Skip if the parent exists */
-                   if (dir_exists(buf)) continue;
-                   /* The parent doesn't exist, so create it or fail */
-                   if (mkdir(buf, 0755) != 0) return false;
-                 }
++    std::vector<std::filesystem::path> missing;
++    std::filesystem::path next_path = path;
 +
-     /*
-      * The path ends on a path separator so have created it already in
-      * the loop above.
-      */
-     if (*(ptr-1) == PATH_SEP[0])
-       {
-           return true;
++    while (1) {
++        if (dir_exists(next_path)) {
++            break;
 +        }
-     return mkdir(path, 0755) == 0 ? true : false;
++        missing.push_back(next_path);
++        if (!next_path.has_relative_path()) {
++              break;
 +      }
-  * the PRIVATE_USER_PATH preprocessor macro has been set. The others are
++      next_path = next_path.parent_path();
++    }
++    for (; !missing.empty(); missing.pop_back()) {
++        if (mkdir(missing.back().native().data(), 0755) != 0) {
++            return false;
++        }
++    }
++    return true;
 +#endif
 +}
 +
 +
 +/*
 + * Create any missing directories. We create only those dirs which may be
 + * empty (user/, save/, apex/, bone/, data/). Only user/ is created when
-     char dirpath[1024];
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_USER, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
++ * the PRIVATE_USER_PATH preprocessor maccro has been set. The others are
 + * assumed to contain required files and therefore must exist at startup
 + * (edit/, pref/, file/, xtra/).
 + *
 + * ToDo: Only create the directories when actually writing files.
 + * Copied over from PosChengband to support main-cocoa.m.  Dropped
 + * creation of help/ (and removed it and info/ in the comment)
 + * since init_file_paths() puts those in libpath which may not be writable
 + * by the user running the application.  Added bone/ since
 + * init_file_paths() puts that in varpath.
 + */
 +void create_needed_dirs(void)
 +{
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_SAVE, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_DEBUG_SAVE, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_APEX, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_BONE, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
-     path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_DATA, "");
-     if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
++    if (!dir_create(ANGBAND_DIR_USER)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_USER.native().data());
 +#ifndef PRIVATE_USER_PATH
++    if (!dir_create(ANGBAND_DIR_SAVE)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_SAVE.native().data());
++    if (!dir_create(ANGBAND_DIR_DEBUG_SAVE)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_DEBUG_SAVE.native().data());
++    if (!dir_create(ANGBAND_DIR_APEX)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_APEX.native().data());
++    if (!dir_create(ANGBAND_DIR_BONE)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_BONE.native().data());
++    if (!dir_create(ANGBAND_DIR_DATA)) quit_fmt("Cannot create '%s'", ANGBAND_DIR_DATA.native().data());
 +#endif /* ndef PRIVATE_USER_PATH */
 +}
 +
  /*!
   * @brief 画面左下にシステムメッセージを表示する / Take notes on line 23
   * @param str 初期化中のコンテンツ文字列
@@@ -11,7 -11,8 +11,9 @@@
   * are included in all such copies.
   */
  
+ #include <filesystem>
  class PlayerType;
  void init_angband(PlayerType *player_ptr, bool no_term);
- void init_file_paths(const char *libpath, const char *varpath);
- void create_needed_dirs(void);
 -void init_file_paths(const std::filesystem::path &libpath);
++void init_file_paths(const std::filesystem::path &libpath, const std::filesystem::path &varpath);
++void create_needed_dirs();
Simple merge