2
* Copyright © 2012 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Author: Ryan Lortie <desrt@desrt.ca>
19
#include "hudstringlist.h"
24
* SECTION:hudstringlist
25
* @title: HudStringList
26
* @short_description: a refcounted list of strings
28
* #HudStringList is a refcounted list of strings.
30
* Borrowing heavily on conventions of many functional programming
31
* languages, a list is a head element connected to a tail list (ie: the
34
* A %NULL pointer is considered to be a valid empty list.
36
* Each list node is refcounted, and holds a reference on its 'tail'
37
* list. This allows common tails to be shared.
39
* This mechanism is ideally suited to the HUD which is interested in
40
* displaying items of the form "File > New" and "File > Open". In this
41
* case, these items would be represented (in reverse) by the lists
42
* <code>['Open', 'File']</code> and <code>['New', 'File']</code> with
43
* the common tail portion shared between both items.
45
* Each #HudStringList node uses only one variable-sized block of
46
* memory. The reference count and pointer to the 'tail' are stored in
47
* a header, followed by the 'head' string data.
53
* This is an opaque structure type.
61
/* variable length. must come last! */
66
* hud_string_list_unref:
67
* @list: (allow-none): a #HudStringList, possibly %NULL
69
* Decreases the reference count on @list, possibly freeing it.
72
hud_string_list_unref (HudStringList *list)
74
if (list && g_atomic_int_dec_and_test (&list->ref_count))
76
hud_string_list_unref (list->tail);
82
* hud_string_list_ref:
83
* @list: (allow-none): a #HudStringList, possibly %NULL
85
* Increases the reference count on @list.
87
* Returns: a new reference to the list
90
hud_string_list_ref (HudStringList *list)
93
g_atomic_int_inc (&list->ref_count);
99
* hud_string_list_cons:
100
* @head: a string for the head item
101
* @tail: (allow-none): the tail #HudStringList, possibly %NULL
103
* Create a new list with @head as the first item and @tail as the rest
106
* A reference is taken on @tail.
108
* Returns: (transfer full): a new list
111
hud_string_list_cons (const gchar *head,
117
headlen = strlen (head);
119
list = g_malloc (G_STRUCT_OFFSET (HudStringList, head) + headlen + 1);
120
list->tail = hud_string_list_ref (tail);
121
/* coverity[secure_coding] */
122
strcpy (list->head, head);
129
* hud_string_list_get_head:
130
* @list: a non-empty (non-%NULL) #HudStringList
132
* Gets the head string of the list.
134
* Returns: the head element, as a normal C string
137
hud_string_list_get_head (HudStringList *list)
143
* hud_string_list_get_tail:
144
* @list: a non-empty (non-%NULL) #HudStringList
146
* Gets the tail of the list.
148
* Returns: (transfer none): the tail of the list
151
hud_string_list_get_tail (HudStringList *list)
157
* hud_string_list_pretty_print:
158
* @list: (allow-none): a #HudStringList, possibly %NULL
160
* Pretty-prints the list.
162
* This function is intended only for debugging purposes.
164
* Returns: the pretty-printed list
167
hud_string_list_pretty_print (HudStringList *list)
171
string = g_string_new (NULL);
174
g_string_prepend (string, list->head);
179
g_string_prepend (string, " > ");
182
return g_string_free (string, FALSE);
186
* hud_string_list_cons_label:
187
* @label: (allow-none): a menuitem label
188
* @tail: (allow-none): the tail #HudStringList, possibly %NULL
190
* Slight "magic" helper function for doing the right thing with
191
* prepending menu labels.
193
* @label is processed, removing mnemonic prefixes (ie: '_' characters)
194
* and then the function acts, essentially as hud_string_list_cons().
196
* Returns: (transfer full): a new #HudStringList
199
hud_string_list_cons_label (const gchar *label,
206
/* For simplicity, over-allocate. In practice, this will only
207
* ever waste one byte at most (since we will only remove one
210
headlen = strlen (label);
212
list = g_malloc (G_STRUCT_OFFSET (HudStringList, head) + headlen + 1);
213
list->tail = hud_string_list_ref (tail);
218
if (label[j] == '_' && label[j + 1])
221
list->head[i++] = label[j++];
223
g_assert (i <= headlen);
224
list->head[i] = '\0';