Introduce the concept of binding.
authorRui Guo <firemeteor.guo@gmail.com>
Tue, 2 Jun 2009 09:00:11 +0000 (2 17:00 +0800)
committerRui Guo <firemeteor.guo@gmail.com>
Tue, 2 Jun 2009 09:00:11 +0000 (2 17:00 +0800)
Bindings are in fact script interpretors. We can have several different
language bindings at the same time, with each registered at the compiling time
and loaded (initialized) dynamically at runtime. It's an bridge between
scripts and screen itself.

1. Rename the scripts struct to binding. Related functions are renamed too.
For example, LoadScripts() is now LoadBindings(); ScriptFInit() is now
FinalizeBindings().

2. Do not need to initialize the binding explicitly.

3. Reorganize the structure of script.c, grouping binding related stuffs
together.

4. Add myself to the copyright line of script.c.

5. Fully implement the logic of ScriptSource().

src/lua.c
src/screen.c
src/script.c
src/script.h

index 5fd9e18..b056ff3 100644 (file)
--- a/src/lua.c
+++ b/src/lua.c
@@ -670,7 +670,7 @@ int LuaForeWindowChanged(void)
   return 0;
 }
 
-int LuaSource(const char *file)
+int LuaSource(const char *file, int async)
 {
   if (!L)
     return 0;
@@ -774,3 +774,15 @@ struct ScriptFuncs LuaFuncs =
   LuaCommandExecuted
 };
 
+struct binding lua_binding =
+{
+    "lua", /*name*/
+    0,     /*inited*/
+    0,     /*registered*/
+    LuaInit,
+    LuaFinit,
+    LuaSource,
+    0,     /*b_next*/
+    &LuaFuncs
+};
+
index 158b9f6..41ac67d 100644 (file)
@@ -1354,8 +1354,7 @@ char **av;
   InitKeytab();
 
 #ifdef SCRIPT
