lua.c
changeset 120 1be9411caf31
parent 118 1ad8103b72d6
child 121 75a7d595817c
equal deleted inserted replaced
119:2e5d5571a4ba 120:1be9411caf31
  1497 	lua_setfield (L, -2, "__index");
  1497 	lua_setfield (L, -2, "__index");
  1498 	luaL_register (L, NULL, lua_mcabber_hook_reg_m);
  1498 	luaL_register (L, NULL, lua_mcabber_hook_reg_m);
  1499 	lua_pop (L, 1);
  1499 	lua_pop (L, 1);
  1500 }
  1500 }
  1501 
  1501 
  1502 #if 0
       
  1503 // OPTION GUARDS
  1502 // OPTION GUARDS
  1504 
  1503 
  1505 GSList *lua_installed_guards = NULL;
  1504 #define MLUA_GUARD_REGISTRY "mcabber_guards"
  1506 
       
  1507 typedef struct {
       
  1508 	lua_State *L;       // lua environment for handler use
       
  1509 	int        nameref; // reference to key name string
       
  1510 	int        cbref;   // reference to guard function
       
  1511 //	int        objref;  // self_reference to object
       
  1512 	guint      hid;     // hook id for object destruction
       
  1513 } lua_guard_t;
       
  1514 
  1505 
  1515 /// guard function
  1506 /// guard function
  1516 /// Function to be called, when option changes it's value.
  1507 /// Function to be called, when option changes it's value.
  1517 /// Old option value is still accessible through main.option.
  1508 /// Old option value is still accessible through main.option.
  1518 /// A: string (key), string (new value)
  1509 /// A: string (key), string (new value)
  1519 /// R: string (value to save in hash table)
  1510 /// R: string (value to save in hash table)
  1520 static gchar *lua_guard_cb (const gchar *key, const gchar *value)
  1511 static gchar *lua_guard_cb (const gchar *key, const gchar *value)
  1521 {
  1512 {
  1522 	lua_guard_t *cb = ;// FIXME
  1513 	lua_State *L = lua; // FIXME
  1523 	lua_State   *L  = cb -> L;
  1514 
  1524 
  1515 	lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY ); // +1
  1525 	if (cb -> cbref == LUA_NOREF)
  1516 	lua_getfield ( L, -1, key );                                // +2
  1526 		return g_strdup (value);
  1517 	if ( ! lua_isfunction ( L, -1 ) ) {
  1527 
  1518 		lua_pop ( L, 2 );
  1528 	lua_rawgeti (L, LUA_REGISTRYINDEX, cb -> cbref);
  1519 		return g_strdup ( value );
  1529 	if (!lua_isfunction (L, -1)) {
  1520 	}
  1530 		lua_pop (L, 1);
  1521 
  1531 		return g_strdup (value);
  1522 	lua_pushstring ( L, key );                                  // +3
  1532 	}
  1523 	lua_pushstring ( L, value );                                // +4
  1533 
  1524 
  1534 	lua_pushstring (L, key);
  1525 	if ( lua_pcall ( L, 2, 1, 0 ) ) {                           // +2
  1535 	lua_psuhstring (L, value);
  1526 		scr_log_print ( LPRINT_NORMAL, "lua: Error in hook handler: %s", lua_tostring ( L, -1 ) );
  1536 
  1527 		lua_pop ( L, 2 );
  1537 	if (lua_pcall (L, 2, 1, 0)) {
  1528 		return g_strdup ( value );
  1538 		scr_log_print (LPRINT_NORMAL, "lua: Error in hook handler: %s", lua_tostring (L, -1));
  1529 	} else {
  1539 		lua_pop (L, 1);
  1530 		gchar *result = g_strdup ( lua_tostring ( L, -1 ) );
  1540 		return g_strdup (value);
  1531 		lua_pop ( L, 2 );
  1541 	}
  1532 		return result;
  1542 
  1533 	}
  1543 	return g_strdup (lua_tostring (L, -1));
  1534 }
  1544 }
  1535 
  1545 
  1536 /// main.add_guard
  1546 /// main.guard
  1537 /// Installs option guard for given option.
  1547 /// Installs option guard for given option. Returns guard object, that
  1538 /// A: string ( option name ), guard function
  1548 /// should be kept around as long, as guard is needed.
  1539 /// R: boolean ( success )
  1549 /// A: string (option name), guard function
  1540 static int lua_main_add_guard ( lua_State *L )
  1550 /// R: userdata (guard object)
  1541 {
  1551 static int lua_main_guard (lua_State *L)
  1542 	const char *name = luaL_checkstring ( L, 1 );
  1552 {
  1543 	luaL_argcheck ( L, lua_isfunction (L, 2), 2, "function expected" );
  1553 	const char   *name      = luaL_checkstring (L, 1);
  1544 	lua_settop ( L, 2 );
  1554 	int           priority  = G_PRIORITY_DEFAULT;
  1545 
  1555 	lua_guard_t   *cb;
  1546 	if ( settings_set_guard ( name, lua_guard_cb ) ) {
  1556 
  1547 		lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
  1557 	luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
  1548 		lua_pushvalue ( L, 2 );
  1558 
  1549 		lua_setfield ( L, 3, name );
  1559 	cb = lua_newuserdata (L, sizeof (lua_guard_t));
  1550 		lua_pushboolean ( L, 1 );
  1560 	luaL_getmetatable (L, "mcabber.guard");
  1551 	} else
  1561 	lua_setmetatable (L, -2);
  1552 		lua_pushboolean ( L, 0 );
  1562 
       
  1563 	lua_pushvalue (L, 1);
       
  1564 	cb -> nameref = luaL_ref (L, LUA_REGISTRYINDEX);
       
  1565 	lua_pushvalue (L, 2);
       
  1566 	cb -> cbref   = luaL_ref (L, LUA_REGISTRYINDEX);
       
  1567 	cb -> L       = L;
       
  1568 
       
  1569 	settings_set_guard (name, lua_guard_cb)
       
  1570 
  1553 
  1571 	return 1;
  1554 	return 1;
  1572 }
  1555 }
  1573 
  1556 
  1574 static void lua_mcabber_unregister_guard (lua_State *L, lua_guard_t *cb)
  1557 /// main.del_guard
  1575 {
  1558 /// Removes option guard from given option.
  1576 	const char *name;
  1559 /// By default, lua will refuse to remove guards, not installed
  1577 
  1560 /// by lua. Still, you can force guard removal.
  1578 	if (cb -> nameref == LUA_NOREF)
  1561 /// A: string ( option name ), boolean ( force removal )
  1579 		return;
  1562 /// R: boolean ( success )
  1580 
  1563 static int lua_main_del_guard ( lua_State *L )
  1581 	lua_rawgeti (L, LUA_REGISTRYINDEX, cb -> nameref);
  1564 {
  1582 	name = lua_tostring (L, -1);
  1565 	const char *name = luaL_checkstring ( L, 1 );
  1583 	if (name) {
  1566 	lua_settop ( L, 2 );
  1584 		settings_del_guard (name);
  1567 
  1585 		luaL_unref (L, LUA_REGISTRYINDEX, cb -> nameref);
  1568 	lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
  1586 		cb -> nameref = LUA_NOREF;
  1569 	lua_getfield ( L, 3, name );
  1587 	}
  1570 
  1588 
  1571 	if ( ! lua_isnil ( L, 4 ) || lua_toboolean ( L, 2 ) ) {
  1589 	lua_pop (L, 1);
  1572 		settings_del_guard ( name );
  1590 }
  1573 		lua_pushnil ( L );
  1591 
  1574 		lua_setfield ( L, 3, name );
  1592 /// guard:del
  1575 		lua_pushboolean ( L, 1 );
  1593 /// Unregisters given option guard from mcabber. Object will be destroyed later.
  1576 	} else
  1594 static int lua_mcabber_guard_del (lua_State *L)
  1577 		lua_pushboolean ( L, 0 );
  1595 {
  1578 
  1596 	lua_guard_t *cb = luaL_checkudata (L, 1, "mcabber.guard");
  1579 	return 1;
  1597 	luaL_argcheck (L, cb != NULL, 1, "mcabber guard object expected");
  1580 }
  1598 	lua_mcabber_unregister_guard (L, cb);
       
  1599 	return 0;
       
  1600 }
       
  1601 
       
  1602 static int lua_mcabber_guard_gc (lua_State *L)
       
  1603 {
       
  1604 	lua_hook_t *cb = luaL_checkudata (L, 1, "mcabber.guard");
       
  1605 	luaL_argcheck (L, cb != NULL, 1, "mcabber guard object expected");
       
  1606 	lua_mcabber_unregister_guard (L, cb);
       
  1607 	if (cb -> cbref != LUA_NOREF)
       
  1608 		luaL_unref (L, LUA_REGISTRYINDEX, cb -> cbref);
       
  1609 	return 0;
       
  1610 }
       
  1611 
       
  1612 static const luaL_Reg lua_mcabber_hook_reg_m[] = {
       
  1613 	{ "del",  lua_mcabber_guard_del },
       
  1614 	{ "__gc", lua_mcabber_guard_gc  },
       
  1615 	{ NULL,   NULL                 },
       
  1616 };
       
  1617 
  1581 
  1618 static void lua_guard_init (lua_State *L)
  1582 static void lua_guard_init (lua_State *L)
  1619 {
  1583 {
  1620 	luaL_newmetatable (L, "mcabber.guard");
  1584 	lua_createtable ( L, 0, 0 );
  1621 	lua_pushvalue (L, -1);
  1585 	lua_setfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
  1622 	lua_setfield (L, -2, "__index");
       
  1623 	luaL_register (L, NULL, lua_mcabber_guard_reg_m);
       
  1624 	lua_pop (L, 1);
       
  1625 }
  1586 }
  1626 
  1587 
  1627 static void lua_guard_uninit (lua_State *L)
  1588 static void lua_guard_uninit (lua_State *L)
  1628 {
  1589 {
  1629 }
  1590 	lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
  1630 #endif
  1591 	lua_pushnil ( L );
       
  1592 	while ( lua_next ( L, -2 ) ) {
       
  1593 		const char *key = lua_tostring ( L, -2 );
       
  1594 		settings_del_guard ( key );
       
  1595 		lua_pop ( L, 1 );
       
  1596 	}
       
  1597 	lua_pop ( L, 1 );
       
  1598 }
  1631 
  1599 
  1632 // MAIN INITIALIZATION CODE
  1600 // MAIN INITIALIZATION CODE
  1633 
  1601 
  1634 #ifdef LLM_LOG_HANDLER
  1602 #ifdef LLM_LOG_HANDLER
  1635 // FIXME: this should not be here
  1603 // FIXME: this should not be here
  1717 	reg ( full_jid       ) 
  1685 	reg ( full_jid       ) 
  1718 	reg ( buddy_info     ) 
  1686 	reg ( buddy_info     ) 
  1719 	reg ( timer          ) 
  1687 	reg ( timer          ) 
  1720 	reg ( bgread         ) 
  1688 	reg ( bgread         ) 
  1721 	reg ( hook           )
  1689 	reg ( hook           )
       
  1690 	reg ( add_guard      )
       
  1691 	reg ( del_guard      )
  1722 	{ NULL, NULL },
  1692 	{ NULL, NULL },
  1723 };
  1693 };
  1724 #undef reg
  1694 #undef reg
  1725 
  1695 
  1726 const gchar *g_module_check_init (GModule *module)
  1696 const gchar *g_module_check_init (GModule *module)
  1774 	lua_lm_log_handler_id = g_log_set_handler ("lua-lm", G_LOG_LEVEL_MASK, (GLogFunc) lua_lm_log_handler, NULL);
  1744 	lua_lm_log_handler_id = g_log_set_handler ("lua-lm", G_LOG_LEVEL_MASK, (GLogFunc) lua_lm_log_handler, NULL);
  1775 #endif
  1745 #endif
  1776 
  1746 
  1777 	lua_hook_init    (lua);
  1747 	lua_hook_init    (lua);
  1778 	lua_command_init (lua);
  1748 	lua_command_init (lua);
       
  1749 	lua_guard_init   (lua);
  1779 
  1750 
  1780 	{
  1751 	{
  1781 		char *initfile = expand_filename (settings_opt_get ("lua_init_filename"));
  1752 		char *initfile = expand_filename (settings_opt_get ("lua_init_filename"));
  1782 
  1753 
  1783 		if (!initfile)
  1754 		if (!initfile)
  1801 		};
  1772 		};
  1802 		hk_run_handlers("hook-lua-start", args);
  1773 		hk_run_handlers("hook-lua-start", args);
  1803 	}
  1774 	}
  1804 }
  1775 }
  1805 
  1776 
  1806 static void lua_events_cancel (gpointer data, gpointer ignore)
  1777 static void lua_events_destroy ( gpointer data )
  1807 {
  1778 {
  1808 	lua_event_callback_t *cb = data;
  1779 	lua_event_callback_t *cb = data;
  1809 	const char *evid;
  1780 	const char *evid;
  1810 	if (cb->evid == LUA_NOREF)
  1781 	if (cb->evid == LUA_NOREF)
  1811 		return;
  1782 		return;
  1812 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->evid);
  1783 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->evid);
  1813 	evid = lua_tostring (cb ->L, -1);
  1784 	evid = lua_tostring (cb ->L, -1);
  1814 	evs_callback (evid, EVS_CONTEXT_CANCEL, "Module unloading");
  1785 	evs_callback (evid, EVS_CONTEXT_CANCEL, "Module unloading");
  1815 }
  1786 	evs_del (evid); // XXX before these were two different runs. is there some reason for that?
  1816 
  1787 }
  1817 static void lua_events_destroy (gpointer data, gpointer ignore)
  1788 
  1818 {
  1789 static void lua_bgreads_destroy ( gpointer data )
  1819 	lua_event_callback_t *cb = data;
  1790 {
  1820 	const char *evid;
  1791 	g_source_remove ( ( gulong ) data );
  1821 	if (cb->evid == LUA_NOREF)
  1792 }
  1822 		return;
  1793 
  1823 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->evid);
  1794 static void lua_timers_destroy ( gpointer data )
  1824 	evid = lua_tostring (cb ->L, -1);
  1795 {
  1825 	evs_del (evid);
  1796 	g_source_remove ( ( gulong ) data );
  1826 }
  1797 }
  1827 
  1798 
  1828 static void lua_bgreads_destroy (guint source, gpointer ignore)
  1799 static void lua_features_destroy ( gpointer data )
  1829 {
  1800 {
  1830 	g_source_remove (source);
  1801 	gchar *xmlns = data;
  1831 }
       
  1832 
       
  1833 static void lua_timers_destroy (guint source, gpointer ignore)
       
  1834 {
       
  1835 	g_source_remove (source);
       
  1836 }
       
  1837 
       
  1838 static void lua_features_destroy (char *xmlns, gpointer ignore)
       
  1839 {
       
  1840 	xmpp_del_feature (xmlns);
  1802 	xmpp_del_feature (xmlns);
  1841 	g_free (xmlns);
  1803 	g_free (xmlns);
  1842 }
  1804 }
  1843 
  1805 
  1844 static void lua_categories_destroy (guint id, gpointer ignore)
  1806 static void lua_categories_destroy ( gpointer data )
  1845 {
  1807 {
  1846 	compl_del_category (id);
  1808 	compl_del_category ( ( gulong ) data );
  1847 }
  1809 }
  1848 
  1810 
  1849 void mlua_uninit (void)
  1811 void mlua_uninit (void)
  1850 {
  1812 {
  1851 	if (lua) {
  1813 	if (lua) {
  1854 		};
  1816 		};
  1855 		hk_run_handlers ("hook-lua-quit", args);
  1817 		hk_run_handlers ("hook-lua-quit", args);
  1856 
  1818 
  1857 		// hook handlers and commands will be unregistered upon objects destruction
  1819 		// hook handlers and commands will be unregistered upon objects destruction
  1858 
  1820 
  1859 		g_slist_foreach (lua_bgreads, (GFunc) lua_bgreads_destroy, NULL);
  1821 		lua_guard_uninit ( lua );
  1860 		g_slist_free (lua_bgreads);
  1822 
       
  1823 		g_slist_free_full ( lua_bgreads, lua_bgreads_destroy );
  1861 		lua_bgreads = NULL;
  1824 		lua_bgreads = NULL;
  1862 
  1825 
  1863 		g_slist_foreach (lua_timers, (GFunc) lua_timers_destroy, NULL);
  1826 		g_slist_free_full ( lua_timers, lua_timers_destroy );
  1864 		g_slist_free (lua_timers);
       
  1865 		lua_timers = NULL;
  1827 		lua_timers = NULL;
  1866 
  1828 
  1867 		g_slist_foreach (lua_events, (GFunc) lua_events_cancel, NULL);
  1829 		g_slist_free_full ( lua_events, lua_events_destroy );
  1868 		g_slist_foreach (lua_events, (GFunc) lua_events_destroy, NULL);
       
  1869 		g_slist_free (lua_events);
       
  1870 		lua_events = NULL;
  1830 		lua_events = NULL;
  1871 
       
  1872 		g_slist_foreach (lua_added_features, (GFunc) lua_features_destroy, NULL);
       
  1873 		g_slist_free (lua_added_features);
       
  1874 		lua_added_features = NULL;
       
  1875 
  1831 
  1876 #ifdef MCABBER_API_HAVE_CMD_ID
  1832 #ifdef MCABBER_API_HAVE_CMD_ID
  1877 		cmd_del (lua_cmdid);
  1833 		cmd_del (lua_cmdid);
  1878 		lua_cmdid = NULL;
  1834 		lua_cmdid = NULL;
  1879 #else
  1835 #else
  1881 #endif
  1837 #endif
  1882 
  1838 
  1883 		lua_close (lua);
  1839 		lua_close (lua);
  1884 		lua = NULL;
  1840 		lua = NULL;
  1885 
  1841 
  1886 		g_slist_foreach (lua_added_categories, (GFunc) lua_categories_destroy, NULL);
  1842 		g_slist_free_full ( lua_added_features, lua_features_destroy );
  1887 		g_slist_free (lua_added_categories);
  1843 		lua_added_features = NULL;
       
  1844 
       
  1845 		g_slist_free_full ( lua_added_categories, lua_categories_destroy );
  1888 		lua_added_categories = NULL;
  1846 		lua_added_categories = NULL;
  1889 
  1847 
  1890 #ifdef LLM_LOG_HANDLER
  1848 #ifdef LLM_LOG_HANDLER
  1891 		// FIXME: shouldn't be here
  1849 		// FIXME: shouldn't be here
  1892 		g_log_remove_handler ("lua-lm", lua_lm_log_handler_id);
  1850 		g_log_remove_handler ("lua-lm", lua_lm_log_handler_id);