aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
authormarkt <markt>2007-12-13 05:48:00 (GMT)
committermarkt <markt>2007-12-13 05:48:00 (GMT)
commit8b7464046cea5e521ac46811591b0fce0c45aca1 (patch)
tree09df752f426a249ae15375a626a98436c8727593 /src/FbTk
parentdaca07edafc2e75eb9ee04d35fe80759308a8583 (diff)
downloadfluxbox-8b7464046cea5e521ac46811591b0fce0c45aca1.zip
fluxbox-8b7464046cea5e521ac46811591b0fce0c45aca1.tar.bz2
added FbTk::CommandRegistry, decentralized command parsing, and made them auto-register
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/CommandRegistry.cc92
-rw-r--r--src/FbTk/CommandRegistry.hh130
-rw-r--r--src/FbTk/LogicCommands.cc93
-rw-r--r--src/FbTk/LogicCommands.hh4
-rw-r--r--src/FbTk/MacroCommand.cc48
-rw-r--r--src/FbTk/Makefile.am1
-rw-r--r--src/FbTk/StringUtil.cc12
-rw-r--r--src/FbTk/StringUtil.hh3
8 files changed, 382 insertions, 1 deletions
diff --git a/src/FbTk/CommandRegistry.cc b/src/FbTk/CommandRegistry.cc
new file mode 100644
index 0000000..1d16c75
--- /dev/null
+++ b/src/FbTk/CommandRegistry.cc
@@ -0,0 +1,92 @@
1// CommandRegistry.cc for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#include "CommandRegistry.hh"
25#include "Command.hh"
26#include "StringUtil.hh"
27
28#include <iostream>
29
30namespace FbTk {
31
32CommandRegistry &CommandRegistry::instance() {
33 static CommandRegistry s_instance;
34 return s_instance;
35}
36
37
38bool CommandRegistry::registerCommand(string name,
39 CreateFunction createFunction) {
40 name = StringUtil::toLower(name);
41 m_commandCreators[name] = createFunction;
42 return true;
43}
44
45bool CommandRegistry::registerBoolCommand(string name,
46 BoolCreateFunction createFunction) {
47 name = StringUtil::toLower(name);
48 m_boolcommandCreators[name] = createFunction;
49 return true;
50}
51
52Command *CommandRegistry::parseLine(const string &line, bool trusted) const {
53 // parse args and command
54 string command, args;
55 StringUtil::getFirstWord(line, command, args);
56
57 // now we have parsed command and args
58 command = StringUtil::toLower(command);
59 return getCommand(command, args, trusted);
60}
61
62BoolCommand *CommandRegistry::parseBoolLine(const string &line, bool trusted) const {
63 // parse args and command
64 string command, args;
65 StringUtil::getFirstWord(line, command, args);
66
67 // now we have parsed command and args
68 command = StringUtil::toLower(command);
69 return getBoolCommand(command, args, trusted);
70}
71
72Command *CommandRegistry::getCommand(const string &name, const string &args,
73 bool trusted) const {
74 string lc = StringUtil::toLower(name);
75 CreatorMap::const_iterator it = m_commandCreators.find(lc.c_str());
76 if (it == m_commandCreators.end())
77 return 0;
78 else
79 return it->second(name, args, trusted);
80}
81
82BoolCommand *CommandRegistry::getBoolCommand(const string &name,
83 const string &args, bool trusted) const {
84 string lc = StringUtil::toLower(name);
85 BoolCreatorMap::const_iterator it = m_boolcommandCreators.find(lc.c_str());
86 if (it == m_boolcommandCreators.end())
87 return 0;
88 else
89 return it->second(name, args, trusted);
90}
91
92}; // end namespace FbTk
diff --git a/src/FbTk/CommandRegistry.hh b/src/FbTk/CommandRegistry.hh
new file mode 100644
index 0000000..f3b6880
--- /dev/null
+++ b/src/FbTk/CommandRegistry.hh
@@ -0,0 +1,130 @@
1// CommandRegistry.hh for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#ifndef COMMANDREGISTRY_HH
25#define COMMANDREGISTRY_HH
26
27#include <string>
28#include <map>
29
30using std::string;
31
32namespace FbTk {
33class Command;
34class BoolCommand;
35
36#define REGISTER_COMMAND_PARSER(name, parser) \
37 namespace { \
38 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, parser); \
39 }
40
41#define REGISTER_BOOLCOMMAND_PARSER(name, parser) \
42 namespace { \
43 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, parser); \
44 }
45
46/* Include some basic command creators */
47template <typename Cmd, typename Ret>
48Ret *CommandCreator(const string &name, const string &args, bool trusted) {
49 return new Cmd();
50}
51
52#define REGISTER_COMMAND(name, classname) \
53 namespace { \
54 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreator<classname, FbTk::Command>); \
55 }
56
57template <typename Cmd, typename Ret>
58Ret *CommandCreatorWithArgs(const string &name, const string &args,
59 bool trusted) {
60 return new Cmd(args);
61}
62
63#define REGISTER_COMMAND_WITH_ARGS(name, classname) \
64 namespace { \
65 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::Command>); \
66 }
67
68#define REGISTER_BOOLCOMMAND_WITH_ARGS(name, classname) \
69 namespace { \
70 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::BoolCommand>); \
71 }
72
73template <typename Cmd, typename Ret>
74Ret *UntrustedCommandCreator(const string &name, const string &args,
75 bool trusted) {
76 if (!trusted) return 0;
77 return new Cmd();
78}
79
80#define REGISTER_UNTRUSTED_COMMAND(name, classname) \
81 namespace { \
82 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreator<classname, FbTk::Command>); \
83 }
84
85template <typename Cmd, typename Ret>
86Ret * UntrustedCommandCreatorWithArgs(const string &name, const string &args,
87 bool trusted) {
88 if (!trusted) return 0;
89 return new Cmd(args);
90}
91
92#define REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(name, classname) \
93 namespace { \
94 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreatorWithArgs<classname, FbTk::Command>); \
95 }
96
97/* Not built to be virtual at the moment */
98class CommandRegistry {
99public:
100 typedef Command * CreateFunction(const string &name, const string &args, bool trusted);
101 typedef BoolCommand * BoolCreateFunction(const string &name,
102 const string &args, bool trusted);
103 typedef std::map<string, CreateFunction *> CreatorMap;
104 typedef std::map<string, BoolCreateFunction *> BoolCreatorMap;
105
106 static CommandRegistry &instance();
107
108 Command *parseLine(const string &line, bool trusted = true) const;
109 BoolCommand *parseBoolLine(const string &line, bool trusted = true) const;
110 Command *getCommand(const string &name, const string &args, bool trusted) const;
111 BoolCommand *getBoolCommand(const string &name, const string &args,
112 bool trusted) const;
113
114 /* Note: the ownership of this object passes to this class */
115 bool registerCommand(string name, CreateFunction createFunction);
116 bool registerBoolCommand(string name, BoolCreateFunction bcf);
117
118 const CreatorMap commandMap() const { return m_commandCreators; }
119
120private:
121 CommandRegistry() {}
122 ~CommandRegistry() {}
123
124 CreatorMap m_commandCreators;
125 BoolCreatorMap m_boolcommandCreators;
126};
127
128}; // end namespace FbTk
129
130#endif // COMMANDREGISTRY_HH
diff --git a/src/FbTk/LogicCommands.cc b/src/FbTk/LogicCommands.cc
index 99b5b53..1c6f238 100644
--- a/src/FbTk/LogicCommands.cc
+++ b/src/FbTk/LogicCommands.cc
@@ -23,8 +23,101 @@
23 23
24#include "LogicCommands.hh" 24#include "LogicCommands.hh"
25 25
26#include "CommandRegistry.hh"
27#include "StringUtil.hh"
28
29using FbTk::StringUtil::removeFirstWhitespace;
30using FbTk::StringUtil::toLower;
31using std::string;
32
26namespace FbTk { 33namespace FbTk {
27 34
35namespace {
36
37template <typename M>
38M *addCommands(M *macro, const string &args, bool trusted) {
39 int pos = 0, err = 0;
40 string cmd;
41
42 while (true) {
43 RefCount<BoolCommand> tmp(0);
44 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
45 '{', '}', " \t\n", true);
46 pos += err;
47 if (err == 0)
48 break;
49
50 tmp = CommandRegistry::instance().parseBoolLine(cmd, trusted);
51 if (*tmp)
52 macro->add(tmp);
53 }
54
55 if (macro->size() > 0)
56 return macro;
57 delete macro;
58 return 0;
59}
60
61BoolCommand *parseLogicCommand(const string &command, const string &args,
62 bool trusted) {
63 if (command == "not") {
64 BoolCommand *boolcmd =
65 CommandRegistry::instance().parseBoolLine(args, trusted);
66 if (!boolcmd)
67 return 0;
68 RefCount<BoolCommand> ref(boolcmd);
69 return new NotCommand(ref);
70 } else if (command == "and")
71 return addCommands<AndCommand>(new AndCommand(), args, trusted);
72 else if (command == "or")
73 return addCommands<OrCommand>(new OrCommand(), args, trusted);
74 else if (command == "xor")
75 return addCommands<XorCommand>(new XorCommand(), args, trusted);
76 return 0;
77}
78
79REGISTER_BOOLCOMMAND_PARSER(not, parseLogicCommand);
80REGISTER_BOOLCOMMAND_PARSER(and, parseLogicCommand);
81REGISTER_BOOLCOMMAND_PARSER(or, parseLogicCommand);
82REGISTER_BOOLCOMMAND_PARSER(xor, parseLogicCommand);
83
84}; // end anonymous namespace
85
86Command *IfCommand::parse(const std::string &command, const std::string &args,
87 bool trusted) {
88 std::string cmd;
89 int err = 0, pos = 0;
90 RefCount<BoolCommand> cond(0);
91 RefCount<Command> t(0), f(0);
92
93 err = StringUtil::getStringBetween(cmd, args.c_str(),
94 '{', '}', " \t\n", true);
95 if (err > 0)
96 cond = CommandRegistry::instance().parseBoolLine(cmd, trusted);
97 if (err == 0 || *cond == 0)
98 return 0;
99
100 pos = err;
101 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
102 '{', '}', " \t\n", true);
103 if (err == 0)
104 return 0;
105 t = CommandRegistry::instance().parseLine(cmd, trusted);
106
107 pos += err;
108 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
109 '{', '}', " \t\n", true);
110 if (err > 0)
111 f = CommandRegistry::instance().parseLine(cmd, trusted);
112 if (err == 0 || *t == 0 && *f == 0)
113 return 0;
114
115 return new IfCommand(cond, t, f);
116}
117
118REGISTER_COMMAND_PARSER(if, IfCommand::parse);
119REGISTER_COMMAND_PARSER(cond, IfCommand::parse);
120
28void OrCommand::add(RefCount<BoolCommand> &com) { 121void OrCommand::add(RefCount<BoolCommand> &com) {
29 m_commandlist.push_back(com); 122 m_commandlist.push_back(com);
30} 123}
diff --git a/src/FbTk/LogicCommands.hh b/src/FbTk/LogicCommands.hh
index 4f20864..3eb3e8c 100644
--- a/src/FbTk/LogicCommands.hh
+++ b/src/FbTk/LogicCommands.hh
@@ -27,6 +27,7 @@
27#include "Command.hh" 27#include "Command.hh"
28#include "RefCount.hh" 28#include "RefCount.hh"
29 29
30#include <string>
30#include <vector> 31#include <vector>
31 32
32namespace FbTk { 33namespace FbTk {
@@ -43,7 +44,8 @@ public:
43 } else 44 } else
44 if (*m_f) m_f->execute(); 45 if (*m_f) m_f->execute();
45 } 46 }
46 47 static Command *parse(const std::string &cmd, const std::string &args,
48 bool trusted);
47private: 49private:
48 RefCount<BoolCommand> m_cond; 50 RefCount<BoolCommand> m_cond;
49 RefCount<Command> m_t, m_f; 51 RefCount<Command> m_t, m_f;
diff --git a/src/FbTk/MacroCommand.cc b/src/FbTk/MacroCommand.cc
index 491b01e..20e91e4 100644
--- a/src/FbTk/MacroCommand.cc
+++ b/src/FbTk/MacroCommand.cc
@@ -23,8 +23,56 @@
23 23
24#include "MacroCommand.hh" 24#include "MacroCommand.hh"
25 25
26#include "CommandRegistry.hh"
27#include "StringUtil.hh"
28
29#include <string>
30
26namespace FbTk { 31namespace FbTk {
27 32
33namespace {
34
35template <typename M>
36M *addCommands(M *macro, const std::string &args, bool trusted) {
37
38 std::string cmd;
39 int err = 0;
40 int pos = 0;
41
42 while (true) {
43 RefCount<Command> next(0);
44 pos += err;
45 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
46 '{', '}', " \t\n", true);
47 if (err == 0)
48 break;
49 if (err > 0)
50 next = CommandRegistry::instance().parseLine(cmd, trusted);
51 if (*next != 0)
52 macro->add(next);
53 }
54
55 if (macro->size() > 0)
56 return macro;
57
58 delete macro;
59 return 0;
60}
61
62Command *parseMacroCmd(const std::string &command, const std::string &args,
63 bool trusted) {
64 if (command == "macrocmd")
65 return addCommands<MacroCommand>(new MacroCommand, args, trusted);
66 else if (command == "togglecmd")
67 return addCommands<ToggleCommand>(new ToggleCommand, args, trusted);
68 return 0;
69}
70
71REGISTER_COMMAND_PARSER(macrocmd, parseMacroCmd);
72REGISTER_COMMAND_PARSER(togglecmd, parseMacroCmd);
73
74}; // end anonymous namespace
75
28void MacroCommand::add(RefCount<Command> &com) { 76void MacroCommand::add(RefCount<Command> &com) {
29 m_commandlist.push_back(com); 77 m_commandlist.push_back(com);
30} 78}
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index 2bf9da7..f3e928d 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -16,6 +16,7 @@ imlib2_SOURCE= ImageImlib2.hh ImageImlib2.cc
16endif 16endif
17 17
18libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \ 18libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
19 CommandRegistry.hh CommandRegistry.cc \
19 FileUtil.hh FileUtil.cc \ 20 FileUtil.hh FileUtil.cc \
20 EventHandler.hh EventManager.hh EventManager.cc \ 21 EventHandler.hh EventManager.hh EventManager.cc \
21 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \ 22 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \
diff --git a/src/FbTk/StringUtil.cc b/src/FbTk/StringUtil.cc
index 869a3b5..9b4928b 100644
--- a/src/FbTk/StringUtil.cc
+++ b/src/FbTk/StringUtil.cc
@@ -233,6 +233,18 @@ string::size_type removeTrailingWhitespace(string &str) {
233 return first_pos; 233 return first_pos;
234} 234}
235 235
236void getFirstWord(const std::string &in, std::string &word, std::string &rest) {
237 word = in;
238 string::size_type first_pos = StringUtil::removeFirstWhitespace(word);
239 string::size_type second_pos = word.find_first_of(" \t", first_pos);
240 if (second_pos != string::npos) {
241 rest = word.substr(second_pos);
242 word.erase(second_pos);
243 removeFirstWhitespace(rest);
244 removeTrailingWhitespace(rest);
245 }
246}
247
236}; // end namespace StringUtil 248}; // end namespace StringUtil
237 249
238}; // end namespace FbTk 250}; // end namespace FbTk
diff --git a/src/FbTk/StringUtil.hh b/src/FbTk/StringUtil.hh
index b45d6a2..7f0cf54 100644
--- a/src/FbTk/StringUtil.hh
+++ b/src/FbTk/StringUtil.hh
@@ -64,6 +64,9 @@ std::string basename(const std::string &basename);
64std::string::size_type removeFirstWhitespace(std::string &str); 64std::string::size_type removeFirstWhitespace(std::string &str);
65std::string::size_type removeTrailingWhitespace(std::string &str); 65std::string::size_type removeTrailingWhitespace(std::string &str);
66 66
67/// removes the first part of a string and returns the two pieces
68void getFirstWord(const std::string &in, std::string &first, std::string &rest);
69
67/// Breaks a string into tokens 70/// Breaks a string into tokens
68template <typename Container> 71template <typename Container>
69static void 72static void