when calculating average slave/master delta, use absolute value.
[ardour.git] / libs / ardour / luascripting.cc
index 2d3c7d744aa1d4498544bc6186578bee95bfded8..5d0b45aaf5506888fe3bc126f11a37c485211846 100644 (file)
@@ -32,7 +32,8 @@
 #include "lua/luastate.h"
 #include "LuaBridge/LuaBridge.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
+#include "sha1.c"
 
 using namespace ARDOUR;
 using namespace PBD;
@@ -55,6 +56,8 @@ LuaScripting::LuaScripting ()
        , _sl_hook (0)
        , _sl_action (0)
        , _sl_snippet (0)
+       , _sl_setup (0)
+       , _sl_tracks (0)
 {
        ;
 }
@@ -68,6 +71,8 @@ LuaScripting::~LuaScripting ()
                delete _sl_hook;
                delete _sl_action;
                delete _sl_snippet;
+               delete _sl_setup;
+               delete _sl_tracks;
        }
 }
 
@@ -82,12 +87,16 @@ LuaScripting::refresh (bool run_scan)
        delete _sl_hook;
        delete _sl_action;
        delete _sl_snippet;
+       delete _sl_setup;
+       delete _sl_tracks;
 
        _sl_dsp = 0;
        _sl_session = 0;
        _sl_hook = 0;
        _sl_action = 0;
        _sl_snippet = 0;
+       _sl_setup = 0;
+       _sl_tracks = 0;
 
        if (run_scan) {
                lm.release ();
@@ -119,6 +128,8 @@ LuaScripting::scan ()
        CLEAR_OR_NEW (_sl_hook)
        CLEAR_OR_NEW (_sl_action)
        CLEAR_OR_NEW (_sl_snippet)
+       CLEAR_OR_NEW (_sl_setup)
+       CLEAR_OR_NEW (_sl_tracks)
 
 #undef CLEAR_OR_NEW
 
@@ -147,6 +158,9 @@ LuaScripting::scan ()
                        case LuaScriptInfo::Snippet:
                                _sl_snippet->push_back(lsi);
                                break;
+                       case LuaScriptInfo::SessionInit:
+                               _sl_setup->push_back(lsi);
+                               break;
                        default:
                                break;
                }
@@ -157,6 +171,8 @@ LuaScripting::scan ()
        std::sort (_sl_hook->begin(), _sl_hook->end(), ScriptSorter());
        std::sort (_sl_action->begin(), _sl_action->end(), ScriptSorter());
        std::sort (_sl_snippet->begin(), _sl_snippet->end(), ScriptSorter());
+       std::sort (_sl_setup->begin(), _sl_setup->end(), ScriptSorter());
+       std::sort (_sl_tracks->begin(), _sl_tracks->end(), ScriptSorter());
 
        scripts_changed (); /* EMIT SIGNAL */
 }
@@ -178,14 +194,14 @@ LuaScripting::scan_script (const std::string &fn, const std::string &sc)
 
        lua_State* L = lua.getState();
        lua.Print.connect (&LuaScripting::lua_print);
-
-       lua.do_command ("io = nil;");
+       lua.sandbox (true);
 
        lua.do_command (
                        "ardourluainfo = {}"
                        "function ardour (entry)"
                        "  ardourluainfo['type'] = assert(entry['type'])"
                        "  ardourluainfo['name'] = assert(entry['name'])"
+                       "  ardourluainfo['category'] = entry['category'] or 'Unknown'"
                        "  ardourluainfo['author'] = entry['author'] or 'Unknown'"
                        "  ardourluainfo['license'] = entry['license'] or ''"
                        "  ardourluainfo['description'] = entry['description'] or ''"
@@ -236,7 +252,24 @@ LuaScripting::scan_script (const std::string &fn, const std::string &sc)
                return LuaScriptInfoPtr();
        }
 
