Bug Summary

File:core/misc.c
Location:line 799, column 3
Description:Value stored to 'dest' is never read

Annotated Source Code

1/*
2 misc.c : irssi
3
4 Copyright (C) 1999 Timo Sirainen
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "module.h"
22#include "misc.h"
23
24#ifdef HAVE_REGEX_H1
25# include <regex.h>
26#endif
27
28typedef struct {
29 int condition;
30 GInputFunction function;
31 void *data;
32} IRSSI_INPUT_REC;
33
34static int irssi_io_invoke(GIOChannel *source, GIOCondition condition,
35 void *data)
36{
37 IRSSI_INPUT_REC *rec = data;
38 int icond = 0;
39
40 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
41 /* error, we have to call the function.. */
42 if (rec->condition & G_IO_IN)
43 icond |= G_INPUT_READ(1 << 0);
44 else
45 icond |= G_INPUT_WRITE(1 << 1);
46 }
47
48 if (condition & (G_IO_IN | G_IO_PRI))
49 icond |= G_INPUT_READ(1 << 0);
50 if (condition & G_IO_OUT)
51 icond |= G_INPUT_WRITE(1 << 1);
52
53 if (rec->condition & icond)
54 rec->function(rec->data, source, icond);
55
56 return TRUE(!(0));
57}
58
59int g_input_add_full(GIOChannel *source, int priority, int condition,
60 GInputFunction function, void *data)
61{
62 IRSSI_INPUT_REC *rec;
63 unsigned int result;
64 GIOCondition cond;
65
66 rec = g_new(IRSSI_INPUT_REC, 1)((IRSSI_INPUT_REC *) g_malloc (((gsize) sizeof (IRSSI_INPUT_REC
)) * ((gsize) (1))))
;
67 rec->condition = condition;
68 rec->function = function;
69 rec->data = data;
70
71 cond = (GIOCondition) (G_IO_ERR|G_IO_HUP|G_IO_NVAL);
72 if (condition & G_INPUT_READ(1 << 0))
73 cond |= G_IO_IN|G_IO_PRI;
74 if (condition & G_INPUT_WRITE(1 << 1))
75 cond |= G_IO_OUT;
76
77 result = g_io_add_watch_full(source, priority, cond,
78 irssi_io_invoke, rec, g_free);
79
80 return result;
81}
82
83int g_input_add(GIOChannel *source, int condition,
84 GInputFunction function, void *data)
85{
86 return g_input_add_full(source, G_PRIORITY_DEFAULT0, condition,
87 function, data);
88}
89
90/* easy way to bypass glib polling of io channel internal buffer */
91int g_input_add_poll(int fd, int priority, int condition,
92 GInputFunction function, void *data)
93{
94 GIOChannel *source = g_io_channel_unix_new(fd);
95 int ret = g_input_add_full(source, priority, condition, function, data);
96 g_io_channel_unref(source);
97 return ret;
98}
99
100int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2)
101{
102 if (tv1->tv_sec < tv2->tv_sec)
103 return -1;
104 if (tv1->tv_sec > tv2->tv_sec)
105 return 1;
106
107 return tv1->tv_usec < tv2->tv_usec ? -1 :
108 tv1->tv_usec > tv2->tv_usec ? 1 : 0;
109}
110
111long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2)
112{
113 long secs, usecs;
114
115 secs = tv1->tv_sec - tv2->tv_sec;
116 usecs = tv1->tv_usec - tv2->tv_usec;
117 if (usecs < 0) {
118 usecs += 1000000;
119 secs--;
120 }
121 usecs = usecs/1000 + secs * 1000;
122
123 return usecs;
124}
125
126int find_substr(const char *list, const char *item)
127{
128 const char *ptr;
129
130 g_return_val_if_fail(list != NULL, FALSE)do{ if (list != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "list != NULL"); return (
(0)); }; }while (0)
;
131 g_return_val_if_fail(item != NULL, FALSE)do{ if (item != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "item != NULL"); return (
(0)); }; }while (0)
;
132
133 if (*item == '\0')
134 return FALSE(0);
135
136 for (;;) {
137 while (i_isspace(*list)__sbistype(((int) (unsigned char) (*list)), 0x00004000L)) list++;
138 if (*list == '\0') break;
139
140 ptr = strchr(list, ' ');
141 if (ptr == NULL((void *)0)) ptr = list+strlen(list);
142
143 if (g_strncasecmp(list, item, ptr-list) == 0 &&
144 item[ptr-list] == '\0')
145 return TRUE(!(0));
146
147 list = ptr;
148 }
149
150 return FALSE(0);
151}
152
153int strarray_length(char **array)
154{
155 int len;
156
157 g_return_val_if_fail(array != NULL, 0)do{ if (array != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "array != NULL"); return
(0); }; }while (0)
;
158
159 len = 0;
160 while (*array) {
161 len++;
162 array++;
163 }
164 return len;
165}
166
167int strarray_find(char **array, const char *item)
168{
169 char **tmp;
170 int index;
171
172 g_return_val_if_fail(array != NULL, 0)do{ if (array != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "array != NULL"); return
(0); }; }while (0)
;
173 g_return_val_if_fail(item != NULL, 0)do{ if (item != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "item != NULL"); return (
0); }; }while (0)
;
174
175 index = 0;
176 for (tmp = array; *tmp != NULL((void *)0); tmp++, index++) {
177 if (g_strcasecmp(*tmp, item) == 0)
178 return index;
179 }
180
181 return -1;
182}
183
184GSList *gslist_find_string(GSList *list, const char *key)
185{
186 for (list = list; list != NULL((void *)0); list = list->next)
187 if (strcmp(list->data, key) == 0) return list;
188
189 return NULL((void *)0);
190}
191
192GSList *gslist_find_icase_string(GSList *list, const char *key)
193{
194 for (list = list; list != NULL((void *)0); list = list->next)
195 if (g_strcasecmp(list->data, key) == 0) return list;
196
197 return NULL((void *)0);
198}
199
200void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data)
201{
202 void *ret;
203
204 while (list != NULL((void *)0)) {
205 ret = func(list->data, (void *) data);
206 if (ret != NULL((void *)0)) return ret;
207
208 list = list->next;
209 }
210
211 return NULL((void *)0);
212}
213
214/* `list' contains pointer to structure with a char* to string. */
215char *gslistptr_to_string(GSList *list, int offset, const char *delimiter)
216{
217 GString *str;
218 char **data, *ret;
219
220 str = g_string_new(NULL((void *)0));
221 while (list != NULL((void *)0)) {
222 data = G_STRUCT_MEMBER_P(list->data, offset)((gpointer) ((guint8*) (list->data) + (glong) (offset)));
223
224 if (str->len != 0) g_string_append(str, delimiter);
225 g_string_append(str, *data);
226 list = list->next;
227 }
228
229 ret = str->str;
230 g_string_free(str, FALSE(0));
231 return ret;
232}
233
234/* `list' contains char* */
235char *gslist_to_string(GSList *list, const char *delimiter)
236{
237 GString *str;
238 char *ret;
239
240 str = g_string_new(NULL((void *)0));
241 while (list != NULL((void *)0)) {
242 if (str->len != 0) g_string_append(str, delimiter);
243 g_string_append(str, list->data);
244
245 list = list->next;
246 }
247
248 ret = str->str;
249 g_string_free(str, FALSE(0));
250 return ret;
251}
252
253void hash_save_key(char *key, void *value, GSList **list)
254{
255 *list = g_slist_append(*list, key);
256}
257
258/* save all keys in hash table to linked list - you shouldn't remove any
259 items while using this list, use g_slist_free() after you're done with it */
260GSList *hashtable_get_keys(GHashTable *hash)
261{
262 GSList *list;
263
264 list = NULL((void *)0);
265 g_hash_table_foreach(hash, (GHFunc) hash_save_key, &list);
266 return list;
267}
268
269GList *glist_find_string(GList *list, const char *key)
270{
271 for (list = list; list != NULL((void *)0); list = list->next)
272 if (strcmp(list->data, key) == 0) return list;
273
274 return NULL((void *)0);
275}
276
277GList *glist_find_icase_string(GList *list, const char *key)
278{
279 for (list = list; list != NULL((void *)0); list = list->next)
280 if (g_strcasecmp(list->data, key) == 0) return list;
281
282 return NULL((void *)0);
283}
284
285char *stristr(const char *data, const char *key)
286{
287 const char *max;
288 int keylen, datalen, pos;
289
290 keylen = strlen(key);
291 datalen = strlen(data);
292
293 if (keylen > datalen)
294 return NULL((void *)0);
295 if (keylen == 0)
296 return (char *) data;
297
298 max = data+datalen-keylen;
299 pos = 0;
300 while (data <= max) {
301 if (key[pos] == '\0')
302 return (char *) data;
303
304 if (i_toupper(data[pos])__sbtoupper((int) (unsigned char) (data[pos])) == i_toupper(key[pos])__sbtoupper((int) (unsigned char) (key[pos])))
305 pos++;
306 else {
307 data++;
308 pos = 0;
309 }
310 }
311
312 return NULL((void *)0);
313}
314
315#define isbound(c)((unsigned char) (c) < 128 && (__sbistype(((int) (
unsigned char) (c)), 0x00004000L) || __sbistype(((int) (unsigned
char) (c)), 0x00002000L)))
\
316 ((unsigned char) (c) < 128 && \
317 (i_isspace(c)__sbistype(((int) (unsigned char) (c)), 0x00004000L) || i_ispunct(c)__sbistype(((int) (unsigned char) (c)), 0x00002000L)))
318
319static char *strstr_full_case(const char *data, const char *key, int icase)
320{
321 const char *start, *max;
322 int keylen, datalen, pos, match;
323
324 keylen = strlen(key);
325 datalen = strlen(data);
326
327 if (keylen > datalen)
328 return NULL((void *)0);
329 if (keylen == 0)
330 return (char *) data;
331
332 max = data+datalen-keylen;
333 start = data; pos = 0;
334 while (data <= max) {
335 if (key[pos] == '\0') {
336 if (data[pos] != '\0' && !isbound(data[pos])((unsigned char) (data[pos]) < 128 && (__sbistype(
((int) (unsigned char) (data[pos])), 0x00004000L) || __sbistype
(((int) (unsigned char) (data[pos])), 0x00002000L)))
) {
337 data++;
338 pos = 0;
339 continue;
340 }
341 return (char *) data;
342 }
343
344 match = icase ? (i_toupper(data[pos])__sbtoupper((int) (unsigned char) (data[pos])) == i_toupper(key[pos])__sbtoupper((int) (unsigned char) (key[pos]))) :
345 data[pos] == key[pos];
346
347 if (match && (pos != 0 || data == start || isbound(data[-1])((unsigned char) (data[-1]) < 128 && (__sbistype((
(int) (unsigned char) (data[-1])), 0x00004000L) || __sbistype
(((int) (unsigned char) (data[-1])), 0x00002000L)))
))
348 pos++;
349 else {
350 data++;
351 pos = 0;
352 }
353 }
354
355 return NULL((void *)0);
356}
357
358char *strstr_full(const char *data, const char *key)
359{
360 return strstr_full_case(data, key, FALSE(0));
361}
362
363char *stristr_full(const char *data, const char *key)
364{
365 return strstr_full_case(data, key, TRUE(!(0)));
366}
367
368int regexp_match(const char *str, const char *regexp)
369{
370#ifdef HAVE_REGEX_H1
371 regex_t preg;
372 int ret;
373
374 if (regcomp(&preg, regexp, REG_EXTENDED0001|REG_ICASE0002|REG_NOSUB0004) != 0)
375 return 0;
376
377 ret = regexec(&preg, str, 0, NULL((void *)0), 0);
378 regfree(&preg);
379
380 return ret == 0;
381#else
382 return FALSE(0);
383#endif
384}
385
386/* Create the directory and all it's parent directories */
387int mkpath(const char *path, int mode)
388{
389 struct stat statbuf;
390 const char *p;
391 char *dir;
392
393 g_return_val_if_fail(path != NULL, -1)do{ if (path != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "path != NULL"); return (
-1); }; }while (0)
;
394
395 p = g_path_skip_root((char *) path);
396 if (p == NULL((void *)0)) {
397 /* not a full path, maybe not what we wanted
398 but continue anyway.. */
399 p = path;
400 }
401 for (;;) {
402 if (*p != G_DIR_SEPARATOR'/' && *p != '\0') {
403 p++;
404 continue;
405 }
406
407 dir = g_strndup(path, (int) (p-path));
408 if (stat(dir, &statbuf) != 0) {
409#ifndef WIN32
410 if (mkdir(dir, mode) == -1)
411#else
412 if (_mkdir(dir) == -1)
413#endif
414 {
415 g_free(dir);
416 return -1;
417 }
418 }
419 g_free(dir);
420
421 if (*p++ == '\0')
422 break;
423 }
424
425 return 0;
426}
427
428/* convert ~/ to $HOME */
429char *convert_home(const char *path)
430{
431 const char *home;
432
433 if (*path == '~' && (*(path+1) == '/' || *(path+1) == '\0')) {
434 home = g_get_home_dir();
435 if (home == NULL((void *)0))
436 home = ".";
437
438 return g_strconcat(home, path+1, NULL((void *)0));
439 } else {
440 return g_strdup(path);
441 }
442}
443
444int g_istr_equal(gconstpointer v, gconstpointer v2)
445{
446 return g_strcasecmp((const char *) v, (const char *) v2) == 0;
447}
448
449int g_istr_cmp(gconstpointer v, gconstpointer v2)
450{
451 return g_strcasecmp((const char *) v, (const char *) v2);
452}
453
454/* a char* hash function from ASU */
455unsigned int g_istr_hash(gconstpointer v)
456{
457 const char *s = (const char *) v;
458 unsigned int h = 0, g;
459
460 while (*s != '\0') {
461 h = (h << 4) + i_toupper(*s)__sbtoupper((int) (unsigned char) (*s));
462 if ((g = h & 0xf0000000UL)) {
463 h = h ^ (g >> 24);
464 h = h ^ g;
465 }
466 s++;
467 }
468
469 return h /* % M */;
470}
471
472/* Find `mask' from `data', you can use * and ? wildcards. */
473int match_wildcards(const char *cmask, const char *data)
474{
475 char *mask, *newmask, *p1, *p2;
476 int ret;
477
478 newmask = mask = g_strdup(cmask);
479 for (; *mask != '\0' && *data != '\0'; mask++) {
480 if (*mask != '*') {
481 if (*mask != '?' && i_toupper(*mask)__sbtoupper((int) (unsigned char) (*mask)) != i_toupper(*data)__sbtoupper((int) (unsigned char) (*data)))
482 break;
483
484 data++;
485 continue;
486 }
487
488 while (*mask == '?' || *mask == '*') mask++;
489 if (*mask == '\0') {
490 data += strlen(data);
491 break;
492 }
493
494 p1 = strchr(mask, '*');
495 p2 = strchr(mask, '?');
496 if (p1 == NULL((void *)0) || (p2 < p1 && p2 != NULL((void *)0))) p1 = p2;
497
498 if (p1 != NULL((void *)0)) *p1 = '\0';
499
500 data = stristr(data, mask);
501 if (data == NULL((void *)0)) break;
502
503 data += strlen(mask);
504 mask += strlen(mask)-1;
505
506 if (p1 != NULL((void *)0)) *p1 = p1 == p2 ? '?' : '*';
507 }
508
509 while (*mask == '*') mask++;
510
511 ret = data != NULL((void *)0) && *data == '\0' && *mask == '\0';
512 g_free(newmask);
513
514 return ret;
515}
516
517/* Return TRUE if all characters in `str' are numbers.
518 Stop when `end_char' is found from string. */
519int is_numeric(const char *str, char end_char)
520{
521 g_return_val_if_fail(str != NULL, FALSE)do{ if (str != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "str != NULL"); return (
(0)); }; }while (0)
;
522
523 if (*str == '\0' || *str == end_char)
524 return FALSE(0);
525
526 while (*str != '\0' && *str != end_char) {
527 if (!i_isdigit(*str)__isctype(((int) (unsigned char) (*str)), 0x00000400L)) return FALSE(0);
528 str++;
529 }
530
531 return TRUE(!(0));
532}
533
534/* replace all `from' chars in string to `to' chars. returns `str' */
535char *replace_chars(char *str, char from, char to)
536{
537 char *p;
538
539 for (p = str; *p != '\0'; p++) {
540 if (*p == from) *p = to;
541 }
542 return str;
543}
544
545int octal2dec(int octal)
546{
547 int dec, n;
548
549 dec = 0; n = 1;
550 while (octal != 0) {
551 dec += n*(octal%10);
552 octal /= 10; n *= 8;
553 }
554
555 return dec;
556}
557
558int dec2octal(int decimal)
559{
560 int octal, pos;
561
562 octal = 0; pos = 0;
563 while (decimal > 0) {
564 octal += (decimal & 7)*(pos == 0 ? 1 : pos);
565 decimal /= 8;
566 pos += 10;
567 }
568
569 return octal;
570}
571
572/* string -> uoff_t */
573uoff_t str_to_uofft(const char *str)
574{
575 uoff_t ret;
576
577 ret = 0;
578 while (*str != '\0') {
579 ret = ret*10 + (*str - '0');
580 str++;
581 }
582
583 return ret;
584}
585
586/* convert all low-ascii (<32) to ^<A..> combinations */
587char *show_lowascii(const char *str)
588{
589 char *ret, *p;
590
591 ret = p = g_malloc(strlen(str)*2+1);
592 while (*str != '\0') {
593 if ((unsigned char) *str >= 32)
594 *p++ = *str;
595 else {
596 *p++ = '^';
597 *p++ = *str + 'A'-1;
598 }
599 str++;
600 }
601 *p = '\0';
602
603 return ret;
604}
605
606/* Get time in human readable form with localtime() + asctime() */
607char *my_asctime(time_t t)
608{
609 struct tm *tm;
610 char *str;
611 int len;
612
613 tm = localtime(&t);
614 str = g_strdup(asctime(tm));
615
616 len = strlen(str);
617 if (len > 0) str[len-1] = '\0';
618 return str;
619}
620
621/* Returns number of columns needed to print items.
622 save_column_widths is filled with length of each column. */
623int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func,
624 int max_width, int max_columns,
625 int item_extra, int item_min_size,
626 int **save_column_widths, int *rows)
627{
628 GSList *tmp;
629 int **columns, *columns_width, *columns_rows;
630 int item_pos, items_count;
631 int ret, len, max_len, n, col;
632
633 items_count = g_slist_length(items);
634 if (items_count == 0) {
635 *save_column_widths = NULL((void *)0);
636 *rows = 0;
637 return 0;
638 }
639
640 len = max_width/(item_extra+item_min_size);
641 if (len <= 0) len = 1;
642 if (max_columns <= 0 || len < max_columns)
643 max_columns = len;
644
645 columns = g_new0(int *, max_columns)((int * *) g_malloc0 (((gsize) sizeof (int *)) * ((gsize) (max_columns
))))
;
646 columns_width = g_new0(int, max_columns)((int *) g_malloc0 (((gsize) sizeof (int)) * ((gsize) (max_columns
))))
;
647 columns_rows = g_new0(int, max_columns)((int *) g_malloc0 (((gsize) sizeof (int)) * ((gsize) (max_columns
))))
;
648
649 for (n = 1; n < max_columns; n++) {
650 columns[n] = g_new0(int, n+1)((int *) g_malloc0 (((gsize) sizeof (int)) * ((gsize) (n+1)))
)
;
651 columns_rows[n] = items_count <= n+1 ? 1 :
652 (items_count+n)/(n+1);
653 }
654
655 /* for each possible column count, save the column widths and
656 find the biggest column count that fits to screen. */
657 item_pos = 0; max_len = 0;
658 for (tmp = items; tmp != NULL((void *)0); tmp = tmp->next) {
659 len = item_extra+len_func(tmp->data);
660 if (max_len < len)
661 max_len = len;
662
663 for (n = 1; n < max_columns; n++) {
664 if (columns_width[n] > max_width)
665 continue; /* too wide */
666
667 col = item_pos/columns_rows[n];
668 if (columns[n][col] < len) {
669 columns_width[n] += len-columns[n][col];
670 columns[n][col] = len;
671 }
672 }
673
674 item_pos++;
675 }
676
677 for (n = max_columns-1; n >= 1; n--) {
678 if (columns_width[n] <= max_width &&
679 columns[n][n] > 0)
680 break;
681 }
682 ret = n+1;
683
684 *save_column_widths = g_new(int, ret)((int *) g_malloc (((gsize) sizeof (int)) * ((gsize) (ret))));
685 if (ret == 1) {
686 **save_column_widths = max_len;
687 *rows = 1;
688 } else {
689 memcpy(*save_column_widths, columns[ret-1], sizeof(int)*ret);
690 *rows = columns_rows[ret-1];
691 }
692
693 for (n = 1; n < max_columns; n++)
694 g_free(columns[n]);
695 g_free(columns_width);
696 g_free(columns_rows);
697 g_free(columns);
698
699 return ret;
700}
701
702/* Return a column sorted copy of a list. */
703GSList *columns_sort_list(GSList *list, int rows)
704{
705 GSList *tmp, *sorted;
706 int row, skip;
707
708 if (list == NULL((void *)0) || rows == 0)
709 return list;
710
711 sorted = NULL((void *)0);
712
713 for (row = 0; row < rows; row++) {
714 tmp = g_slist_nth(list, row);
715 skip = 1;
716 for (; tmp != NULL((void *)0); tmp = tmp->next) {
717 if (--skip == 0) {
718 skip = rows;
719 sorted = g_slist_append(sorted, tmp->data);
720 }
721 }
722 }
723
724 g_return_val_if_fail(g_slist_length(sorted) ==do{ if (g_slist_length(sorted) == g_slist_length(list)) { } else
{ g_return_if_fail_warning (((gchar*) 0), __PRETTY_FUNCTION__
, "g_slist_length(sorted) == g_slist_length(list)"); return (
sorted); }; }while (0)
725 g_slist_length(list), sorted)do{ if (g_slist_length(sorted) == g_slist_length(list)) { } else
{ g_return_if_fail_warning (((gchar*) 0), __PRETTY_FUNCTION__
, "g_slist_length(sorted) == g_slist_length(list)"); return (
sorted); }; }while (0)
;
726 return sorted;
727}
728
729/* Expand escape string, the first character in data should be the
730 one after '\'. Returns the expanded character or -1 if error. */
731int expand_escape(const char **data)
732{
733 char digit[4];
734
735 switch (**data) {
736 case 't':
737 return '\t';
738 case 'r':
739 return '\r';
740 case 'n':
741 return '\n';
742 case 'e':
743 return 27; /* ESC */
744
745 case 'x':
746 /* hex digit */
747 if (!i_isxdigit((*data)[1])__isctype(((int) (unsigned char) ((*data)[1])), 0x00010000L) || !i_isxdigit((*data)[2])__isctype(((int) (unsigned char) ((*data)[2])), 0x00010000L))
748 return -1;
749
750 digit[0] = (*data)[1];
751 digit[1] = (*data)[2];
752 digit[2] = '\0';
753 *data += 2;
754 return strtol(digit, NULL((void *)0), 16);
755 case 'c':
756 /* control character (\cA = ^A) */
757 (*data)++;
758 return i_toupper(**data)__sbtoupper((int) (unsigned char) (**data)) - 64;
759 default:
760 if (!i_isdigit(**data)__isctype(((int) (unsigned char) (**data)), 0x00000400L))
761 return -1;
762
763 /* octal */
764 digit[0] = (*data)[0];
765 digit[1] = (*data)[1];
766 digit[2] = (*data)[2];
767 digit[3] = '\0';
768 *data += 2;
769 return strtol(digit, NULL((void *)0), 8);
770 }
771}
772
773/* Escape all '"', "'" and '\' chars with '\' */
774char *escape_string(const char *str)
775{
776 char *ret, *p;
777
778 p = ret = g_malloc(strlen(str)*2+1);
779 while (*str != '\0') {
780 if (*str == '"' || *str == '\'' || *str == '\\')
781 *p++ = '\\';
782 *p++ = *str++;
783 }
784 *p = '\0';
785
786 return ret;
787}
788
789int strocpy(char *dest, const char *src, size_t dstsize)
790{
791 if (dstsize == 0)
792 return -1;
793
794 while (*src != '\0' && dstsize > 1) {
795 *dest++ = *src++;
796 dstsize--;
797 }
798
799 *dest++ = '\0';
Value stored to 'dest' is never read
800 return *src == '\0' ? 0 : -1;
801}
802
803int nearest_power(int num)
804{
805 int n = 1;
806
807 while (n < num) n <<= 1;
808 return n;
809}
810
811int parse_time_interval(const char *time, int *msecs)
812{
813 const char *desc;
814 int number, sign, len, ret;
815
816 *msecs = 0;
817
818 /* max. return value is around 24 days */
819 number = 0; sign = 1; ret = TRUE(!(0));
820 for (;;) {
821 if (*time == '-') {
822 sign = -sign;
823 time++;
824 continue;
825 }
826
827 if (i_isdigit(*time)__isctype(((int) (unsigned char) (*time)), 0x00000400L)) {
828 number = number*10 + (*time - '0');
829 time++;
830 continue;
831 }
832
833 /* skip punctuation */
834 while (*time != '\0' && i_ispunct(*time)__sbistype(((int) (unsigned char) (*time)), 0x00002000L))
835 time++;
836
837 /* get description */
838 for (len = 0, desc = time; i_isalpha(*time)__sbistype(((int) (unsigned char) (*time)), 0x00000100L); time++)
839 len++;
840
841 if (len == 0) {
842 *msecs += number * 1000; /* assume seconds */
843 *msecs *= sign;
844 return TRUE(!(0));
845 }
846
847 if (g_ascii_strncasecmp(desc, "days", len) == 0) {
848 if (number > 24) {
849 /* would overflow */
850 return FALSE(0);
851 }
852 *msecs += number * 1000*3600*24;
853 } else if (g_ascii_strncasecmp(desc, "hours", len) == 0)
854 *msecs += number * 1000*3600;
855 else if (g_ascii_strncasecmp(desc, "minutes", len) == 0 ||
856 g_ascii_strncasecmp(desc, "mins", len) == 0)
857 *msecs += number * 1000*60;
858 else if (g_ascii_strncasecmp(desc, "seconds", len) == 0 ||
859 g_ascii_strncasecmp(desc, "secs", len) == 0)
860 *msecs += number * 1000;
861 else if (g_ascii_strncasecmp(desc, "milliseconds", len) == 0 ||
862 g_ascii_strncasecmp(desc, "millisecs", len) == 0 ||
863 g_ascii_strncasecmp(desc, "mseconds", len) == 0 ||
864 g_ascii_strncasecmp(desc, "msecs", len) == 0)
865 *msecs += number;
866 else {
867 ret = FALSE(0);
868 }
869
870 /* skip punctuation */
871 while (*time != '\0' && i_ispunct(*time)__sbistype(((int) (unsigned char) (*time)), 0x00002000L))
872 time++;
873
874 if (*time == '\0')
875 break;
876
877 number = 0;
878 }
879
880 *msecs *= sign;
881 return ret;
882}
883
884int parse_size(const char *size, int *bytes)
885{
886 const char *desc;
887 int number, len;
888
889 *bytes = 0;
890
891 /* max. return value is about 1.6 years */
892 number = 0;
893 while (*size != '\0') {
894 if (i_isdigit(*size)__isctype(((int) (unsigned char) (*size)), 0x00000400L)) {
895 number = number*10 + (*size - '0');
896 size++;
897 continue;
898 }
899
900 /* skip punctuation */
901 while (*size != '\0' && i_ispunct(*size)__sbistype(((int) (unsigned char) (*size)), 0x00002000L))
902 size++;
903
904 /* get description */
905 for (len = 0, desc = size; i_isalpha(*size)__sbistype(((int) (unsigned char) (*size)), 0x00000100L); size++)
906 len++;
907
908 if (len == 0) {
909 if (number == 0) {
910 /* "0" - allow it */
911 return TRUE(!(0));
912 }
913
914 *bytes += number*1024; /* assume kilobytes */
915 return FALSE(0);
916 }
917
918 if (g_ascii_strncasecmp(desc, "gbytes", len) == 0)
919 *bytes += number * 1024*1024*1024;
920 if (g_ascii_strncasecmp(desc, "mbytes", len) == 0)
921 *bytes += number * 1024*1024;
922 if (g_ascii_strncasecmp(desc, "kbytes", len) == 0)
923 *bytes += number * 1024;
924 if (g_ascii_strncasecmp(desc, "bytes", len) == 0)
925 *bytes += number;
926
927 /* skip punctuation */
928 while (*size != '\0' && i_ispunct(*size)__sbistype(((int) (unsigned char) (*size)), 0x00002000L))
929 size++;
930 }
931
932 return TRUE(!(0));
933}