OSDN Git Service

[Refactor] #39970 Moved load_all_pref_files() from core.c to read-pref-file.c/h
[hengbandforosx/hengbandosx.git] / src / io / read-pref-file.c
1 /*
2  * @file cmd-dump.c
3  * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
4  * @date 2020/03/01
5  * @author Mogami & Hourier
6  * -Mogami-
7  * remove_auto_dump(orig_file, mark)
8  *     Remove the old automatic dump of type "mark".
9  * auto_dump_printf(fmt, ...)
10  *     Dump a formatted string using fprintf().
11  * open_auto_dump(buf, mark)
12  *     Open a file, remove old dump, and add new header.
13  * close_auto_dump(void)
14  *     Add a footer, and close the file.
15  */
16
17 #include "angband.h"
18 #include "io/dump-remover.h"
19 #include "io/read-pref-file.h"
20 #include "io/interpret-pref-file.h"
21 #include "autopick/autopick-pref-processor.h"
22 #include "files.h" // 暫定。コールバック化して後で消す.
23 #include "world/world.h"
24 #include "core.h"
25 #include "autopick/autopick-reader-writer.h"
26
27 // todo コールバック関数に変更するので、いずれ消す.
28 #define PREF_TYPE_NORMAL   0
29 #define PREF_TYPE_AUTOPICK 1
30 #define PREF_TYPE_HISTPREF 2
31
32 char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
33 char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
34
35 // Mark strings for auto dump
36
37 // Variables for auto dump
38 static int auto_dump_line_num;
39
40 /*!
41  * todo 関数名を変更する
42  * @brief process_pref_fileのサブルーチン /
43  * Open the "user pref file" and parse it.
44  * @param creature_ptr プレーヤーへの参照ポインタ
45  * @param name 読み込むファイル名
46  * @param preftype prefファイルのタイプ
47  * @return エラーコード
48  */
49 static errr process_pref_file_aux(player_type *creature_ptr, concptr name, int preftype, void(*process_autopick_file_command)(char*))
50 {
51         FILE *fp;
52         fp = my_fopen(name, "r");
53         if (!fp) return -1;
54
55         char buf[1024];
56         char old[1024];
57         int line = -1;
58         errr err = 0;
59         bool bypass = FALSE;
60         while (my_fgets(fp, buf, sizeof(buf)) == 0)
61         {
62                 line++;
63                 if (!buf[0]) continue;
64
65 #ifdef JP
66                 if (!iskanji(buf[0]))
67 #endif
68                         if (iswspace(buf[0])) continue;
69
70                 if (buf[0] == '#') continue;
71                 strcpy(old, buf);
72
73                 /* Process "?:<expr>" */
74                 if ((buf[0] == '?') && (buf[1] == ':'))
75                 {
76                         char f;
77                         char *s;
78                         s = buf + 2;
79                         concptr v = process_pref_file_expr(creature_ptr, &s, &f);
80                         bypass = streq(v, "0");
81                         continue;
82                 }
83
84                 if (bypass) continue;
85
86                 /* Process "%:<file>" */
87                 if (buf[0] == '%')
88                 {
89                         static int depth_count = 0;
90                         if (depth_count > 20) continue;
91
92                         depth_count++;
93                         switch (preftype)
94                         {
95                         case PREF_TYPE_AUTOPICK:
96                                 (void)process_autopick_file(creature_ptr, buf + 2, process_autopick_file_command);
97                                 break;
98                         case PREF_TYPE_HISTPREF:
99                                 (void)process_histpref_file(creature_ptr, buf + 2, process_autopick_file_command);
100                                 break;
101                         default:
102                                 (void)process_pref_file(creature_ptr, buf + 2, process_autopick_file_command);
103                                 break;
104                         }
105
106                         depth_count--;
107                         continue;
108                 }
109
110                 err = interpret_pref_file(creature_ptr, buf);
111                 if (err != 0)
112                 {
113                         if (preftype != PREF_TYPE_AUTOPICK)
114                                 break;
115                         
116                         (*process_autopick_file_command)(buf);
117                         err = 0;
118                 }
119         }
120
121         if (err != 0)
122         {
123                 /* Print error message */
124                 /* ToDo: Add better error messages */
125                 msg_format(_("ファイル'%s'の%d行でエラー番号%dのエラー。", "Error %d in line %d of file '%s'."),
126                         _(name, err), line, _(err, name));
127                 msg_format(_("('%s'を解析中)", "Parsing '%s'"), old);
128                 msg_print(NULL);
129         }
130
131         my_fclose(fp);
132         return (err);
133 }
134
135
136 /*!
137  * @brief pref設定ファイルを読み込み設定を反映させる /
138  * Process the "user pref file" with the given name
139  * @param creature_ptr プレーヤーへの参照ポインタ
140  * @param name 読み込むファイル名
141  * @return エラーコード
142  * @details
143  * <pre>
144  * See the functions above for a list of legal "commands".
145  * We also accept the special "?" and "%" directives, which
146  * allow conditional evaluation and filename inclusion.
147  * </pre>
148  */
149 errr process_pref_file(player_type *creature_ptr, concptr name, void(*process_autopick_file_command)(char*))
150 {
151         char buf[1024];
152         path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, name);
153
154         errr err1 = process_pref_file_aux(creature_ptr, buf, PREF_TYPE_NORMAL, process_autopick_file_command);
155         if (err1 > 0) return err1;
156
157         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name);
158         errr err2 = process_pref_file_aux(creature_ptr, buf, PREF_TYPE_NORMAL, process_autopick_file_command);
159         if (err2 < 0 && !err1)
160                 return -2;
161
162         return err2;
163 }
164
165
166 /*!
167  * @brief 自動拾いファイルを読み込む /
168  * @param creature_ptr プレーヤーへの参照ポインタ
169  * @param name ファイル名
170  * @details
171  */
172 errr process_autopick_file(player_type *creature_ptr, concptr name, void(*process_autopick_file_command)(char*))
173 {
174         char buf[1024];
175         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name);
176         errr err = process_pref_file_aux(creature_ptr, buf, PREF_TYPE_AUTOPICK, process_autopick_file_command);
177         return err;
178 }
179
180
181 /*!
182  * @brief プレイヤーの生い立ちファイルを読み込む /
183  * Process file for player's history editor.
184  * @param creature_ptr プレーヤーへの参照ポインタ
185  * @param name ファイル名
186  * @return エラーコード
187  * @details
188  */
189 errr process_histpref_file(player_type *creature_ptr, concptr name, void(*process_autopick_file_command)(char*))
190 {
191         bool old_character_xtra = current_world_ptr->character_xtra;
192         char buf[1024];
193         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name);
194
195         /* Hack -- prevent modification birth options in this file */
196         current_world_ptr->character_xtra = TRUE;
197         errr err = process_pref_file_aux(creature_ptr, buf, PREF_TYPE_HISTPREF, process_autopick_file_command);
198         current_world_ptr->character_xtra = old_character_xtra;
199         return err;
200 }
201
202
203 /*!
204  * @brief prfファイルのフォーマットに従った内容を出力する /
205  * Dump a formatted line, using "vstrnfmt()".
206  * @param fmt 出力内容
207  */
208 void auto_dump_printf(FILE *auto_dump_stream, concptr fmt, ...)
209 {
210         va_list vp;
211         char buf[1024];
212         va_start(vp, fmt);
213         (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
214         va_end(vp);
215         for (concptr p = buf; *p; p++)
216         {
217                 if (*p == '\n') auto_dump_line_num++;
218         }
219
220         fprintf(auto_dump_stream, "%s", buf);
221 }
222
223
224 /*!
225  * @brief prfファイルをファイルオープンする /
226  * Open file to append auto dump.
227  * @param buf ファイル名
228  * @param mark 出力するヘッダマーク
229  * @return ファイルポインタを取得できたらTRUEを返す
230  */
231 bool open_auto_dump(FILE **fpp, concptr buf, concptr mark)
232 {
233         char header_mark_str[80];
234         concptr auto_dump_mark = mark;
235         sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
236         remove_auto_dump(buf, mark);
237         *fpp = my_fopen(buf, "a");
238         if (!fpp)
239         {
240                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
241                 msg_print(NULL);
242                 return FALSE;
243         }
244
245         fprintf(*fpp, "%s\n", header_mark_str);
246         auto_dump_line_num = 0;
247         auto_dump_printf(*fpp, _("# *警告!!* 以降の行は自動生成されたものです。\n",
248                 "# *Warning!*  The lines below are an automatic dump.\n"));
249         auto_dump_printf(*fpp, _("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
250                 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
251         return TRUE;
252 }
253
254 /*!
255  * @brief prfファイルをファイルクローズする /
256  * Append foot part and close auto dump.
257  * @return なし
258  */
259 void close_auto_dump(FILE **fpp, concptr auto_dump_mark)
260 {
261         char footer_mark_str[80];
262         sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
263         auto_dump_printf(*fpp, _("# *警告!!* 以降の行は自動生成されたものです。\n",
264                 "# *Warning!*  The lines below are an automatic dump.\n"));
265         auto_dump_printf(*fpp, _("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
266                 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
267         fprintf(*fpp, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
268         my_fclose(*fpp);
269 }
270
271 /*!
272  * @brief 全ユーザプロファイルをロードする / Load some "user pref files"
273  * @paaram player_ptr プレーヤーへの参照ポインタ
274  * @return なし
275  * @note
276  * Modified by Arcum Dagsson to support
277  * separate macro files for different realms.
278  */
279 void load_all_pref_files(player_type* player_ptr)
280 {
281     char buf[1024];
282     sprintf(buf, "user.prf");
283     process_pref_file(player_ptr, buf, process_autopick_file_command);
284     sprintf(buf, "user-%s.prf", ANGBAND_SYS);
285     process_pref_file(player_ptr, buf, process_autopick_file_command);
286     sprintf(buf, "%s.prf", rp_ptr->title);
287     process_pref_file(player_ptr, buf, process_autopick_file_command);
288     sprintf(buf, "%s.prf", cp_ptr->title);
289     process_pref_file(player_ptr, buf, process_autopick_file_command);
290     sprintf(buf, "%s.prf", player_ptr->base_name);
291     process_pref_file(player_ptr, buf, process_autopick_file_command);
292     if (player_ptr->realm1 != REALM_NONE) {
293         sprintf(buf, "%s.prf", realm_names[player_ptr->realm1]);
294         process_pref_file(player_ptr, buf, process_autopick_file_command);
295     }
296
297     if (player_ptr->realm2 != REALM_NONE) {
298         sprintf(buf, "%s.prf", realm_names[player_ptr->realm2]);
299         process_pref_file(player_ptr, buf, process_autopick_file_command);
300     }
301
302     autopick_load_pref(player_ptr, FALSE);
303 }