struct Vector_ add;
struct Vector_ rem;
struct Vector_ lib;
+ struct Vector_ mod;
Vector ref;
m_bool loop;
unsigned quit : 1;
#define __GWION
typedef struct Gwion_* Gwion;
struct Gwion_ {
+// Vector args
+// PlugInfo
+// => Vector v[GWION_NVEC];
// sym
// mem
// rnd
--- /dev/null
+#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
#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
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;
}
vector_release(&arg->add);
vector_release(&arg->rem);
vector_release(&arg->lib);
+ vector_release(&arg->mod);
}
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 }
};
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 '?':
case 'P':
vector_add(&arg->lib, (vtype)optarg);
break;
+ case 'm':
+ vector_add(&arg->mod, (vtype)optarg);
+ break;
default:
arg_drvr(di, i);
}
#define VMBENCH_END
#endif
+#include "gwion.h"
#include "plug.h"
+#include "module.h"
extern void parse_args(Arg*, DriverInfo*);
static VM* some_static_vm;
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};
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));
arg_release(&arg);
if(d.del)
d.del(gwion.vm, &di);
- plug_end(pi);
+ plug_end(&gwion, pi);
gwion_release(&gwion);
return 0;
}
#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;
}
}
-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);
+ }
+ }
}
--- /dev/null
+#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");
+}
#!/bin/bash
-# [test] #26
+# [test] #27
n=0
[ "$1" ] && n="$1"
-// [skip]
-// [contains] swith inside an other switch
switch(maybe) {
case 1: <<<1>>>;break;
case 0: