src/lua_objs.c
changeset 103 454aea1e4f11
parent 99 155a6c7d3886
child 104 fc196bb4bcc2
equal deleted inserted replaced
102:af4190b743a5 103:454aea1e4f11
    37     // ok
    37     // ok
    38     return ud;
    38     return ud;
    39 }
    39 }
    40 
    40 
    41 /**
    41 /**
       
    42  * Convenience function to create a new metatable for a type, a userdata for that type, and register it as a global
       
    43  */
       
    44 static void* lua_obj_create_global_type (lua_State *L, const char *type_name, const struct luaL_Reg methods[], const char *global_name, size_t size)
       
    45 {
       
    46     // allocate the global object
       
    47     void *obj = lua_newuserdata(L, size);
       
    48     
       
    49     // create the type metatable
       
    50     lua_obj_create_type(L, type_name, methods);
       
    51 
       
    52     // set the userdata's metatable
       
    53     lua_setmetatable(L, -2);
       
    54 
       
    55     // store it as a global
       
    56     lua_setglobal(L, global_name);
       
    57     
       
    58     // ok
       
    59     return obj;
       
    60 }
       
    61 
       
    62 /**
    42  * Convenience function to get a userdata with the given type metatable name as the first argument for a function
    63  * Convenience function to get a userdata with the given type metatable name as the first argument for a function
    43  */
    64  */
    44 static void* lua_obj_get_obj (lua_State *L, const char *func, const char *name)
    65 static void* lua_obj_get_obj (lua_State *L, const char *func, const char *name)
    45 {
    66 {
    46     void *ud;
    67     void *ud;
    47 
    68 
    48     // validate the userdata arg
    69     // validate the userdata arg
    49     if ((ud = luaL_checkudata(L, 1, name)) == NULL) {
    70     if ((ud = luaL_checkudata(L, 1, name)) == NULL) {
    50         luaL_error(L, "bad type argument to %s: `%s` expected", func, name);
    71         luaL_error(L, "bad type argument to %s: `%s` expected", func, name);
       
    72         
       
    73         // XXX: needs a __noreturn__ attribute
       
    74         return NULL;
    51 
    75 
    52     } else {
    76     } else {
    53         // ok
    77         // ok
    54         return ud;
    78         return ud;
    55 
    79 
   309     {   "quit",         &lua_client_quit            },
   333     {   "quit",         &lua_client_quit            },
   310     {   NULL,           NULL                        }
   334     {   NULL,           NULL                        }
   311 };
   335 };
   312 
   336 
   313 /**
   337 /**
   314  * Initializes a lua_irc_client wrapper for the given client in the give lua state. This registers a set of globals for
   338  * Initialize the evirc.client type for lua_client, and registers an instance bound to the given irc_client at
   315  * 'client' and 'networks'.
   339  * 'client'.
   316  */
   340  */
   317 static void lua_client_init (lua_State *L, struct irc_client *client)
   341 static void lua_client_init (lua_State *L, struct irc_client *client)
   318 {
   342 {
   319     // allocate the global "client" object
   343     // allocate the global "client" object
   320     struct lua_client *lua_client = lua_newuserdata(L, sizeof(*lua_client));
   344     struct lua_client *lua_client = lua_obj_create_global_type(L, "evirc.client", lua_client_methods, "client", sizeof(*lua_client));
   321     
   345     
   322     // create the type metatable
       
   323     lua_obj_create_type(L, "evirc.client", lua_client_methods);
       
   324 
       
   325     // set the client userdata's metatable
       
   326     lua_setmetatable(L, -2);
       
   327 
       
   328     // initialize it
   346     // initialize it
   329     lua_client->client = client;
   347     lua_client->client = client;
   330 
   348 }
   331     // store it as a global
   349 
   332     lua_setglobal(L, "client");
   350 /**
       
   351  * Wrapper for module
       
   352  */
       
   353 struct lua_module {
       
   354     struct module *module;
       
   355 };
       
   356 
       
   357 /**
       
   358  * Create a lua_module userdata from the given module and push it onto the stack, returning 1.
       
   359  */
       
   360 static int lua_module_create (lua_State *L, struct module *module)
       
   361 {
       
   362     // create the new obj
       
   363     struct lua_module *lua_module = lua_obj_create_obj(L, "spbot.module", sizeof(*lua_module));
       
   364 
       
   365     // initialize
       
   366     lua_module->module = module;
       
   367 
       
   368     // ok
       
   369     return 1;
       
   370 }
       
   371 
       
   372 static int lua_module_conf (lua_State *L)
       
   373 {
       
   374     struct lua_module *lua_module = lua_obj_get_obj(L, __func__, "spbot.module");
       
   375     const struct config_option *option;
       
   376     struct config_value value;
       
   377     struct error_info err;
       
   378 
       
   379     // XXX: come up with some better way...
       
   380     struct nexus *nexus = lua_module->module->modules->nexus;
       
   381 
       
   382     // the config name
       
   383     const char *conf_name = luaL_checkstring(L, 2);
       
   384 
       
   385     // the config value
       
   386     // XXX: support lua_chan
       
   387     const char *conf_value = luaL_checkstring(L, 3);
       
   388     
       
   389     // mutable version of the conf_value
       
   390     char conf_value_buf[strlen(conf_value) + 1];
       
   391     strcpy(conf_value_buf, conf_value);
       
   392 
       
   393     // look it up
       
   394     if ((option = module_conf_lookup(lua_module->module, conf_name, &err)) == NULL)
       
   395         return luaL_error(L, "module_conf_lookup: %s/%s: %s", module_name(lua_module->module), conf_name, error_msg(&err));
       
   396     
       
   397     // parse it
       
   398     if (config_parse(option, nexus, &value, conf_value_buf, &err))
       
   399         return luaL_error(L, "config_parse: %s/%s: %s", option->name, conf_value_buf, error_msg(&err));
       
   400 
       
   401     // apply it
       
   402     if (module_conf(lua_module->module, option, &value, &err))
       
   403         return luaL_error(L, "module_conf: %s/%s/%s: %s", module_name(lua_module->module), option->name, conf_value_buf, error_msg(&err));
       
   404     
       
   405     // ok
       
   406     return 0;
       
   407 }
       
   408 
       
   409 static const struct luaL_Reg lua_module_methods[] = {
       
   410     {   "conf",         &lua_module_conf            },
       
   411     {   NULL,           NULL                        }
       
   412 };
       
   413 
       
   414 /**
       
   415  * Initialize the lua_module object type
       
   416  */
       
   417 static void lua_module_init (lua_State *L)
       
   418 {
       
   419     lua_obj_create_type(L, "spbot.module", lua_module_methods);
       
   420 }
       
   421 
       
   422 /**
       
   423  * Wrapper for modules
       
   424  */
       
   425 struct lua_modules {
       
   426     struct modules *modules;
       
   427 };
       
   428 
       
   429 static int lua_modules_load (lua_State *L)
       
   430 {
       
   431     struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules");
       
   432     struct module *module;
       
   433     struct module_info info;
       
   434     struct error_info err;
       
   435 
       
   436     // the module name/path
       
   437     info.name = luaL_checkstring(L, 2);
       
   438     info.path = luaL_checkstring(L, 3);
       
   439 
       
   440     // load
       
   441     if (module_load(lua_modules->modules, &module, &info, &err))
       
   442         return luaL_error(L, "module_load: %s/%s: %s", info.name, info.path, error_msg(&err));
       
   443 
       
   444     // wrap
       
   445     return lua_module_create(L, module);
       
   446 }
       
   447 
       
   448 static int lua_modules_module (lua_State *L)
       
   449 {
       
   450     struct lua_modules *lua_modules = lua_obj_get_obj(L, __func__, "spbot.modules");
       
   451     struct module *module;
       
   452     
       
   453     // the module name
       
   454     const char *name = luaL_checkstring(L, 2);
       
   455 
       
   456     // look it up
       
   457     if ((module = module_get(lua_modules->modules, name)) == NULL)
       
   458         return luaL_error(L, "module_get: %s: no such module", name);
       
   459 
       
   460     // wrap
       
   461     return lua_module_create(L, module);
       
   462 }
       
   463 
       
   464 static const struct luaL_Reg lua_modules_methods[] = {
       
   465     {   "load",         &lua_modules_load           },
       
   466     {   "module",       &lua_modules_module         },
       
   467     {   NULL,           NULL                        }
       
   468 };
       
   469 
       
   470 /**
       
   471  * Initialize the spbot.modules type for lua_modules, and registers an instance bound to the given modules list at
       
   472  * 'modules'.
       
   473  */
       
   474 static void lua_modules_init (lua_State *L, struct modules *modules)
       
   475 {
       
   476     // allocate the global "modules" object
       
   477     struct lua_modules *lua_modules = lua_obj_create_global_type(L, "spbot.modules", lua_modules_methods, "modules", sizeof(*lua_modules));
       
   478     
       
   479     // initialize it
       
   480     lua_modules->modules = modules;
       
   481 }
       
   482 
       
   483 /**
       
   484  * Wrapper for nexus
       
   485  */
       
   486 struct lua_nexus {
       
   487     struct nexus *nexus;
       
   488 };
       
   489 
       
   490 static int lua_nexus_shutdown (lua_State *L)
       
   491 {
       
   492     struct lua_nexus *lua_nexus = lua_obj_get_obj(L, __func__, "spbot.nexus");
       
   493 
       
   494     // just shut it down
       
   495     nexus_shutdown(lua_nexus->nexus);
       
   496 
       
   497     return 0;
       
   498 }
       
   499 
       
   500 static const struct luaL_Reg lua_nexus_methods[] = {
       
   501     {   "shutdown",     &lua_nexus_shutdown         },
       
   502     {   NULL,           NULL                        }
       
   503 };
       
   504 
       
   505 /**
       
   506  * Initialize the spbot.nexus type for lua_nexus, and registers an instance bound to the given nexus list at
       
   507  * 'nexus'.
       
   508  */
       
   509 static void lua_nexus_init (lua_State *L, struct nexus *nexus)
       
   510 {
       
   511     // allocate the global "nexus" object
       
   512     struct lua_nexus *lua_nexus = lua_obj_create_global_type(L, "spbot.nexus", lua_nexus_methods, "nexus", sizeof(*lua_nexus));
       
   513     
       
   514     // initialize it
       
   515     lua_nexus->nexus = nexus;
   333 }
   516 }
   334 
   517 
   335 /**
   518 /**
   336  * Set up the lua state in protected mode
   519  * Set up the lua state in protected mode
   337  */
   520  */
   342     // read the nexus off the stack
   525     // read the nexus off the stack
   343     if ((nexus = lua_touserdata(L, 1)) == NULL)
   526     if ((nexus = lua_touserdata(L, 1)) == NULL)
   344         luaL_error(L, "lua_touserdata: NULL");
   527         luaL_error(L, "lua_touserdata: NULL");
   345 
   528 
   346     // init the various bits
   529     // init the various bits
       
   530     lua_nexus_init(L, nexus);
       
   531     lua_modules_init(L, nexus->modules);
       
   532     lua_module_init(L);
   347     lua_client_init(L, nexus->client);
   533     lua_client_init(L, nexus->client);
   348     lua_net_init(L);
   534     lua_net_init(L);
   349     lua_chan_init(L);
   535     lua_chan_init(L);
   350 
   536 
   351     // nothing
   537     // nothing