Fix all warnings -Wall spews
[lsnes.git] / keymapper.cpp
blob97c06a9f80051f4e864f7d54f26b1395c7721386
1 #include "keymapper.hpp"
2 #include <stdexcept>
3 #include "lua.hpp"
4 #include <list>
5 #include <map>
6 #include <set>
7 #include "misc.hpp"
8 #include "zip.hpp"
9 #include "videodumper2.hpp"
10 #include "settings.hpp"
11 #include "memorymanip.hpp"
12 #include "fieldsplit.hpp"
14 namespace
16 std::map<std::string, std::list<std::string>> aliases;
18 void handle_alias(std::string cmd, window* win)
20 std::string syntax = "Syntax: alias-command <alias> <command>";
21 tokensplitter t(cmd);
22 std::string dummy = t;
23 std::string aliasname = t;
24 std::string command = t.tail();
25 if(command == "")
26 throw std::runtime_error(syntax);
27 aliases[aliasname].push_back(command);
28 out(win) << "Command '" << aliasname << "' aliased to '" << command << "'" << std::endl;
31 void handle_unalias(std::string cmd, window* win) throw(std::bad_alloc, std::runtime_error)
33 std::string syntax = "Syntax: unalias-command <alias>";
34 tokensplitter t(cmd);
35 std::string dummy = t;
36 std::string aliasname = t;
37 if(aliasname == "" || t.tail() != "")
38 throw std::runtime_error(syntax);
39 aliases.erase(aliasname);
40 out(win) << "Removed alias '" << aliasname << "'" << std::endl;
43 void handle_aliases(window* win) throw(std::bad_alloc, std::runtime_error)
45 for(auto i = aliases.begin(); i != aliases.end(); i++)
46 for(auto j = i->second.begin(); j != i->second.end(); j++)
47 out(win) << "alias " << i->first << " " << *j << std::endl;
50 void handle_run(std::string cmd, window* win, aliasexpand_commandhandler& cmdh,
51 std::set<std::string>& recursive_commands) throw(std::bad_alloc, std::runtime_error)
53 std::string syntax = "Syntax: run-script <file>";
54 tokensplitter t(cmd);
55 std::string dummy = t;
56 std::string file = t.tail();
57 if(file == "")
58 throw std::runtime_error(syntax);
59 std::istream* o = NULL;
60 try {
61 o = &open_file_relative(file, "");
62 out(win) << "Running '" << file << "'" << std::endl;
63 std::string line;
64 while(std::getline(*o, line))
65 cmdh.docommand(line, win, recursive_commands);
66 delete o;
67 } catch(std::bad_alloc& e) {
68 OOM_panic(win);
69 } catch(std::exception& e) {
70 out(win) << "Error running script: " << e.what() << std::endl;
71 if(o)
72 delete o;
76 void handle_set(std::string cmd, window* win) throw(std::bad_alloc, std::runtime_error)
78 std::string syntax = "Syntax: set-setting <setting> [<value>]";
79 tokensplitter t(cmd);
80 std::string dummy = t;
81 std::string settingname = t;
82 std::string settingvalue = t.tail();
83 if(settingname == "")
84 throw std::runtime_error(syntax);
85 setting_set(settingname, settingvalue);
86 out(win) << "Setting '" << settingname << "' set to '" << settingvalue << "'" << std::endl;
89 void handle_unset(std::string cmd, window* win) throw(std::bad_alloc, std::runtime_error)
91 std::string syntax = "Syntax: unset-setting <setting>";
92 tokensplitter t(cmd);
93 std::string dummy = t;
94 std::string settingname = t;
95 if(settingname == "" || t.tail() != "")
96 throw std::runtime_error(syntax);
97 setting_blank(settingname);
98 out(win) << "Setting '" << settingname << "' blanked" << std::endl;
101 void handle_get(std::string cmd, window* win) throw(std::bad_alloc, std::runtime_error)
103 std::string syntax = "Syntax: get-setting <setting>";
104 tokensplitter t(cmd);
105 std::string dummy = t;
106 std::string settingname = t;
107 if(settingname == "" || t.tail() != "")
108 throw std::runtime_error(syntax);
109 if(!setting_isblank(settingname))
110 out(win) << "Setting '" << settingname << "' has value '" << setting_get(settingname)
111 << "'" << std::endl;
112 else
113 out(win) << "Setting '" << settingname << "' unset" << std::endl;
116 struct binding_request
118 binding_request(std::string& cmd) throw(std::bad_alloc, std::runtime_error);
119 bool polarity;
120 std::string mod;
121 std::string modmask;
122 std::string keyname;
123 std::string command;
126 struct set_raii
128 set_raii(std::set<std::string>& _set, const std::string& _foo) throw(std::bad_alloc)
129 : set(_set), foo(_foo)
131 set.insert(foo);
134 ~set_raii() throw()
136 set.erase(foo);
139 std::set<std::string>& set;
140 std::string foo;
144 aliasexpand_commandhandler::aliasexpand_commandhandler() throw()
148 aliasexpand_commandhandler::~aliasexpand_commandhandler() throw()
152 void aliasexpand_commandhandler::docommand(std::string& cmd, window* win) throw(std::bad_alloc)
154 std::set<std::string> recursive_commands;
155 docommand(cmd, win, recursive_commands);
158 void aliasexpand_commandhandler::docommand(std::string& cmd, window* win, std::set<std::string>& recursive_commands)
159 throw(std::bad_alloc)
161 std::string tmp = cmd;
162 bool noalias = false;
163 if(cmd.length() > 0 && cmd[0] == '*') {
164 tmp = cmd.substr(1);
165 noalias = true;
167 if(recursive_commands.count(tmp)) {
168 out(win) << "Not executing '" << tmp << "' recursively" << std::endl;
169 return;
171 set_raii rce(recursive_commands, tmp);
172 try {
173 if(is_cmd_prefix(tmp, "set-setting")) {
174 handle_set(tmp, win);
175 return;
177 if(is_cmd_prefix(tmp, "get-setting")) {
178 handle_get(tmp, win);
179 return;
181 if(is_cmd_prefix(tmp, "print-settings")) {
182 setting_print_all(win);
183 return;
185 if(is_cmd_prefix(tmp, "unset-setting")) {
186 handle_unset(tmp, win);
187 return;
189 if(is_cmd_prefix(tmp, "print-keybindings")) {
190 if(win)
191 win->dumpbindings();
192 else
193 throw std::runtime_error("Can't list bindings without graphics context");
194 return;
196 if(is_cmd_prefix(tmp, "print-aliases")) {
197 handle_aliases(win);
198 return;
200 if(is_cmd_prefix(tmp, "alias-command")) {
201 handle_alias(tmp, win);
202 return;
204 if(is_cmd_prefix(tmp, "unalias-command")) {
205 handle_unalias(tmp, win);
206 return;
208 if(is_cmd_prefix(tmp, "run-script")) {
209 handle_run(tmp, win, *this, recursive_commands);
210 return;
212 if(is_cmd_prefix(tmp, "bind-key")) {
213 binding_request req(tmp);
214 if(win)
215 win->bind(req.mod, req.modmask, req.keyname, req.command);
216 else
217 throw std::runtime_error("Can't bind keys without graphics context");
218 return;
220 if(is_cmd_prefix(tmp, "unbind-key")) {
221 binding_request req(tmp);
222 if(win)
223 win->unbind(req.mod, req.modmask, req.keyname);
224 else
225 throw std::runtime_error("Can't unbind keys without graphics context");
226 return;
228 if(win && win->exec_command(tmp))
229 return;
230 if(vid_dumper_command(tmp, win))
231 return;
232 if(memorymanip_command(tmp, win))
233 return;
234 if(lua_command(tmp, win))
235 return;
236 } catch(std::bad_alloc& e) {
237 OOM_panic(win);
238 } catch(std::exception& e) {
239 out(win) << "Error: " << e.what() << std::endl;
240 return;
242 if(!noalias && aliases.count(tmp)) {
243 auto& x = aliases[tmp];
244 for(auto i = x.begin(); i != x.end(); i++) {
245 std::string y = *i;
246 docommand(y, win, recursive_commands);
248 } else {
249 docommand2(tmp, win);
253 std::string fixup_command_polarity(std::string cmd, bool polarity) throw(std::bad_alloc)
255 if(cmd == "")
256 return "";
257 if(cmd[0] != '+' && polarity)
258 return "";
259 if(cmd[0] == '+' && !polarity)
260 cmd[0] = '-';
261 return cmd;
264 binding_request::binding_request(std::string& cmd) throw(std::bad_alloc, std::runtime_error)
266 if(is_cmd_prefix(cmd, "bind-key")) {
267 std::string syntax = "Syntax: bind-key [<mod>/<modmask>] <key> <command>";
268 tokensplitter t(cmd);
269 std::string dummy = t;
270 std::string mod_or_key = t;
271 if(mod_or_key.find_first_of("/") < mod_or_key.length()) {
272 //Mod field.
273 size_t split = mod_or_key.find_first_of("/");
274 mod = mod_or_key.substr(0, split);
275 modmask = mod_or_key.substr(split + 1);
276 mod_or_key = static_cast<std::string>(t);
278 if(mod_or_key == "")
279 throw std::runtime_error(syntax);
280 keyname = mod_or_key;
281 command = t.tail();
282 if(command == "")
283 throw std::runtime_error(syntax);
284 polarity = true;
285 } else if(is_cmd_prefix(cmd, "unbind-key")) {
286 std::string syntax = "Syntax: unbind-key [<mod>/<modmask>] <key>";
287 tokensplitter t(cmd);
288 std::string dummy = t;
289 std::string mod_or_key = t;
290 if(mod_or_key.find_first_of("/") < mod_or_key.length()) {
291 //Mod field.
292 size_t split = mod_or_key.find_first_of("/");
293 mod = mod_or_key.substr(0, split);
294 modmask = mod_or_key.substr(split + 1);
295 mod_or_key = static_cast<std::string>(t);
297 if(mod_or_key == "")
298 throw std::runtime_error(syntax);
299 keyname = mod_or_key;
300 if(t.tail() != "")
301 throw std::runtime_error(syntax);
302 polarity = false;
303 } else
304 throw std::runtime_error("Not a valid binding request");