1 /*
2 roxterm - VTE/GTK terminal emulator with tabs
3 Copyright (C) 2004-2015 Tony Houghton <h@realh.co.uk>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21 #include "defns.h"
22
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "dlg.h"
28 #include "options.h"
29 #include "optsfile.h"
30
options_reload_keyfile(Options * options)31 void options_reload_keyfile(Options *options)
32 {
33 if (options->kf)
34 options_delete_keyfile(options);
35 options->kf = options_file_open(options->name, options->group_name);
36 options->kf_dirty = FALSE;
37 }
38
options_open(const char * leafname,const char * group_name)39 Options *options_open(const char *leafname, const char *group_name)
40 {
41 Options *options = g_new0(Options, 1);
42
43 options->group_name = group_name;
44 options->name = g_strdup(leafname);
45 options->ref = 1;
46 options_reload_keyfile(options);
47 return options;
48 }
49
options_copy_keyfile(Options * dest,const Options * src)50 gboolean options_copy_keyfile(Options *dest, const Options *src)
51 {
52 gsize l = 0;
53 GError *err = NULL;
54 char *kf_data = g_key_file_to_data(src->kf, &l, &err);
55 GKeyFile *old_kf = NULL;
56 gboolean result = TRUE;
57
58 if (dest->kf)
59 {
60 old_kf = dest->kf;
61 dest->kf = NULL;
62 }
63 if (err)
64 goto copy_err;
65 dest->kf = g_key_file_new();
66 if (!l || g_key_file_load_from_data(dest->kf, kf_data, l,
67 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &err))
68 {
69 goto copy_done;
70 }
71
72 copy_err:
73 result = FALSE;
74 if (err && err->message)
75 g_critical(_("Unable to copy options keyfile data: %s"), err->message);
76 if (dest->kf)
77 g_key_file_free(dest->kf);
78 dest->kf = old_kf;
79 old_kf = NULL;
80
81 copy_done:
82 if (old_kf)
83 g_key_file_free(old_kf);
84 g_free(kf_data);
85 return result;
86 }
87
options_copy(const Options * old_opts)88 Options *options_copy(const Options *old_opts)
89 {
90 Options *new_opts = g_new(Options, 1);
91
92 *new_opts = *old_opts;
93 new_opts->kf = NULL;
94 new_opts->user_data = NULL;
95 if (options_copy_keyfile(new_opts, old_opts))
96 {
97 new_opts->name = g_strdup(old_opts->name);
98 }
99 else
100 {
101 g_free(new_opts);
102 new_opts = NULL;
103 }
104 return new_opts;
105 }
106
options_delete_keyfile(Options * options)107 void options_delete_keyfile(Options * options)
108 {
109 options_file_delete(options->kf);
110 options->kf = NULL;
111 }
112
options_delete(Options * options)113 void options_delete(Options *options)
114 {
115 if (options->kf)
116 options_delete_keyfile(options);
117 g_free(options->name);
118 g_free(options);
119 }
120
121 /* Deletes options and returns true if ref reaches zero */
options_unref(Options * options)122 gboolean options_unref(Options * options)
123 {
124 if (!--options->ref)
125 {
126 options_delete(options);
127 return TRUE;
128 }
129 return FALSE;
130 }
131
options_lookup_string_with_default(Options * options,const char * key,const char * default_value)132 char *options_lookup_string_with_default(Options * options,
133 const char *key, const char *default_value)
134 {
135 return options_file_lookup_string_with_default(
136 options->kf, options->group_name,
137 key, default_value);
138 }
139
options_lookup_int_with_default(Options * options,const char * key,int default_value)140 int options_lookup_int_with_default(Options * options,
141 const char *key, int default_value)
142 {
143 return options_file_lookup_int_with_default(
144 options->kf, options->group_name,
145 key, default_value);
146 }
147
options_lookup_double_with_default(Options * options,const char * key,double d)148 double options_lookup_double_with_default(Options *options, const char *key,
149 double d)
150 {
151 char *str_val = options_lookup_string(options, key);
152 double result = d;
153
154 if (str_val)
155 {
156 char *endptr;
157
158 errno = 0;
159 result = strtod(str_val, &endptr);
160 if (endptr == str_val)
161 {
162 dlg_warning(NULL,
163 _("Unable to convert value '%s' for key '%s' in '%s' to number"),
164 str_val, key, options->name);
165 result = d;
166 }
167 else if (errno)
168 {
169 dlg_warning(NULL,
170 _("Unable to convert value '%s' for key '%s' in '%s' "
171 "to number: %s"),
172 str_val, key, options->name, strerror(errno));
173 result = d;
174 }
175 }
176 return result;
177 }
178
179
options_set_string(Options * options,const char * key,const char * value)180 void options_set_string(Options * options, const char *key, const char *value)
181 {
182 if (!options->kf)
183 options->kf = g_key_file_new();
184 g_key_file_set_string(options->kf, options->group_name, key,
185 value ? value : "");
186 }
187
options_set_int(Options * options,const char * key,int value)188 void options_set_int(Options * options, const char *key, int value)
189 {
190 if (!options->kf)
191 options->kf = g_key_file_new();
192 g_key_file_set_integer(options->kf, options->group_name, key, value);
193 }
194
options_set_double(Options * options,const char * key,double value)195 void options_set_double(Options * options, const char *key, double value)
196 {
197 char *str_val = g_strdup_printf("%f", value);
198
199 options_set_string(options, key, str_val);
200 g_free(str_val);
201 }
202
options_get_leafname(Options * options)203 const char *options_get_leafname(Options *options)
204 {
205 const char *leafname = strrchr(options->name, G_DIR_SEPARATOR);
206
207 return leafname ? leafname + 1 : options->name;
208 }
209
options_change_leafname(Options * options,const char * new_leaf)210 void options_change_leafname(Options *options, const char *new_leaf)
211 {
212 char *old_name = options->name;
213 char *old_leaf = strrchr(options->name, G_DIR_SEPARATOR);
214
215 if (old_leaf)
216 {
217 *old_leaf = 0;
218 options->name = g_build_filename(old_name, new_leaf, NULL);
219 }
220 else
221 {
222 options->name = g_strdup(new_leaf);
223 }
224 g_free(old_name);
225 }
226
227 /* vi:set sw=4 ts=4 noet cindent cino= */
228