From 169d72505f0c5c2152bb0f42fd59fcd1eee12279 Mon Sep 17 00:00:00 2001 From: Hourier Date: Thu, 20 Aug 2020 20:53:16 +0900 Subject: [PATCH] [Refactor] #40635 Moved init_*_info() from init.c to info-initializer.c/h --- Hengband/Hengband/Hengband.vcxproj | 2 + Hengband/Hengband/Hengband.vcxproj.filters | 6 + src/Makefile.am | 1 + src/info-reader/feature-reader.c | 3 +- src/info-reader/feature-reader.h | 2 - src/main/angband-headers.c | 12 + src/main/angband-headers.h | 14 ++ src/main/info-initializer.c | 359 +++++++++++++++++++++++++++++ src/main/info-initializer.h | 9 + src/main/init.c | 347 +--------------------------- 10 files changed, 405 insertions(+), 350 deletions(-) create mode 100644 src/main/angband-headers.c create mode 100644 src/main/angband-headers.h diff --git a/Hengband/Hengband/Hengband.vcxproj b/Hengband/Hengband/Hengband.vcxproj index e46ff4836..f9df85095 100644 --- a/Hengband/Hengband/Hengband.vcxproj +++ b/Hengband/Hengband/Hengband.vcxproj @@ -283,6 +283,7 @@ + @@ -913,6 +914,7 @@ + diff --git a/Hengband/Hengband/Hengband.vcxproj.filters b/Hengband/Hengband/Hengband.vcxproj.filters index 201d48652..145969c1f 100644 --- a/Hengband/Hengband/Hengband.vcxproj.filters +++ b/Hengband/Hengband/Hengband.vcxproj.filters @@ -2114,6 +2114,9 @@ main + + main + @@ -4579,6 +4582,9 @@ main + + main + diff --git a/src/Makefile.am b/src/Makefile.am index 5e62248ce..825e053be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -379,6 +379,7 @@ hengband_SOURCES = \ \ main.c main-x11.c main-gcu.c \ \ + main/angband-headers.c main/angband-headers.h \ main/info-initializer.c main/info-initializer.h \ main/init.c main/init.h \ main/music-definitions-table.c main/music-definitions-table.h \ diff --git a/src/info-reader/feature-reader.c b/src/info-reader/feature-reader.c index 9762120c3..b746d5bfb 100644 --- a/src/info-reader/feature-reader.c +++ b/src/info-reader/feature-reader.c @@ -5,14 +5,13 @@ #include "grid/trap.h" #include "info-reader/feature-info-tokens-table.h" #include "info-reader/parse-error-types.h" +#include "main/angband-headers.h" #include "room/door-definition.h" #include "term/gameterm.h" #include "util/bit-flags-calculator.h" #include "util/string-processor.h" #include "view/display-messages.h" -angband_header f_head; /*!< 地形情報のヘッダ構造体 */ - /*! 地形タグ情報から地形IDを得られなかった場合にTRUEを返す */ static bool feat_tag_is_not_found = FALSE; diff --git a/src/info-reader/feature-reader.h b/src/info-reader/feature-reader.h index 02ac33058..b79952e8a 100644 --- a/src/info-reader/feature-reader.h +++ b/src/info-reader/feature-reader.h @@ -3,8 +3,6 @@ #include "system/angband.h" #include "info-reader/info-reader-util.h" -extern angband_header f_head; - errr parse_f_info(char *buf, angband_header *head); errr init_feat_variables(void); s16b f_tag_to_index(concptr str); diff --git a/src/main/angband-headers.c b/src/main/angband-headers.c new file mode 100644 index 000000000..a671048ba --- /dev/null +++ b/src/main/angband-headers.c @@ -0,0 +1,12 @@ +#include "main/angband-headers.h" +#include "info-reader/info-reader-util.h" + +angband_header f_head; /*!< ’nŒ`î•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header v_head; /*!< Vaultî•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header k_head; /*!< ƒy[ƒXƒAƒCƒeƒ€î•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header a_head; /*!< ŒÅ’èƒA[ƒeƒBƒtƒ@ƒNƒgî•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header e_head; /*!< ƒAƒCƒeƒ€ƒGƒSî•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header r_head; /*!< ƒ‚ƒ“ƒXƒ^[Ží‘°î•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header d_head; /*!< ƒ_ƒ“ƒWƒ‡ƒ“î•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header s_head; /*!< ƒvƒŒƒCƒ„[E‹Æ‹Z”\î•ñ‚̃wƒbƒ_\‘¢‘Ì */ +angband_header m_head; /*!< ƒvƒŒƒCƒ„[E‹Æ–‚–@î•ñ‚̃wƒbƒ_\‘¢‘Ì */ diff --git a/src/main/angband-headers.h b/src/main/angband-headers.h new file mode 100644 index 000000000..569b381d0 --- /dev/null +++ b/src/main/angband-headers.h @@ -0,0 +1,14 @@ +#pragma once + +#include "system/angband.h" + +typedef struct angband_header angband_header; +extern angband_header f_head; +extern angband_header v_head; +extern angband_header k_head; +extern angband_header a_head; +extern angband_header e_head; +extern angband_header r_head; +extern angband_header d_head; +extern angband_header s_head; +extern angband_header m_head; diff --git a/src/main/info-initializer.c b/src/main/info-initializer.c index c38de1ddd..deda5c02e 100644 --- a/src/main/info-initializer.c +++ b/src/main/info-initializer.c @@ -1,5 +1,35 @@ #include "main/info-initializer.h" +#include "dungeon/dungeon.h" +#include "grid/feature.h" +#include "info-reader/artifact-reader.h" +#include "info-reader/dungeon-reader.h" +#include "info-reader/ego-reader.h" +#include "info-reader/feature-reader.h" #include "info-reader/fixed-map-parser.h" +#include "info-reader/general-parser.h" +#include "info-reader/kind-reader.h" +#include "info-reader/magic-reader.h" +#include "info-reader/race-reader.h" +#include "info-reader/skill-reader.h" +#include "info-reader/vault-reader.h" +#include "io/files-util.h" +#include "io/uid-checker.h" +#include "main/angband-headers.h" +#include "monster-race/monster-race.h" +#include "object-enchant/object-ego.h" +#include "object/object-kind.h" +#include "player/player-class.h" +#include "player/player-skill.h" +#include "room/rooms-vault.h" +#include "system/angband-version.h" +#include "system/artifact-type-definition.h" +#include "util/angband-files.h" +#include "view/display-messages.h" +#include "world/world.h" +#include +#ifndef WINDOWS +#include // Windows ‚Å‚ÍŽg‚í‚ê‚Ä‚¢‚È‚¢. +#endif /*! * @brief Šî–{î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / @@ -8,3 +38,332 @@ * @return ƒGƒ‰[ƒR[ƒh */ errr init_misc(player_type *player_ptr) { return parse_fixed_map(player_ptr, "misc.txt", 0, 0, 0, 0); } + +/*! + * @brief rawƒtƒ@ƒCƒ‹‚©‚ç‚̃f[ƒ^‚Ì“Ç‚ÝŽæ‚菈— + * Initialize the "*_info" array, by parsing a binary "image" file + * @param fd ƒtƒ@ƒCƒ‹ƒfƒBƒXƒNƒŠƒvƒ^ + * @param head rawƒtƒ@ƒCƒ‹‚̃wƒbƒ_ + * @return ƒGƒ‰[ƒR[ƒh + */ +static errr init_info_raw(int fd, angband_header *head) +{ + angband_header test; + if (fd_read(fd, (char *)(&test), sizeof(angband_header)) || (test.v_major != head->v_major) || (test.v_minor != head->v_minor) + || (test.v_patch != head->v_patch) || (test.info_num != head->info_num) || (test.info_len != head->info_len) || (test.head_size != head->head_size) + || (test.info_size != head->info_size)) { + return -1; + } + + *head = test; + C_MAKE(head->info_ptr, head->info_size, char); + fd_read(fd, head->info_ptr, head->info_size); + if (head->name_size) { + C_MAKE(head->name_ptr, head->name_size, char); + fd_read(fd, head->name_ptr, head->name_size); + } + + if (head->text_size) { + C_MAKE(head->text_ptr, head->text_size, char); + fd_read(fd, head->text_ptr, head->text_size); + } + + if (head->tag_size) { + C_MAKE(head->tag_ptr, head->tag_size, char); + fd_read(fd, head->tag_ptr, head->tag_size); + } + + return 0; +} + +static void update_header(angband_header *head, void **info, char **name, char **text, char **tag) +{ + if (info) + *info = head->info_ptr; + + if (name) + *name = head->name_ptr; + + if (text) + *text = head->text_ptr; + + if (tag) + *tag = head->tag_ptr; +} + +/*! + * @brief ƒwƒbƒ_\‘¢‘̂̍XV + * Initialize the header of an *_info.raw file. + * @param head rawƒtƒ@ƒCƒ‹‚̃wƒbƒ_ + * @param num ƒf[ƒ^” + * @param len ƒf[ƒ^‚Ì’·‚³ + * @return ƒGƒ‰[ƒR[ƒh + */ +static void init_header(angband_header *head, IDX num, int len) +{ + head->v_major = FAKE_VER_MAJOR; + head->v_minor = FAKE_VER_MINOR; + head->v_patch = FAKE_VER_PATCH; + head->v_extra = 0; + + head->info_num = (IDX)num; + head->info_len = len; + + head->head_size = sizeof(angband_header); + head->info_size = head->info_num * head->info_len; +} + +/*! + * @brief ƒeƒLƒXƒgƒtƒ@ƒCƒ‹‚Ærawƒtƒ@ƒCƒ‹‚̍XVŽž‚ð”äŠr‚·‚é + * Find the default paths to all of our important sub-directories. + * @param fd ƒtƒ@ƒCƒ‹ƒfƒBƒXƒNƒŠƒvƒ^ + * @param template_file ƒtƒ@ƒCƒ‹–¼ + * @return ƒeƒLƒXƒg‚Ì•û‚ªV‚µ‚¢‚©Arawƒtƒ@ƒCƒ‹‚ª‚È‚­XV‚Ì•K—v‚ª‚ ‚éê‡-1AXV‚Ì•K—v‚ª‚È‚¢ê‡0B + */ +static errr check_modification_date(int fd, concptr template_file) +{ + struct stat txt_stat, raw_stat; + char buf[1024]; + path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file); + if (stat(buf, &txt_stat)) + return 0; + + if (fstat(fd, &raw_stat)) + return -1; + + if (txt_stat.st_mtime > raw_stat.st_mtime) + return -1; + + return 0; +} + +/*! + * @brief ƒwƒbƒ_\‘¢‘̂̍XV + * Initialize the "*_info" array + * @param filename ƒtƒ@ƒCƒ‹–¼(Šg’£Žqtxt/raw) + * @param head ˆ—‚É—p‚¢‚éƒwƒbƒ_\‘¢‘Ì + * @param info ƒf[ƒ^•ÛŠÇæ‚̍\‘¢‘̃|ƒCƒ“ƒ^ + * @param name –¼Ì—p‰Â•Ï•¶Žš—ñ‚̕ۊǐæ + * @param text ƒeƒLƒXƒg—p‰Â•Ï•¶Žš—ñ‚̕ۊǐæ + * @param tag ƒ^ƒO—p‰Â•Ï•¶Žš—ñ‚̕ۊǐæ + * @return ƒGƒ‰[ƒR[ƒh + * @note + * Note that we let each entry have a unique "name" and "text" string, + * even if the string happens to be empty (everyone has a unique '\0'). + */ +static errr init_info(player_type *player_ptr, concptr filename, angband_header *head, void **info, char **name, char **text, char **tag) +{ + char buf[1024]; + path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); + int fd = fd_open(buf, O_RDONLY); + errr err = 1; + if (fd >= 0) { + err = check_modification_date(fd, format("%s.txt", filename)); + if (!err) + err = init_info_raw(fd, head); + + (void)fd_close(fd); + } + + BIT_FLAGS file_permission = 0644; + if (err == 0) { + update_header(head, info, name, text, tag); + return 0; + } + + C_MAKE(head->info_ptr, head->info_size, char); + if (name) + C_MAKE(head->name_ptr, FAKE_NAME_SIZE, char); + + if (text) + C_MAKE(head->text_ptr, FAKE_TEXT_SIZE, char); + + if (tag) + C_MAKE(head->tag_ptr, FAKE_TAG_SIZE, char); + + if (info) + *info = head->info_ptr; + + if (name) + *name = head->name_ptr; + + if (text) + *text = head->text_ptr; + + if (tag) + *tag = head->tag_ptr; + + path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename)); + FILE *fp; + fp = angband_fopen(buf, "r"); + if (!fp) + quit(format(_("'%s.txt'ƒtƒ@ƒCƒ‹‚ðƒI[ƒvƒ“‚Å‚«‚Ü‚¹‚ñB", "Cannot open '%s.txt' file."), filename)); + + err = init_info_txt(fp, buf, head, head->parse_info_txt); + angband_fclose(fp); + if (err) { + concptr oops; + oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : _("–¢’m‚Ì", "unknown")); +#ifdef JP + msg_format("'%s.txt'ƒtƒ@ƒCƒ‹‚Ì %d s–ڂɃGƒ‰[B", filename, error_line); +#else + msg_format("Error %d at line %d of '%s.txt'.", err, error_line, filename); +#endif + msg_format(_("ƒŒƒR[ƒh %d ‚Í '%s' ƒGƒ‰[‚ª‚ ‚è‚Ü‚·B", "Record %d contains a '%s' error."), error_idx, oops); + msg_format(_("\•¶ '%s'B", "Parsing '%s'."), buf); + msg_print(NULL); + quit(format(_("'%s.txt'ƒtƒ@ƒCƒ‹‚ɃGƒ‰[", "Error in '%s.txt' file."), filename)); + } + + if (head->retouch) + (*head->retouch)(head); + + path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); + safe_setuid_grab(player_ptr); + (void)fd_kill(buf); + fd = fd_make(buf, file_permission); + safe_setuid_drop(); + if (fd >= 0) { + fd_write(fd, (concptr)(head), head->head_size); + fd_write(fd, head->info_ptr, head->info_size); + fd_write(fd, head->name_ptr, head->name_size); + fd_write(fd, head->text_ptr, head->text_size); + fd_write(fd, head->tag_ptr, head->tag_size); + (void)fd_close(fd); + } + + C_KILL(head->info_ptr, head->info_size, char); + if (name) + C_KILL(head->name_ptr, FAKE_NAME_SIZE, char); + + if (text) + C_KILL(head->text_ptr, FAKE_TEXT_SIZE, char); + + if (tag) + C_KILL(head->tag_ptr, FAKE_TAG_SIZE, char); + + path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); + fd = fd_open(buf, O_RDONLY); + if (fd < 0) + quit(format(_("'%s_j.raw'ƒtƒ@ƒCƒ‹‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñB", "Cannot load '%s.raw' file."), filename)); + + err = init_info_raw(fd, head); + (void)fd_close(fd); + if (err) + quit(format(_("'%s_j.raw'ƒtƒ@ƒCƒ‹‚ð‰ðÍ‚Å‚«‚Ü‚¹‚ñB", "Cannot parse '%s.raw' file."), filename)); + + update_header(head, info, name, text, tag); + return 0; +} + +/*! + * @brief ’nŒ`î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "f_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_f_info(player_type *player_ptr) +{ + init_header(&f_head, max_f_idx, sizeof(feature_type)); + f_head.parse_info_txt = parse_f_info; + f_head.retouch = retouch_f_info; + return init_info(player_ptr, "f_info", &f_head, (void *)&f_info, &f_name, NULL, &f_tag); +} + +/*! + * @brief ƒx[ƒXƒAƒCƒeƒ€î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "k_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_k_info(player_type *player_ptr) +{ + init_header(&k_head, max_k_idx, sizeof(object_kind)); + k_head.parse_info_txt = parse_k_info; + return init_info(player_ptr, "k_info", &k_head, (void *)&k_info, &k_name, &k_text, NULL); +} + +/*! + * @brief ŒÅ’èƒA[ƒeƒBƒtƒ@ƒNƒgî•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "a_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_a_info(player_type *player_ptr) +{ + init_header(&a_head, max_a_idx, sizeof(artifact_type)); + a_head.parse_info_txt = parse_a_info; + return init_info(player_ptr, "a_info", &a_head, (void *)&a_info, &a_name, &a_text, NULL); +} + +/*! + * @brief ŒÅ’èƒA[ƒeƒBƒtƒ@ƒNƒgî•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "e_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_e_info(player_type *player_ptr) +{ + init_header(&e_head, max_e_idx, sizeof(ego_item_type)); + e_head.parse_info_txt = parse_e_info; + return init_info(player_ptr, "e_info", &e_head, (void *)&e_info, &e_name, &e_text, NULL); +} + +/*! + * @brief ƒ‚ƒ“ƒXƒ^[Ží‘°î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "r_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_r_info(player_type *player_ptr) +{ + init_header(&r_head, max_r_idx, sizeof(monster_race)); + r_head.parse_info_txt = parse_r_info; + return init_info(player_ptr, "r_info", &r_head, (void *)&r_info, &r_name, &r_text, NULL); +} + +/*! + * @brief ƒ_ƒ“ƒWƒ‡ƒ“î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "d_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_d_info(player_type *player_ptr) +{ + init_header(&d_head, current_world_ptr->max_d_idx, sizeof(dungeon_type)); + d_head.parse_info_txt = parse_d_info; + return init_info(player_ptr, "d_info", &d_head, (void *)&d_info, &d_name, &d_text, NULL); +} + +/*! + * @brief Vaultî•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "v_info" array + * @return ƒGƒ‰[ƒR[ƒh + * @note + * Note that we let each entry have a unique "name" and "text" string, + * even if the string happens to be empty (everyone has a unique '\0'). + */ +errr init_v_info(player_type *player_ptr) +{ + init_header(&v_head, max_v_idx, sizeof(vault_type)); + v_head.parse_info_txt = parse_v_info; + return init_info(player_ptr, "v_info", &v_head, (void *)&v_info, &v_name, &v_text, NULL); +} + +/*! + * @brief E‹Æ‹Z”\î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "s_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_s_info(player_type *player_ptr) +{ + init_header(&s_head, MAX_CLASS, sizeof(skill_table)); + s_head.parse_info_txt = parse_s_info; + return init_info(player_ptr, "s_info", &s_head, (void *)&s_info, NULL, NULL, NULL); +} + +/*! + * @brief E‹Æ–‚–@î•ñ“ǂݍž‚݂̃ƒCƒ“ƒ‹[ƒ`ƒ“ / + * Initialize the "m_info" array + * @return ƒGƒ‰[ƒR[ƒh + */ +errr init_m_info(player_type *player_ptr) +{ + init_header(&m_head, MAX_CLASS, sizeof(player_magic)); + m_head.parse_info_txt = parse_m_info; + return init_info(player_ptr, "m_info", &m_head, (void *)&m_info, NULL, NULL, NULL); +} diff --git a/src/main/info-initializer.h b/src/main/info-initializer.h index 471ebe74c..568d30337 100644 --- a/src/main/info-initializer.h +++ b/src/main/info-initializer.h @@ -3,3 +3,12 @@ #include "system/angband.h" errr init_misc(player_type *player_ptr); +errr init_f_info(player_type *player_ptr); +errr init_k_info(player_type *player_ptr); +errr init_a_info(player_type *player_ptr); +errr init_e_info(player_type *player_ptr); +errr init_r_info(player_type *player_ptr); +errr init_d_info(player_type *player_ptr); +errr init_v_info(player_type *player_ptr); +errr init_s_info(player_type *player_ptr); +errr init_m_info(player_type *player_ptr); diff --git a/src/main/init.c b/src/main/init.c index 0c132898c..5bb22b284 100644 --- a/src/main/init.c +++ b/src/main/init.c @@ -56,6 +56,7 @@ #include "io/files-util.h" #include "io/read-pref-file.h" #include "io/uid-checker.h" +#include "main/angband-headers.h" #include "main/info-initializer.h" #include "market/articles-on-sale.h" #include "monster-race/monster-race.h" @@ -83,9 +84,6 @@ #include "view/display-messages.h" #include "world/world.h" -#include -#include - /*! * @brief マクロ登録の最大数 / Maximum number of macros (see "io.c") * @note Default: assume at most 256 macros are used @@ -199,349 +197,6 @@ concptr err_str[PARSE_ERROR_MAX] = { _("未定義地形タグ", "undefined terrain tag"), }; -/* - * File headers - */ -static angband_header v_head; /*!< Vault情報のヘッダ構造体 */ -static angband_header k_head; /*!< ペースアイテム情報のヘッダ構造体 */ -static angband_header a_head; /*!< 固定アーティファクト情報のヘッダ構造体 */ -static angband_header e_head; /*!< アイテムエゴ情報のヘッダ構造体 */ -static angband_header r_head; /*!< モンスター種族情報のヘッダ構造体 */ -static angband_header d_head; /*!< ダンジョン情報のヘッダ構造体 */ -static angband_header s_head; /*!< プレイヤー職業技能情報のヘッダ構造体 */ -static angband_header m_head; /*!< プレイヤー職業魔法情報のヘッダ構造体 */ - -/*! - * @brief テキストファイルとrawファイルの更新時刻を比較する - * Find the default paths to all of our important sub-directories. - * @param fd ファイルディスクリプタ - * @param template_file ファイル名 - * @return テキストの方が新しいか、rawファイルがなく更新の必要がある場合-1、更新の必要がない場合0。 - */ -static errr check_modification_date(int fd, concptr template_file) -{ - struct stat txt_stat, raw_stat; - char buf[1024]; - path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file); - if (stat(buf, &txt_stat)) - return 0; - - if (fstat(fd, &raw_stat)) - return -1; - - if (txt_stat.st_mtime > raw_stat.st_mtime) - return -1; - - return 0; -} - -/*** Initialize from binary image files ***/ - -/*! - * @brief rawファイルからのデータの読み取り処理 - * Initialize the "*_info" array, by parsing a binary "image" file - * @param fd ファイルディスクリプタ - * @param head rawファイルのヘッダ - * @return エラーコード - */ -static errr init_info_raw(int fd, angband_header *head) -{ - angband_header test; - if (fd_read(fd, (char *)(&test), sizeof(angband_header)) || (test.v_major != head->v_major) || (test.v_minor != head->v_minor) - || (test.v_patch != head->v_patch) || (test.info_num != head->info_num) || (test.info_len != head->info_len) || (test.head_size != head->head_size) - || (test.info_size != head->info_size)) { - return -1; - } - - *head = test; - C_MAKE(head->info_ptr, head->info_size, char); - fd_read(fd, head->info_ptr, head->info_size); - if (head->name_size) { - C_MAKE(head->name_ptr, head->name_size, char); - fd_read(fd, head->name_ptr, head->name_size); - } - - if (head->text_size) { - C_MAKE(head->text_ptr, head->text_size, char); - fd_read(fd, head->text_ptr, head->text_size); - } - - if (head->tag_size) { - C_MAKE(head->tag_ptr, head->tag_size, char); - fd_read(fd, head->tag_ptr, head->tag_size); - } - - return 0; -} - -/*! - * @brief ヘッダ構造体の更新 - * Initialize the header of an *_info.raw file. - * @param head rawファイルのヘッダ - * @param num データ数 - * @param len データの長さ - * @return エラーコード - */ -static void init_header(angband_header *head, IDX num, int len) -{ - head->v_major = FAKE_VER_MAJOR; - head->v_minor = FAKE_VER_MINOR; - head->v_patch = FAKE_VER_PATCH; - head->v_extra = 0; - - head->info_num = (IDX)num; - head->info_len = len; - - head->head_size = sizeof(angband_header); - head->info_size = head->info_num * head->info_len; -} - -static void update_header(angband_header *head, void **info, char **name, char **text, char **tag) -{ - if (info) - *info = head->info_ptr; - - if (name) - *name = head->name_ptr; - - if (text) - *text = head->text_ptr; - - if (tag) - *tag = head->tag_ptr; -} - -/*! - * @brief ヘッダ構造体の更新 - * Initialize the "*_info" array - * @param filename ファイル名(拡張子txt/raw) - * @param head 処理に用いるヘッダ構造体 - * @param info データ保管先の構造体ポインタ - * @param name 名称用可変文字列の保管先 - * @param text テキスト用可変文字列の保管先 - * @param tag タグ用可変文字列の保管先 - * @return エラーコード - * @note - * Note that we let each entry have a unique "name" and "text" string, - * even if the string happens to be empty (everyone has a unique '\0'). - */ -static errr init_info(player_type *player_ptr, concptr filename, angband_header *head, void **info, char **name, char **text, char **tag) -{ - char buf[1024]; - path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); - int fd = fd_open(buf, O_RDONLY); - errr err = 1; - if (fd >= 0) { - err = check_modification_date(fd, format("%s.txt", filename)); - if (!err) - err = init_info_raw(fd, head); - - (void)fd_close(fd); - } - - BIT_FLAGS file_permission = 0644; - if (err == 0) { - update_header(head, info, name, text, tag); - return 0; - } - - C_MAKE(head->info_ptr, head->info_size, char); - if (name) - C_MAKE(head->name_ptr, FAKE_NAME_SIZE, char); - - if (text) - C_MAKE(head->text_ptr, FAKE_TEXT_SIZE, char); - - if (tag) - C_MAKE(head->tag_ptr, FAKE_TAG_SIZE, char); - - if (info) - *info = head->info_ptr; - - if (name) - *name = head->name_ptr; - - if (text) - *text = head->text_ptr; - - if (tag) - *tag = head->tag_ptr; - - path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename)); - FILE *fp; - fp = angband_fopen(buf, "r"); - if (!fp) - quit(format(_("'%s.txt'ファイルをオープンできません。", "Cannot open '%s.txt' file."), filename)); - - err = init_info_txt(fp, buf, head, head->parse_info_txt); - angband_fclose(fp); - if (err) { - concptr oops; - oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : _("未知の", "unknown")); -#ifdef JP - msg_format("'%s.txt'ファイルの %d 行目にエラー。", filename, error_line); -#else - msg_format("Error %d at line %d of '%s.txt'.", err, error_line, filename); -#endif - msg_format(_("レコード %d は '%s' エラーがあります。", "Record %d contains a '%s' error."), error_idx, oops); - msg_format(_("構文 '%s'。", "Parsing '%s'."), buf); - msg_print(NULL); - quit(format(_("'%s.txt'ファイルにエラー", "Error in '%s.txt' file."), filename)); - } - - if (head->retouch) - (*head->retouch)(head); - - path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); - safe_setuid_grab(player_ptr); - (void)fd_kill(buf); - fd = fd_make(buf, file_permission); - safe_setuid_drop(); - if (fd >= 0) { - fd_write(fd, (concptr)(head), head->head_size); - fd_write(fd, head->info_ptr, head->info_size); - fd_write(fd, head->name_ptr, head->name_size); - fd_write(fd, head->text_ptr, head->text_size); - fd_write(fd, head->tag_ptr, head->tag_size); - (void)fd_close(fd); - } - - C_KILL(head->info_ptr, head->info_size, char); - if (name) - C_KILL(head->name_ptr, FAKE_NAME_SIZE, char); - - if (text) - C_KILL(head->text_ptr, FAKE_TEXT_SIZE, char); - - if (tag) - C_KILL(head->tag_ptr, FAKE_TAG_SIZE, char); - - path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename)); - fd = fd_open(buf, O_RDONLY); - if (fd < 0) - quit(format(_("'%s_j.raw'ファイルをロードできません。", "Cannot load '%s.raw' file."), filename)); - - err = init_info_raw(fd, head); - (void)fd_close(fd); - if (err) - quit(format(_("'%s_j.raw'ファイルを解析できません。", "Cannot parse '%s.raw' file."), filename)); - - update_header(head, info, name, text, tag); - return 0; -} - -/*! - * @brief 地形情報読み込みのメインルーチン / - * Initialize the "f_info" array - * @return エラーコード - */ -static errr init_f_info(player_type *player_ptr) -{ - init_header(&f_head, max_f_idx, sizeof(feature_type)); - f_head.parse_info_txt = parse_f_info; - f_head.retouch = retouch_f_info; - return init_info(player_ptr, "f_info", &f_head, (void *)&f_info, &f_name, NULL, &f_tag); -} - -/*! - * @brief ベースアイテム情報読み込みのメインルーチン / - * Initialize the "k_info" array - * @return エラーコード - */ -static errr init_k_info(player_type *player_ptr) -{ - init_header(&k_head, max_k_idx, sizeof(object_kind)); - k_head.parse_info_txt = parse_k_info; - return init_info(player_ptr, "k_info", &k_head, (void *)&k_info, &k_name, &k_text, NULL); -} - -/*! - * @brief 固定アーティファクト情報読み込みのメインルーチン / - * Initialize the "a_info" array - * @return エラーコード - */ -static errr init_a_info(player_type *player_ptr) -{ - init_header(&a_head, max_a_idx, sizeof(artifact_type)); - a_head.parse_info_txt = parse_a_info; - return init_info(player_ptr, "a_info", &a_head, (void *)&a_info, &a_name, &a_text, NULL); -} - -/*! - * @brief 固定アーティファクト情報読み込みのメインルーチン / - * Initialize the "e_info" array - * @return エラーコード - */ -static errr init_e_info(player_type *player_ptr) -{ - init_header(&e_head, max_e_idx, sizeof(ego_item_type)); - e_head.parse_info_txt = parse_e_info; - return init_info(player_ptr, "e_info", &e_head, (void *)&e_info, &e_name, &e_text, NULL); -} - -/*! - * @brief モンスター種族情報読み込みのメインルーチン / - * Initialize the "r_info" array - * @return エラーコード - */ -static errr init_r_info(player_type *player_ptr) -{ - init_header(&r_head, max_r_idx, sizeof(monster_race)); - r_head.parse_info_txt = parse_r_info; - return init_info(player_ptr, "r_info", &r_head, (void *)&r_info, &r_name, &r_text, NULL); -} - -/*! - * @brief ダンジョン情報読み込みのメインルーチン / - * Initialize the "d_info" array - * @return エラーコード - */ -static errr init_d_info(player_type *player_ptr) -{ - init_header(&d_head, current_world_ptr->max_d_idx, sizeof(dungeon_type)); - d_head.parse_info_txt = parse_d_info; - return init_info(player_ptr, "d_info", &d_head, (void *)&d_info, &d_name, &d_text, NULL); -} - -/*! - * @brief Vault情報読み込みのメインルーチン / - * Initialize the "v_info" array - * @return エラーコード - * @note - * Note that we let each entry have a unique "name" and "text" string, - * even if the string happens to be empty (everyone has a unique '\0'). - */ -errr init_v_info(player_type *player_ptr) -{ - init_header(&v_head, max_v_idx, sizeof(vault_type)); - v_head.parse_info_txt = parse_v_info; - return init_info(player_ptr, "v_info", &v_head, (void *)&v_info, &v_name, &v_text, NULL); -} - -/*! - * @brief 職業技能情報読み込みのメインルーチン / - * Initialize the "s_info" array - * @return エラーコード - */ -static errr init_s_info(player_type *player_ptr) -{ - init_header(&s_head, MAX_CLASS, sizeof(skill_table)); - s_head.parse_info_txt = parse_s_info; - return init_info(player_ptr, "s_info", &s_head, (void *)&s_info, NULL, NULL, NULL); -} - -/*! - * @brief 職業魔法情報読み込みのメインルーチン / - * Initialize the "m_info" array - * @return エラーコード - */ -static errr init_m_info(player_type *player_ptr) -{ - init_header(&m_head, MAX_CLASS, sizeof(player_magic)); - m_head.parse_info_txt = parse_m_info; - return init_info(player_ptr, "m_info", &m_head, (void *)&m_info, NULL, NULL, NULL); -} - /*! * @brief 町情報読み込みのメインルーチン / * Initialize town array -- 2.11.0