-  LoadScripts();
-  ScriptInit();
+  LoadBindings();
   if (script_file)
     {
       ScriptSource(script_file);
@@ -1774,7 +1773,7 @@ int i;
   debug1("Finit(%d);\n", i);
 
 #ifdef SCRIPT
-  ScriptFinit();
+  FinalizeBindings();
 #endif
 
   while (windows)
index 9f0e6d5..4293be4 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (c) 2008 Sadrul Habib Chowdhury (sadrul@users.sf.net)
+ * 2009 Rui Guo (firemeteor.guo@gmail.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "config.h"
 #include "screen.h"
 
-struct scripts
-{
-  struct scripts *s_next;
-  struct ScriptFuncs *fns;
-};
-
-struct scripts *scripts;
+struct binding *bindings = NULL;
 
 static void
-AddScript(struct ScriptFuncs *sf)
+register_binding (struct binding *new_binding)
 {
-  struct scripts *ns = (struct scripts *)calloc(1, sizeof(*ns));
-  if (!ns)
-    return;
-  ns->fns = sf;
-  ns->s_next = scripts;
-  scripts = ns;
+  if (!new_binding->registered)
+    {
+      new_binding->b_next = bindings;
+      bindings = new_binding;
+      new_binding->registered = 1;
+    }
 }
 
-#define ALL_SCRIPTS(fn, params, stop) do { \
-  struct scripts *iter; \
-  for (iter = scripts; iter; iter = iter->s_next) \
-    { \
-      if (iter->fns->fn && (ret = (iter->fns->fn params)) && stop) \
-       break; \
-    } \
-} while (0)
-
-void ScriptInit(void)
-{
-  int ret;
-  ALL_SCRIPTS(sf_Init, (), 0);
-}
+#ifdef LUA_BINDING
+extern struct binding lua_binding;
+#endif
 
-void ScriptFinit(void)
+void LoadBindings(void)
 {
-  int ret;
-  ALL_SCRIPTS(sf_Finit, (), 0);
+#ifdef LUA_BINDING
+  register_binding(&lua_binding);
+#endif
 }
 
-void ScriptForeWindowChanged(void)
+void
+FinalizeBindings (void)
 {
-  int ret;
-  ALL_SCRIPTS(sf_ForeWindowChanged, (), 0);
+  struct binding *binding=bindings;
+  while(binding)
+    {
+      if (binding->inited)
+        binding->bd_Finit();
+      binding = binding->b_next;
+    }
 }
 
-void ScriptSource(int argc, const char **argv)
+void 
+ScriptSource(int argc, const char **argv)
 {
-  int ret;
+  int ret = 0;
   int async = 0;
-  const char *binding = 0, *path;
+  const char *bd_select = 0, *script;
+  struct binding *binding = bindings;
 
+  /* Parse the commandline options
+   * sourcescript [-async|-a] [-binding|-b <binding>] script
+   */
   while (*argv && **argv == '-') {
       // check for (-a | -async)
       if ((*argv[1] == 'a' && !*argv[2])
@@ -82,18 +78,41 @@ void ScriptSource(int argc, const char **argv)
       else if ((*argv[1] == 'b' && !*argv[2])
                || strcmp(*argv, "-binding") == 0) {
           argv++;
-          binding = *argv;
+          bd_select = *argv;
       }
       argv++;
   }
+  script = *argv;
+
+  while (binding) {
+      if (!bd_select || strcmp(bd_select, binding->name) == 0) {
+          //dynamically initialize the binding
+          if (!binding->inited)
+            binding->bd_Init();
 
-  path = *argv;
-  if (!binding) {
-  /* If one script loader accepts the file, we don't send it to any other loader */
-  ALL_SCRIPTS(sf_Source, (path), 1);
-  } else {
-      //TODO: select the specified engine.
+          //and source the script
+          if (ret = binding->bd_Source(script, async))
+            break;
+      }
+      binding = binding->b_next;
   }
+  if (!ret)
+    LMsg(1, "Could not source specified script %s", script);
+}
+
+#define ALL_SCRIPTS(fn, params, stop) do { \
+  struct binding *iter; \
+  for (iter = bindings; iter; iter = iter->b_next) \
+    { \
+      if (iter->fns->fn && (ret = (iter->fns->fn params)) && stop) \
+       break; \
+    } \
+} while (0)
+
+void ScriptForeWindowChanged(void)
+{
+  int ret;
+  ALL_SCRIPTS(sf_ForeWindowChanged, (), 0);
 }
 
 int ScriptProcessCaption(const char *str, struct win *win, int len)
@@ -110,16 +129,3 @@ int ScriptCommandExecuted(const char *command, const char **args, int argc)
   return ret;
 }
 
-#define HAVE_LUA 1   /* XXX: Remove */
-#if HAVE_LUA
-extern struct ScriptFuncs LuaFuncs;
-#endif
-
-void LoadScripts(void)
-{
-  /* XXX: We could load the script loaders dynamically */
-#if HAVE_LUA
-  AddScript(&LuaFuncs);
-#endif
-}
-
index 78259b9..67b151a 100644 (file)
@@ -18,7 +18,8 @@
  ****************************************************************
  * $Id$ FAU
  */
-
+#ifndef SCRIPT_H
+#define SCRIPT_H
 struct win;
 
 struct ScriptFuncs
@@ -26,10 +27,26 @@ struct ScriptFuncs
   int (*sf_Init) __P((void));
   int (*sf_Finit) __P((void));
   int (*sf_ForeWindowChanged) __P((void));
-  int (*sf_Source) __P((const char *));
+  int (*sf_Source) __P((const char *, int));
   int (*sf_ProcessCaption) __P((const char *, struct win *, int len));
   int (*sf_CommandExecuted) __P((const char *, const char **, int));
 };
 
-void LoadScripts(void);
+struct binding
+{
+  char * name;
+  int inited;
+  int registered;
+  int (*bd_Init) __P((void));
+  int (*bd_Finit) __P((void));
+  /*Returns zero on failure, non zero on success*/
+  int (*bd_Source) __P((const char *, int));
+  struct binding *b_next;
+  struct ScriptFuncs *fns;
+};
+
+void LoadBindings(void);
+void FinializeBindings(void);
+
 
+#endif