Dillo v3.2.0-88-g47ab7c70
Loading...
Searching...
No Matches
dlib.c
Go to the documentation of this file.
1/*
2 * File: dlib.c
3 *
4 * Copyright (C) 2006-2007 Jorge Arellano Cid <jcid@dillo.org>
5 * Copyright (C) 2024-2025 Rodrigo Arias Mallo <rodarima@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
13/* Memory allocation, Simple dynamic strings, Lists (simple and sorted),
14 * and a few utility functions
15 */
16
17/*
18 * TODO: vsnprintf() is in C99, maybe a simple replacement if necessary.
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <unistd.h>
26#include <errno.h>
27#include <ctype.h>
28#include <time.h>
29
30#include "dlib.h"
31
33
34/* dlib msgs go to stderr to avoid problems with filter dpis */
35#define DLIB_MSG(...) \
36 D_STMT_START { \
37 if (dLib_show_msg) \
38 fprintf(stderr, __VA_ARGS__); \
39 } D_STMT_END
40
41/*
42 *- Memory --------------------------------------------------------------------
43 */
44
45void *dMalloc (size_t size)
46{
47 void *value = malloc (size);
48 if (value == 0)
49 exit(1);
50 return value;
51}
52
53void *dRealloc (void *mem, size_t size)
54{
55 void *value = realloc (mem, size);
56 if (value == 0)
57 exit(1);
58 return value;
59}
60
61void *dMalloc0 (size_t size)
62{
63 void *value = dMalloc (size);
64 memset (value, 0, size);
65 return value;
66}
67
68void dFree (void *mem)
69{
70 free(mem);
71}
72
73/*
74 *- strings (char *) ----------------------------------------------------------
75 */
76
77char *dStrdup(const char *s)
78{
79 if (s) {
80 int len = strlen(s)+1;
81 char *ns = dNew(char, len);
82 memcpy(ns, s, len);
83 return ns;
84 }
85 return NULL;
86}
87
88char *dStrndup(const char *s, size_t sz)
89{
90 if (s) {
91 char *ns = dNew(char, sz+1);
92 memcpy(ns, s, sz);
93 ns[sz] = 0;
94 return ns;
95 }
96 return NULL;
97}
98
102char *dStrconcat(const char *s1, ...)
103{
104 va_list args;
105 char *s, *ns = NULL;
106
107 if (s1) {
108 Dstr *dstr = dStr_sized_new(64);
109 va_start(args, s1);
110 for (s = (char*)s1; s; s = va_arg(args, char*))
111 dStr_append(dstr, s);
112 va_end(args);
113 ns = dstr->str;
114 dStr_free(dstr, 0);
115 }
116 return ns;
117}
118
122char *dStrstrip(char *s)
123{
124 char *p;
125 int len;
126
127 if (s && *s) {
128 for (p = s; dIsspace(*p); ++p);
129 for (len = strlen(p); len && dIsspace(p[len-1]); --len);
130 if (p > s)
131 memmove(s, p, len);
132 s[len] = 0;
133 }
134 return s;
135}
136
140void dStrshred(char *s)
141{
142 if (s)
143 memset(s, 0, strlen(s));
144}
145
149char *dStrnfill(size_t len, char c)
150{
151 char *ret = dNew(char, len+1);
152 for (ret[len] = 0; len > 0; ret[--len] = c);
153 return ret;
154}
155
159char *dStrsep(char **orig, const char *delim)
160{
161 char *str, *p;
162
163 if (!(str = *orig))
164 return NULL;
165
166 p = strpbrk(str, delim);
167 if (p) {
168 *p++ = 0;
169 *orig = p;
170 } else {
171 *orig = NULL;
172 }
173 return str;
174}
175
176/*
177 * ASCII functions to avoid the case difficulties introduced by I/i in
178 * Turkic locales.
179 */
180
184char *dStriAsciiStr(const char *haystack, const char *needle)
185{
186 int i, j;
187 char *ret = NULL;
188
189 if (haystack && needle) {
190 for (i = 0, j = 0; haystack[i] && needle[j]; ++i)
191 if (D_ASCII_TOLOWER(haystack[i]) == D_ASCII_TOLOWER(needle[j])) {
192 ++j;
193 } else if (j) {
194 i -= j;
195 j = 0;
196 }
197 if (!needle[j]) /* Got all */
198 ret = (char *)(haystack + i - j);
199 }
200 return ret;
201}
202
203int dStrAsciiCasecmp(const char *s1, const char *s2)
204{
205 int ret = 0;
206
207 while ((*s1 || *s2) &&
208 !(ret = D_ASCII_TOLOWER(*s1) - D_ASCII_TOLOWER(*s2))) {
209 s1++;
210 s2++;
211 }
212 return ret;
213}
214
215int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
216{
217 int ret = 0;
218
219 while (n-- && (*s1 || *s2) &&
220 !(ret = D_ASCII_TOLOWER(*s1) - D_ASCII_TOLOWER(*s2))) {
221 s1++;
222 s2++;
223 }
224 return ret;
225}
226
227/*
228 *- dStr ----------------------------------------------------------------------
229 */
230
234static void dStr_resize(Dstr *ds, int n_sz, int keep)
235{
236 if (n_sz >= 0) {
237 if (keep && n_sz > ds->len) {
238 ds->str = (Dstr_char_t*) dRealloc (ds->str, n_sz*sizeof(Dstr_char_t));
239 ds->sz = n_sz;
240 } else {
241 dFree(ds->str);
242 ds->str = dNew(Dstr_char_t, n_sz);
243 ds->sz = n_sz;
244 ds->len = 0;
245 ds->str[0] = 0;
246 }
247 }
248}
249
255{
256 Dstr *ds;
257 if (sz < 2)
258 sz = 2;
259
260 ds = dNew(Dstr, 1);
261 ds->str = NULL;
262 dStr_resize(ds, sz + 1, 0); /* (sz + 1) for the extra '\0' */
263 return ds;
264}
265
269void dStr_fit (Dstr *ds)
270{
271 dStr_resize(ds, ds->len + 1, 1);
272}
273
278void dStr_insert_l (Dstr *ds, int pos_0, const char *s, int l)
279{
280 int n_sz;
281
282 if (ds && s && l && pos_0 >= 0 && pos_0 <= ds->len) {
283 for (n_sz = ds->sz; ds->len + l >= n_sz; n_sz *= 2);
284 if (n_sz > ds->sz) {
285 dStr_resize(ds, n_sz, (ds->len > 0) ? 1 : 0);
286 }
287 if (pos_0 < ds->len)
288 memmove(ds->str+pos_0+l, ds->str+pos_0, ds->len-pos_0);
289 memcpy(ds->str+pos_0, s, l);
290 ds->len += l;
291 ds->str[ds->len] = 0;
292 }
293}
294
298void dStr_insert (Dstr *ds, int pos_0, const char *s)
299{
300 if (s)
301 dStr_insert_l(ds, pos_0, s, strlen(s));
302}
303
308void dStr_append_l (Dstr *ds, const char *s, int l)
309{
310 dStr_insert_l(ds, ds->len, s, l);
311}
312
316void dStr_append (Dstr *ds, const char *s)
317{
318 dStr_append_l(ds, s, strlen(s));
319}
320
325Dstr *dStr_new (const char *s)
326{
327 Dstr *ds = dStr_sized_new(0);
328 if (s && *s)
329 dStr_append(ds, s);
330 return ds;
331}
332
337void dStr_free (Dstr *ds, int all)
338{
339 if (ds) {
340 if (all)
341 dFree(ds->str);
342 dFree(ds);
343 }
344}
345
349void dStr_append_c (Dstr *ds, int c)
350{
351 char cs[2];
352
353 if (ds) {
354 if (ds->sz > ds->len + 1) {
355 ds->str[ds->len++] = (Dstr_char_t)c;
356 ds->str[ds->len] = 0;
357 } else {
358 cs[0] = (Dstr_char_t)c;
359 cs[1] = 0;
360 dStr_append_l (ds, cs, 1);
361 }
362 }
363}
364
368void dStr_truncate (Dstr *ds, int len)
369{
370 if (ds && len < ds->len) {
371 ds->str[len] = 0;
372 ds->len = len;
373 }
374}
375
379void dStr_shred (Dstr *ds)
380{
381 if (ds && ds->sz > 0)
382 memset(ds->str, '\0', ds->sz);
383}
384
388void dStr_erase (Dstr *ds, int pos_0, int len)
389{
390 if (ds && pos_0 >= 0 && len > 0 && pos_0 + len <= ds->len) {
391 memmove(ds->str + pos_0, ds->str + pos_0 + len, ds->len - pos_0 - len);
392 ds->len -= len;
393 ds->str[ds->len] = 0;
394 }
395}
396
401void dStr_vsprintfa (Dstr *ds, const char *format, va_list argp)
402{
403 int n, n_sz;
404
405 if (ds && format) {
406 va_list argp2; /* Needed in case of looping on non-32bit arch */
407 while (1) {
408 va_copy(argp2, argp);
409 n = vsnprintf(ds->str + ds->len, ds->sz - ds->len, format, argp2);
410 va_end(argp2);
411#if defined(__sgi)
412 /* IRIX does not conform to C99; if the entire argument did not fit
413 * into the buffer, n = buffer space used (minus 1 for terminator)
414 */
415 if (n > -1 && n + 1 < ds->sz - ds->len) {
416 ds->len += n; /* Success! */
417 break;
418 } else {
419 n_sz = ds->sz * 2;
420 }
421#else
422 if (n > -1 && n < ds->sz - ds->len) {
423 ds->len += n; /* Success! */
424 break;
425 } else if (n > -1) { /* glibc >= 2.1 */
426 n_sz = ds->len + n + 1;
427 } else { /* old glibc */
428 n_sz = ds->sz * 2;
429 }
430#endif
431 dStr_resize(ds, n_sz, (ds->len > 0) ? 1 : 0);
432 }
433 }
434}
435
439void dStr_vsprintf (Dstr *ds, const char *format, va_list argp)
440{
441 if (ds) {
442 dStr_truncate(ds, 0);
443 dStr_vsprintfa(ds, format, argp);
444 }
445}
446
450void dStr_sprintf (Dstr *ds, const char *format, ...)
451{
452 va_list argp;
453
454 if (ds && format) {
455 va_start(argp, format);
456 dStr_vsprintf(ds, format, argp);
457 va_end(argp);
458 }
459}
460
464void dStr_sprintfa (Dstr *ds, const char *format, ...)
465{
466 va_list argp;
467
468 if (ds && format) {
469 va_start(argp, format);
470 dStr_vsprintfa(ds, format, argp);
471 va_end(argp);
472 }
473}
474
478int dStr_cmp(Dstr *ds1, Dstr *ds2)
479{
480 int ret = 0;
481
482 if (ds1 && ds2)
483 ret = memcmp(ds1->str, ds2->str, MIN(ds1->len+1, ds2->len+1));
484 return ret;
485}
486
490char *dStr_memmem(Dstr *haystack, Dstr *needle)
491{
492 int i;
493
494 if (needle && haystack) {
495 if (needle->len == 0)
496 return haystack->str;
497
498 for (i = 0; i <= (haystack->len - needle->len); i++) {
499 if (haystack->str[i] == needle->str[0] &&
500 !memcmp(haystack->str + i, needle->str, needle->len))
501 return haystack->str + i;
502 }
503 }
504 return NULL;
505}
506
513const char *dStr_printable(Dstr *in, int maxlen)
514{
515 int i;
516 static const char *const HEX = "0123456789ABCDEF";
517 static Dstr *out = NULL;
518
519 if (in == NULL)
520 return NULL;
521
522 if (out)
523 dStr_truncate(out, 0);
524 else
525 out = dStr_sized_new(in->len);
526
527 for (i = 0; (i < in->len) && (out->len < maxlen); ++i) {
528 if (isprint(in->str[i]) || (in->str[i] == '\n')) {
529 dStr_append_c(out, in->str[i]);
530 } else {
531 dStr_append_l(out, "\\x", 2);
532 dStr_append_c(out, HEX[(in->str[i] >> 4) & 15]);
533 dStr_append_c(out, HEX[in->str[i] & 15]);
534 }
535 }
536 if (out->len >= maxlen)
537 dStr_append(out, "...");
538 return out->str;
539}
540
551void dStr_shorten(Dstr *dst, const char *src, int n)
552{
553 if (n < 9)
554 n = 9;
555
556 int len = strlen(src);
557 if (len > n) {
558 int m = n - 3;
559 int n1 = m / 2; /* First half */
560 int n2 = m - n1; /* Second half */
561 dStr_append_l(dst, src, n1);
562 dStr_append(dst, "...");
563 dStr_append(dst, &src[len - n2]);
564 } else {
565 dStr_append(dst, src);
566 }
567}
568
569/*
570 *- dList ---------------------------------------------------------------------
571 */
572
576Dlist *dList_new(int size)
577{
578 Dlist *l;
579 if (size <= 0)
580 return NULL;
581
582 l = dNew(Dlist, 1);
583 l->len = 0;
584 l->sz = size;
585 l->list = dNew(void*, l->sz);
586 return l;
587}
588
593{
594 if (!lp)
595 return;
596
597 dFree(lp->list);
598 dFree(lp);
599}
600
604void dList_insert_pos (Dlist *lp, void *data, int pos0)
605{
606 int i;
607
608 if (!lp || pos0 < 0 || pos0 > lp->len)
609 return;
610
611 if (lp->sz == lp->len) {
612 lp->sz *= 2;
613 lp->list = (void**) dRealloc (lp->list, lp->sz*sizeof(void*));
614 }
615 ++lp->len;
616
617 for (i = lp->len - 1; i > pos0; --i)
618 lp->list[i] = lp->list[i - 1];
619 lp->list[pos0] = data;
620}
621
625void dList_append (Dlist *lp, void *data)
626{
627 dList_insert_pos(lp, data, lp->len);
628}
629
633void dList_prepend (Dlist *lp, void *data)
634{
635 dList_insert_pos(lp, data, 0);
636}
637
642{
643 if (!lp)
644 return 0;
645 return lp->len;
646}
647
651void dList_remove_fast (Dlist *lp, const void *data)
652{
653 int i;
654
655 if (!lp)
656 return;
657
658 for (i = 0; i < lp->len; ++i) {
659 if (lp->list[i] == data) {
660 lp->list[i] = lp->list[--lp->len];
661 break;
662 }
663 }
664}
665
666/*
667 * Remove a data item preserving order.
668 */
669void dList_remove (Dlist *lp, const void *data)
670{
671 int i, j;
672
673 if (!lp)
674 return;
675
676 for (i = 0; i < lp->len; ++i) {
677 if (lp->list[i] == data) {
678 --lp->len;
679 for (j = i; j < lp->len; ++j)
680 lp->list[j] = lp->list[j + 1];
681 break;
682 }
683 }
684}
685
690void *dList_nth_data (Dlist *lp, int n0)
691{
692 if (!lp || n0 < 0 || n0 >= lp->len)
693 return NULL;
694 return lp->list[n0];
695}
696
700void *dList_find (Dlist *lp, const void *data)
701{
702 int i = dList_find_idx(lp, data);
703 return (i >= 0) ? lp->list[i] : NULL;
704}
705
711int dList_find_idx (Dlist *lp, const void *data)
712{
713 int i, ret = -1;
714
715 if (!lp)
716 return ret;
717
718 for (i = 0; i < lp->len; ++i) {
719 if (lp->list[i] == data) {
720 ret = i;
721 break;
722 }
723 }
724 return ret;
725}
726
732void *dList_find_custom (Dlist *lp, const void *data, dCompareFunc func)
733{
734 int i;
735 void *ret = NULL;
736
737 if (!lp)
738 return ret;
739
740 for (i = 0; i < lp->len; ++i) {
741 if (func(lp->list[i], data) == 0) {
742 ret = lp->list[i];
743 break;
744 }
745 }
746 return ret;
747}
748
753static void QuickSort(void **left, void **right, dCompareFunc compare)
754{
755 void **p = left, **q = right, **t = left;
756
757 while (1) {
758 while (p != t && compare(*p, *t) < 0)
759 ++p;
760 while (q != t && compare(*q, *t) > 0)
761 --q;
762 if (p > q)
763 break;
764 if (p < q) {
765 void *tmp = *p;
766 *p = *q;
767 *q = tmp;
768 if (t == p)
769 t = q;
770 else if (t == q)
771 t = p;
772 }
773 if (++p > --q)
774 break;
775 }
776
777 if (left < q)
778 QuickSort(left, q, compare);
779 if (p < right)
780 QuickSort(p, right, compare);
781}
782
787{
788 if (lp && lp->len > 1) {
789 QuickSort(lp->list, lp->list + lp->len - 1, func);
790 }
791}
792
797void dList_insert_sorted (Dlist *lp, void *data, dCompareFunc func)
798{
799 int i, st, min, max;
800
801 if (lp) {
802 min = st = i = 0;
803 max = lp->len - 1;
804 while (min <= max) {
805 i = (min + max) / 2;
806 st = func(lp->list[i], data);
807 if (st < 0) {
808 min = i + 1;
809 } else if (st > 0) {
810 max = i - 1;
811 } else {
812 break;
813 }
814 }
815 dList_insert_pos(lp, data, (st >= 0) ? i : i+1);
816 }
817}
818
824void *dList_find_sorted (Dlist *lp, const void *data, dCompareFunc func)
825{
826 int i, st, min, max;
827 void *ret = NULL;
828
829 if (lp && lp->len) {
830 min = 0;
831 max = lp->len - 1;
832 while (min <= max) {
833 i = (min + max) / 2;
834 st = func(lp->list[i], data);
835 if (st < 0) {
836 min = i + 1;
837 } else if (st > 0) {
838 max = i - 1;
839 } else {
840 ret = lp->list[i];
841 break;
842 }
843 }
844 }
845
846 return ret;
847}
848
849/*
850 *- Parse function ------------------------------------------------------------
851 */
852
862int dParser_parse_rc_line(char **line, char **name, char **value)
863{
864 char *eq, *p;
865 int len, ret = -1;
866
867 dReturn_val_if_fail(*line, ret);
868
869 *name = NULL;
870 *value = NULL;
871 dStrstrip(*line);
872 if (!*line[0] || *line[0] == '#') {
873 /* blank line or comment */
874 ret = 1;
875 } else if ((eq = strchr(*line, '='))) {
876 /* get name */
877 for (p = *line; *p && *p != '=' && !dIsspace(*p); ++p);
878 *p = 0;
879 *name = *line;
880
881 /* skip whitespace */
882 if (p < eq)
883 for (++p; dIsspace(*p); ++p);
884
885 /* get value */
886 if (p == eq) {
887 for (++p; dIsspace(*p); ++p);
888 len = strlen(p);
889 if (len >= 2 && *p == '"' && p[len-1] == '"') {
890 p[len-1] = 0;
891 ++p;
892 }
893 *value = p;
894 ret = 0;
895 }
896 }
897
898 return ret;
899}
900
901/*
902 *- Dlib messages -------------------------------------------------------------
903 */
905{
906 dLib_show_msg = show;
907}
908
909/*
910 *- Misc utility functions ----------------------------------------------------
911 */
912
916char *dGetcwd (void)
917{
918 size_t size = 128;
919
920 while (1) {
921 char *buffer = dNew(char, size);
922 if (getcwd (buffer, size) == buffer)
923 return buffer;
924 dFree (buffer);
925 if (errno != ERANGE)
926 return 0;
927 size *= 2;
928 }
929}
930
934char *dGethomedir (void)
935{
936 static char *homedir = NULL;
937
938 if (!homedir) {
939 if (getenv("HOME")) {
940 homedir = dStrdup(getenv("HOME"));
941
942 } else if (getenv("HOMEDRIVE") && getenv("HOMEPATH")) {
943 homedir = dStrconcat(getenv("HOMEDRIVE"), getenv("HOMEPATH"), NULL);
944 } else {
945 DLIB_MSG("dGethomedir: $HOME not set, using '/'.\n");
946 homedir = dStrdup("/");
947 }
948 }
949 return homedir;
950}
951
956char *dGetline (FILE *stream)
957{
958 int ch;
959 Dstr *dstr;
960 char *line;
961
962 dReturn_val_if_fail (stream, 0);
963
964 dstr = dStr_sized_new(64);
965 while ((ch = fgetc(stream)) != EOF) {
966 dStr_append_c(dstr, ch);
967 if (ch == '\n')
968 break;
969 }
970
971 line = (dstr->len) ? dstr->str : NULL;
972 dStr_free(dstr, (line) ? 0 : 1);
973 return line;
974}
975
979int dClose(int fd)
980{
981 int st;
982
983 do
984 st = close(fd);
985 while (st == -1 && errno == EINTR);
986 return st;
987}
988
995int dUsleep(unsigned long usec)
996{
997 struct timespec ts;
998 int res;
999
1000 ts.tv_sec = usec / 1000000UL;
1001 ts.tv_nsec = (usec % 1000000UL) * 1000UL;
1002
1003 do {
1004 res = nanosleep(&ts, &ts);
1005 } while (res && errno == EINTR);
1006
1007 return res;
1008}
unsigned char bool_t
Definition d_size.h:21
char * dGetline(FILE *stream)
Get a line from a FILE stream.
Definition dlib.c:956
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dList_insert_sorted(Dlist *lp, void *data, dCompareFunc func)
Insert an element into a sorted list.
Definition dlib.c:797
int dStr_cmp(Dstr *ds1, Dstr *ds2)
Compare two dStrs.
Definition dlib.c:478
char * dStrsep(char **orig, const char *delim)
strsep() implementation
Definition dlib.c:159
void * dMalloc0(size_t size)
Definition dlib.c:61
void dFree(void *mem)
Definition dlib.c:68
char * dStr_memmem(Dstr *haystack, Dstr *needle)
Return a pointer to the first occurrence of needle in haystack.
Definition dlib.c:490
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
void dStr_sprintfa(Dstr *ds, const char *format,...)
Printf-like function that appends.
Definition dlib.c:464
char * dStrstrip(char *s)
Remove leading and trailing whitespace.
Definition dlib.c:122
void dLib_show_messages(bool_t show)
Definition dlib.c:904
void dStr_append(Dstr *ds, const char *s)
Append a C string to a Dstr.
Definition dlib.c:316
void dList_insert_pos(Dlist *lp, void *data, int pos0)
Insert an element at a given position [0 based].
Definition dlib.c:604
char * dStrdup(const char *s)
Definition dlib.c:77
Dlist * dList_new(int size)
Create a new empty list.
Definition dlib.c:576
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
Definition dlib.c:254
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
Definition dlib.c:215
void dStr_erase(Dstr *ds, int pos_0, int len)
Erase a substring.
Definition dlib.c:388
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c:641
void dStr_shorten(Dstr *dst, const char *src, int n)
Shorten string so it fits in n characters.
Definition dlib.c:551
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:690
void dList_remove_fast(Dlist *lp, const void *data)
Remove a data item without preserving order.
Definition dlib.c:651
void * dMalloc(size_t size)
Definition dlib.c:45
void dStr_free(Dstr *ds, int all)
Free a dillo string.
Definition dlib.c:337
static void dStr_resize(Dstr *ds, int n_sz, int keep)
Private allocator.
Definition dlib.c:234
void dStrshred(char *s)
Clear the contents of the string.
Definition dlib.c:140
int dClose(int fd)
Close a FD handling EINTR.
Definition dlib.c:979
char * dStriAsciiStr(const char *haystack, const char *needle)
Case insensitive strstr.
Definition dlib.c:184
int dList_find_idx(Dlist *lp, const void *data)
Search a data item.
Definition dlib.c:711
static void QuickSort(void **left, void **right, dCompareFunc compare)
QuickSort implementation.
Definition dlib.c:753
void dStr_append_l(Dstr *ds, const char *s, int l)
Append a C string to a Dstr (providing length).
Definition dlib.c:308
void dStr_append_c(Dstr *ds, int c)
Append one character.
Definition dlib.c:349
int dUsleep(unsigned long usec)
Portable usleep() function.
Definition dlib.c:995
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
static bool_t dLib_show_msg
Definition dlib.c:32
void dStr_sprintf(Dstr *ds, const char *format,...)
Printf-like function.
Definition dlib.c:450
void dList_sort(Dlist *lp, dCompareFunc func)
Sort the list using a custom function.
Definition dlib.c:786
void dStr_vsprintfa(Dstr *ds, const char *format, va_list argp)
vsprintf-like function that appends.
Definition dlib.c:401
Dstr * dStr_new(const char *s)
Create a new string.
Definition dlib.c:325
void dStr_shred(Dstr *ds)
Clear a Dstr.
Definition dlib.c:379
void dList_append(Dlist *lp, void *data)
Append a data item to the list.
Definition dlib.c:625
void dStr_vsprintf(Dstr *ds, const char *format, va_list argp)
vsprintf-like function.
Definition dlib.c:439
void * dList_find_sorted(Dlist *lp, const void *data, dCompareFunc func)
Search a sorted list.
Definition dlib.c:824
void dList_free(Dlist *lp)
Free a list (not its elements)
Definition dlib.c:592
#define DLIB_MSG(...)
Definition dlib.c:35
void dStr_insert_l(Dstr *ds, int pos_0, const char *s, int l)
Insert a C string, at a given position, into a Dstr (providing length).
Definition dlib.c:278
void * dList_find_custom(Dlist *lp, const void *data, dCompareFunc func)
Search a data item using a custom function.
Definition dlib.c:732
int dParser_parse_rc_line(char **line, char **name, char **value)
Take a dillo rc line and return 'name' and 'value' pointers to it.
Definition dlib.c:862
void dList_prepend(Dlist *lp, void *data)
Prepend a data item to the list.
Definition dlib.c:633
void dStr_fit(Dstr *ds)
Return memory if there's too much allocated.
Definition dlib.c:269
const char * dStr_printable(Dstr *in, int maxlen)
Return a printable representation of the provided Dstr, limited to a length of roughly maxlen.
Definition dlib.c:513
void * dRealloc(void *mem, size_t size)
Definition dlib.c:53
void dStr_insert(Dstr *ds, int pos_0, const char *s)
Insert a C string, at a given position, into a Dstr.
Definition dlib.c:298
void dStr_truncate(Dstr *ds, int len)
Truncate a Dstr to be 'len' bytes long.
Definition dlib.c:368
void dList_remove(Dlist *lp, const void *data)
Definition dlib.c:669
char * dStrnfill(size_t len, char c)
Return a new string of length 'len' filled with 'c' characters.
Definition dlib.c:149
char * dGethomedir(void)
Return the home directory in a static string (don't free)
Definition dlib.c:934
char * dGetcwd(void)
Return the current working directory in a new string.
Definition dlib.c:916
void * dList_find(Dlist *lp, const void *data)
Return the found data item, or NULL if not present.
Definition dlib.c:700
#define MIN(a, b)
Definition dlib.h:42
int(* dCompareFunc)(const void *a, const void *b)
Definition dlib.h:157
#define dReturn_val_if_fail(expr, val)
Definition dlib.h:88
#define dIsspace(c)
Definition dlib.h:45
#define Dstr_char_t
Definition dlib.h:112
#define D_ASCII_TOLOWER(c)
Definition dlib.h:49
#define TRUE
Definition dlib.h:35
#define dNew(type, count)
Definition dlib.h:61
Definition dlib.h:144
int len
Definition dlib.h:146
int sz
Definition dlib.h:145
void ** list
Definition dlib.h:147
Definition dlib.h:114
Dstr_char_t * str
Definition dlib.h:117
int len
Definition dlib.h:116
int sz
Definition dlib.h:115
static const char * HEX
Definition url.c:54