diff --git a/NEWS b/NEWS index 5b2040e8..95f2c385 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,23 @@ -v1.3.2 2022-xx-xx The Irssi team +v1.4.0 2022-xx-xx The Irssi team + * Format the output of /QUOTE HELP (#1371, an#82). By Val + Lorentz. Add /SHELP as default alias (an#83) + + GLib log message filter: /SET glib_log_domains (an#50, + an#59). By Andrej Kacian + + An option to clear the cutbuffer: + /SET empty_kill_clears_cutbuffer (an#58). By Mikael + Magnusson + + Scriptable pastebin (an#60) + + Configurable actlist separator: /SET actlist_separator + (#1364, an#61) + - Fix window left/right not skipping visible windows + (an#57). By Mikael Magnusson + - Fix wrong printf-format on OpenBSD (an#66, an#68). Reported + by Aaron Bieber + - Fix erroneous output produced by autoload_modules (an#72) + - Fix scroll_page_count setting with `.' (#1365, an#76) + - Fix memory leak in /IGNORE (#1373, an#84). Found by Jookia + - Misc fixes (an#45, an#67, an#70, #1368, an#77) + - CHANTYPES take precedence over (missing) STATUSMSG in /join (#1358, an#54) - Fix crash in Perl's $view->set_bookmark (freebsd#254237, diff --git a/README.md b/README.md index ea4b817b..4e1bb88d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ built in, and there are third party [Quassel](https://github.com/phhusson/quassel-irssi) protocol modules available. -![irssi](https://user-images.githubusercontent.com/5665186/32180643-cf127f60-bd92-11e7-8aa2-882313ce1d8e.png) +![irssi](https://user-images.githubusercontent.com/5665186/154820868-50c35841-04f4-4f4c-8df9-dd5aa4bbcde8.png) ## [Download information](https://irssi.org/download/) diff --git a/configure.ac b/configure.ac index c91bde95..d0de185b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.3.2) +AC_INIT(irssi, 1.4.0) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) diff --git a/docs/help/in/ignore.in b/docs/help/in/ignore.in index 0fbf970d..433490e1 100644 --- a/docs/help/in/ignore.in +++ b/docs/help/in/ignore.in @@ -14,6 +14,8 @@ -network: Ignores only on a specific network. -channels: Ignores only on specific channels. -time: The timeout to automatically remove the ignore. + Accepts units specified in days, hours, minutes, seconds, + milliseconds, or no unit for seconds. The mask, channels and levels to ignore; if no argument is provided, the list of ignores will be displayed. @@ -44,6 +46,8 @@ /IGNORE #irssi NO_ACT JOINS PARTS QUITS /IGNORE mike NO_ACT -MSGS /IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS + /IGNORE -time 5days christmas PUBLICS + /IGNORE -time 300 mike PUBLICS %9See also:%9 ACCEPT, SILENCE, UNIGNORE diff --git a/docs/signals.txt b/docs/signals.txt index da72ef57..81a1e3fa 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -351,6 +351,7 @@ Text FE gui-readline.c: "gui key pressed", int key + "paste event", char *paste, char *arg gui-printtext.c: "beep" diff --git a/irssi.conf b/irssi.conf index 21c3ba4c..010520fd 100644 --- a/irssi.conf +++ b/irssi.conf @@ -147,6 +147,7 @@ aliases = { SAY = "MSG *"; SB = "SCROLLBACK"; SBAR = "STATUSBAR"; + SHELP = "QUOTE HELP"; SIGNOFF = "QUIT"; SV = "MSG * Irssi $J ($V) - https://irssi.org"; T = "TOPIC"; diff --git a/meson.build b/meson.build index 58052054..59a26f3c 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('irssi', 'c', - version : '1.3.2', + version : '1.4.0', meson_version : '>=0.49', default_options : ['warning_level=1']) diff --git a/src/common.h b/src/common.h index d2dd2f7c..7271c149 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ -#define IRSSI_ABI_VERSION 41 +#define IRSSI_ABI_VERSION 46 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/ignore.c b/src/core/ignore.c index 0bc12ed3..da892c1e 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -490,6 +490,11 @@ static void read_ignores(void) nickmatch_rebuild(nickmatch); } +static void free_cache_matches(GSList *matches) +{ + g_slist_free(matches); +} + static void ignore_nick_cache(GHashTable *list, CHANNEL_REC *channel, NICK_REC *nick) { @@ -520,7 +525,7 @@ static void ignore_nick_cache(GHashTable *list, CHANNEL_REC *channel, void ignore_init(void) { ignores = NULL; - nickmatch = nickmatch_init(ignore_nick_cache); + nickmatch = nickmatch_init(ignore_nick_cache, (GDestroyNotify) free_cache_matches); time_tag = g_timeout_add(1000, (GSourceFunc) unignore_timeout, NULL); read_ignores(); diff --git a/src/core/nickmatch-cache.c b/src/core/nickmatch-cache.c index cae6620d..c8fc1157 100644 --- a/src/core/nickmatch-cache.c +++ b/src/core/nickmatch-cache.c @@ -28,12 +28,13 @@ static GSList *lists; -NICKMATCH_REC *nickmatch_init(NICKMATCH_REBUILD_FUNC func) +NICKMATCH_REC *nickmatch_init(NICKMATCH_REBUILD_FUNC func, GDestroyNotify value_destroy_func) { NICKMATCH_REC *rec; rec = g_new0(NICKMATCH_REC, 1); rec->func = func; + rec->value_destroy_func = value_destroy_func; lists = g_slist_append(lists, rec); return rec; @@ -43,8 +44,9 @@ void nickmatch_deinit(NICKMATCH_REC *rec) { lists = g_slist_remove(lists, rec); - g_hash_table_destroy(rec->nicks); - g_free(rec); + if (rec->nicks != NULL) + g_hash_table_destroy(rec->nicks); + g_free(rec); } static void nickmatch_check_channel(CHANNEL_REC *channel, NICKMATCH_REC *rec) @@ -65,8 +67,8 @@ void nickmatch_rebuild(NICKMATCH_REC *rec) if (rec->nicks != NULL) g_hash_table_destroy(rec->nicks); - rec->nicks = g_hash_table_new((GHashFunc) g_direct_hash, - (GCompareFunc) g_direct_equal); + rec->nicks = g_hash_table_new_full((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal, + NULL, (GDestroyNotify) rec->value_destroy_func); g_slist_foreach(channels, (GFunc) nickmatch_check_channel, rec); } diff --git a/src/core/nickmatch-cache.h b/src/core/nickmatch-cache.h index ff58d853..bae99c1d 100644 --- a/src/core/nickmatch-cache.h +++ b/src/core/nickmatch-cache.h @@ -7,9 +7,10 @@ typedef void (*NICKMATCH_REBUILD_FUNC) (GHashTable *list, typedef struct { GHashTable *nicks; NICKMATCH_REBUILD_FUNC func; + GDestroyNotify value_destroy_func; } NICKMATCH_REC; -NICKMATCH_REC *nickmatch_init(NICKMATCH_REBUILD_FUNC func); +NICKMATCH_REC *nickmatch_init(NICKMATCH_REBUILD_FUNC func, GDestroyNotify value_destroy_func); void nickmatch_deinit(NICKMATCH_REC *rec); /* Calls rebuild function for all nicks in all channels. diff --git a/src/core/settings.c b/src/core/settings.c index 28f953ba..1e7ef2ee 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -928,6 +928,7 @@ void settings_deinit(void) g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL); g_hash_table_destroy(settings); + settings = NULL; if (mainconfig != NULL) config_close(mainconfig); } diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 1fcd5df1..9724354f 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -57,6 +57,7 @@ static int autocon_port; static int no_autoconnect; static char *cmdline_nick; static char *cmdline_hostname; +GLogFunc logger_old; void fe_core_log_init(void); void fe_core_log_deinit(void); @@ -165,6 +166,7 @@ void fe_common_core_init(void) settings_add_bool("lookandfeel", "use_msgs_window", FALSE); g_get_charset(&str); settings_add_str("lookandfeel", "term_charset", str); + settings_add_str("lookandfeel", "glib_log_domains", "all"); themes_init(); theme_register(fecommon_core_formats); @@ -252,11 +254,58 @@ void fe_common_core_deinit(void) signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created); signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); + + g_log_set_default_handler(logger_old, NULL); } -void i_log_func(const char *log_domain, GLogLevelFlags log_level, const char *message) +static gboolean glib_domain_wanted(const char *domain) { - const char *reason; + const char *domains; + char *c, *cur; + int len = 0; + int print_it = 0; /* -1 for exclude, 0 for undecided, 1 for include */ + int incl; + + /* Go through each item in glib_log_domains setting to determine whether + * or not we want to print message from this domain */ + domains = settings_get_str("glib_log_domains"); + c = cur = (char *) domains; + + do { + /* Advance through the string until we hit a space or the end */ + while (*cur != '\0' && *cur != ' ') { + cur++; + len++; + } + + /* Handle '-' prefix */ + incl = 1; + if (*c == '-') { + incl = -1; + c++; + len--; + } + + /* If we got a valid item, process it */ + if (len > 0 && (!strncmp(domain, c, len) || !strncasecmp("all", c, len) || + !strncmp("*", c, len))) + print_it = incl; + + /* Go past any spaces towards the next item */ + while (*cur == ' ') + cur++; + + /* Move on beyond the item we just handled */ + c = cur; + len = 0; + } while (*c != '\0' && print_it != -1); + + return (print_it == 1); +} + +static void i_log_func(const char *log_domain, GLogLevelFlags log_level, const char *message) +{ + const char *reason, *domain; switch (log_level) { case G_LOG_LEVEL_WARNING: @@ -265,16 +314,33 @@ void i_log_func(const char *log_domain, GLogLevelFlags log_level, const char *me case G_LOG_LEVEL_CRITICAL: reason = "critical"; break; + case G_LOG_LEVEL_DEBUG: + reason = "debug"; + break; + case G_LOG_LEVEL_MESSAGE: + reason = "message"; + break; + case G_LOG_LEVEL_INFO: + reason = "info"; + break; default: reason = "error"; break; } + /* If log_domain parameter is NULL, GLib means to tell us that this is + * meant to be some nebulous "default" log domain name. */ + domain = (log_domain ? log_domain : "default"); + + /* Only print the message if we decided to */ + if (!glib_domain_wanted(domain)) + return; + if (windows == NULL) - fprintf(stderr, "GLib %s: %s\n", reason, message); + fprintf(stderr, "GLib (%s) %s: %s\n", domain, reason, message); else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_GLIB_ERROR, reason, message); + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_GLIB_ERROR, domain, reason, + message); } } @@ -458,7 +524,7 @@ void fe_common_core_finish_init(void) signal_add_first("setup changed", (SIGNAL_FUNC) sig_setup_changed); /* _after_ windows are created.. */ - g_log_set_default_handler((GLogFunc) i_log_func, NULL); + logger_old = g_log_set_default_handler((GLogFunc) i_log_func, NULL); if (setup_changed) signal_emit("setup changed", 0); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 276169df..3594b6f6 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -115,9 +115,9 @@ static void cmd_ignore_show(void) } /* SYNTAX: IGNORE [-regexp | -full] [-pattern ] [-except] [-replies] - [-network ] [-channels ] [-time ] [] + [-network ] [-channels ] [-time