1 /*
2 * Copyright (c) 2002-2013 Balabit
3 * Copyright (c) 1998-2013 Balázs Scheidler
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * As an additional exemption you are allowed to compile & link against the
20 * OpenSSL libraries as published by the OpenSSL project. See the file
21 * COPYING for details.
22 *
23 */
24 #include "cfg-args.h"
25 #include "messages.h"
26 #include "str-utils.h"
27 #include "str-repr/encode.h"
28
29 struct _CfgArgs
30 {
31 gint ref_cnt;
32 GHashTable *args;
33 gboolean accept_varargs;
34 };
35
36 gboolean
cfg_args_is_accepting_varargs(CfgArgs * self)37 cfg_args_is_accepting_varargs(CfgArgs *self)
38 {
39 return self->accept_varargs;
40 }
41
42 void
cfg_args_accept_varargs(CfgArgs * self)43 cfg_args_accept_varargs(CfgArgs *self)
44 {
45 self->accept_varargs = TRUE;
46 }
47
48 void
cfg_args_foreach(CfgArgs * self,GHFunc func,gpointer user_data)49 cfg_args_foreach(CfgArgs *self, GHFunc func, gpointer user_data)
50 {
51 g_hash_table_foreach(self->args, func, user_data);
52 }
53
54 static void
_resolve_unknown_blockargs_as_varargs(gpointer key,gpointer value,gpointer user_data)55 _resolve_unknown_blockargs_as_varargs(gpointer key, gpointer value, gpointer user_data)
56 {
57 CfgArgs *defaults = ((gpointer *) user_data)[0];
58 GString *varargs = ((gpointer *) user_data)[1];
59
60 if (!defaults || !cfg_args_contains(defaults, key))
61 {
62 g_string_append_printf(varargs, "%s(%s) ", (gchar *)key, (gchar *)value);
63 }
64 }
65
66 gchar *
cfg_args_format_varargs(CfgArgs * self,CfgArgs * defaults)67 cfg_args_format_varargs(CfgArgs *self, CfgArgs *defaults)
68 {
69 GString *varargs = g_string_new("");
70 gpointer user_data[] = { defaults, varargs };
71
72 cfg_args_foreach(self, _resolve_unknown_blockargs_as_varargs, user_data);
73 return g_string_free(varargs, FALSE);
74 }
75
76 void
cfg_args_set(CfgArgs * self,const gchar * name,const gchar * value)77 cfg_args_set(CfgArgs *self, const gchar *name, const gchar *value)
78 {
79 g_hash_table_insert(self->args, __normalize_key(name), g_strdup(value));
80 }
81
82 const gchar *
cfg_args_get(CfgArgs * self,const gchar * name)83 cfg_args_get(CfgArgs *self, const gchar *name)
84 {
85 const gchar *value = g_hash_table_lookup(self->args, name);
86
87 if (!value)
88 {
89 gchar *normalized_name = __normalize_key(name);
90 value = g_hash_table_lookup(self->args, normalized_name);
91 g_free(normalized_name);
92 }
93
94 return value;
95 }
96
97 gboolean
cfg_args_contains(CfgArgs * self,const gchar * name)98 cfg_args_contains(CfgArgs *self, const gchar *name)
99 {
100 gchar *normalized_name = __normalize_key(name);
101 gboolean contains = g_hash_table_lookup_extended(self->args, normalized_name, NULL, NULL);
102 g_free(normalized_name);
103 return contains;
104 }
105
106 void
cfg_args_remove_normalized(CfgArgs * self,const gchar * normalized_name)107 cfg_args_remove_normalized(CfgArgs *self, const gchar *normalized_name)
108 {
109 gpointer orig_key;
110 if (g_hash_table_lookup_extended(self->args, normalized_name, &orig_key, NULL))
111 {
112 g_hash_table_remove(self->args, orig_key);
113 }
114 }
115
116 void
cfg_args_remove(CfgArgs * self,const gchar * name)117 cfg_args_remove(CfgArgs *self, const gchar *name)
118 {
119 gchar *normalized_name = __normalize_key(name);
120 cfg_args_remove_normalized(self, normalized_name);
121 g_free(normalized_name);
122 }
123
124 CfgArgs *
cfg_args_new(void)125 cfg_args_new(void)
126 {
127 CfgArgs *self = g_new0(CfgArgs, 1);
128
129 self->args = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
130 self->ref_cnt = 1;
131 return self;
132 }
133
134 CfgArgs *
cfg_args_ref(CfgArgs * self)135 cfg_args_ref(CfgArgs *self)
136 {
137 if (self)
138 self->ref_cnt++;
139 return self;
140 }
141
142 void
cfg_args_unref(CfgArgs * self)143 cfg_args_unref(CfgArgs *self)
144 {
145 if (self && --self->ref_cnt == 0)
146 {
147 g_hash_table_destroy(self->args);
148 g_free(self);
149 }
150 }
151