Add a wrapper around system() call named runcmd() which allows easier debugging....
[geeqie.git] / src / misc.c
1 /*
2  * Geeqie
3  * Copyright (C) 2008 The Geeqie Team
4  *
5  * Authors: Vladimir Nadvornik / Laurent Monin
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11
12 #include "main.h"
13 #include "misc.h"
14
15 gdouble get_zoom_increment(void)
16 {
17         return ((options->image.zoom_increment != 0) ? (gdouble)options->image.zoom_increment / 10.0 : 1.0);
18 }
19
20 gchar *utf8_validate_or_convert(const gchar *text)
21 {
22         gint len;
23
24         if (!text) return NULL;
25         
26         len = strlen(text);
27         if (!g_utf8_validate(text, len, NULL))
28                 return g_convert(text, len, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
29
30         return g_strdup(text);
31 }
32
33 gint utf8_compare(const gchar *s1, const gchar *s2, gboolean case_sensitive)
34 {
35         gchar *s1_key, *s2_key;
36         gchar *s1_t, *s2_t;
37         gint ret;
38
39         g_assert(g_utf8_validate(s1, -1, NULL));
40         g_assert(g_utf8_validate(s2, -1, NULL));
41
42         if (!case_sensitive)
43                 {
44                 s1_t = g_utf8_casefold(s1, -1);
45                 s2_t = g_utf8_casefold(s2, -1);
46                 }
47
48         s1_key = g_utf8_collate_key(s1_t, -1);
49         s2_key = g_utf8_collate_key(s2_t, -1);
50
51         ret = strcmp(s1_key, s2_key);
52
53         g_free(s1_key);
54         g_free(s2_key);
55
56         if (!case_sensitive)
57                 {
58                 g_free(s1_t);
59                 g_free(s2_t);
60                 }
61
62         return ret;
63 }
64
65 /* Borrowed from gtkfilesystemunix.c */
66 gchar *expand_tilde(const gchar *filename)
67 {
68 #ifndef G_OS_UNIX
69         return g_strdup(filename);
70 #else
71         const gchar *notilde;
72         const gchar *slash;
73         const gchar *home;
74
75         if (filename[0] != '~')
76                 return g_strdup(filename);
77
78         notilde = filename + 1;
79         slash = strchr(notilde, G_DIR_SEPARATOR);
80         if (slash == notilde || !*notilde)
81                 {
82                 home = g_get_home_dir();
83                 if (!home)
84                         return g_strdup(filename);
85                 }
86         else
87                 {
88                 gchar *username;
89                 struct passwd *passwd;
90
91                 if (slash)
92                         username = g_strndup(notilde, slash - notilde);
93                 else
94                         username = g_strdup(notilde);
95
96                 passwd = getpwnam(username);
97                 g_free(username);
98
99                 if (!passwd)
100                         return g_strdup(filename);
101
102                 home = passwd->pw_dir;
103                 }
104
105         if (slash)
106                 return g_build_filename(home, G_DIR_SEPARATOR_S, slash + 1, NULL);
107         else
108                 return g_build_filename(home, G_DIR_SEPARATOR_S, NULL);
109 #endif
110 }
111
112 /*
113    returns text without quotes or NULL for empty or broken string
114    any text up to first '"' is skipped
115    tail is set to point at the char after the second '"'
116    or at the ending \0
117
118 */
119
120 gchar *quoted_value(const gchar *text, const gchar **tail)
121 {
122         const gchar *ptr;
123         gint c = 0;
124         gint l = strlen(text);
125         gchar *retval = NULL;
126
127         if (tail) *tail = text;
128
129         if (l == 0) return retval;
130
131         while (c < l && text[c] != '"') c++;
132         if (text[c] == '"')
133                 {
134                 gint e;
135                 c++;
136                 ptr = text + c;
137                 e = c;
138                 while (e < l)
139                         {
140                         if (text[e-1] != '\\' && text[e] == '"') break;
141                         e++;
142                         }
143                 if (text[e] == '"')
144                         {
145                         if (e - c > 0)
146                                 {
147                                 gchar *substring = g_strndup(ptr, e - c);
148
149                                 if (substring)
150                                         {
151                                         retval = g_strcompress(substring);
152                                         g_free(substring);
153                                         }
154                                 }
155                         }
156                 if (tail) *tail = text + e + 1;
157                 }
158         else
159                 /* for compatibility with older formats (<0.3.7)
160                  * read a line without quotes too */
161                 {
162                 c = 0;
163                 while (c < l && text[c] != '\n' && !g_ascii_isspace(text[c])) c++;
164                 if (c != 0)
165                         {
166                         retval = g_strndup(text, c);
167                         }
168                 if (tail) *tail = text + c;
169                 }
170
171         return retval;
172 }
173
174 gchar *escquote_value(const gchar *text)
175 {
176         gchar *e;
177
178         if (!text) return g_strdup("\"\"");
179
180         e = g_strescape(text, "");
181         if (e)
182                 {
183                 gchar *retval = g_strdup_printf("\"%s\"", e);
184                 g_free(e);
185                 return retval;
186                 }
187         return g_strdup("\"\"");
188 }
189
190 /* Run a command like system() but may output debug messages. */
191 int runcmd(gchar *cmd)
192 {
193 #if 1
194         return system(cmd);
195         return 0;
196 #else
197         /* For debugging purposes */
198         int retval = -1;
199         FILE *in;
200
201         DEBUG_1("Running command: %s", cmd);
202
203         in = popen(cmd, "r");
204         if (in)
205                 {
206                 int status;
207                 const gchar *msg;
208                 gchar buf[2048];
209
210                 while (fgets(buf, sizeof(buf), in) != NULL )
211                         {
212                         DEBUG_1("Output: %s", buf);
213                         }
214
215                 status = pclose(in);
216
217                 if (WIFEXITED(status))
218                         {
219                         msg = "Command terminated with exit code";
220                         retval = WEXITSTATUS(status);
221                         }
222                 else if (WIFSIGNALED(status))
223                         {
224                         msg = "Command was killed by signal";
225                         retval = WTERMSIG(status);
226                         }
227                 else
228                         {
229                         msg = "pclose() returned";
230                         retval = status;
231                         }
232
233                 DEBUG_1("%s : %d\n", msg, retval);
234         }
235         
236         return retval;
237 #endif
238 }
239
240
241 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */