2 * Utility functions shared between modules, but not exported.
14 /* initialize a generic dynamic array struct */
15 int dynarray_init(struct dynamic_array
*da
, size_t entry_size
, size_t grow_size
) {
20 if (entry_size
== 0 || grow_size
== 0) {
21 fprintf(stderr
, "%s: internal error: sizes cannot be zero\n", __func__
);
28 da
->entry_size
= entry_size
;
29 da
->grow_size
= grow_size
;
30 da
->a
= malloc(da
->entry_size
* da
->grow_size
);
32 fprintf(stderr
, "%s():%s\n", "malloc", strerror(errno
));
35 da
->allocated
= da
->grow_size
;
39 /* allocate and initialize a new generic dynamic array */
40 struct dynamic_array
*dynarray_new(size_t entry_size
, size_t grow_size
) {
41 struct dynamic_array
*da
;
46 da
= calloc(1, sizeof *da
);
48 fprintf(stderr
, "%s():%s\n", "calloc", strerror(errno
));
52 if (dynarray_init(da
, entry_size
, grow_size
)) {
53 fprintf(stderr
, "%s():%s\n", "dynarray_init", strerror(errno
));
61 /* copy item onto end of array */
62 void *dynarray_add(struct dynamic_array
*da
, void *item
) {
68 /* make room, make room */
69 if (da
->entries
== da
->allocated
) {
70 size_t new_allocated
= da
->allocated
+ da
->grow_size
;
71 void *tmp_ptr
= realloc(da
->a
, new_allocated
* da
->entry_size
);
72 if (tmp_ptr
== NULL
) {
73 fprintf(stderr
, "%s():%s\n", "realloc", strerror(errno
));
77 da
->allocated
= new_allocated
;
81 dst
= DYNARRAY_ITEM(*da
, da
->entries
);
82 memcpy(dst
, item
, da
->entry_size
);
89 /* simplified strtoul with range checking */
90 int str_to_word(char *s
) {
97 l
= strtoul(s
, &ep
, 0);
100 || !(*s
&& *ep
== '\0') ) {
101 /* out of range of conversion, or invalid character encountered */
105 if (l
>= DCPU16_RAM
) {
106 /* out of range for our needs */
114 /* just like strtok_r, but ignores separators within quotes */
115 char *strqtok_r(char *str
, const char *sep
, int esc
, const char *quote
, char **lastq
, char **lasts
) {
128 /* next token starts after any leading seps */
129 while (**lasts
&& strchr(sep
, **lasts
)) {
141 /* the previous character was the escape, do not consider this character any further */
148 /* this character is the escape, do not consider the next character */
149 if (**lasts
== esc
) {
155 /* we have a quote open, only consider matching quote to close */
157 if (**lasts
== **lastq
)
163 /* this character is an opening quote, remember what it is */
164 if (strchr(quote
, **lasts
)) {
170 /* this character is a separator, separate and be done */
171 if (strchr(sep
, **lasts
)) {
179 /* were we left with an unmatched quote?
180 remember where we had trouble
181 try everything following lonely quote again, but pretend quote is there */
190 /* now strip escape characters */
191 for (src
= dst
= tok
; *src
; src
++, dst
++) {
201 /* remember where we had trouble */