Dillo v3.1.1-46-g8a360e32
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 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
541/*
542 *- dList ---------------------------------------------------------------------
543 */
544
548Dlist *dList_new(int size)
549{
550 Dlist *l;
551 if (size <= 0)
552 return NULL;
553
554 l = dNew(Dlist, 1);
555 l->len = 0;
556 l->sz = size;
557 l->list = dNew(void*, l->sz);
558 return l;
559}
560
565{
566 if (!lp)
567 return;
568
569 dFree(lp->list);
570 dFree(lp);
571}
572
576void dList_insert_pos (Dlist *lp, void *data, int pos0)
577{
578 int i;
579
580 if (!lp || pos0 < 0 || pos0 > lp->len)
581 return;
582
583 if (lp->sz == lp->len) {
584 lp->sz *= 2;
585 lp->list = (void**) dRealloc (lp->list, lp->sz*sizeof(void*));
586 }
587 ++lp->len;
588
589 for (i = lp->len - 1; i > pos0; --i)
590 lp->list[i] = lp->list[i - 1];
591 lp->list[pos0] = data;
592}
593
597void dList_append (Dlist *lp, void *data)
598{
599 dList_insert_pos(lp, data, lp->len);
600}
601
605void dList_prepend (Dlist *lp, void *data)
606{
607 dList_insert_pos(lp, data, 0);
608}
609
614{
615 if (!lp)
616 return 0;
617 return lp->len;
618}
619
623void dList_remove_fast (Dlist *lp, const void *data)
624{
625 int i;
626
627 if (!lp)
628 return;
629
630 for (i = 0; i < lp->len; ++i) {
631 if (lp->list[i] == data) {
632 lp->list[i] = lp->list[--lp->len];
633 break;
634 }
635 }
636}
637
638/*
639 * Remove a data item preserving order.
640 */
641void dList_remove (Dlist *lp, const void *data)
642{
643 int i, j;
644
645 if (!lp)
646 return;
647
648 for (i = 0; i < lp->len; ++i) {
649 if (lp->list[i] == data) {
650 --lp->len;
651 for (j = i; j < lp->len; ++j)
652 lp->list[j] = lp->list[j + 1];
653 break;
654 }
655 }
656}
657
662void *dList_nth_data (Dlist *lp, int n0)
663{
664 if (!lp || n0 < 0 || n0 >= lp->len)
665 return NULL;
666 return lp->list[n0];
667}
668
672void *dList_find (Dlist *lp, const void *data)
673{
674 int i = dList_find_idx(lp, data);
675 return (i >= 0) ? lp->list[i] : NULL;
676}
677
683int dList_find_idx (Dlist *lp, const void *data)
684{
685 int i, ret = -1;
686
687 if (!lp)
688 return ret;
689
690 for (i = 0; i < lp->len; ++i) {
691 if (lp->list[i] == data) {
692 ret = i;
693 break;
694 }
695 }
696 return ret;
697}
698
704void *dList_find_custom (Dlist *lp, const void *data, dCompareFunc func)
705{
706 int i;
707 void *ret = NULL;
708
709 if (!lp)
710 return ret;
711
712 for (i = 0; i < lp->len; ++i) {
713 if (func(lp->list[i], data) == 0) {
714 ret = lp->list[i];
715 break;
716 }
717 }
718 return ret;
719}
720
725static void QuickSort(void **left, void **right, dCompareFunc compare)
726{
727 void **p = left, **q = right, **t = left;
728
729 while (1) {
730 while (p != t && compare(*p, *t) < 0)
731 ++p;
732 while (q != t && compare(*q, *t) > 0)
733 --q;
734 if (p > q)
735 break;
736 if (p < q) {
737 void *tmp = *p;
738 *p = *q;
739 *q = tmp;
740 if (t == p)
741 t = q;
742 else if (t == q)
743 t = p;
744 }
745 if (++p > --q)
746 break;
747 }
748
749 if (left < q)
750 QuickSort(left, q, compare);
751 if (p < right)
752 QuickSort(p, right, compare);
753}
754
759{
760 if (lp && lp->len > 1) {
761 QuickSort(lp->list, lp->list + lp->len - 1, func);
762 }
763}
764
769void dList_insert_sorted (Dlist *lp, void *data, dCompareFunc func)
770{
771 int i, st, min, max;
772
773 if (lp) {
774 min = st = i = 0;
775 max = lp->len - 1;
776 while (min <= max) {
777 i = (min + max) / 2;
778 st = func(lp->list[i], data);
779 if (st < 0) {
780 min = i + 1;
781 } else if (st > 0) {
782 max = i - 1;
783 } else {
784 break;
785 }
786 }
787 dList_insert_pos(lp, data, (st >= 0) ? i : i+1);
788 }
789}
790
796void *dList_find_sorted (Dlist *lp, const void *data, dCompareFunc func)
797{
798 int i, st, min, max;
799 void *ret = NULL;
800
801 if (lp && lp->len) {
802 min = 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 ret = lp->list[i];
813 break;
814 }
815 }
816 }
817
818 return ret;
819}
820
821/*
822 *- Parse function ------------------------------------------------------------
823 */
824
834int dParser_parse_rc_line(char **line, char **name, char **value)
835{
836 char *eq, *p;
837 int len, ret = -1;
838
839 dReturn_val_if_fail(*line, ret);
840
841 *name = NULL;
842 *value = NULL;
843 dStrstrip(*line);
844 if (!*line[0] || *line[0] == '#') {
845 /* blank line or comment */
846 ret = 1;
847 } else if ((eq = strchr(*line, '='))) {
848 /* get name */
849 for (p = *line; *p && *p != '=' && !dIsspace(*p); ++p);
850 *p = 0;
851 *name = *line;
852
853 /* skip whitespace */
854 if (p < eq)
855 for (++p; dIsspace(*p); ++p);
856
857 /* get value */
858 if (p == eq) {
859 for (++p; dIsspace(*p); ++p);
860 len = strlen(p);
861 if (len >= 2 && *p == '"' && p[len-1] == '"') {
862 p[len-1] = 0;
863 ++p;
864 }
865 *value = p;
866 ret = 0;
867 }
868 }
869
870 return ret;
871}
872
873/*
874 *- Dlib messages -------------------------------------------------------------
875 */
877{
878 dLib_show_msg = show;
879}
880
881/*
882 *- Misc utility functions ----------------------------------------------------
883 */
884
888char *dGetcwd (void)
889{
890 size_t size = 128;
891
892 while (1) {
893 char *buffer = dNew(char, size);
894 if (getcwd (buffer, size) == buffer)
895 return buffer;
896 dFree (buffer);
897 if (errno != ERANGE)
898 return 0;
899 size *= 2;
900 }
901}
902
906char *dGethomedir (void)
907{
908 static char *homedir = NULL;
909
910 if (!homedir) {
911 if (getenv("HOME")) {
912 homedir = dStrdup(getenv("HOME"));
913
914 } else if (getenv("HOMEDRIVE") && getenv("HOMEPATH")) {
915 homedir = dStrconcat(getenv("HOMEDRIVE"), getenv("HOMEPATH"), NULL);
916 } else {
917 DLIB_MSG("dGethomedir: $HOME not set, using '/'.\n");
918 homedir = dStrdup("/");
919 }
920 }
921 return homedir;
922}
923
928char *dGetline (FILE *stream)
929{
930 int ch;
931 Dstr *dstr;
932 char *line;
933
934 dReturn_val_if_fail (stream, 0);
935
936 dstr = dStr_sized_new(64);
937 while ((ch = fgetc(stream)) != EOF) {
938 dStr_append_c(dstr, ch);
939 if (ch == '\n')
940 break;
941 }
942
943 line = (dstr->len) ? dstr->str : NULL;
944 dStr_free(dstr, (line) ? 0 : 1);
945 return line;
946}
947
951int dClose(int fd)
952{
953 int st;
954
955 do
956 st = close(fd);
957 while (st == -1 && errno == EINTR);
958 return st;
959}
960
967int dUsleep(unsigned long usec)
968{
969 struct timespec ts;
970 int res;
971
972 ts.tv_sec = usec / 1000000UL;
973 ts.tv_nsec = (usec % 1000000UL) * 1000UL;
974
975 do {
976 res = nanosleep(&ts, &ts);
977 } while (res && errno == EINTR);
978
979 return res;
980}
unsigned char bool_t
Definition d_size.h:21
char * dGetline(FILE *stream)
Get a line from a FILE stream.
Definition dlib.c:928
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:769
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:876
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:576
char * dStrdup(const char *s)
Definition dlib.c:77
Dlist * dList_new(int size)
Create a new empty list.
Definition dlib.c:548
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:613
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:662
void dList_remove_fast(Dlist *lp, const void *data)
Remove a data item without preserving order.
Definition dlib.c:623
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:951
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:683
static void QuickSort(void **left, void **right, dCompareFunc compare)
QuickSort implementation.
Definition dlib.c:725
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:967
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:758
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:597
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:796
void dList_free(Dlist *lp)
Free a list (not its elements)
Definition dlib.c:564
#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:704
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:834
void dList_prepend(Dlist *lp, void *data)
Prepend a data item to the list.
Definition dlib.c:605
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:641
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:906
char * dGetcwd(void)
Return the current working directory in a new string.
Definition dlib.c:888
void * dList_find(Dlist *lp, const void *data)
Return the found data item, or NULL if not present.
Definition dlib.c:672
#define MIN(a, b)
Definition dlib.h:30
int(* dCompareFunc)(const void *a, const void *b)
Definition dlib.h:144
#define dReturn_val_if_fail(expr, val)
Definition dlib.h:76
#define dIsspace(c)
Definition dlib.h:33
#define Dstr_char_t
Definition dlib.h:100
#define D_ASCII_TOLOWER(c)
Definition dlib.h:37
#define TRUE
Definition dlib.h:23
#define dNew(type, count)
Definition dlib.h:49
Definition dlib.h:131
int len
Definition dlib.h:133
int sz
Definition dlib.h:132
void ** list
Definition dlib.h:134
Definition dlib.h:102
Dstr_char_t * str
Definition dlib.h:105
int len
Definition dlib.h:104
int sz
Definition dlib.h:103
static const char * HEX
Definition url.c:54