1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 static inline void dstr_zero (dstring_t
*s
) {
28 s
->size
= sizeof(s
->sbuf
);
34 void dstr_init (dstring_t
*s
) {
39 void dstr_init_cstr (dstring_t
*s
, const void *str
) {
41 dstr_push_cstr(s
, str
);
45 void dstr_init_buf (dstring_t
*s
, const void *start
, int len
) {
47 dstr_push_buf(s
, start
, len
);
51 void dstr_init_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
53 dstr_push_memrange(s
, start
, finish
);
57 void dstr_done (dstring_t
*s
) {
59 if (s
->str
!= s
->sbuf
) free(s
->str
);
65 void dstr_clear (dstring_t
*s
) {
72 void dstr_empty (dstring_t
*s
) {
74 if (s
->str
!= s
->sbuf
) free(s
->str
);
80 static void dstr_resv (dstring_t
*s
, int size
) {
82 if (size
< 0) size
= 0;
84 if (s
->str
== s
->sbuf
) {
85 s
->str
= malloc(size
);
86 if (s
->len
> 0) memcpy(s
->str
, s
->sbuf
, s
->len
);
89 char *ns
= realloc(s
->str
, size
);
90 if (ns
== NULL
) { fprintf(stderr
, "FATAL: out of memory!\n"); abort(); }
99 void dstr_reserve (dstring_t
*s
, int size
) {
100 if (s
!= NULL
&& size
> s
->size
) dstr_resv(s
, size
);
104 // make room for at least `spc` chars
105 static inline void dstr_expand (dstring_t
*s
, int spc
) {
106 if (s
!= NULL
&& spc
>= 0) dstr_reserve(s
, ((s
->len
+spc
+1)|0x3ff)+1);
110 void dstr_push_buf (dstring_t
*s
, const void *start
, int len
) {
112 if (len
< 0) len
= (start
!= NULL
? strlen((const char *)start
) : 0);
115 if (start
== NULL
) memset(s
->str
+s
->len
, 32, len
); else memmove(s
->str
+s
->len
, start
, len
);
116 s
->str
[s
->len
+=len
] = 0;
122 void dstr_push_cstr (dstring_t
*s
, const void *str
) {
123 dstr_push_buf(s
, str
, -1);
127 void dstr_push_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
128 if (s
!= NULL
&& finish
> start
) dstr_push_buf(s
, start
, ((const char *)finish
)-((const char *)start
));
132 void dstr_push_char (dstring_t
*s
, int x
) {
135 s
->str
[s
->len
++] = x
&0xff;
141 void dstr_set_cstr (dstring_t
*s
, const void *cstr
) {
143 dstr_push_cstr(s
, cstr
);
147 void dstr_set_buf (dstring_t
*s
, const void *start
, int len
) {
149 dstr_push_buf(s
, start
, len
);
152 void dstr_set_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
154 dstr_push_memrange(s
, start
, finish
);
158 void dstr_chop (dstring_t
*s
, int n
) {
160 if (n
< 0) n
= 0; else if (n
> s
->len
) n
= s
->len
;
161 s
->str
[s
->len
=n
] = 0;
166 int dstr_pop_char (dstring_t
*s
) {
168 int res
= (s
->len
> 0 ? (unsigned char)(s
->str
[--s
->len
]) : 0);
176 char dstr_last_char (dstring_t
*s
) {
177 return (s
!= NULL
&& s
->len
> 0 ? s
->str
[s
->len
-1] : 0);
181 char *dstr_cstr (dstring_t
*s
) {
182 return (s
!= NULL
? s
->str
: NULL
);
186 int dstr_len (dstring_t
*s
) {
187 return (s
!= NULL
? s
->len
: 0);