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, version 3 of the License ONLY.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 static inline void dstr_zero (dstring_t
*s
) {
27 s
->size
= sizeof(s
->sbuf
);
33 void dstr_init (dstring_t
*s
) {
38 void dstr_init_cstr (dstring_t
*s
, const void *str
) {
40 dstr_push_cstr(s
, str
);
44 void dstr_init_buf (dstring_t
*s
, const void *start
, int len
) {
46 dstr_push_buf(s
, start
, len
);
50 void dstr_init_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
52 dstr_push_memrange(s
, start
, finish
);
56 void dstr_done (dstring_t
*s
) {
58 if (s
->str
!= s
->sbuf
) free(s
->str
);
64 void dstr_clear (dstring_t
*s
) {
71 void dstr_empty (dstring_t
*s
) {
73 if (s
->str
!= s
->sbuf
) free(s
->str
);
79 static void dstr_resv (dstring_t
*s
, int size
) {
81 if (size
< 0) size
= 0;
83 if (s
->str
== s
->sbuf
) {
84 s
->str
= malloc(size
);
85 if (s
->len
> 0) memcpy(s
->str
, s
->sbuf
, s
->len
);
88 char *ns
= realloc(s
->str
, size
);
89 if (ns
== NULL
) { fprintf(stderr
, "FATAL: out of memory!\n"); abort(); }
98 void dstr_reserve (dstring_t
*s
, int size
) {
99 if (s
!= NULL
&& size
> s
->size
) dstr_resv(s
, size
);
103 // make room for at least `spc` chars
104 static inline void dstr_expand (dstring_t
*s
, int spc
) {
105 if (s
!= NULL
&& spc
>= 0) dstr_reserve(s
, ((s
->len
+spc
+1)|0x3ff)+1);
109 void dstr_push_buf (dstring_t
*s
, const void *start
, int len
) {
111 if (len
< 0) len
= (start
!= NULL
? strlen((const char *)start
) : 0);
114 if (start
== NULL
) memset(s
->str
+s
->len
, 32, len
); else memmove(s
->str
+s
->len
, start
, len
);
115 s
->str
[s
->len
+=len
] = 0;
121 void dstr_push_cstr (dstring_t
*s
, const void *str
) {
122 dstr_push_buf(s
, str
, -1);
126 void dstr_push_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
127 if (s
!= NULL
&& finish
> start
) dstr_push_buf(s
, start
, ((const char *)finish
)-((const char *)start
));
131 void dstr_push_char (dstring_t
*s
, int x
) {
134 s
->str
[s
->len
++] = x
&0xff;
140 void dstr_set_cstr (dstring_t
*s
, const void *cstr
) {
142 dstr_push_cstr(s
, cstr
);
146 void dstr_set_buf (dstring_t
*s
, const void *start
, int len
) {
148 dstr_push_buf(s
, start
, len
);
151 void dstr_set_memrange (dstring_t
*s
, const void *start
, const void *finish
) {
153 dstr_push_memrange(s
, start
, finish
);
157 void dstr_chop (dstring_t
*s
, int n
) {
159 if (n
< 0) n
= 0; else if (n
> s
->len
) n
= s
->len
;
160 s
->str
[s
->len
=n
] = 0;
165 int dstr_pop_char (dstring_t
*s
) {
167 int res
= (s
->len
> 0 ? (unsigned char)(s
->str
[--s
->len
]) : 0);
175 char dstr_last_char (dstring_t
*s
) {
176 return (s
!= NULL
&& s
->len
> 0 ? s
->str
[s
->len
-1] : 0);
180 char *dstr_cstr (dstring_t
*s
) {
181 return (s
!= NULL
? s
->str
: NULL
);
185 int dstr_len (dstring_t
*s
) {
186 return (s
!= NULL
? s
->len
: 0);