Codebase list libmawk / debian/latest src / libmawk / split.h
debian/latest

Tree @debian/latest (Download .tar.gz)

split.h @debian/latestraw · history · blame

/* 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)