summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2024-04-07 10:09:04 +0200
committerSébastien Helleu <flashcode@flashtux.org>2024-04-07 13:18:14 +0200
commit89fe540b531705d8455685173c692522e81cd134 (patch)
tree717a3b15ef5e7d254a2515371efac6d79329f527 /src/gui
parent40a68549b5d4d99c0083f15242aab7516a87871f (diff)
downloadweechat-89fe540b531705d8455685173c692522e81cd134.zip
core: add unique "id" in nicklist group and nick (issue #2081)
The id is a "long long" variable with the current time (microseconds precision). It is guaranteed to be unique for all groups and nicks inside the buffer, and the same number is never used again in the same buffer, during the lifetime of the process. It persists and is unchanged after `/upgrade`.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui-buffer.c20
-rw-r--r--src/gui/gui-buffer.h1
-rw-r--r--src/gui/gui-nicklist.c124
-rw-r--r--src/gui/gui-nicklist.h17
4 files changed, 148 insertions, 14 deletions
diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c
index 8941affea..d7edf0c90 100644
--- a/src/gui/gui-buffer.c
+++ b/src/gui/gui-buffer.c
@@ -110,9 +110,9 @@ char *gui_buffer_properties_get_integer[] =
};
char *gui_buffer_properties_get_string[] =
{ "id", "plugin", "name", "full_name", "old_full_name", "short_name", "title",
- "input", "text_search_input", "highlight_words", "highlight_disable_regex",
- "highlight_regex", "highlight_tags_restrict", "highlight_tags",
- "hotlist_max_level_nicks",
+ "nicklist_last_id_assigned", "input", "text_search_input", "highlight_words",
+ "highlight_disable_regex", "highlight_regex", "highlight_tags_restrict",
+ "highlight_tags", "hotlist_max_level_nicks",
NULL
};
char *gui_buffer_properties_get_pointer[] =
@@ -888,10 +888,11 @@ gui_buffer_new_props_with_id (long long id,
new_buffer->nicklist_groups_visible_count = 0;
new_buffer->nicklist_nicks_count = 0;
new_buffer->nicklist_nicks_visible_count = 0;
+ new_buffer->nicklist_last_id_assigned = -1;
new_buffer->nickcmp_callback = NULL;
new_buffer->nickcmp_callback_pointer = NULL;
new_buffer->nickcmp_callback_data = NULL;
- gui_nicklist_add_group (new_buffer, NULL, "root", NULL, 0);
+ gui_nicklist_add_group_with_id (new_buffer, 0, NULL, "root", NULL, 0);
/* input */
new_buffer->input = 1;
@@ -1539,6 +1540,12 @@ gui_buffer_get_string (struct t_gui_buffer *buffer, const char *property)
return gui_buffer_type_string[buffer->type];
else if (strcmp (property, "title") == 0)
return buffer->title;
+ else if (strcmp (property, "nicklist_last_id_assigned") == 0)
+ {
+ snprintf (str_value, sizeof (str_value),
+ "%lld", buffer->nicklist_last_id_assigned);
+ return str_value;
+ }
else if (strcmp (property, "input") == 0)
return buffer->input_buffer;
else if (strcmp (property, "text_search_input") == 0)
@@ -5188,6 +5195,7 @@ gui_buffer_hdata_buffer_cb (const void *pointer, void *data,
HDATA_VAR(struct t_gui_buffer, nicklist_groups_visible_count, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_buffer, nicklist_nicks_count, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_buffer, nicklist_nicks_visible_count, INTEGER, 0, NULL, NULL);
+ HDATA_VAR(struct t_gui_buffer, nicklist_last_id_assigned, LONGLONG, 0, NULL, NULL);
HDATA_VAR(struct t_gui_buffer, nickcmp_callback, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_buffer, nickcmp_callback_pointer, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_buffer, nickcmp_callback_data, POINTER, 0, NULL, NULL);
@@ -5407,6 +5415,9 @@ gui_buffer_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!infolist_new_var_integer (ptr_item, "nicklist_nicks_visible_count", buffer->nicklist_nicks_visible_count))
return 0;
+ snprintf (str_value, sizeof (str_value), "%lld", buffer->nicklist_last_id_assigned);
+ if (!infolist_new_var_string (ptr_item, "nicklist_last_id_assigned", str_value))
+ return 0;
if (!infolist_new_var_string (ptr_item, "title", buffer->title))
return 0;
if (!infolist_new_var_integer (ptr_item, "input", buffer->input))
@@ -5643,6 +5654,7 @@ gui_buffer_print_log ()
log_printf (" nicklist_groups_vis_cnt : %d", ptr_buffer->nicklist_groups_visible_count);
log_printf (" nicklist_nicks_count. . : %d", ptr_buffer->nicklist_nicks_count);
log_printf (" nicklist_nicks_vis_cnt. : %d", ptr_buffer->nicklist_nicks_visible_count);
+ log_printf (" nicklist_last_id_assigned: %lld", ptr_buffer->nicklist_last_id_assigned);
log_printf (" nickcmp_callback. . . . : %p", ptr_buffer->nickcmp_callback);
log_printf (" nickcmp_callback_pointer: %p", ptr_buffer->nickcmp_callback_pointer);
log_printf (" nickcmp_callback_data . : %p", ptr_buffer->nickcmp_callback_data);
diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h
index f3de457b6..09373e9be 100644
--- a/src/gui/gui-buffer.h
+++ b/src/gui/gui-buffer.h
@@ -169,6 +169,7 @@ struct t_gui_buffer
int nicklist_groups_visible_count; /* number of groups displayed */
int nicklist_nicks_count; /* number of nicks */
int nicklist_nicks_visible_count; /* number of nicks displayed */
+ long long nicklist_last_id_assigned; /* last id assigned for a grp/nick */
int (*nickcmp_callback)(const void *pointer, /* called to compare nicks */
void *data, /* (search in nicklist) */
struct t_gui_buffer *buffer,
diff --git a/src/gui/gui-nicklist.c b/src/gui/gui-nicklist.c
index 535c8c6b8..4d0443887 100644
--- a/src/gui/gui-nicklist.c
+++ b/src/gui/gui-nicklist.c
@@ -252,15 +252,45 @@ gui_nicklist_search_group (struct t_gui_buffer *buffer,
}
/*
- * Adds a group to nicklist.
+ * Returns a new unique id for a group/nick.
+ *
+ * The id is the current time with microseconds precision.
+ * The same time (including microseconds) can be used only one time, so that
+ * all group/nick ids in a given buffer are guaranteed to be unique.
+ */
+
+long long
+gui_nicklist_generate_id (struct t_gui_buffer *buffer)
+{
+ struct timeval tv;
+ long long id;
+
+ gettimeofday (&tv, NULL);
+
+ id = ((long long)tv.tv_sec * 1000000LL) + (long long)(tv.tv_usec);
+
+ /*
+ * ensure we never use the same id for two groups/nicks in the buffer
+ * and that the returned id is strictly greater than the last assigned one
+ * in the buffer
+ */
+ if (id <= buffer->nicklist_last_id_assigned)
+ id = buffer->nicklist_last_id_assigned + 1;
+
+ return id;
+}
+
+/*
+ * Adds a group to nicklist with identifier (internal use).
*
* Returns pointer to new group, NULL if error.
*/
struct t_gui_nick_group *
-gui_nicklist_add_group (struct t_gui_buffer *buffer,
- struct t_gui_nick_group *parent_group, const char *name,
- const char *color, int visible)
+gui_nicklist_add_group_with_id (struct t_gui_buffer *buffer, long long id,
+ struct t_gui_nick_group *parent_group,
+ const char *name, const char *color,
+ int visible)
{
struct t_gui_nick_group *new_group;
@@ -271,6 +301,9 @@ gui_nicklist_add_group (struct t_gui_buffer *buffer,
if (!new_group)
return NULL;
+ new_group->id = id;
+ if (new_group->id > buffer->nicklist_last_id_assigned)
+ buffer->nicklist_last_id_assigned = new_group->id;
new_group->name = (char *)string_shared_get (name);
new_group->color = (color) ? (char *)string_shared_get (color) : NULL;
new_group->visible = visible;
@@ -309,6 +342,29 @@ gui_nicklist_add_group (struct t_gui_buffer *buffer,
}
/*
+ * Adds a group to nicklist.
+ *
+ * Returns pointer to new group, NULL if error.
+ */
+
+struct t_gui_nick_group *
+gui_nicklist_add_group (struct t_gui_buffer *buffer,
+ struct t_gui_nick_group *parent_group, const char *name,
+ const char *color, int visible)
+{
+ if (!buffer)
+ return NULL;
+
+ return gui_nicklist_add_group_with_id (
+ buffer,
+ gui_nicklist_generate_id (buffer),
+ parent_group,
+ name,
+ color,
+ visible);
+}
+
+/*
* Searches for position of a nick (to keep nicklist sorted).
*/
@@ -430,17 +486,17 @@ gui_nicklist_search_nick (struct t_gui_buffer *buffer,
}
/*
- * Adds a nick to nicklist.
+ * Adds a nick to nicklist with identifier (internal use).
*
* Returns pointer to new nick, NULL if error.
*/
struct t_gui_nick *
-gui_nicklist_add_nick (struct t_gui_buffer *buffer,
- struct t_gui_nick_group *group,
- const char *name, const char *color,
- const char *prefix, const char *prefix_color,
- int visible)
+gui_nicklist_add_nick_with_id (struct t_gui_buffer *buffer, long long id,
+ struct t_gui_nick_group *group,
+ const char *name, const char *color,
+ const char *prefix, const char *prefix_color,
+ int visible)
{
struct t_gui_nick *new_nick;
@@ -451,6 +507,9 @@ gui_nicklist_add_nick (struct t_gui_buffer *buffer,
if (!new_nick)
return NULL;
+ new_nick->id = id;
+ if (new_nick->id > buffer->nicklist_last_id_assigned)
+ buffer->nicklist_last_id_assigned = new_nick->id;
new_nick->group = (group) ? group : buffer->nicklist_root;
new_nick->name = (char *)string_shared_get (name);
new_nick->color = (color) ? (char *)string_shared_get (color) : NULL;
@@ -479,6 +538,33 @@ gui_nicklist_add_nick (struct t_gui_buffer *buffer,
}
/*
+ * Adds a nick to nicklist.
+ *
+ * Returns pointer to new nick, NULL if error.
+ */
+
+struct t_gui_nick *
+gui_nicklist_add_nick (struct t_gui_buffer *buffer,
+ struct t_gui_nick_group *group,
+ const char *name, const char *color,
+ const char *prefix, const char *prefix_color,
+ int visible)
+{
+ if (!buffer)
+ return NULL;
+
+ return gui_nicklist_add_nick_with_id (
+ buffer,
+ gui_nicklist_generate_id (buffer),
+ group,
+ name,
+ color,
+ prefix,
+ prefix_color,
+ visible);
+}
+
+/*
* Removes a nick from a group.
*/
@@ -1078,6 +1164,7 @@ gui_nicklist_hdata_nick_group_cb (const void *pointer, void *data,
0, 0, NULL, NULL);
if (hdata)
{
+ HDATA_VAR(struct t_gui_nick_group, id, LONGLONG, 0, NULL, NULL);
HDATA_VAR(struct t_gui_nick_group, name, SHARED_STRING, 0, NULL, NULL);
HDATA_VAR(struct t_gui_nick_group, color, SHARED_STRING, 0, NULL, NULL);
HDATA_VAR(struct t_gui_nick_group, visible, INTEGER, 0, NULL, NULL);
@@ -1111,6 +1198,7 @@ gui_nicklist_hdata_nick_cb (const void *pointer, void *data,
0, 0, NULL, NULL);
if (hdata)
{
+ HDATA_VAR(struct t_gui_nick, id, LONGLONG, 0, NULL, NULL);
HDATA_VAR(struct t_gui_nick, group, POINTER, 0, NULL, "nick_group");
HDATA_VAR(struct t_gui_nick, name, SHARED_STRING, 0, NULL, NULL);
HDATA_VAR(struct t_gui_nick, color, SHARED_STRING, 0, NULL, NULL);
@@ -1136,6 +1224,7 @@ gui_nicklist_add_group_to_infolist (struct t_infolist *infolist,
struct t_gui_nick_group *group)
{
struct t_infolist_item *ptr_item;
+ char str_value[64];
if (!infolist || !group)
return 0;
@@ -1144,6 +1233,9 @@ gui_nicklist_add_group_to_infolist (struct t_infolist *infolist,
if (!ptr_item)
return 0;
+ snprintf (str_value, sizeof (str_value), "%lld", group->id);
+ if (!infolist_new_var_string (ptr_item, "id", str_value))
+ return 0;
if (!infolist_new_var_string (ptr_item, "type", "group"))
return 0;
if (group->parent)
@@ -1176,6 +1268,7 @@ gui_nicklist_add_nick_to_infolist (struct t_infolist *infolist,
struct t_gui_nick *nick)
{
struct t_infolist_item *ptr_item;
+ char str_value[64];
if (!infolist || !nick)
return 0;
@@ -1184,6 +1277,9 @@ gui_nicklist_add_nick_to_infolist (struct t_infolist *infolist,
if (!ptr_item)
return 0;
+ snprintf (str_value, sizeof (str_value), "%lld", nick->id);
+ if (!infolist_new_var_string (ptr_item, "id", str_value))
+ return 0;
if (!infolist_new_var_string (ptr_item, "type", "nick"))
return 0;
if (nick->group)
@@ -1274,6 +1370,10 @@ gui_nicklist_print_log (struct t_gui_nick_group *group, int indent)
(indent * 2) + 4);
log_printf (format, " ", group);
snprintf (format, sizeof (format),
+ "%%-%dsid. . . . . : %%lld",
+ (indent * 2) + 6);
+ log_printf (format, " ", group->id);
+ snprintf (format, sizeof (format),
"%%-%dsname. . . . : '%%s'",
(indent * 2) + 6);
log_printf (format, " ", group->name);
@@ -1337,6 +1437,10 @@ gui_nicklist_print_log (struct t_gui_nick_group *group, int indent)
(indent * 2) + 6);
log_printf (format, " ", ptr_nick->group);
snprintf (format, sizeof (format),
+ "%%-%dsid. . . . . . . : %%lld",
+ (indent * 2) + 6);
+ log_printf (format, " ", ptr_nick->id);
+ snprintf (format, sizeof (format),
"%%-%dsname. . . . . . : '%%s'",
(indent * 2) + 6);
log_printf (format, " ", ptr_nick->name);
diff --git a/src/gui/gui-nicklist.h b/src/gui/gui-nicklist.h
index 752767e12..ce0d3c7e9 100644
--- a/src/gui/gui-nicklist.h
+++ b/src/gui/gui-nicklist.h
@@ -25,6 +25,7 @@ struct t_infolist;
struct t_gui_nick_group
{
+ long long id; /* unique id for group/nick in buffer*/
char *name; /* group name */
char *color; /* color for group in nicklist */
int visible; /* 1 if group is displayed */
@@ -40,6 +41,7 @@ struct t_gui_nick_group
struct t_gui_nick
{
+ long long id; /* unique id for group/nick in buffer*/
struct t_gui_nick_group *group; /* group which contains nick */
char *name; /* nick name */
char *color; /* color for nick in nicklist */
@@ -55,6 +57,13 @@ struct t_gui_nick
extern struct t_gui_nick_group *gui_nicklist_search_group (struct t_gui_buffer *buffer,
struct t_gui_nick_group *from_group,
const char *name);
+extern long long gui_nicklist_generate_id (struct t_gui_buffer *buffer);
+extern struct t_gui_nick_group *gui_nicklist_add_group_with_id (struct t_gui_buffer *buffer,
+ long long id,
+ struct t_gui_nick_group *parent_group,
+ const char *name,
+ const char *color,
+ int visible);
extern struct t_gui_nick_group *gui_nicklist_add_group (struct t_gui_buffer *buffer,
struct t_gui_nick_group *parent_group,
const char *name,
@@ -63,6 +72,14 @@ extern struct t_gui_nick_group *gui_nicklist_add_group (struct t_gui_buffer *buf
extern struct t_gui_nick *gui_nicklist_search_nick (struct t_gui_buffer *buffer,
struct t_gui_nick_group *from_group,
const char *name);
+extern struct t_gui_nick *gui_nicklist_add_nick_with_id (struct t_gui_buffer *buffer,
+ long long id,
+ struct t_gui_nick_group *group,
+ const char *name,
+ const char *color,
+ const char *prefix,
+ const char *prefix_color,
+ int visible);
extern struct t_gui_nick *gui_nicklist_add_nick (struct t_gui_buffer *buffer,
struct t_gui_nick_group *group,
const char *name,