src/lua_irc.c
changeset 145 a5582e1a83da
parent 143 1edab39c88a8
child 180 22967b165692
equal deleted inserted replaced
144:51f96539f9f3 145:a5582e1a83da
     2 #include "lua_func.h"
     2 #include "lua_func.h"
     3 
     3 
     4 #include <stdlib.h>
     4 #include <stdlib.h>
     5 #include <string.h>
     5 #include <string.h>
     6 
     6 
       
     7 static struct lua_type lua_chan_type = LUA_TYPE("evirc.chan");
       
     8 
     7 /**
     9 /**
     8  * Create a lua_chan userdata from the given irc_chan and leave it on the stack, returning 1
    10  * Create a lua_chan userdata from the given irc_chan and leave it on the stack, returning 1
     9  */
    11  */
    10 static int lua_chan_create (lua_State *L, struct irc_chan *chan)
    12 static int lua_chan_create (lua_State *L, struct irc_chan *chan)
    11 {
    13 {
    12     // create the new obj
    14     // create the new obj
    13     struct lua_chan *lua_chan = lua_obj_create_obj(L, "evirc.chan", sizeof(*lua_chan));
    15     struct lua_chan *lua_chan = lua_type_create(L, &lua_chan_type, sizeof(*lua_chan));
    14 
    16 
    15     // initialize
    17     // initialize
    16     lua_chan->chan = chan;
    18     lua_chan->chan = chan;
    17 
    19 
    18     // ok
    20     // ok
    20 }
    22 }
    21 
    23 
    22 /**
    24 /**
    23  * Return the channel name as a lua string
    25  * Return the channel name as a lua string
    24  */
    26  */
    25 static int lua_chan_tostring (lua_State *L)
    27 static struct lua_func lua_chan__tostring_func = LUA_FUNC(&lua_chan_type, "__tostring",
    26 {
    28         "format using channel name",
    27     struct lua_chan *lua_chan = lua_obj_get_obj(L, __func__, "evirc.chan");
    29 
       
    30         LUA_FUNC_ARG_END
       
    31     );
       
    32 
       
    33 static int lua_chan__tostring (lua_State *L)
       
    34 {
       
    35     struct lua_chan *lua_chan;
       
    36 
       
    37     lua_args_parse(L, &lua_chan__tostring_func, (void *) &lua_chan);
    28     
    38     
    29     lua_pushfstring(L, "<irc_chan %s>", irc_chan_name(lua_chan->chan));
    39     lua_pushfstring(L, "<irc_chan %s>", irc_chan_name(lua_chan->chan));
    30 
    40 
    31     return 1;
    41     return 1;
    32 }
    42 }
    33 
    43 
    34 /**
    44 /**
    35  * Send a PRIVMSG to the channel
    45  * Send a PRIVMSG to the channel
    36  */
    46  */
       
    47 static struct lua_func lua_chan_say_func = LUA_FUNC(&lua_chan_type, "evirc.chan.say",
       
    48         "send a message to a channel",
       
    49 
       
    50         LUA_FUNC_ARG_STRING("message",      LUA_ARG_STRING_REQUIRED )
       
    51     );
       
    52 
    37 static int lua_chan_say (lua_State *L)
    53 static int lua_chan_say (lua_State *L)
    38 {
    54 {
       
    55     struct lua_chan *lua_chan;
    39     err_t err;
    56     err_t err;
    40 
    57     const char *message;
    41     struct lua_chan *lua_chan = lua_obj_get_obj(L, __func__, "evirc.chan");
    58 
    42     
    59     // parse args
    43     // the message
    60     lua_args_parse(L, &lua_chan_say_func, (void *) &lua_chan,
    44     const char *message = luaL_checkstring(L, 2);
    61             &message
       
    62         );
    45 
    63 
    46     // send
    64     // send
    47     if ((err = irc_chan_PRIVMSG(lua_chan->chan, message)))
    65     if ((err = irc_chan_PRIVMSG(lua_chan->chan, message)))
    48         return luaL_error(L, "irc_chan_PRIVMSG: '%s': %s", message, error_name(err));
    66         return luaL_error(L, "irc_chan_PRIVMSG: '%s': %s", message, error_name(err));
    49     
    67     
    50     // ok
    68     // ok
    51     return 0;
    69     return 0;
    52 }
    70 }
    53 
    71 
    54 static const struct luaL_Reg lua_chan_methods[] = {
    72 static struct lua_method lua_chan_methods[] = LUA_METHODS(
    55     {   "__tostring",       &lua_chan_tostring  },
    73         LUA_METHOD("__tostring",    lua_chan__tostring, &lua_chan__tostring_func    ),
    56     {   "say",              &lua_chan_say       },
    74         LUA_METHOD("say",           lua_chan_say,       &lua_chan_say_func          )
    57     {   NULL,               NULL                },
    75     );
    58 };
    76 
    59 
    77 
    60 /**
    78 
    61  * Initialize the lua_chan object type
    79 static struct lua_type lua_net_type = LUA_TYPE("evirc.net");
    62  */
       
    63 static void lua_chan_init (lua_State *L)
       
    64 {
       
    65     lua_obj_create_type(L, "evirc.chan", lua_chan_methods);
       
    66 }
       
    67 
    80 
    68 /**
    81 /**
    69  * Create a lua_net userdata from the given irc_net and push it onto the stack, returning 1.
    82  * Create a lua_net userdata from the given irc_net and push it onto the stack, returning 1.
    70  */
    83  */
    71 static int lua_net_create (lua_State *L, struct irc_net *net)
    84 static int lua_net_create (lua_State *L, struct irc_net *net)
    72 {
    85 {
    73     // create the new obj
    86     // create the new obj
    74     struct lua_net *lua_net = lua_obj_create_obj(L, "evirc.net", sizeof(*lua_net));
    87     struct lua_net *lua_net = lua_type_create(L, &lua_net_type, sizeof(*lua_net));
    75 
    88 
    76     // initialize
    89     // initialize
    77     lua_net->net = net;
    90     lua_net->net = net;
    78 
    91 
    79     // ok
    92     // ok
    81 }
    94 }
    82 
    95 
    83 /**
    96 /**
    84  * Return the network name as a lua string
    97  * Return the network name as a lua string
    85  */
    98  */
    86 static int lua_net_tostring (lua_State *L)
    99 static struct lua_func lua_net__tostring_func = LUA_FUNC(&lua_net_type, "__tostring",
    87 {
   100         "format using network name",
    88     struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net");
   101 
       
   102         LUA_FUNC_ARG_END
       
   103     );
       
   104 
       
   105 static int lua_net__tostring (lua_State *L)
       
   106 {
       
   107     struct lua_net *lua_net;
       
   108 
       
   109     lua_args_parse(L, &lua_net__tostring_func, (void *) &lua_net);
    89     
   110     
    90     lua_pushfstring(L, "<irc_net %s>", irc_net_name(lua_net->net));
   111     lua_pushfstring(L, "<irc_net %s>", irc_net_name(lua_net->net));
    91 
   112 
    92     return 1;
   113     return 1;
    93 }
   114 }
    94 
   115 
    95 /**
   116 /**
    96  * Join a new channel, returning the lua_chan
   117  * Join a new channel, returning the lua_chan
    97  */
   118  */
       
   119 static struct lua_func lua_net_join_func = LUA_FUNC(&lua_net_type, "join",
       
   120         "create a new channel and join it",
       
   121 
       
   122         LUA_FUNC_ARG_STRING("channel",      LUA_ARG_STRING_REQUIRED)
       
   123     );
       
   124 
       
   125 
    98 static int lua_net_join (lua_State *L)
   126 static int lua_net_join (lua_State *L)
    99 {
   127 {
   100     struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net");
   128     struct lua_net *lua_net;
   101     struct irc_chan_info chan_info;
   129     struct irc_chan_info chan_info;
   102     struct irc_chan *chan;
   130     struct irc_chan *chan;
   103     struct error_info err;
   131     struct error_info err;
   104     
   132     
   105     // the channel name
   133     // the channel name
   106     // XXX: bad! bad! bad!
   134     lua_args_parse(L, &lua_net_join_func, (void *) &lua_net,
   107     chan_info.channel = strdup(luaL_checkstring(L, 2));
   135             &chan_info.channel
       
   136         );
   108     
   137     
   109     // add it
   138     // add it
   110     if (irc_net_add_chan(lua_net->net, &chan, &chan_info, &err))
   139     if (irc_net_add_chan(lua_net->net, &chan, &chan_info, &err))
   111         return luaL_error(L, "irc_net_add_chan: %s: %s", chan_info.channel, error_msg(&err));
   140         return luaL_error(L, "irc_net_add_chan: %s: %s", chan_info.channel, error_msg(&err));
   112     
   141     
   115 }
   144 }
   116 
   145 
   117 /**
   146 /**
   118  * Look up a channel by name, returning the lua_chan
   147  * Look up a channel by name, returning the lua_chan
   119  */
   148  */
       
   149 static struct lua_func lua_net_get_chan_func = LUA_FUNC(&lua_net_type, "channel",
       
   150         "look up a channel by name",
       
   151 
       
   152         LUA_FUNC_ARG_STRING("channel",      LUA_ARG_STRING_REQUIRED)
       
   153     );
       
   154 
   120 static int lua_net_get_chan (lua_State *L)
   155 static int lua_net_get_chan (lua_State *L)
   121 {
   156 {
   122     struct lua_net *lua_net = lua_obj_get_obj(L, __func__, "evirc.net");
   157     struct lua_net *lua_net;
   123     struct irc_chan *chan;
   158     struct irc_chan *chan;
   124     
   159     const char *channel;
   125     // the channel name
   160 
   126     const char *channel = luaL_checkstring(L, 2);
   161     // parse args
       
   162     lua_args_parse(L, &lua_net_get_chan_func, (void *) &lua_net,
       
   163             &channel
       
   164         );
   127     
   165     
   128     // lookup the irc_chan
   166     // lookup the irc_chan
   129     if ((chan = irc_net_get_chan(lua_net->net, channel)) == NULL)
   167     if ((chan = irc_net_get_chan(lua_net->net, channel)) == NULL)
   130         return luaL_error(L, "irc_net_get_chan: no such channel: %s", channel);
   168         return luaL_error(L, "irc_net_get_chan: no such channel: %s", channel);
   131 
   169 
   132     // wrap it
   170     // wrap it
   133     return lua_chan_create(L, chan);
   171     return lua_chan_create(L, chan);
   134 }
   172 }
   135 
   173 
   136 static const struct luaL_Reg lua_net_methods[] = {
   174 static struct lua_method lua_net_methods[] = LUA_METHODS(
   137     {   "__tostring",   &lua_net_tostring   },
   175         LUA_METHOD("__tostring",    lua_net__tostring,  &lua_net__tostring_func ),
   138     {   "join",         &lua_net_join       },
   176         LUA_METHOD("join",          lua_net_join,       &lua_net_join_func      ),
   139     {   "channel",      &lua_net_get_chan   },
   177         LUA_METHOD("channel",       lua_net_get_chan,   &lua_net_get_chan_func  )
   140     {   NULL,           NULL                }
   178     );
   141 };
   179 
   142 
   180 
   143 /**
   181 
   144  * Initialize the lua_net object type
   182 static struct lua_type lua_client_type = LUA_TYPE("evirc.client");
   145  */
   183 
   146 static void lua_net_init (lua_State *L)
   184 
   147 {
   185 static struct lua_func lua_client_set_defaults_func = LUA_FUNC(&lua_client_type, "set_defaults", 
   148     lua_obj_create_type(L, "evirc.net", lua_net_methods);
       
   149 }
       
   150 
       
   151 static struct lua_func lua_client_set_defaults_func = LUA_FUNC("evirc.client", "set_defaults", 
       
   152         "set the default settings to use for evirc.client.connect",
   186         "set the default settings to use for evirc.client.connect",
   153 
   187 
   154         LUA_FUNC_ARG_STRING("nickname",     LUA_ARG_STRING_REQUIRED ),
   188         LUA_FUNC_ARG_STRING("nickname",     LUA_ARG_STRING_REQUIRED ),
   155         LUA_FUNC_ARG_STRING("username",     LUA_ARG_STRING_REQUIRED ),
   189         LUA_FUNC_ARG_STRING("username",     LUA_ARG_STRING_REQUIRED ),
   156         LUA_FUNC_ARG_STRING("realname",     LUA_ARG_STRING_REQUIRED ),
   190         LUA_FUNC_ARG_STRING("realname",     LUA_ARG_STRING_REQUIRED ),
   157         LUA_FUNC_ARG_STRING("service",      IRC_PORT                ),
   191         LUA_FUNC_ARG_STRING("service",      IRC_PORT                ),
   158         LUA_FUNC_ARG_STRING("service_ssl",  IRC_SSL_PORT            )
   192         LUA_FUNC_ARG_STRING("service_ssl",  IRC_SSL_PORT            )
   159 );
   193     );
   160 
   194 
   161 static int lua_client_set_defaults (lua_State *L)
   195 static int lua_client_set_defaults (lua_State *L)
   162 {
   196 {
   163     struct lua_client *lua_client;
   197     struct lua_client *lua_client;
   164     const char *nickname, *username, *realname, *service, *service_ssl;
   198     const char *nickname, *username, *realname, *service, *service_ssl;
   165 
   199 
   166     // parse args
   200     // parse args
   167     lua_args_parse(L, &lua_client_set_defaults_func, (void *) &lua_client,
   201     lua_args_parse(L, &lua_client_set_defaults_func, (void *) &lua_client,
   168         &nickname, &username, &realname, &service, &service_ssl
   202             &nickname, &username, &realname, &service, &service_ssl
   169     );
   203         );
   170 
   204 
   171     // set
   205     // set
   172     struct irc_client_defaults defaults = {
   206     struct irc_client_defaults defaults = {
   173         .register_info = {
   207         .register_info = {
   174             .nickname   = nickname,
   208             .nickname   = nickname,
   185 
   219 
   186     // ok
   220     // ok
   187     return 0;
   221     return 0;
   188 }
   222 }
   189 
   223 
   190 static struct lua_func lua_client_connect_func = LUA_FUNC("evirc.client", "connect",
   224 static struct lua_func lua_client_connect_func = LUA_FUNC(&lua_client_type, "connect",
   191         "Create and return a new IRC network",
   225         "Create and return a new IRC network",
   192 
   226 
   193         LUA_FUNC_ARG_STRING("network",      LUA_ARG_STRING_REQUIRED ),
   227         LUA_FUNC_ARG_STRING("network",      LUA_ARG_STRING_REQUIRED ),
   194         LUA_FUNC_ARG_STRING("hostname",     LUA_ARG_STRING_REQUIRED ),
   228         LUA_FUNC_ARG_STRING("hostname",     LUA_ARG_STRING_REQUIRED ),
   195         LUA_FUNC_ARG_STRING("service",      NULL                    ),
   229         LUA_FUNC_ARG_STRING("service",      NULL                    ),
   237 
   271 
   238     // wrap it
   272     // wrap it
   239     return lua_net_create(L, net);
   273     return lua_net_create(L, net);
   240 }
   274 }
   241 
   275 
       
   276 static struct lua_func lua_client_get_network_func = LUA_FUNC(&lua_client_type, "network",
       
   277         "Lookup an existing network by name",
       
   278 
       
   279         LUA_FUNC_ARG_STRING("network",  LUA_ARG_STRING_REQUIRED)
       
   280     );
       
   281 
   242 static int lua_client_get_network (lua_State *L)
   282 static int lua_client_get_network (lua_State *L)
   243 {
   283 {
   244     struct lua_client *lua_client = lua_obj_get_obj(L, __func__, "evirc.client");
   284     struct lua_client *lua_client;
   245     struct irc_net *net;
   285     struct irc_net *net;
   246     
   286     const char *network;
   247     // the network name
   287 
   248     const char *network = luaL_checkstring(L, 2);
   288     // parse args
       
   289     lua_args_parse(L, &lua_client_get_network_func, (void *) &lua_client,
       
   290             &network
       
   291         );
   249     
   292     
   250     // lookup the irc_net
   293     // lookup the irc_net
   251     if ((net = irc_client_get_net(lua_client->client, network)) == NULL)
   294     if ((net = irc_client_get_net(lua_client->client, network)) == NULL)
   252         return luaL_error(L, "irc_client_get_net: no such network: %s", network);
   295         return luaL_error(L, "irc_client_get_net: no such network: %s", network);
   253 
   296 
   254     // wrap it
   297     // wrap it
   255     return lua_net_create(L, net);
   298     return lua_net_create(L, net);
   256 }
   299 }
   257 
   300 
       
   301 static struct lua_func lua_client_quit_func = LUA_FUNC(&lua_client_type, "quit",
       
   302         "Disconnect from all networks",
       
   303 
       
   304         LUA_FUNC_ARG_STRING("message",  "Bye")
       
   305     );
       
   306 
   258 static int lua_client_quit (lua_State *L)
   307 static int lua_client_quit (lua_State *L)
   259 {
   308 {
   260     struct lua_client *lua_client = lua_obj_get_obj(L, __func__, "evirc.client");
   309     struct lua_client *lua_client;
   261     err_t err;
   310     err_t err;
   262    
   311     const char *message;
   263     // the message
   312 
   264     const char *message = luaL_checkstring(L, 2);
   313     // parse args
       
   314     lua_args_parse(L, &lua_client_quit_func, (void *) &lua_client,
       
   315             &message
       
   316         );
   265 
   317 
   266     // execute
   318     // execute
   267     if ((err = irc_client_quit(lua_client->client, message)))
   319     if ((err = irc_client_quit(lua_client->client, message)))
   268         return luaL_error(L, "irc_client_quit: %s", error_name(err));
   320         return luaL_error(L, "irc_client_quit: %s", error_name(err));
   269 
   321 
   270     // ok
   322     // ok
   271     return 0;
   323     return 0;
   272 }
   324 }
   273 
   325 
   274 static const struct luaL_Reg lua_client_methods[] = {
   326 static struct lua_method lua_client_methods[] = LUA_METHODS(
   275     {   "set_defaults", &lua_client_set_defaults    },
   327         LUA_METHOD("set_defaults",  lua_client_set_defaults,    &lua_client_set_defaults_func   ),
   276     {   "connect",      &lua_client_connect         },
   328         LUA_METHOD("connect",       lua_client_connect,         &lua_client_connect_func        ),
   277     {   "network",      &lua_client_get_network     },
   329         LUA_METHOD("network",       lua_client_get_network,     &lua_client_get_network_func    ),
   278     {   "quit",         &lua_client_quit            },
   330         LUA_METHOD("quit",          lua_client_quit,            &lua_client_quit_func           )
   279     {   NULL,           NULL                        }
   331     );
   280 };
   332 
   281 
   333 void lua_irc_init (struct nexus_lua *lua)
   282 /**
   334 {
   283  * Initialize the evirc.client type for lua_client, and registers an instance bound to the given irc_client at
   335     // register types
   284  * 'client'.
   336     lua_type_register(lua->st, &lua_chan_type, lua_chan_methods);
   285  */
   337     lua_type_register(lua->st, &lua_net_type, lua_net_methods);
   286 static void lua_client_init (lua_State *L, struct irc_client *client)
   338 
   287 {
   339     // register the global "client" object
   288     // allocate the global "client" object
   340     struct lua_client *lua_client = lua_type_register_global(lua->st, &lua_client_type, lua_client_methods, "client", sizeof(*lua_client));
   289     struct lua_client *lua_client = lua_obj_create_global_type(L, "evirc.client", lua_client_methods, "client", sizeof(*lua_client));
       
   290     
   341     
   291     // initialize it
   342     // initialize it
   292     lua_client->client = client;
   343     lua_client->client = lua->nexus->client;
   293 }
   344 }
   294 
   345 
   295 void lua_irc_init (struct nexus_lua *lua)
       
   296 {
       
   297     lua_client_init(lua->st, lua->nexus->client);
       
   298     lua_net_init(lua->st);
       
   299     lua_chan_init(lua->st);
       
   300 }
       
   301