OSDN Git Service

Merge pull request #41491 (taotao/hengband/fix-impure_calc_num_blow into develop).
[hengband/hengband.git] / src / cmd-io / macro-util.c
1 #include "cmd-io/macro-util.h"
2
3 /* Array of macro types [MACRO_MAX] */
4 bool *macro__cmd;
5
6 /* Current macro action [1024] */
7 char *macro__buf;
8
9 /* Array of macro patterns [MACRO_MAX] */
10 concptr *macro__pat;
11
12 /* Array of macro actions [MACRO_MAX] */
13 concptr *macro__act;
14
15 /* Number of active macros */
16 s16b macro__num;
17
18 /* Expand macros in "get_com" or not */
19 bool get_com_no_macros = FALSE;
20
21 /* Determine if any macros have ever started with a given character */
22 static bool macro__use[256];
23
24 /* Find the macro (if any) which exactly matches the given pattern */
25 int macro_find_exact(concptr pat)
26 {
27     if (!macro__use[(byte)(pat[0])]) {
28         return -1;
29     }
30
31     for (int i = 0; i < macro__num; ++i) {
32         if (!streq(macro__pat[i], pat))
33             continue;
34
35         return (i);
36     }
37
38     return -1;
39 }
40
41 /*
42  * Find the first macro (if any) which contains the given pattern
43  */
44 int macro_find_check(concptr pat)
45 {
46     if (!macro__use[(byte)(pat[0])]) {
47         return -1;
48     }
49
50     for (int i = 0; i < macro__num; ++i) {
51         if (!prefix(macro__pat[i], pat))
52             continue;
53
54         return (i);
55     }
56
57     return -1;
58 }
59
60 /*
61  * Find the first macro (if any) which contains the given pattern and more
62  */
63 int macro_find_maybe(concptr pat)
64 {
65     if (!macro__use[(byte)(pat[0])]) {
66         return -1;
67     }
68
69     for (int i = 0; i < macro__num; ++i) {
70         if (!prefix(macro__pat[i], pat))
71             continue;
72         if (streq(macro__pat[i], pat))
73             continue;
74
75         return (i);
76     }
77
78     return -1;
79 }
80
81 /*
82  * Find the longest macro (if any) which starts with the given pattern
83  */
84 int macro_find_ready(concptr pat)
85 {
86     int t, n = -1, s = -1;
87
88     if (!macro__use[(byte)(pat[0])]) {
89         return -1;
90     }
91
92     for (int i = 0; i < macro__num; ++i) {
93         if (!prefix(pat, macro__pat[i]))
94             continue;
95
96         t = strlen(macro__pat[i]);
97         if ((n >= 0) && (s > t))
98             continue;
99
100         n = i;
101         s = t;
102     }
103
104     return (n);
105 }
106
107 /*
108  * Add a macro definition (or redefinition).
109  *
110  * We should use "act == NULL" to "remove" a macro, but this might make it
111  * impossible to save the "removal" of a macro definition.
112  *
113  * We should consider refusing to allow macros which contain existing macros,
114  * or which are contained in existing macros, because this would simplify the
115  * macro analysis code.
116  *
117  * We should consider removing the "command macro" crap, and replacing it
118  * with some kind of "powerful keymap" ability, but this might make it hard
119  * to change the "roguelike" option from inside the game.
120  */
121 errr macro_add(concptr pat, concptr act)
122 {
123     if (!pat || !act)
124         return -1;
125
126     int n = macro_find_exact(pat);
127     if (n >= 0) {
128         string_free(macro__act[n]);
129     } else {
130         n = macro__num++;
131         macro__pat[n] = string_make(pat);
132     }
133
134     macro__act[n] = string_make(act);
135     macro__use[(byte)(pat[0])] = TRUE;
136     return 0;
137 }