mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
added expando_get_signals() and special_vars_get_signals() to return list
of signals the expandos use. Also added "time changed" signal which gets emitted when $Z changes. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1814 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
a51170c00f
commit
26d84e25ab
@ -54,7 +54,10 @@ static time_t client_start_time;
|
|||||||
static char *last_sent_msg, *last_sent_msg_body;
|
static char *last_sent_msg, *last_sent_msg_body;
|
||||||
static char *last_privmsg_from, *last_public_from;
|
static char *last_privmsg_from, *last_public_from;
|
||||||
static char *sysname, *sysrelease, *sysarch;
|
static char *sysname, *sysrelease, *sysarch;
|
||||||
|
|
||||||
static const char *timestamp_format;
|
static const char *timestamp_format;
|
||||||
|
static int timestamp_seconds;
|
||||||
|
static time_t last_timestamp;
|
||||||
|
|
||||||
#define CHAR_EXPANDO(chr) \
|
#define CHAR_EXPANDO(chr) \
|
||||||
(char_expandos[(int) (unsigned char) chr])
|
(char_expandos[(int) (unsigned char) chr])
|
||||||
@ -209,6 +212,38 @@ void expando_unbind(const char *key, int funccount, SIGNAL_FUNC *funcs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns [<signal id>, EXPANDO_ARG_xxx, <signal id>, ..., -1] */
|
||||||
|
int *expando_get_signals(const char *key)
|
||||||
|
{
|
||||||
|
EXPANDO_REC *rec;
|
||||||
|
int *signals;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
g_return_val_if_fail(key != NULL, NULL);
|
||||||
|
|
||||||
|
rec = expando_find(key);
|
||||||
|
if (rec == NULL || rec->signals < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (rec->signals == 0) {
|
||||||
|
/* it's unknown when this expando changes..
|
||||||
|
check it once in a second */
|
||||||
|
signals = g_new(int, 3);
|
||||||
|
signals[0] = signal_get_uniq_id("expando timer");
|
||||||
|
signals[1] = EXPANDO_ARG_NONE;
|
||||||
|
signals[2] = -1;
|
||||||
|
return signals;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals = g_new(int, rec->signals*2+1);
|
||||||
|
for (n = 0; n < rec->signals; n++) {
|
||||||
|
signals[n*2] = rec->signal_ids[n];
|
||||||
|
signals[n*2+1] = rec->signal_args[n];
|
||||||
|
}
|
||||||
|
signals[rec->signals*2] = -1;
|
||||||
|
return signals;
|
||||||
|
}
|
||||||
|
|
||||||
EXPANDO_FUNC expando_find_char(char chr)
|
EXPANDO_FUNC expando_find_char(char chr)
|
||||||
{
|
{
|
||||||
return CHAR_EXPANDO(chr) == NULL ? NULL :
|
return CHAR_EXPANDO(chr) == NULL ? NULL :
|
||||||
@ -437,13 +472,41 @@ static void sig_message_own_private(SERVER_REC *server, const char *msg,
|
|||||||
|
|
||||||
static int sig_timer(void)
|
static int sig_timer(void)
|
||||||
{
|
{
|
||||||
|
time_t now;
|
||||||
|
struct tm *tm;
|
||||||
|
int last_min;
|
||||||
|
|
||||||
signal_emit("expando timer", 0);
|
signal_emit("expando timer", 0);
|
||||||
|
|
||||||
|
/* check if $Z has changed */
|
||||||
|
now = time(NULL);
|
||||||
|
if (last_timestamp != now) {
|
||||||
|
if (!timestamp_seconds) {
|
||||||
|
/* assume it changes every minute */
|
||||||
|
tm = localtime(&last_timestamp);
|
||||||
|
last_min = tm->tm_min;
|
||||||
|
|
||||||
|
tm = localtime(&now);
|
||||||
|
if (tm->tm_min == last_min)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_emit("time changed", 0);
|
||||||
|
last_timestamp = now;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_settings(void)
|
static void read_settings(void)
|
||||||
{
|
{
|
||||||
timestamp_format = settings_get_str("timestamp_format");
|
timestamp_format = settings_get_str("timestamp_format");
|
||||||
|
timestamp_seconds =
|
||||||
|
strstr(timestamp_format, "%r") != NULL ||
|
||||||
|
strstr(timestamp_format, "%s") != NULL ||
|
||||||
|
strstr(timestamp_format, "%S") != NULL ||
|
||||||
|
strstr(timestamp_format, "%T") != NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void expandos_init(void)
|
void expandos_init(void)
|
||||||
@ -457,6 +520,7 @@ void expandos_init(void)
|
|||||||
client_start_time = time(NULL);
|
client_start_time = time(NULL);
|
||||||
last_sent_msg = NULL; last_sent_msg_body = NULL;
|
last_sent_msg = NULL; last_sent_msg_body = NULL;
|
||||||
last_privmsg_from = NULL; last_public_from = NULL;
|
last_privmsg_from = NULL; last_public_from = NULL;
|
||||||
|
last_timestamp = 0;
|
||||||
|
|
||||||
sysname = sysrelease = sysarch = NULL;
|
sysname = sysrelease = sysarch = NULL;
|
||||||
#ifdef HAVE_SYS_UTSNAME_H
|
#ifdef HAVE_SYS_UTSNAME_H
|
||||||
@ -523,7 +587,8 @@ void expandos_init(void)
|
|||||||
expando_create("Y", expando_realname,
|
expando_create("Y", expando_realname,
|
||||||
"window changed", EXPANDO_ARG_NONE,
|
"window changed", EXPANDO_ARG_NONE,
|
||||||
"window server changed", EXPANDO_ARG_WINDOW, NULL);
|
"window server changed", EXPANDO_ARG_WINDOW, NULL);
|
||||||
expando_create("Z", expando_time, NULL);
|
expando_create("Z", expando_time,
|
||||||
|
"time changed", EXPANDO_ARG_NONE, NULL);
|
||||||
expando_create("$", expando_dollar,
|
expando_create("$", expando_dollar,
|
||||||
"", EXPANDO_NEVER, NULL);
|
"", EXPANDO_NEVER, NULL);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/* first argument of signal must match to active .. */
|
/* first argument of signal must match to active .. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EXPANDO_ARG_NONE,
|
EXPANDO_ARG_NONE = 1,
|
||||||
EXPANDO_ARG_SERVER,
|
EXPANDO_ARG_SERVER,
|
||||||
EXPANDO_ARG_WINDOW,
|
EXPANDO_ARG_WINDOW,
|
||||||
EXPANDO_ARG_WINDOW_ITEM,
|
EXPANDO_ARG_WINDOW_ITEM,
|
||||||
@ -28,6 +28,9 @@ void expando_destroy(const char *key, EXPANDO_FUNC func);
|
|||||||
void expando_bind(const char *key, int funccount, SIGNAL_FUNC *funcs);
|
void expando_bind(const char *key, int funccount, SIGNAL_FUNC *funcs);
|
||||||
void expando_unbind(const char *key, int funccount, SIGNAL_FUNC *funcs);
|
void expando_unbind(const char *key, int funccount, SIGNAL_FUNC *funcs);
|
||||||
|
|
||||||
|
/* Returns [<signal id>, EXPANDO_ARG_xxx, <signal id>, ..., -1] */
|
||||||
|
int *expando_get_signals(const char *key);
|
||||||
|
|
||||||
/* internal: */
|
/* internal: */
|
||||||
EXPANDO_FUNC expando_find_char(char chr);
|
EXPANDO_FUNC expando_find_char(char chr);
|
||||||
EXPANDO_FUNC expando_find_long(const char *key);
|
EXPANDO_FUNC expando_find_long(const char *key);
|
||||||
|
@ -597,41 +597,126 @@ void special_history_func_set(SPECIAL_HISTORY_FUNC func)
|
|||||||
history_func = func;
|
history_func = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void special_vars_signals_do(const char *text, int funccount,
|
static void update_signals_hash(GHashTable **hash, int *signals)
|
||||||
SIGNAL_FUNC *funcs, int bind)
|
|
||||||
{
|
{
|
||||||
char *ret;
|
void *signal_id;
|
||||||
int need_free;
|
int arg_type;
|
||||||
|
|
||||||
|
if (*hash == NULL) {
|
||||||
|
*hash = g_hash_table_new((GHashFunc) g_direct_hash,
|
||||||
|
(GCompareFunc) g_direct_equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*signals != -1) {
|
||||||
|
signal_id = GINT_TO_POINTER(*signals);
|
||||||
|
arg_type = GPOINTER_TO_INT(g_hash_table_lookup(*hash, signal_id));
|
||||||
|
if (arg_type != 0 && arg_type != signals[1]) {
|
||||||
|
/* same signal is used for different purposes ..
|
||||||
|
not sure if this should ever happen, but change
|
||||||
|
the argument type to none so it will at least
|
||||||
|
work. */
|
||||||
|
arg_type = EXPANDO_ARG_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_type == 0) arg_type = signals[1];
|
||||||
|
g_hash_table_insert(*hash, signal_id,
|
||||||
|
GINT_TO_POINTER(arg_type));
|
||||||
|
signals += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_signal_hash(void *signal_id, void *arg_type, int **pos)
|
||||||
|
{
|
||||||
|
(*pos)[0] = GPOINTER_TO_INT(signal_id);
|
||||||
|
(*pos)[1] = GPOINTER_TO_INT(arg_type);
|
||||||
|
(*pos) += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int *get_signals_list(GHashTable *hash)
|
||||||
|
{
|
||||||
|
int *signals, *pos;
|
||||||
|
|
||||||
|
if (hash == NULL) {
|
||||||
|
/* no expandos in text - never needs updating */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = signals = g_new(int, g_hash_table_size(hash)*2 + 1);
|
||||||
|
g_hash_table_foreach(hash, (GHFunc) get_signal_hash, &pos);
|
||||||
|
*pos = -1;
|
||||||
|
|
||||||
|
g_hash_table_destroy(hash);
|
||||||
|
return signals;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TASK_BIND 1
|
||||||
|
#define TASK_UNBIND 2
|
||||||
|
#define TASK_GET_SIGNALS 3
|
||||||
|
|
||||||
|
static int *special_vars_signals_task(const char *text, int funccount,
|
||||||
|
SIGNAL_FUNC *funcs, int task)
|
||||||
|
{
|
||||||
|
GHashTable *signals;
|
||||||
|
char *expando;
|
||||||
|
int need_free, *expando_signals;
|
||||||
|
|
||||||
|
signals = NULL;
|
||||||
while (*text != '\0') {
|
while (*text != '\0') {
|
||||||
if (*text == '\\' && text[1] != '\0') {
|
if (*text == '\\' && text[1] != '\0') {
|
||||||
|
/* escape */
|
||||||
text += 2;
|
text += 2;
|
||||||
} else if (*text == '$' && text[1] != '\0') {
|
} else if (*text == '$' && text[1] != '\0') {
|
||||||
|
/* expando */
|
||||||
text++;
|
text++;
|
||||||
ret = parse_special((char **) &text, NULL, NULL,
|
expando = parse_special((char **) &text, NULL, NULL,
|
||||||
NULL, &need_free, NULL,
|
NULL, &need_free, NULL,
|
||||||
PARSE_FLAG_GETNAME);
|
PARSE_FLAG_GETNAME);
|
||||||
if (ret != NULL) {
|
if (expando == NULL)
|
||||||
if (bind)
|
continue;
|
||||||
expando_bind(ret, funccount, funcs);
|
|
||||||
else
|
|
||||||
expando_unbind(ret, funccount, funcs);
|
|
||||||
if (need_free) g_free(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (task) {
|
||||||
|
case TASK_BIND:
|
||||||
|
expando_bind(expando, funccount, funcs);
|
||||||
|
break;
|
||||||
|
case TASK_UNBIND:
|
||||||
|
expando_unbind(expando, funccount, funcs);
|
||||||
|
break;
|
||||||
|
case TASK_GET_SIGNALS:
|
||||||
|
expando_signals = expando_get_signals(expando);
|
||||||
|
if (expando_signals != NULL) {
|
||||||
|
update_signals_hash(&signals,
|
||||||
|
expando_signals);
|
||||||
|
g_free(expando_signals);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (need_free) g_free(expando);
|
||||||
|
} else {
|
||||||
|
/* just a char */
|
||||||
|
text++;
|
||||||
}
|
}
|
||||||
else text++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (task == TASK_GET_SIGNALS)
|
||||||
|
return get_signals_list(signals);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void special_vars_add_signals(const char *text,
|
void special_vars_add_signals(const char *text,
|
||||||
int funccount, SIGNAL_FUNC *funcs)
|
int funccount, SIGNAL_FUNC *funcs)
|
||||||
{
|
{
|
||||||
special_vars_signals_do(text, funccount, funcs, TRUE);
|
special_vars_signals_task(text, funccount, funcs, TASK_BIND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void special_vars_remove_signals(const char *text,
|
void special_vars_remove_signals(const char *text,
|
||||||
int funccount, SIGNAL_FUNC *funcs)
|
int funccount, SIGNAL_FUNC *funcs)
|
||||||
{
|
{
|
||||||
special_vars_signals_do(text, funccount, funcs, FALSE);
|
special_vars_signals_task(text, funccount, funcs, TASK_UNBIND);
|
||||||
|
}
|
||||||
|
|
||||||
|
int *special_vars_get_signals(const char *text)
|
||||||
|
{
|
||||||
|
return special_vars_signals_task(text, 0, NULL, TASK_GET_SIGNALS);
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,7 @@ void special_vars_add_signals(const char *text,
|
|||||||
int funccount, SIGNAL_FUNC *funcs);
|
int funccount, SIGNAL_FUNC *funcs);
|
||||||
void special_vars_remove_signals(const char *text,
|
void special_vars_remove_signals(const char *text,
|
||||||
int funccount, SIGNAL_FUNC *funcs);
|
int funccount, SIGNAL_FUNC *funcs);
|
||||||
|
/* Returns [<signal id>, EXPANDO_ARG_xxx, <signal id>, ..., -1] */
|
||||||
|
int *special_vars_get_signals(const char *text);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user