OSDN Git Service

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