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