-       LuaScriptInfoPtr lsi (new LuaScriptInfo (type, name, fn));
+       char hash[41];
+       Sha1Digest s;
+       sha1_init (&s);
+
+       if (fn.empty()) {
+               sha1_write (&s, (const uint8_t *) sc.c_str(), sc.size ());
+       } else {
+               try {
+                       std::string script = Glib::file_get_contents (fn);
+                       sha1_write (&s, (const uint8_t *) script.c_str(), script.size ());
+               } catch (Glib::FileError err) {
+                       return LuaScriptInfoPtr();
+               }
+       }
+       sha1_result_hash (&s, hash);
+
+
+       LuaScriptInfoPtr lsi (new LuaScriptInfo (type, name, fn, hash));
 
        for (luabridge::Iterator i(nfo); !i.isNil (); ++i) {
                if (!i.key().isString() || !i.value().isString()) {
@@ -248,6 +281,26 @@ LuaScripting::scan_script (const std::string &fn, const std::string &sc)
                if (key == "author") { lsi->author = val; }
                if (key == "license") { lsi->license = val; }
                if (key == "description") { lsi->description = val; }
+               if (key == "category") { lsi->category = val; }
+       }
+
+
+       if (type == LuaScriptInfo::EditorAction) {
+
+               luabridge::LuaRef lua_rs = luabridge::getGlobal (L, "route_setup");
+               if (lua_rs.isFunction ()) {
+                       lsi->subtype |= LuaScriptInfo::RouteSetup;
+               }
+
+               luabridge::LuaRef lua_ss = luabridge::getGlobal (L, "session_setup");
+               if (lua_ss.isFunction ()) {
+                       try {
+                               if (lua_ss () == true) {
+                                       lsi->subtype |= LuaScriptInfo::SessionSetup;
+                               }
+                       } catch (...) { }
+               }
+
        }
 
        return lsi;
@@ -256,7 +309,7 @@ LuaScripting::scan_script (const std::string &fn, const std::string &sc)
 LuaScriptList &
 LuaScripting::scripts (LuaScriptInfo::ScriptType type) {
 
-       if (!_sl_dsp || !_sl_session || !_sl_hook || !_sl_action || !_sl_snippet) {
+       if (!_sl_dsp || !_sl_session || !_sl_hook || !_sl_action || !_sl_snippet || ! _sl_setup || ! _sl_tracks) {
                scan ();
        }
 
@@ -276,6 +329,9 @@ LuaScripting::scripts (LuaScriptInfo::ScriptType type) {
                case LuaScriptInfo::Snippet:
                        return *_sl_snippet;
                        break;
+               case LuaScriptInfo::SessionInit:
+                       return *_sl_setup;
+                       break;
                default:
                        break;
        }
@@ -291,6 +347,7 @@ LuaScriptInfo::type2str (const ScriptType t) {
                case LuaScriptInfo::EditorHook: return "EditorHook";
                case LuaScriptInfo::EditorAction: return "EditorAction";
                case LuaScriptInfo::Snippet: return "Snippet";
+               case LuaScriptInfo::SessionInit: return "SessionInit";
                default: return "Invalid";
        }
 }
@@ -303,11 +360,12 @@ LuaScriptInfo::str2type (const std::string& str) {
        if (!strcasecmp (type, "EditorHook")) {return LuaScriptInfo::EditorHook;}
        if (!strcasecmp (type, "EditorAction")) {return LuaScriptInfo::EditorAction;}
        if (!strcasecmp (type, "Snippet")) {return LuaScriptInfo::Snippet;}
+       if (!strcasecmp (type, "SessionInit")) {return LuaScriptInfo::SessionInit;}
        return LuaScriptInfo::Invalid;
 }
 
 LuaScriptParamList
-LuaScriptParams::script_params (LuaScriptInfoPtr lsi, const std::string &pname)
+LuaScriptParams::script_params (const LuaScriptInfoPtr& lsi, const std::string &pname)
 {
        assert (lsi);
        return LuaScriptParams::script_params (lsi->path, pname);
@@ -320,7 +378,7 @@ LuaScriptParams::script_params (const std::string& s, const std::string &pname,
 
        LuaState lua;
        lua_State* L = lua.getState();
-       lua.do_command ("io = nil;");
+       lua.sandbox (true);
        lua.do_command ("function ardour () end");
 
        try {
@@ -329,7 +387,7 @@ LuaScriptParams::script_params (const std::string& s, const std::string &pname,
                } else {
                        lua.do_command (s);
                }
-       } catch (luabridge::LuaException const& e) {
+       } catch (...) {
                return rv;
        }
 
@@ -397,6 +455,7 @@ LuaScripting::try_compile (const std::string& script, const LuaScriptParamList&
        }
        LuaState l;
        l.Print.connect (&LuaScripting::lua_print);
+       l.sandbox (true);
        lua_State* L = l.getState();
 
        l.do_command (""
@@ -406,7 +465,7 @@ LuaScripting::try_compile (const std::string& script, const LuaScriptParamList&
                        "  assert(type(f) == 'string', 'Assigned ByteCode must be string')"
                        "  local factory = load(f)"
                        "  assert(type(factory) == 'function', 'Factory is a not a function')"
-                       "  local env = _ENV;  env.f = nil env.debug = nil os.exit = nil"
+                       "  local env = _ENV; env.f = nil env.os = nil env.io = nil"
                        "  load (string.dump(factory, true), nil, nil, env)(a)"
                        " end"
                        );
@@ -425,16 +484,17 @@ LuaScripting::try_compile (const std::string& script, const LuaScriptParamList&
                cerr << e.what() << "\n";
 #endif
                lua_print (e.what());
-       }
+       } catch (...) { }
 
        return false;
 }
 
 std::string
-LuaScripting::get_factory_bytecode (const std::string& script)
+LuaScripting::get_factory_bytecode (const std::string& script, const std::string& ffn, const std::string& fp)
 {
        LuaState l;
        l.Print.connect (&LuaScripting::lua_print);
+       l.sandbox (true);
        lua_State* L = l.getState();
 
        l.do_command (
@@ -442,7 +502,7 @@ LuaScripting::get_factory_bytecode (const std::string& script)
                        ""
                        " function dump_function (f)"
                        "  assert(type(f) == 'function', 'Factory is a not a function')"
-                       "  return string.format(\"f = %q\", string.dump(f, true))"
+                       "  return string.format(\"" + fp + " = %q\", string.dump(f, true))"
                        " end"
                        );
 
@@ -450,12 +510,12 @@ LuaScripting::get_factory_bytecode (const std::string& script)
                luabridge::LuaRef lua_dump = luabridge::getGlobal (L, "dump_function");
                l.do_command ("dump_function = nil"); // hide it
                l.do_command (script); // register "factory"
-               luabridge::LuaRef lua_factory = luabridge::getGlobal (L, "factory");
+               luabridge::LuaRef lua_factory = luabridge::getGlobal (L, ffn.c_str());
 
                if (lua_factory.isFunction()) {
                        return (lua_dump(lua_factory)).cast<std::string> ();
                }
-       } catch (luabridge::LuaException const& e) { }
+       } catch (...) { }
        return "";
 }