summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Grueneis <gimpf@spreadspace.org>2010-11-24 00:51:03 +0000
committerMarkus Grueneis <gimpf@spreadspace.org>2010-11-24 00:51:03 +0000
commit727471067c25f14e5ef5b05ee0107a25c069fad9 (patch)
treeaebb791c75cd0dd5a1f02df17452231768b418ac
parentadded cleanup function to exec child (diff)
implemented dispatch-table
added example dispatch-table table... using dispatcher in stdio and exec module git-svn-id: https://svn.spreadspace.org/gcsd/trunk@58 ac14a137-c7f1-4531-abe0-07747231d213
-rw-r--r--examples/simple_dispatcher.lua6
-rw-r--r--src/Makefile1
-rw-r--r--src/dispatch_table.lua79
-rw-r--r--src/main_loop.lua11
-rw-r--r--src/modules/exec.lua5
-rw-r--r--src/modules/stdio.lua5
6 files changed, 100 insertions, 7 deletions
diff --git a/examples/simple_dispatcher.lua b/examples/simple_dispatcher.lua
new file mode 100644
index 0000000..5a931e3
--- /dev/null
+++ b/examples/simple_dispatcher.lua
@@ -0,0 +1,6 @@
+return {
+ ["%w+%s*"] = function(match)
+ local cmd = string.match("(%w+)%s*", match)
+ command_queue:enqueue_command(cmd)
+ end
+} \ No newline at end of file
diff --git a/src/Makefile b/src/Makefile
index 603b3d2..358fb85 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -56,6 +56,7 @@ C_SRCS := $(C_OBJS:%.o=%.c)
LUA_SRCS := client_list.lua \
module_list.lua \
command_queue.lua \
+ dispatch_table.lua \
main_loop.lua
LUA_BYTECODE := $(EXECUTABLE).lc
diff --git a/src/dispatch_table.lua b/src/dispatch_table.lua
new file mode 100644
index 0000000..912394a
--- /dev/null
+++ b/src/dispatch_table.lua
@@ -0,0 +1,79 @@
+--
+-- gcsd
+--
+-- gcsd the generic command sequencer daemon can be used to serialize
+-- commands sent over various paralell communication channels to a
+-- single command output. It can be seen as a multiplexer for any
+-- kind of communication between a single resource and various clients
+-- which want to submit commands to it or query information from it.
+-- gcsd is written in C and Lua. The goal is to provide an easy to
+-- understand high level API based on Lua which can be used to
+-- implement the business logic of the so formed multiplexer daemon.
+--
+--
+-- Copyright (C) 2009-2010 Markus Grueneis <gimpf@spreadspace.org>
+-- Christian Pointner <equinox@spreadspace.org>
+--
+-- This file is part of gcsd.
+--
+-- gcsd is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- any later version.
+--
+-- gcsd is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with gcsd. If not, see <http://www.gnu.org/licenses/>.
+--
+
+dispatch_table = {}
+dispatch_table.regex_to_handler = {
+ -- TODO basic mode
+}
+
+function dispatch_table:load_handler_table_file(filename)
+ local defines = require('defines')
+ if (type(filename) ~= "nil") then
+ if (type(filename) ~= "string") then
+ log.printf(log.ERROR, "filename must be of type 'string' and denote a valid path")
+ return defines.KILL_DAEMON
+ end
+ local chunk = loadfile(filename)
+ if (not chunk) then
+ log.printf(log.ERROR, "failed to load lua-file '%s'", filename)
+ return defines.KILL_DAEMON
+ end
+ self:register_handler_table(chunk())
+ log.printf(log.NOTICE, "loaded dispatch table from file %s", filename)
+ end
+ return defines.OK
+end
+
+function dispatch_table:register_handler_table(handler_table)
+ if (type(handler_table) ~= "table") then
+ error("handler_table must be of type 'table'")
+ end
+ self.regex_to_handler = handler_table
+end
+
+function dispatch_table:dispatch(command_buffer)
+ local init = 1
+ repeat
+ local had_match = false
+ for regex, handler in pairs(self.regex_to_handler) do
+ local match = string.match(command_buffer, "^" .. regex, init)
+ if match then
+ handler(match)
+ had_match = true
+ init = init + string.len(match)
+ break
+ end
+ end
+ until (not had_match)
+
+ return string.sub(command_buffer, init + 1)
+end
diff --git a/src/main_loop.lua b/src/main_loop.lua
index 2a34477..42cc74c 100644
--- a/src/main_loop.lua
+++ b/src/main_loop.lua
@@ -74,11 +74,16 @@ function main_loop(opt)
log.printf(log.NOTICE, "main_loop started")
local sig = signal.init()
- local return_value = module_list:init(opt)
- if(return_value == defines.KILL_DAEMON) then
+ local return_value = dispatch_table:load_handler_table_file(opt.lua_code)
+ if (return_value == defines.KILL_DAEMON) then
return_value = -1
else
- return_value = 0
+ return_value = module_list:init(opt)
+ if(return_value == defines.KILL_DAEMON) then
+ return_value = -1
+ else
+ return_value = 0
+ end
end
while return_value == 0 do
diff --git a/src/modules/exec.lua b/src/modules/exec.lua
index 14a8856..09a6335 100644
--- a/src/modules/exec.lua
+++ b/src/modules/exec.lua
@@ -83,9 +83,10 @@ function exec:new(config)
return defines.KILL_MODULE_CLASS
end
- -- TODO: support read until matched command
self.in_buffer = self.in_buffer .. buffer
- -- TODO: dispatch table et al
+ self.in_buffer = dispatch_table:dispatch(self.in_buffer)
+
+ -- TODO: part of expected response handling
command_queue:command_completed()
return defines.OK
diff --git a/src/modules/stdio.lua b/src/modules/stdio.lua
index e31aa89..4069a87 100644
--- a/src/modules/stdio.lua
+++ b/src/modules/stdio.lua
@@ -61,9 +61,10 @@ function stdio:new(config)
return defines.KILL_MODULE_CLASS
end
- -- TODO: support read until matched command
self.in_buffer = self.in_buffer .. buffer
- -- TODO: dispatch table et al
+ self.in_buffer = dispatch_table:dispatch(self.in_buffer)
+
+ -- TODO: part of expected response handling
command_queue:command_completed()
return defines.OK