]> Nishi Git Mirror - gwion.git/commitdiff
:art: Initial module commit :smile:
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 22 Feb 2019 13:03:18 +0000 (14:03 +0100)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 22 Feb 2019 13:03:18 +0000 (14:03 +0100)
include/arg.h
include/gwion.h
include/module.h [new file with mode: 0644]
include/plug.h
src/arg.c
src/main.c
src/plug.c
tests/import/basic_module.c [new file with mode: 0644]
tests/sh/plugin.sh
tests/tree/nested_switch.gw [moved from tests/error/switch_in.gw with 72% similarity]

index 09c4179acb924b670b35ea00a7184b197e5b66e8..2e4d19dfe955ca4bf1453481e5c80decdd7d58fb 100644 (file)
@@ -6,6 +6,7 @@ typedef struct {
   struct Vector_ add;
   struct Vector_ rem;
   struct Vector_ lib;
+  struct Vector_ mod;
   Vector ref;
   m_bool loop;
   unsigned quit : 1;
index 6f68675cd2524f0e60183f0ed91cfb7a01d899c8..6041953441cccd5442daec83a7de033d319a160e 100644 (file)
@@ -2,6 +2,9 @@
 #define __GWION
 typedef struct Gwion_* Gwion;
 struct Gwion_ {
+// Vector args
+// PlugInfo
+// => Vector v[GWION_NVEC];
 // sym
 // mem
 // rnd
diff --git a/include/module.h b/include/module.h
new file mode 100644 (file)
index 0000000..f6a5338
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __MODULE
+#define __MODULE
+#define GWMODNAME_NAME "gwmodname"
+#define GWMODINI_NAME  "gwmodini"
+#define GWMODEND_NAME  "gwmodend"
+#define GWMODNAME_FUNC gwmodname
+#define GWMODINI_FUNC  gwmodini
+#define GWMODEND_FUNC  gwmodend
+#define GWMODNAME(a) m_str GWMODNAME_FUNC() { return a; }
+#define GWMODINI(a)  ANN void* GWMODINI_FUNC(const Gwion gwion, const Vector args)
+#define GWMODEND(a)  ANN void  GWMODEND_FUNC(const Gwion gwion, void* self)
+
+//typedef void* (*f_gwmodname)(void);
+typedef void* (*f_gwmodini)(const Gwion, const Vector);
+typedef void* (*f_gwmodend)(const Gwion, void*);
+void module_ini(const Gwion gwion, Vector v, Vector);
+#endif
index 2d09d313ddcd18bc2a7e543e364ad86683e59b56..fb437a0f717369a18e2dfa448951faf11e76e2c4 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef __PLUG
 #define __PLUG
-#define NPLUG_VEC 2
-typedef struct Vector_ PlugInfo[NPLUG_VEC];
+
+enum plug_t {
+  GWPLUG_DL,
+  GWPLUG_IMPORT,
+  GWPLUG_MODULE,
+  GWPLUG_LAST
+};
+
+typedef struct Vector_ PlugInfo[GWPLUG_LAST];
 void plug_ini(PlugInfo, Vector);
-void plug_end(PlugInfo);
+void plug_end(const Gwion gwion, PlugInfo);
 #endif
index ba4ceff9865123abf99c006860a94ea2c79a3863..9564d8eb964fff36173a9341e13a54ce478a62b6 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -14,6 +14,7 @@ ANN void arg_init(Arg* arg) {
   vector_init(&arg->add);
   vector_init(&arg->rem);
   vector_init(&arg->lib);
+  vector_init(&arg->mod);
   vector_add(&arg->lib, (vtype)GWPLUG_DIR);
   arg->ref = &arg->add;
 }
@@ -22,6 +23,7 @@ ANN void arg_release(Arg* arg) {
   vector_release(&arg->add);
   vector_release(&arg->rem);
   vector_release(&arg->lib);
+  vector_release(&arg->mod);
 }
 
 static const struct option long_option[] = {
@@ -48,6 +50,7 @@ static const struct option long_option[] = {
   { "help",     0, NULL, '?' },
   { "version",  0, NULL, 'v' },
   { "config",   0, NULL, 'C' },
+  { "module",   0, NULL, 'm' },
   /*  { "status"  , 0, NULL, '%' },*/
   { NULL,       0, NULL, 0   }
 };
@@ -136,7 +139,7 @@ ANN static void arg_drvr(DriverInfo* di, const int i) {
 
 ANN void parse_args(Arg* arg, DriverInfo* di) {
   int i, index;
-  while((i = getopt_long(arg->argc, arg->argv, "?vqh:p:i:o:n:b:e:s:d:l:g:-:rc:f:P:C ",
+  while((i = getopt_long(arg->argc, arg->argv, "?vqh:p:i:o:n:b:e:s:d:l:g:-:rc:f:m:P:C ",
       long_option, &index)) != -1) {
     switch(i) {
       case '?':
@@ -155,6 +158,9 @@ ANN void parse_args(Arg* arg, DriverInfo* di) {
       case 'P':
         vector_add(&arg->lib, (vtype)optarg);
         break;
+      case 'm':
+        vector_add(&arg->mod, (vtype)optarg);
+        break;
       default:
         arg_drvr(di, i);
     }
index a41534be0b7293ed72f2cafa79a7231e9e44d60d..e577fcefedfe853cef2094f17bb08913009be7ac 100644 (file)
@@ -29,7 +29,9 @@
 #define VMBENCH_END
 #endif
 
+#include "gwion.h"
 #include "plug.h"
+#include "module.h"
 
 extern void parse_args(Arg*, DriverInfo*);
 static VM* some_static_vm;
@@ -38,7 +40,6 @@ static void sig(int unused __attribute__((unused))) {
   some_static_vm->is_running = 0;
 }
 
-#include "gwion.h"
 int main(int argc, char** argv) {
   Driver d = { };
   Arg arg = { .argc = argc, .argv=argv, .loop=-1, .quit=0};
@@ -73,8 +74,9 @@ struct Gwion_ gwion;
   shreduler_set_loop(gwion.vm->shreduler, arg.loop);
   if(d.ini(gwion.vm, &di) < 0 || !(gwion.vm->bbq = new_bbq(&di)))
     goto clean;
-  if(type_engine_init(gwion.vm, &pi[1]) < 0)
+  if(type_engine_init(gwion.vm, &pi[GWPLUG_IMPORT]) < 0)
     goto clean;
+  module_ini(&gwion, &pi[GWPLUG_MODULE], &arg.mod);
   srand((uint)time(NULL));
   for(m_uint i = 0; i < vector_size(&arg.add); i++)
     compile_filename(&gwion, (m_str)vector_at(&arg.add, i));
@@ -86,7 +88,7 @@ clean:
   arg_release(&arg);
   if(d.del)
     d.del(gwion.vm, &di);
-  plug_end(pi);
+  plug_end(&gwion, pi);
   gwion_release(&gwion);
   return 0;
 }
index 8728faffe24bc32f74ec40a63a6db1cb97d78380..69ae120da7f05f99bc10231d80e080a7e09832c1 100644 (file)
 #include "instr.h"
 #include "object.h"
 #include "import.h"
+#include "gwion.h"
 #include "plug.h"
+#include "module.h"
 
 static inline int so_filter(const struct dirent* dir) {
   return strstr(dir->d_name, ".so") ? 1 : 0;
 }
 
+struct Plug_ {
+  m_str name;
+  f_gwmodini ini;
+  f_gwmodend end;
+  void* self;
+};
+
 ANN static void handle_plug(PlugInfo v, const m_str c) {
   void* handler = dlopen(c, RTLD_LAZY);
   if(handler) {
-    vector_add(&v[0], (vtype)handler);
-    m_bool(*import)(Gwi) = (m_bool(*)(Gwi))(intptr_t)dlsym(handler, "import");
+    vector_add(&v[GWPLUG_DL], (vtype)handler);
+    m_bool (*import)(Gwi) = (m_bool(*)(Gwi))(intptr_t)dlsym(handler, "import");
     if(import)
-      vector_add(&v[1], (vtype)import);
+      vector_add(&v[GWPLUG_IMPORT], (vtype)import);
+    const f_gwmodini ini = (f_gwmodini)(intptr_t)dlsym(handler, GWMODINI_NAME);
+    if(ini) {
+      struct Plug_ *plug = mp_alloc(Plug);
+      plug->ini  = ini;
+      m_str (*name)() = (m_str(*)())(intptr_t)dlsym(handler, GWMODNAME_NAME);
+      plug->name = name();
+      plug->end  = (f_gwmodend)(intptr_t)dlsym(handler, GWMODEND_NAME);
+      vector_add(&v[GWPLUG_MODULE], (vtype)plug);
+    }
   } else
     err_msg(0, "error in %s.", dlerror());
 }
 
 void plug_ini(PlugInfo v, Vector list) {
-  vector_init(&v[0]);
-  vector_init(&v[1]);
+  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
+    vector_init(&v[i]);
   for(m_uint i = 0; i < vector_size(list); i++) {
    const m_str dirname = (m_str)vector_at(list, i);
    struct dirent **namelist;
@@ -47,9 +65,47 @@ void plug_ini(PlugInfo v, Vector list) {
   }
 }
 
-void plug_end(PlugInfo v) {
-  for(m_uint i = 0; i < vector_size(&v[0]); ++i)
-    dlclose((void*)vector_at(&v[0], i));
-  vector_release(&v[0]);
-  vector_release(&v[1]);
+void plug_end(const Gwion gwion, PlugInfo v) {
+  for(m_uint i = 0; i < vector_size(&v[GWPLUG_MODULE]); ++i) {
+    struct Plug_ *plug = (struct Plug_*)vector_at(&v[GWPLUG_MODULE], i);
+    if(plug->end)
+      plug->end(gwion, plug->self);
+    mp_free(Plug, plug);
+  }
+  for(m_uint i = 0; i < vector_size(&v[GWPLUG_DL]); ++i)
+    dlclose((void*)vector_at(&v[GWPLUG_DL], i));
+  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
+    vector_release(&v[i]);
+}
+
+ANN static Vector get_arg(const m_str name, const Vector v) {
+  const size_t len = strlen(name);
+  for(m_uint i = vector_size(v) + 1; --i;) {
+    const m_str str = (m_str)vector_at(v, i - 1);
+    const m_str arg = strchr(str, '=');
+    if(!strncmp(name, str, len)) {
+      m_str c, d = strdup(arg+1);
+      c = d;
+      const Vector args = new_vector();
+      while(d)
+        vector_add(args, (vtype)strdup(strsep(&d, ",")));
+      free(d);
+      free(c);
+      return args;
+    }
+  }
+  return NULL;
+}
+
+void module_ini(const Gwion gwion, Vector v, Vector args) {
+  for(m_uint i = 0; i < vector_size(v); ++i) {
+    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
+    const Vector arg = get_arg(plug->name, args);
+    plug->self = plug->ini(gwion, arg);
+    if(arg) {
+      for(m_uint i = 0; i < vector_size(arg); ++i)
+        xfree((m_str)vector_at(arg, i));
+      free_vector(arg);
+    }
+  }
 }
diff --git a/tests/import/basic_module.c b/tests/import/basic_module.c
new file mode 100644 (file)
index 0000000..0aa21e6
--- /dev/null
@@ -0,0 +1,23 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "gwion.h"
+#include "plug.h"
+#include "module.h"
+
+GWMODNAME("basic_module")
+
+GWMODINI(basic_module) {
+  puts("ini module");
+  if(args) {
+    puts("have arguments");
+    for(vtype i = 0; i < vector_size(args); ++i)
+      puts((m_str)vector_at(args, i));
+  }
+}
+
+GWMODEND(basic_module) {
+  puts("end module");
+}
index bd14c626adf2a78bb224eaabc6815e286a5dabc3..705a73fba6f03cc43266eb34b4c2b134f13c9e1f 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# [test] #26
+# [test] #27
 
 n=0
 [ "$1" ] && n="$1"
similarity index 72%
rename from tests/error/switch_in.gw
rename to tests/tree/nested_switch.gw
index 098f0ff5cb04ab76818040a298a8b3da4dac53ff..fabddf099d3b158fa0ba50175cb20b2b8fd8896e 100644 (file)
@@ -1,5 +1,3 @@
-// [skip]
-// [contains] swith inside an other switch
 switch(maybe) {
   case 1: <<<1>>>;break;
   case 0: