From 4edae3f518353bb21a02fcda2dfcff83c5a72fc3 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 26 Jan 2012 12:08:39 +0100 Subject: New onCommit scripting system. --- server/src/luascript.cc | 303 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 server/src/luascript.cc (limited to 'server/src/luascript.cc') diff --git a/server/src/luascript.cc b/server/src/luascript.cc new file mode 100644 index 0000000..f4aef40 --- /dev/null +++ b/server/src/luascript.cc @@ -0,0 +1,303 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * luascript.cc + * + * Tue Jan 10 14:43:39 CET 2012 + * Copyright 2012 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro 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 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "luascript.h" + +#include "configuration.h" +#include "debug.h" + +#include "luautil.h" +#include "luapraxisd.h" + +#define GLOBAL_POINTER "_pracroGlobalLUAObjectPointerThisShouldBeANameThatIsNotAccidentallyOverwritten" + +static int _value(lua_State *L) +{ + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + + std::string name = lua_tostring(L, lua_gettop(L)); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + if(lua->hasValue(name)) { + lua_pushstring(L, lua->value(name).c_str()); + } else { + lua_pushnil(L); + } + + return 1; +} + +static int _patientid(lua_State *L) +{ + Pracro::checkParameters(L, Pracro::T_END); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua_pushstring(L, lua->env(LUAScript::ENV_PATIENTID).c_str()); + + return 1; +} + +static int _template(lua_State *L) +{ + Pracro::checkParameters(L, Pracro::T_END); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua_pushstring(L, lua->env(LUAScript::ENV_TEMPLATE).c_str()); + + return 1; +} + +static int _macro(lua_State *L) +{ + Pracro::checkParameters(L, Pracro::T_END); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua_pushstring(L, lua->env(LUAScript::ENV_MACRO).c_str()); + + return 1; +} + +static int _user(lua_State *L) +{ + Pracro::checkParameters(L, Pracro::T_END); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua_pushstring(L, lua->env(LUAScript::ENV_USER).c_str()); + + return 1; +} + +LUAScript::LUAScript() +{ + L = NULL; +} + +void LUAScript::init() + throw(Exception) +{ + if(L) return; + + L = luaL_newstate(); + if(L == NULL) { + ERR(luaresume, "Could not create LUA state.\n"); + throw Exception("Could not create LUA state."); + } + + luaL_openlibs(L); + + lua_pushlightuserdata(L, this); // Push the pointer to 'this' instance + lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var. + + lua_register(L, "value", _value); + lua_register(L, "patientid", _patientid); + lua_register(L, "template", _template); + lua_register(L, "macro", _macro); + lua_register(L, "user", _user); + + register_praxisd(L); +} + +void LUAScript::addFile(std::string src) +{ + std::string file = + Conf::xml_basedir + "/include/" + src; + FILE *fp = fopen(file.c_str(), "r"); + if(fp) { + char buf[64]; + size_t sz; + std::string inc; + while((sz = fread(buf, 1, sizeof(buf), fp)) != 0) { + inc.append(buf, sz); + } + fclose(fp); + addCode(inc, file); + } +} + +void LUAScript::addCode(std::string c, std::string name) +{ + scripts.push_back(std::make_pair(c, name)); +} + +void LUAScript::addValue(std::string name, const std::string &value) +{ + values[name] = value; +} + +void LUAScript::addScripts(std::vector< Script > &scripts) +{ + std::vector< Script >::iterator spi = scripts.begin(); + while(spi != scripts.end()) { + if(spi->attributes.find("src") != spi->attributes.end()) { + std::string src = spi->attributes["src"]; + addFile(src); + } else { + addCode(spi->code); + } + spi++; + } +} + +void LUAScript::run() + throw(Exception) +{ + try { + init(); + } catch(Exception &e) { + throw Exception(e.msg); + } + + if(L == NULL) { + ERR(luaresume, "LUA state not initialized!"); + return; + } + + top = lua_gettop(L); + + std::vector >::iterator i = + scripts.begin(); + while(i != scripts.end()) { + std::string program = i->first; + std::string codename = name(); + if(i->second != "") codename += ": " + i->second; + + DEBUG(luaresume, "Running %s: %s\n", codename.c_str(), program.c_str()); + + if(luaL_loadbuffer(L, program.c_str(), program.size(), codename.c_str())) { + ERR(luaresume, "loadbufer: %s\n", lua_tostring(L, lua_gettop(L))); + throw Exception(lua_tostring(L, lua_gettop(L))); + } + + // Run the loaded code + if(lua_pcall(L, 0, LUA_MULTRET, 0)) { + ERR(luaresume, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); + throw Exception(lua_tostring(L, lua_gettop(L))); + } + + i++; + } +} + +std::string LUAScript::resultString() throw(Exception) +{ + if(top != lua_gettop(L) - 1) { + ERR(luaresume, "Program did not return a single value.\n"); + throw Exception("Program did not return a single value."); + } + + if(lua_isstring(L, lua_gettop(L)) == false) { + ERR(luaresume, "Program did not return a string value.\n"); + throw Exception("Program did not return a string value."); + } + + std::string res = lua_tostring(L, lua_gettop(L)); + lua_pop(L, 1); + + return res; +} + +bool LUAScript::hasValue(std::string name) +{ + return values.find(name) != values.end(); +} + +std::string LUAScript::value(std::string name) +{ + if(values.find(name) != values.end()) return values[name]; + return ""; +} + +std::string LUAScript::env(LUAScript::env_t id) +{ + if(_env.find(id) == _env.end()) return ""; + return _env[id]; +} + +void LUAScript::setEnv(LUAScript::env_t id, std::string value) +{ + _env[id] = value; +} + +#ifdef TEST_LUASCRIPT +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" + +TEST_BEGIN; + +// TODO: Put some testcode here (see test.h for usable macros). +TEST_TRUE(false, "No tests yet!"); + +TEST_END; + +#endif/*TEST_LUASCRIPT*/ -- cgit v1.2.3 From 9833601f819239aa1034d2c5189214f29445dcb0 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 3 May 2012 14:46:48 +0200 Subject: Add debug function for use in lua scripts --- server/src/luascript.cc | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'server/src/luascript.cc') diff --git a/server/src/luascript.cc b/server/src/luascript.cc index f4aef40..6ba52a9 100644 --- a/server/src/luascript.cc +++ b/server/src/luascript.cc @@ -35,6 +35,19 @@ #define GLOBAL_POINTER "_pracroGlobalLUAObjectPointerThisShouldBeANameThatIsNotAccidentallyOverwritten" +static int _debug(lua_State *L) +{ + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + + std::string msg = lua_tostring(L, lua_gettop(L)); + + DEBUG(luascript, "%s\n", msg.c_str()); + + return 0; +} + static int _value(lua_State *L) { Pracro::checkParameters(L, @@ -145,7 +158,7 @@ void LUAScript::init() L = luaL_newstate(); if(L == NULL) { - ERR(luaresume, "Could not create LUA state.\n"); + ERR(luascript, "Could not create LUA state.\n"); throw Exception("Could not create LUA state."); } @@ -159,6 +172,7 @@ void LUAScript::init() lua_register(L, "template", _template); lua_register(L, "macro", _macro); lua_register(L, "user", _user); + lua_register(L, "debug", _debug); register_praxisd(L); } @@ -214,7 +228,7 @@ void LUAScript::run() } if(L == NULL) { - ERR(luaresume, "LUA state not initialized!"); + ERR(luascript, "LUA state not initialized!"); return; } @@ -227,16 +241,16 @@ void LUAScript::run() std::string codename = name(); if(i->second != "") codename += ": " + i->second; - DEBUG(luaresume, "Running %s: %s\n", codename.c_str(), program.c_str()); + DEBUG(luascript, "Running %s: %s\n", codename.c_str(), program.c_str()); if(luaL_loadbuffer(L, program.c_str(), program.size(), codename.c_str())) { - ERR(luaresume, "loadbufer: %s\n", lua_tostring(L, lua_gettop(L))); + ERR(luascript, "loadbuffer: %s\n", lua_tostring(L, lua_gettop(L))); throw Exception(lua_tostring(L, lua_gettop(L))); } // Run the loaded code if(lua_pcall(L, 0, LUA_MULTRET, 0)) { - ERR(luaresume, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); + ERR(luascript, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); throw Exception(lua_tostring(L, lua_gettop(L))); } @@ -247,12 +261,12 @@ void LUAScript::run() std::string LUAScript::resultString() throw(Exception) { if(top != lua_gettop(L) - 1) { - ERR(luaresume, "Program did not return a single value.\n"); + ERR(luascript, "Program did not return a single value.\n"); throw Exception("Program did not return a single value."); } if(lua_isstring(L, lua_gettop(L)) == false) { - ERR(luaresume, "Program did not return a string value.\n"); + ERR(luascript, "Program did not return a string value.\n"); throw Exception("Program did not return a string value."); } -- cgit v1.2.3