From: fennecdjay Date: Fri, 22 Feb 2019 13:03:18 +0000 (+0100) Subject: :art: Initial module commit :smile: X-Git-Tag: nightly~2761^2~11 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=dd68a1138b948a36f2b000f44354c4ff1c2e4e8a;p=gwion.git :art: Initial module commit :smile: --- diff --git a/include/arg.h b/include/arg.h index 09c4179a..2e4d19df 100644 --- a/include/arg.h +++ b/include/arg.h @@ -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; diff --git a/include/gwion.h b/include/gwion.h index 6f68675c..60419534 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -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 index 00000000..f6a53384 --- /dev/null +++ b/include/module.h @@ -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 diff --git a/include/plug.h b/include/plug.h index 2d09d313..fb437a0f 100644 --- a/include/plug.h +++ b/include/plug.h @@ -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 diff --git a/src/arg.c b/src/arg.c index ba4ceff9..9564d8eb 100644 --- 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); } diff --git a/src/main.c b/src/main.c index a41534be..e577fcef 100644 --- a/src/main.c +++ b/src/main.c @@ -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; } diff --git a/src/plug.c b/src/plug.c index 8728faff..69ae120d 100644 --- a/src/plug.c +++ b/src/plug.c @@ -11,26 +11,44 @@ #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 index 00000000..0aa21e6e --- /dev/null +++ b/tests/import/basic_module.c @@ -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"); +} diff --git a/tests/sh/plugin.sh b/tests/sh/plugin.sh index bd14c626..705a73fb 100644 --- a/tests/sh/plugin.sh +++ b/tests/sh/plugin.sh @@ -1,5 +1,5 @@ #!/bin/bash -# [test] #26 +# [test] #27 n=0 [ "$1" ] && n="$1" diff --git a/tests/error/switch_in.gw b/tests/tree/nested_switch.gw similarity index 72% rename from tests/error/switch_in.gw rename to tests/tree/nested_switch.gw index 098f0ff5..fabddf09 100644 --- a/tests/error/switch_in.gw +++ b/tests/tree/nested_switch.gw @@ -1,5 +1,3 @@ -// [skip] -// [contains] swith inside an other switch switch(maybe) { case 1: <<<1>>>;break; case 0: