Back to index

indicator-appmenu  12.10.0
hudstringlist.c
Go to the documentation of this file.
00001 /*
00002  * Copyright © 2012 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License version 3, as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License along
00014  * with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Author: Ryan Lortie <desrt@desrt.ca>
00017  */
00018 
00019 #include "hudstringlist.h"
00020 
00021 #include <string.h>
00022 
00056 struct _HudStringList
00057 {
00058   HudStringList *tail;
00059   gint ref_count;
00060 
00061   /* variable length.  must come last! */
00062   gchar head[1];
00063 };
00064 
00071 void
00072 hud_string_list_unref (HudStringList *list)
00073 {
00074   if (list && g_atomic_int_dec_and_test (&list->ref_count))
00075     {
00076       hud_string_list_unref (list->tail);
00077       g_free (list);
00078     }
00079 }
00080 
00089 HudStringList *
00090 hud_string_list_ref (HudStringList *list)
00091 {
00092   if (list)
00093     g_atomic_int_inc (&list->ref_count);
00094 
00095   return list;
00096 }
00097 
00110 HudStringList *
00111 hud_string_list_cons (const gchar   *head,
00112                       HudStringList *tail)
00113 {
00114   HudStringList *list;
00115   gsize headlen;
00116 
00117   headlen = strlen (head);
00118 
00119   list = g_malloc (G_STRUCT_OFFSET (HudStringList, head) + headlen + 1);
00120   list->tail = hud_string_list_ref (tail);
00121   /* coverity[secure_coding] */
00122   strcpy (list->head, head);
00123   list->ref_count = 1;
00124 
00125   return list;
00126 }
00127 
00136 const gchar *
00137 hud_string_list_get_head (HudStringList *list)
00138 {
00139   return list->head;
00140 }
00141 
00150 HudStringList *
00151 hud_string_list_get_tail (HudStringList *list)
00152 {
00153   return list->tail;
00154 }
00155 
00166 gchar *
00167 hud_string_list_pretty_print (HudStringList *list)
00168 {
00169   GString *string;
00170 
00171   string = g_string_new (NULL);
00172   while (list)
00173     {
00174       g_string_prepend (string, list->head);
00175 
00176       list = list->tail;
00177 
00178       if (list)
00179         g_string_prepend (string, " > ");
00180     }
00181 
00182   return g_string_free (string, FALSE);
00183 }
00184 
00198 HudStringList *
00199 hud_string_list_cons_label (const gchar   *label,
00200                             HudStringList *tail)
00201 {
00202   HudStringList *list;
00203   gint i = 0, j = 0;
00204   gsize headlen;
00205 
00206   /* For simplicity, over-allocate.  In practice, this will only
00207    * ever waste one byte at most (since we will only remove one
00208    * underscore).
00209    */
00210   headlen = strlen (label);
00211 
00212   list = g_malloc (G_STRUCT_OFFSET (HudStringList, head) + headlen + 1);
00213   list->tail = hud_string_list_ref (tail);
00214   list->ref_count = 1;
00215 
00216   while (label[j])
00217     {
00218       if (label[j] == '_' && label[j + 1])
00219         j++;
00220 
00221       list->head[i++] = label[j++];
00222     }
00223   g_assert (i <= headlen);
00224   list->head[i] = '\0';
00225 
00226   return list;
00227 }