/* Walk the split buffer (first the list above SPLIT_MAX then the
array below SPLIT_MAX, unordered walk) and run action_macro
for each item. Action_macro is pasted twice: once for the list,
then for the array.
cnt is the number of fields.
If free_list is non-zero, the ov list items are freed after
action_macro. Not deleting the list is useful if multiple runs
are required.
Calling convention for the action macro is:
action(idx, sval)
where idx is an integer index numbered from 0 and sval is a mawk_string_t.
*/
#define mawk_split_walk(MAWK, cnt, free_list, action_macro) \
do { \
int spwlk__cnt = cnt; \
mawk_split_walk_top(MAWK, spwlk__cnt, free_list, action_macro); \
mawk_split_walk_bottom(MAWK, spwlk__cnt, action_macro); \
} while(0)
/* walk items above MAX_SPLIT from a linked list
sets cnt to MAX_SPLIT if it was larger than MAX_SPLIT;
NOTE: this is half of the job mawk_split_walk does */
#define mawk_split_walk_top(MAWK, cnt, free_list, action_macro) \
do { \
if (cnt > MAX_SPLIT) { \
SPLIT_OV *spwlk__p = MAWK->split_ov_list; \
SPLIT_OV *spwlk__q; \
int spwlk__i; \
MAWK->split_ov_list = (SPLIT_OV *) 0; \
spwlk__i = MAX_SPLIT; \
while (spwlk__p) { \
{ action_macro(spwlk__i, (spwlk__p->sval)); } \
spwlk__q = spwlk__p; \
spwlk__p = spwlk__q->link; \
if (free_list) \
MAWK_ZFREE(MAWK, spwlk__q); \
spwlk__i++; \
} \
cnt = MAX_SPLIT; \
} \
} while(0)
/* walk items below MAX_SPLIT from the split buff, up to cnt;
cnt must not be larger or equal to MAX_SPLIT! cnt is not modified
NOTE: this is half of the job mawk_split_walk does */
#define mawk_split_walk_bottom(MAWK, cnt, action_macro) \
do { \
int spwlk__i; \
for (spwlk__i = 0; spwlk__i < cnt; spwlk__i++) { \
action_macro(spwlk__i, split_buff[spwlk__i]); \
} \
} while(0)