1744 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1744 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| dnl ---------------------------------------------------------------------------
 | |
| changequote(`[[', `]]')dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_comp_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl
 | |
| int _fn_name_ (const _char_type_* str1, hawk_oow_t len1, const _char_type_* str2, hawk_oow_t len2, int ignorecase)
 | |
| {
 | |
| 	_chau_type_ c1, c2;
 | |
| 	const _char_type_* end1 = str1 + len1;
 | |
| 	const _char_type_* end2 = str2 + len2;
 | |
| 
 | |
| 	if (ignorecase)
 | |
| 	{
 | |
| 		while (str1 < end1)
 | |
| 		{
 | |
| 			c1 = _to_lower_()(*str1);
 | |
| 			if (str2 < end2) 
 | |
| 			{
 | |
| 				c2 = _to_lower_()(*str2);
 | |
| 				if (c1 > c2) return 1;
 | |
| 				if (c1 < c2) return -1;
 | |
| 			}
 | |
| 			else return 1;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		while (str1 < end1)
 | |
| 		{
 | |
| 			c1 = *str1;
 | |
| 			if (str2 < end2) 
 | |
| 			{
 | |
| 				c2 = *str2;
 | |
| 				if (c1 > c2) return 1;
 | |
| 				if (c1 < c2) return -1;
 | |
| 			}
 | |
| 			else return 1;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return (str2 < end2)? -1: 0;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_comp_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl
 | |
| int _fn_name_ (const _char_type_* str1, const _char_type_* str2, int ignorecase)
 | |
| {
 | |
| 	if (ignorecase)
 | |
| 	{
 | |
| 		while (_to_lower_()(*str1) == _to_lower_()(*str2))
 | |
| 		{
 | |
| 			if (*str1 == '\0') return 0;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 
 | |
| 		return ((_chau_type_)_to_lower_()(*str1) > (_chau_type_)_to_lower_()(*str2))? 1: -1;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		while (*str1 == *str2)
 | |
| 		{
 | |
| 			if (*str1 == '\0') return 0;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 
 | |
| 		return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1;
 | |
| 	}
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_comp_cstr_limited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl
 | |
| int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hawk_oow_t maxlen, int ignorecase)
 | |
| {
 | |
| 	if (maxlen == 0) return 0;
 | |
| 
 | |
| 	if (ignorecase)
 | |
| 	{
 | |
| 		while (_to_lower_()(*str1) == _to_lower_()(*str2))
 | |
| 		{
 | |
| 			 if (*str1 == '\0' || maxlen == 1) return 0;
 | |
| 			 str1++; str2++; maxlen--;
 | |
| 		}
 | |
| 
 | |
| 		return ((_chau_type_)_to_lower_()(*str1) > (_chau_type_)_to_lower_()(*str2))? 1: -1;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		while (*str1 == *str2)
 | |
| 		{
 | |
| 			 if (*str1 == '\0' || maxlen == 1) return 0;
 | |
| 			 str1++; str2++; maxlen--;
 | |
| 		}
 | |
| 
 | |
| 		return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1;
 | |
| 	}
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_comp_chars_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl
 | |
| int _fn_name_ (const _char_type_* str1, hawk_oow_t len, const _char_type_* str2, int ignorecase)
 | |
| {
 | |
| 	/* for "abc\0" of length 4 vs "abc", the fourth character
 | |
| 	 * of the first string is equal to the terminating null of
 | |
| 	 * the second string. the first string is still considered 
 | |
| 	 * bigger */
 | |
| 	if (ignorecase)
 | |
| 	{
 | |
| 		const _char_type_* end = str1 + len;
 | |
| 		_char_type_ c1;
 | |
| 		_char_type_ c2;
 | |
| 		while (str1 < end && *str2 != '\0') 
 | |
| 		{
 | |
| 			c1 = _to_lower_()(*str1);
 | |
| 			c2 = _to_lower_()(*str2);
 | |
| 			if (c1 != c2) return ((_chau_type_)c1 > (_chau_type_)c2)? 1: -1;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 		return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		const _char_type_* end = str1 + len;
 | |
| 		while (str1 < end && *str2 != '\0') 
 | |
| 		{
 | |
| 			if (*str1 != *str2) return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1;
 | |
| 			str1++; str2++;
 | |
| 		}
 | |
| 		return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
 | |
| 	}
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_concat_chars_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_count_str_]], $3)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* str, hawk_oow_t len)
 | |
| {
 | |
| 	_char_type_* p, * p2;
 | |
| 	const _char_type_* end;
 | |
| 	hawk_oow_t blen;
 | |
| 
 | |
| 	blen = _count_str_()(buf);
 | |
| 	if (blen >= bsz) return blen; /* something wrong */
 | |
| 
 | |
| 	p = buf + blen;
 | |
| 	p2 = buf + bsz - 1;
 | |
| 
 | |
| 	end = str + len;
 | |
| 
 | |
| 	while (p < p2) 
 | |
| 	{
 | |
| 		if (str >= end) break;
 | |
| 		*p++ = *str++;
 | |
| 	}
 | |
| 
 | |
| 	if (bsz > 0) *p = '\0';
 | |
| 	return p - buf;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_count_str_]])dnl
 | |
| ]])dnl
 | |
| 
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_concat_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_count_str_]], $3)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* str)
 | |
| {
 | |
| 	_char_type_* p, * p2;
 | |
| 	hawk_oow_t blen;
 | |
| 
 | |
| 	blen = _count_str_()(buf);
 | |
| 	if (blen >= bsz) return blen; /* something wrong */
 | |
| 
 | |
| 	p = buf + blen;
 | |
| 	p2 = buf + bsz - 1;
 | |
| 
 | |
| 	while (p < p2) 
 | |
| 	{
 | |
| 		if (*str == '\0') break;
 | |
| 		*p++ = *str++;
 | |
| 	}
 | |
| 
 | |
| 	if (bsz > 0) *p = '\0';
 | |
| 	return p - buf;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_count_str_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| void _fn_name_ (_char_type_* dst, const _char_type_* src, hawk_oow_t len)
 | |
| {
 | |
| 	/* take note of no forced null termination */
 | |
| 	hawk_oow_t i;
 | |
| 	for (i = 0; i < len; i++) dst[i] = src[i];
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_chars_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t dlen, const _char_type_* src, hawk_oow_t slen)
 | |
| {
 | |
| 	hawk_oow_t i;
 | |
| 	if (dlen <= 0) return 0;
 | |
| 	if (dlen <= slen) slen = dlen - 1;
 | |
| 	for (i = 0; i < slen; i++) dst[i] = src[i];
 | |
| 	dst[i] = '\0';
 | |
| 	return i;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_chars_to_cstr_unlimited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* dst, const _char_type_* src, hawk_oow_t len)
 | |
| {
 | |
| 	hawk_oow_t i;
 | |
| 	for (i = 0; i < len; i++) dst[i] = src[i];
 | |
| 	dst[i] = '\0';
 | |
| 	return i;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_cstr_to_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t len, const _char_type_* src)
 | |
| {
 | |
| 	/* no null termination */
 | |
| 	_char_type_* p, * p2;
 | |
| 
 | |
| 	p = dst; p2 = dst + len - 1;
 | |
| 
 | |
| 	while (p < p2)
 | |
| 	{
 | |
| 		if (*src == '\0') break;
 | |
| 		*p++ = *src++;
 | |
| 	}
 | |
| 
 | |
| 	return p - dst;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t len, const _char_type_* src)
 | |
| {
 | |
| 	_char_type_* p, * p2;
 | |
| 
 | |
| 	p = dst; p2 = dst + len - 1;
 | |
| 
 | |
| 	while (p < p2)
 | |
| 	{
 | |
| 		if (*src == '\0') break;
 | |
| 		*p++ = *src++;
 | |
| 	}
 | |
| 
 | |
| 	if (len > 0) *p = '\0';
 | |
| 	return p - dst;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_cstr_unlimited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* dst, const _char_type_* src)
 | |
| {
 | |
| 	_char_type_* org = dst;
 | |
| 	while ((*dst++ = *src++) != '\0');
 | |
| 	return dst - org - 1;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_fmt_cstrs_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* fmt, const _char_type_* str[])
 | |
| {
 | |
| 	_char_type_* b = buf;
 | |
| 	_char_type_* end = buf + bsz - 1;
 | |
| 	const _char_type_* f = fmt;
 | |
| 
 | |
| 	if (bsz <= 0) return 0;
 | |
| 
 | |
| 	while (*f != '\0')
 | |
| 	{
 | |
| 		if (*f == '\\')
 | |
| 		{
 | |
| 			/* get the escaped character and treat it normally.
 | |
| 			 * if the escaper is the last character, treat it
 | |
| 			 * normally also. */
 | |
| 			if (f[1] != '\0') f++;
 | |
| 		}
 | |
| 		else if (*f == '$')
 | |
| 		{
 | |
| 			if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9'))
 | |
| 			{
 | |
| 				const _char_type_* tmp;
 | |
| 				hawk_oow_t idx = 0;
 | |
| 
 | |
| 				tmp = f;
 | |
| 				f += 2;
 | |
| 
 | |
| 				do idx = idx * 10 + (*f++ - '0');
 | |
| 				while (*f >= '0' && *f <= '9');
 | |
| 
 | |
| 				if (*f != '}')
 | |
| 				{
 | |
| 					f = tmp;
 | |
| 					goto normal;
 | |
| 				}
 | |
| 
 | |
| 				f++;
 | |
| 
 | |
| 				tmp = str[idx];
 | |
| 				while (*tmp != '\0')
 | |
| 				{
 | |
| 					if (b >= end) goto fini;
 | |
| 					*b++ = *tmp++;
 | |
| 				}
 | |
| 				continue;
 | |
| 			}
 | |
| 			else if (f[1] == '$') f++;
 | |
| 		}
 | |
| 
 | |
| 	normal:
 | |
| 		if (b >= end) break;
 | |
| 		*b++ = *f++;
 | |
| 	}
 | |
| 
 | |
| fini:
 | |
| 	*b = '\0';
 | |
| 	return b - buf;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_copy_fmt_cses_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_cs_type_]], $3)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* fmt, const _cs_type_ str[])
 | |
| {
 | |
| 	_char_type_* b = buf;
 | |
| 	_char_type_* end = buf + bsz - 1;
 | |
| 	const _char_type_* f = fmt;
 | |
|  
 | |
| 	if (bsz <= 0) return 0;
 | |
|  
 | |
| 	while (*f != '\0')
 | |
| 	{
 | |
| 		if (*f == '\\')
 | |
| 		{
 | |
| 			/* get the escaped character and treat it normally.
 | |
| 			 * if the escaper is the last character, treat it 
 | |
| 			 * normally also. */
 | |
| 			if (f[1] != '\0') f++;
 | |
| 		}
 | |
| 		else if (*f == '$')
 | |
| 		{
 | |
| 			if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9'))
 | |
| 			{
 | |
| 				const _char_type_* tmp, * tmpend;
 | |
| 				hawk_oow_t idx = 0;
 | |
|  
 | |
| 				tmp = f;
 | |
| 				f += 2;
 | |
|  
 | |
| 				do idx = idx * 10 + (*f++ - '0');
 | |
| 				while (*f >= '0' && *f <= '9');
 | |
| 	
 | |
| 				if (*f != '}')
 | |
| 				{
 | |
| 					f = tmp;
 | |
| 					goto normal;
 | |
| 				}
 | |
|  
 | |
| 				f++;
 | |
| 				
 | |
| 				tmp = str[idx].ptr;
 | |
| 				tmpend = tmp + str[idx].len;
 | |
|  
 | |
| 				while (tmp < tmpend)
 | |
| 				{
 | |
| 					if (b >= end) goto fini;
 | |
| 					*b++ = *tmp++;
 | |
| 				}
 | |
| 				continue;
 | |
| 			}
 | |
| 			else if (f[1] == '$') f++;
 | |
| 		}
 | |
|  
 | |
| 	normal:
 | |
| 		if (b >= end) break;
 | |
| 		*b++ = *f++;
 | |
| 	}
 | |
|  
 | |
| fini:
 | |
| 	*b = '\0';
 | |
| 	return b - buf;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_count_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (const _char_type_* str)
 | |
| {
 | |
| 	const _char_type_* ptr = str;
 | |
| 	while (*ptr != '\0') ptr++;
 | |
| 	return ptr - str;
 | |
| } 
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_count_cstr_limited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (const _char_type_* str, hawk_oow_t maxlen)
 | |
| {
 | |
| 	hawk_oow_t i;
 | |
| 	for (i = 0; i < maxlen; i++)
 | |
| 	{
 | |
| 		if (str[i] == '\0') break;
 | |
| 	}
 | |
| 	return i;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_equal_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hawk_oow_t len)
 | |
| {
 | |
| 	hawk_oow_t i;
 | |
| 
 | |
| 	/* NOTE: you should call this function after having ensured that
 | |
| 	 *       str1 and str2 are in the same length */
 | |
| 
 | |
| 	for (i = 0; i < len; i++)
 | |
| 	{
 | |
| 		if (str1[i] != str2[i]) return 0;
 | |
| 	}
 | |
| 
 | |
| 	return 1;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_fill_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| void _fn_name_ (_char_type_* dst, _char_type_ ch, hawk_oow_t len)
 | |
| {
 | |
|         hawk_oow_t i;
 | |
|         for (i = 0; i < len; i++) dst[i] = ch;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_find_char_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* ptr, hawk_oow_t len, _char_type_ c)
 | |
| {
 | |
| 	const _char_type_* end;
 | |
| 
 | |
| 	end = ptr + len;
 | |
| 	while (ptr < end)
 | |
| 	{
 | |
| 		if (*ptr == c) return (_char_type_*)ptr;
 | |
| 		ptr++;
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_rfind_char_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* ptr, hawk_oow_t len, _char_type_ c)
 | |
| {
 | |
| 	const _char_type_* cur;
 | |
| 
 | |
| 	cur = ptr + len;
 | |
| 	while (cur > ptr)
 | |
| 	{
 | |
| 		--cur;
 | |
| 		if (*cur == c) return (_char_type_*)cur;
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_find_char_in_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* ptr, _char_type_ c)
 | |
| {
 | |
| 	while (*ptr != '\0')
 | |
| 	{
 | |
| 		if (*ptr == c) return (_char_type_*)ptr;
 | |
| 		ptr++;
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_rfind_char_in_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* str, _char_type_ c)
 | |
| {
 | |
| 	const _char_type_* ptr = str;
 | |
| 	while (*ptr != '\0') ptr++;
 | |
| 
 | |
| 	while (ptr > str)
 | |
| 	{
 | |
| 		--ptr;
 | |
| 		if (*ptr == c) return (_char_type_*)ptr;
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_find_chars_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t strsz, const _char_type_* sub, hawk_oow_t subsz, int ignorecase)
 | |
| {
 | |
| 	const _char_type_* end, * subp;
 | |
| 
 | |
| 	if (subsz == 0) return (_char_type_*)str;
 | |
| 	if (strsz < subsz) return HAWK_NULL;
 | |
| 	
 | |
| 	end = str + strsz - subsz;
 | |
| 	subp = sub + subsz;
 | |
| 
 | |
| 	if (HAWK_UNLIKELY(ignorecase))
 | |
| 	{
 | |
| 		while (str <= end) 
 | |
| 		{
 | |
| 			const _char_type_* x = str;
 | |
| 			const _char_type_* y = sub;
 | |
| 
 | |
| 			while (1)
 | |
| 			{
 | |
| 				if (y >= subp) return (_char_type_*)str;
 | |
| 				if (_to_lower_()(*x) != _to_lower_()(*y)) break;
 | |
| 				x++; y++;
 | |
| 			}
 | |
| 
 | |
| 			str++;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		while (str <= end) 
 | |
| 		{
 | |
| 			const _char_type_* x = str;
 | |
| 			const _char_type_* y = sub;
 | |
| 
 | |
| 			while (1)
 | |
| 			{
 | |
| 				if (y >= subp) return (_char_type_*)str;
 | |
| 				if (*x != *y) break;
 | |
| 				x++; y++;
 | |
| 			}
 | |
| 
 | |
| 			str++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_rfind_chars_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t strsz, const _char_type_* sub, hawk_oow_t subsz, int ignorecase)
 | |
| {
 | |
| 	const _char_type_* p = str + strsz;
 | |
| 	const _char_type_* subp = sub + subsz;
 | |
| 
 | |
| 	if (subsz == 0) return (_char_type_*)p;
 | |
| 	if (strsz < subsz) return HAWK_NULL;
 | |
| 
 | |
| 	p = p - subsz;
 | |
| 
 | |
| 	if (HAWK_UNLIKELY(ignorecase))
 | |
| 	{
 | |
| 		while (p >= str) 
 | |
| 		{
 | |
| 			const _char_type_* x = p;
 | |
| 			const _char_type_* y = sub;
 | |
| 
 | |
| 			while (1) 
 | |
| 			{
 | |
| 				if (y >= subp) return (_char_type_*)p;
 | |
| 				if (_to_lower_()(*x) != _to_lower_()(*y)) break;
 | |
| 				x++; y++;
 | |
| 			}
 | |
| 
 | |
| 			p--;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		while (p >= str) 
 | |
| 		{
 | |
| 			const _char_type_* x = p;
 | |
| 			const _char_type_* y = sub;
 | |
| 
 | |
| 			while (1) 
 | |
| 			{
 | |
| 				if (y >= subp) return (_char_type_*)p;
 | |
| 				if (*x != *y) break;
 | |
| 				x++; y++;
 | |
| 			}	
 | |
| 
 | |
| 			p--;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return HAWK_NULL;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_compact_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* str, hawk_oow_t len)
 | |
| {
 | |
| 	_char_type_* p = str, * q = str, * end = str + len;
 | |
| 	int followed_by_space = 0;
 | |
| 	int state = 0;
 | |
| 
 | |
| 	while (p < end) 
 | |
| 	{
 | |
| 		if (state == 0) 
 | |
| 		{
 | |
| 			if (!_is_space_()(*p)) 
 | |
| 			{
 | |
| 				*q++ = *p;
 | |
| 				state = 1;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (state == 1) 
 | |
| 		{
 | |
| 			if (_is_space_()(*p)) 
 | |
| 			{
 | |
| 				if (!followed_by_space) 
 | |
| 				{
 | |
| 					followed_by_space = 1;
 | |
| 					*q++ = *p;
 | |
| 				}
 | |
| 			}
 | |
| 			else 
 | |
| 			{
 | |
| 				followed_by_space = 0;
 | |
| 				*q++ = *p;	
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		p++;
 | |
| 	}
 | |
| 
 | |
| 	return (followed_by_space) ? (q - str -1): (q - str);
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_rotate_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl
 | |
| hawk_oow_t _fn_name_ (_char_type_* str, hawk_oow_t len, int dir, hawk_oow_t n)
 | |
| {
 | |
| 	hawk_oow_t first, last, count, index, nk;
 | |
| 	_char_type_ c;
 | |
| 
 | |
| 	if (dir == 0 || len == 0) return len;
 | |
| 	if ((n %= len) == 0) return len;
 | |
| 
 | |
| 	if (dir > 0) n = len - n;
 | |
| 	first = 0; nk = len - n; count = 0;
 | |
| 
 | |
| 	while (count < n)
 | |
| 	{
 | |
| 		last = first + nk;
 | |
| 		index = first;
 | |
| 		c = str[first];
 | |
| 		do
 | |
| 		{
 | |
| 			count++;
 | |
| 			while (index < nk)
 | |
| 			{
 | |
| 				str[index] = str[index + n];
 | |
| 				index += n;
 | |
| 			}
 | |
| 			if (index == last) break;
 | |
| 			str[index] = str[index - nk];
 | |
| 			index -= nk;
 | |
| 		}
 | |
| 		while (1);
 | |
| 		str[last] = c; first++;
 | |
| 	}
 | |
| 	return len;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_trim_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)pushdef([[_prefix_]], $4)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t* len, int flags)
 | |
| {
 | |
| 	const _char_type_* p = str, * end = str + *len;
 | |
| 
 | |
| 	if (p < end)
 | |
| 	{
 | |
| 		const _char_type_* s = HAWK_NULL, * e = HAWK_NULL;
 | |
| 
 | |
| 		do
 | |
| 		{
 | |
| 			if (!_is_space_()(*p))
 | |
| 			{
 | |
| 				if (s == HAWK_NULL) s = p;
 | |
| 				e = p;
 | |
| 			}
 | |
| 			p++;
 | |
| 		}
 | |
| 		while (p < end);
 | |
| 
 | |
| 		if (e)
 | |
| 		{
 | |
| 			if (flags & _prefix_()_RIGHT) 
 | |
| 			{
 | |
| 				*len -= end - e - 1;
 | |
| 			}
 | |
| 			if (flags & _prefix_()_LEFT) 
 | |
| 			{
 | |
| 				*len -= s - str;
 | |
| 				str = s;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			/* the entire string need to be deleted */
 | |
| 			if ((flags & _prefix_()_RIGHT) || 
 | |
| 			    (flags & _prefix_()_LEFT)) *len = 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return (_char_type_*)str;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_split_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)pushdef([[_copy_str_unlimited_]], $4)dnl
 | |
| int _fn_name_ (_char_type_* s, const _char_type_* delim, _char_type_ lquote, _char_type_ rquote, _char_type_ escape)
 | |
| {
 | |
| 	_char_type_* p = s, *d;
 | |
| 	_char_type_* sp = HAWK_NULL, * ep = HAWK_NULL;
 | |
| 	int delim_mode;
 | |
| 	int cnt = 0;
 | |
| 
 | |
| 	if (delim == HAWK_NULL) delim_mode = 0;
 | |
| 	else 
 | |
| 	{
 | |
| 		delim_mode = 1;
 | |
| 		for (d = (_char_type_*)delim; *d != '\0'; d++)
 | |
| 			if (!_is_space_()(*d)) delim_mode = 2;
 | |
| 	}
 | |
| 
 | |
| 	if (delim_mode == 0) 
 | |
| 	{
 | |
| 		/* skip preceding space characters */
 | |
| 		while (_is_space_()(*p)) p++;
 | |
| 
 | |
| 		/* when 0 is given as "delim", it has an effect of cutting
 | |
| 		   preceding and trailing space characters off "s". */
 | |
| 		if (lquote != '\0' && *p == lquote) 
 | |
| 		{
 | |
| 			_copy_str_unlimited_ (p, p + 1);
 | |
| 
 | |
| 			for (;;) 
 | |
| 			{
 | |
| 				if (*p == '\0') return -1;
 | |
| 
 | |
| 				if (escape != '\0' && *p == escape) 
 | |
| 				{
 | |
| 					_copy_str_unlimited_ (p, p + 1);
 | |
| 				}
 | |
| 				else 
 | |
| 				{
 | |
| 					if (*p == rquote) 
 | |
| 					{
 | |
| 						p++;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				if (sp == 0) sp = p;
 | |
| 				ep = p;
 | |
| 				p++;
 | |
| 			}
 | |
| 			while (_is_space_()(*p)) p++;
 | |
| 			if (*p != '\0') return -1;
 | |
| 
 | |
| 			if (sp == 0 && ep == 0) s[0] = '\0';
 | |
| 			else 
 | |
| 			{
 | |
| 				ep[1] = '\0';
 | |
| 				if (s != (_char_type_*)sp) _copy_str_unlimited_ (s, sp);
 | |
| 				cnt++;
 | |
| 			}
 | |
| 		}
 | |
| 		else 
 | |
| 		{
 | |
| 			while (*p) 
 | |
| 			{
 | |
| 				if (!_is_space_()(*p)) 
 | |
| 				{
 | |
| 					if (sp == 0) sp = p;
 | |
| 					ep = p;
 | |
| 				}
 | |
| 				p++;
 | |
| 			}
 | |
| 
 | |
| 			if (sp == 0 && ep == 0) s[0] = '\0';
 | |
| 			else 
 | |
| 			{
 | |
| 				ep[1] = '\0';
 | |
| 				if (s != (_char_type_*)sp) _copy_str_unlimited_ (s, sp);
 | |
| 				cnt++;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else if (delim_mode == 1) 
 | |
| 	{
 | |
| 		_char_type_* o;
 | |
| 
 | |
| 		while (*p) 
 | |
| 		{
 | |
| 			o = p;
 | |
| 			while (_is_space_()(*p)) p++;
 | |
| 			if (o != p) { _copy_str_unlimited_ (o, p); p = o; }
 | |
| 
 | |
| 			if (lquote != '\0' && *p == lquote) 
 | |
| 			{
 | |
| 				_copy_str_unlimited_ (p, p + 1);
 | |
| 
 | |
| 				for (;;) 
 | |
| 				{
 | |
| 					if (*p == '\0') return -1;
 | |
| 
 | |
| 					if (escape != '\0' && *p == escape) 
 | |
| 					{
 | |
| 						_copy_str_unlimited_ (p, p + 1);
 | |
| 					}
 | |
| 					else 
 | |
| 					{
 | |
| 						if (*p == rquote) 
 | |
| 						{
 | |
| 							*p++ = '\0';
 | |
| 							cnt++;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 					p++;
 | |
| 				}
 | |
| 			}
 | |
| 			else 
 | |
| 			{
 | |
| 				o = p;
 | |
| 				for (;;) 
 | |
| 				{
 | |
| 					if (*p == '\0') 
 | |
| 					{
 | |
| 						if (o != p) cnt++;
 | |
| 						break;
 | |
| 					}
 | |
| 					if (_is_space_()(*p)) 
 | |
| 					{
 | |
| 						*p++ = '\0';
 | |
| 						cnt++;
 | |
| 						break;
 | |
| 					}
 | |
| 					p++;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else /* if (delim_mode == 2) */
 | |
| 	{
 | |
| 		_char_type_* o;
 | |
| 		int ok;
 | |
| 
 | |
| 		while (*p != '\0') 
 | |
| 		{
 | |
| 			o = p;
 | |
| 			while (_is_space_()(*p)) p++;
 | |
| 			if (o != p) { _copy_str_unlimited_ (o, p); p = o; }
 | |
| 
 | |
| 			if (lquote != '\0' && *p == lquote) 
 | |
| 			{
 | |
| 				_copy_str_unlimited_ (p, p + 1);
 | |
| 
 | |
| 				for (;;) 
 | |
| 				{
 | |
| 					if (*p == '\0') return -1;
 | |
| 
 | |
| 					if (escape != '\0' && *p == escape) 
 | |
| 					{
 | |
| 						_copy_str_unlimited_ (p, p + 1);
 | |
| 					}
 | |
| 					else 
 | |
| 					{
 | |
| 						if (*p == rquote) 
 | |
| 						{
 | |
| 							*p++ = '\0';
 | |
| 							cnt++;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 					p++;
 | |
| 				}
 | |
| 
 | |
| 				ok = 0;
 | |
| 				while (_is_space_()(*p)) p++;
 | |
| 				if (*p == '\0') ok = 1;
 | |
| 				for (d = (_char_type_*)delim; *d != '\0'; d++) 
 | |
| 				{
 | |
| 					if (*p == *d) 
 | |
| 					{
 | |
| 						ok = 1;
 | |
| 						_copy_str_unlimited_ (p, p + 1);
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 				if (ok == 0) return -1;
 | |
| 			}
 | |
| 			else 
 | |
| 			{
 | |
| 				o = p; sp = ep = 0;
 | |
| 
 | |
| 				for (;;) 
 | |
| 				{
 | |
| 					if (*p == '\0') 
 | |
| 					{
 | |
| 						if (ep) 
 | |
| 						{
 | |
| 							ep[1] = '\0';
 | |
| 							p = &ep[1];
 | |
| 						}
 | |
| 						cnt++;
 | |
| 						break;
 | |
| 					}
 | |
| 					for (d = (_char_type_*)delim; *d != '\0'; d++) 
 | |
| 					{
 | |
| 						if (*p == *d)  
 | |
| 						{
 | |
| 							if (sp == HAWK_NULL) 
 | |
| 							{
 | |
| 								_copy_str_unlimited_ (o, p); p = o;
 | |
| 								*p++ = '\0';
 | |
| 							}
 | |
| 							else 
 | |
| 							{
 | |
| 								_copy_str_unlimited_ (&ep[1], p);
 | |
| 								_copy_str_unlimited_ (o, sp);
 | |
| 								o[ep - sp + 1] = '\0';
 | |
| 								p = &o[ep - sp + 2];
 | |
| 							}
 | |
| 							cnt++;
 | |
| 							/* last empty field after delim */
 | |
| 							if (*p == '\0') cnt++;
 | |
| 							goto exit_point;
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					if (!_is_space_()(*p)) 
 | |
| 					{
 | |
| 						if (sp == HAWK_NULL) sp = p;
 | |
| 						ep = p;
 | |
| 					}
 | |
| 					p++;
 | |
| 				}
 | |
| exit_point:
 | |
| 				;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return cnt;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])popdef([[_copy_str_unlimited_]])dnl
 | |
| ]])dnl
 | |
| define([[fn_tokenize_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_cs_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_to_lower_]], $5)dnl
 | |
| _char_type_* _fn_name_ (const _char_type_* s, hawk_oow_t len, const _char_type_* delim, hawk_oow_t delim_len, _cs_type_* tok, int ignorecase)
 | |
| {
 | |
| 	const _char_type_* p = s, *d;
 | |
| 	const _char_type_* end = s + len;
 | |
| 	const _char_type_* sp = HAWK_NULL, * ep = HAWK_NULL;
 | |
| 	const _char_type_* delim_end = delim + delim_len;
 | |
| 	_char_type_ c; 
 | |
| 	int delim_mode;
 | |
| 
 | |
| #define __DELIM_NULL      0
 | |
| #define __DELIM_EMPTY     1
 | |
| #define __DELIM_SPACES    2
 | |
| #define __DELIM_NOSPACES  3
 | |
| #define __DELIM_COMPOSITE 4
 | |
| 	if (delim == HAWK_NULL) delim_mode = __DELIM_NULL;
 | |
| 	else 
 | |
| 	{
 | |
| 		delim_mode = __DELIM_EMPTY;
 | |
| 
 | |
| 		for (d = delim; d < delim_end; d++) 
 | |
| 		{
 | |
| 			if (_is_space_()(*d)) 
 | |
| 			{
 | |
| 				if (delim_mode == __DELIM_EMPTY)
 | |
| 					delim_mode = __DELIM_SPACES;
 | |
| 				else if (delim_mode == __DELIM_NOSPACES)
 | |
| 				{
 | |
| 					delim_mode = __DELIM_COMPOSITE;
 | |
| 					break;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if (delim_mode == __DELIM_EMPTY)
 | |
| 					delim_mode = __DELIM_NOSPACES;
 | |
| 				else if (delim_mode == __DELIM_SPACES)
 | |
| 				{
 | |
| 					delim_mode = __DELIM_COMPOSITE;
 | |
| 					break;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/* TODO: verify the following statement... */
 | |
| 		if (delim_mode == __DELIM_SPACES && delim_len == 1 && delim[0] != ' ') delim_mode = __DELIM_NOSPACES;
 | |
| 	}		
 | |
| 	
 | |
| 	if (delim_mode == __DELIM_NULL) 
 | |
| 	{ 
 | |
| 		/* when HAWK_NULL is given as "delim", it trims off the 
 | |
| 		 * leading and trailing spaces characters off the source
 | |
| 		 * string "s" eventually. */
 | |
| 
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 		while (p < end) 
 | |
| 		{
 | |
| 			c = *p;
 | |
| 
 | |
| 			if (!_is_space_()(c)) 
 | |
| 			{
 | |
| 				if (sp == HAWK_NULL) sp = p;
 | |
| 				ep = p;
 | |
| 			}
 | |
| 			p++;
 | |
| 		}
 | |
| 	}
 | |
| 	else if (delim_mode == __DELIM_EMPTY)
 | |
| 	{
 | |
| 		/* each character in the source string "s" becomes a token. */
 | |
| 		if (p < end)
 | |
| 		{
 | |
| 			c = *p;
 | |
| 			sp = p;
 | |
| 			ep = p++;
 | |
| 		}
 | |
| 	}
 | |
| 	else if (delim_mode == __DELIM_SPACES) 
 | |
| 	{
 | |
| 		/* each token is delimited by space characters. all leading
 | |
| 		 * and trailing spaces are removed. */
 | |
| 
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 		while (p < end) 
 | |
| 		{
 | |
| 			c = *p;
 | |
| 			if (_is_space_()(c)) break;
 | |
| 			if (sp == HAWK_NULL) sp = p;
 | |
| 			ep = p++;
 | |
| 		}
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 	}
 | |
| 	else if (delim_mode == __DELIM_NOSPACES)
 | |
| 	{
 | |
| 		/* each token is delimited by one of charaters 
 | |
| 		 * in the delimeter set "delim". */
 | |
| 		if (ignorecase)
 | |
| 		{
 | |
| 			while (p < end) 
 | |
| 			{
 | |
| 				c = _to_lower_()(*p);
 | |
| 				for (d = delim; d < delim_end; d++) 
 | |
| 				{
 | |
| 					if (c == _to_lower_()(*d)) goto exit_loop;
 | |
| 				}
 | |
| 
 | |
| 				if (sp == HAWK_NULL) sp = p;
 | |
| 				ep = p++;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			while (p < end) 
 | |
| 			{
 | |
| 				c = *p;
 | |
| 				for (d = delim; d < delim_end; d++) 
 | |
| 				{
 | |
| 					if (c == *d) goto exit_loop;
 | |
| 				}
 | |
| 
 | |
| 				if (sp == HAWK_NULL) sp = p;
 | |
| 				ep = p++;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else /* if (delim_mode == __DELIM_COMPOSITE) */ 
 | |
| 	{
 | |
| 		/* each token is delimited by one of non-space charaters
 | |
| 		 * in the delimeter set "delim". however, all space characters
 | |
| 		 * surrounding the token are removed */
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 		if (ignorecase)
 | |
| 		{
 | |
| 			while (p < end) 
 | |
| 			{
 | |
| 				c = _to_lower_()(*p);
 | |
| 				if (_is_space_()(c)) 
 | |
| 				{
 | |
| 					p++;
 | |
| 					continue;
 | |
| 				}
 | |
| 				for (d = delim; d < delim_end; d++) 
 | |
| 				{
 | |
| 					if (c == _to_lower_()(*d)) goto exit_loop;
 | |
| 				}
 | |
| 				if (sp == HAWK_NULL) sp = p;
 | |
| 				ep = p++;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			while (p < end) 
 | |
| 			{
 | |
| 				c = *p;
 | |
| 				if (_is_space_()(c)) 
 | |
| 				{
 | |
| 					p++;
 | |
| 					continue;
 | |
| 				}
 | |
| 				for (d = delim; d < delim_end; d++) 
 | |
| 				{
 | |
| 					if (c == *d) goto exit_loop;
 | |
| 				}
 | |
| 				if (sp == HAWK_NULL) sp = p;
 | |
| 				ep = p++;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| exit_loop:
 | |
| 	if (sp == HAWK_NULL) 
 | |
| 	{
 | |
| 		tok->ptr = HAWK_NULL;
 | |
| 		tok->len = (hawk_oow_t)0;
 | |
| 	}
 | |
| 	else 
 | |
| 	{
 | |
| 		tok->ptr = (_char_type_*)sp;
 | |
| 		tok->len = ep - sp + 1;
 | |
| 	}
 | |
| 
 | |
| 	/* if HAWK_NULL is returned, this function should not be called again */
 | |
| 	if (p >= end) return HAWK_NULL;
 | |
| 	if (delim_mode == __DELIM_EMPTY || delim_mode == __DELIM_SPACES) return (_char_type_*)p;
 | |
| 	return (_char_type_*)++p;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])popdef([[_is_space_]])popdef([[_to_lower_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_byte_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_prefix_]], $3)dnl
 | |
| hawk_oow_t _fn_name_ (hawk_uint8_t byte, _char_type_* buf, hawk_oow_t size, int flagged_radix, _char_type_ fill)
 | |
| {
 | |
| 	_char_type_ tmp[(HAWK_SIZEOF(hawk_uint8_t) * HAWK_BITS_PER_BYTE)];
 | |
| 	_char_type_* p = tmp, * bp = buf, * be = buf + size - 1;
 | |
| 	int radix;
 | |
| 	_char_type_ radix_char;
 | |
| 
 | |
| 	radix = (flagged_radix & _prefix_()_RADIXMASK);
 | |
| 	radix_char = (flagged_radix & _prefix_()_LOWERCASE)? 'a': 'A';
 | |
| 	if (radix < 2 || radix > 36 || size <= 0) return 0;
 | |
| 
 | |
| 	do 
 | |
| 	{
 | |
| 		hawk_uint8_t digit = byte % radix;
 | |
| 		if (digit < 10) *p++ = digit + '0';
 | |
| 		else *p++ = digit + radix_char - 10;
 | |
| 		byte /= radix;
 | |
| 	}
 | |
| 	while (byte > 0);
 | |
| 
 | |
| 	if (fill != '\0') 
 | |
| 	{
 | |
| 		while (size - 1 > p - tmp) 
 | |
| 		{
 | |
| 			*bp++ = fill;
 | |
| 			size--;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	while (p > tmp && bp < be) *bp++ = *--p;
 | |
| 	*bp = '\0';
 | |
| 	return bp - buf;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])popdef([[_prefix_]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| ]])dnl
 | |
| define([[fn_int_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_count_cstr_]], $4)dnl
 | |
| hawk_oow_t _fn_name_ (_int_type_ value, int radix, const _char_type_* prefix, _char_type_* buf, hawk_oow_t size)
 | |
| {
 | |
| 	_int_type_ t, rem;
 | |
| 	hawk_oow_t len, ret, i;
 | |
| 	hawk_oow_t prefix_len;
 | |
| 
 | |
| 	prefix_len = (prefix != HAWK_NULL)? _count_cstr_()(prefix): 0;
 | |
| 
 | |
| 	t = value;
 | |
| 	if (t == 0)
 | |
| 	{
 | |
| 		/* zero */
 | |
| 		if (buf == HAWK_NULL) 
 | |
| 		{
 | |
| 			/* if buf is not given, 
 | |
| 			 * return the number of bytes required */
 | |
| 			return prefix_len + 1;
 | |
| 		}
 | |
| 
 | |
| 		if (size < prefix_len+1) 
 | |
| 		{
 | |
| 			/* buffer too small */
 | |
| 			return (hawk_oow_t)-1;
 | |
| 		}
 | |
| 
 | |
| 		for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
 | |
| 		buf[prefix_len] = '0';
 | |
| 		if (size > prefix_len+1) buf[prefix_len+1] = '\0';
 | |
| 		return prefix_len+1;
 | |
| 	}
 | |
| 
 | |
| 	/* non-zero values */
 | |
| 	len = prefix_len;
 | |
| 	if (t < 0) { t = -t; len++; }
 | |
| 	while (t > 0) { len++; t /= radix; }
 | |
| 
 | |
| 	if (buf == HAWK_NULL)
 | |
| 	{
 | |
| 		/* if buf is not given, return the number of bytes required */
 | |
| 		return len;
 | |
| 	}
 | |
| 
 | |
| 	if (size < len) return (hawk_oow_t)-1; /* buffer too small */
 | |
| 	if (size > len) buf[len] = '\0';
 | |
| 	ret = len;
 | |
| 
 | |
| 	t = value;
 | |
| 	if (t < 0) t = -t;
 | |
| 
 | |
| 	while (t > 0) 
 | |
| 	{
 | |
| 		rem = t % radix;
 | |
| 		if (rem >= 10)
 | |
| 			buf[--len] = (_char_type_)rem + 'a' - 10;
 | |
| 		else
 | |
| 			buf[--len] = (_char_type_)rem + '0';
 | |
| 		t /= radix;
 | |
| 	}
 | |
| 
 | |
| 	if (value < 0) 
 | |
| 	{
 | |
| 		for (i = 1; i <= prefix_len; i++) 
 | |
| 		{
 | |
| 			buf[i] = prefix[i-1];
 | |
| 			len--;
 | |
| 		}
 | |
| 		buf[--len] = '-';
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
 | |
| 	}
 | |
| 
 | |
| 	return ret;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_count_cstr_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_chars_to_int]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_prefix_]], $5)dnl
 | |
| _int_type_ _fn_name_ (const _char_type_* str, hawk_oow_t len, int option, const _char_type_** endptr, int* is_sober)
 | |
| {
 | |
| 	_int_type_ n = 0;
 | |
| 	const _char_type_* p, * pp;
 | |
| 	const _char_type_* end;
 | |
| 	hawk_oow_t rem;
 | |
| 	int digit, negative = 0;
 | |
| 	int base = _prefix_()_GET_OPTION_BASE(option);
 | |
| 
 | |
| 	p = str; 
 | |
| 	end = str + len;
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_LTRIM(option))
 | |
| 	{
 | |
| 		/* strip off leading spaces */
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 	}
 | |
| 
 | |
| 	/* check for a sign */
 | |
| 	while (p < end)
 | |
| 	{
 | |
| 		if (*p == '-') 
 | |
| 		{
 | |
| 			negative = ~negative;
 | |
| 			p++;
 | |
| 		}
 | |
| 		else if (*p == '+') p++;
 | |
| 		else break;
 | |
| 	}
 | |
| 
 | |
| 	/* check for a binary/octal/hexadecimal notation */
 | |
| 	rem = end - p;
 | |
| 	if (base == 0) 
 | |
| 	{
 | |
| 		if (rem >= 1 && *p == '0') 
 | |
| 		{
 | |
| 			p++;
 | |
| 
 | |
| 			if (rem == 1) base = 8;
 | |
| 			else if (*p == 'x' || *p == 'X')
 | |
| 			{
 | |
| 				p++; base = 16;
 | |
| 			} 
 | |
| 			else if (*p == 'b' || *p == 'B')
 | |
| 			{
 | |
| 				p++; base = 2;
 | |
| 			}
 | |
| 			else base = 8;
 | |
| 		}
 | |
| 		else base = 10;
 | |
| 	} 
 | |
| 	else if (rem >= 2 && base == 16)
 | |
| 	{
 | |
| 		if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; 
 | |
| 	}
 | |
| 	else if (rem >= 2 && base == 2)
 | |
| 	{
 | |
| 		if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; 
 | |
| 	}
 | |
| 
 | |
| 	/* process the digits */
 | |
| 	pp = p;
 | |
| 	while (p < end)
 | |
| 	{
 | |
| 		digit = HAWK_ZDIGIT_TO_NUM(*p, base);
 | |
| 		if (digit >= base) break;
 | |
| 		n = n * base + digit;
 | |
| 		p++;
 | |
| 	}
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_E(option))
 | |
| 	{
 | |
| 		if (*p == 'E' || *p == 'e')
 | |
| 		{
 | |
| 			_int_type_ e = 0, i;
 | |
| 			int e_neg = 0;
 | |
| 			p++;
 | |
| 			if (*p == '+')
 | |
| 			{
 | |
| 				p++;
 | |
| 			}
 | |
| 			else if (*p == '-')
 | |
| 			{
 | |
| 				p++; e_neg = 1;
 | |
| 			}
 | |
| 			while (p < end)
 | |
| 			{
 | |
| 				digit = HAWK_ZDIGIT_TO_NUM(*p, base);
 | |
| 				if (digit >= base) break;
 | |
| 				e = e * base + digit;
 | |
| 				p++;
 | |
| 			}
 | |
| 			if (e_neg)
 | |
| 				for (i = 0; i < e; i++) n /= 10;
 | |
| 			else
 | |
| 				for (i = 0; i < e; i++) n *= 10;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* base 8: at least a zero digit has been seen.
 | |
| 	 * other case: p > pp to be able to have at least 1 meaningful digit. */
 | |
| 	if (is_sober) *is_sober = (base == 8 || p > pp); 
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_RTRIM(option))
 | |
| 	{
 | |
| 		/* consume trailing spaces */
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 	}
 | |
| 
 | |
| 	if (endptr) *endptr = p;
 | |
| 	return (negative)? -n: n;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl
 | |
| ]])dnl
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_chars_to_uint]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_prefix_]], $5)dnl
 | |
| _int_type_ _fn_name_ (const _char_type_* str, hawk_oow_t len, int option, const _char_type_** endptr, int* is_sober)
 | |
| {
 | |
| 	_int_type_ n = 0;
 | |
| 	const _char_type_* p, * pp;
 | |
| 	const _char_type_* end;
 | |
| 	hawk_oow_t rem;
 | |
| 	int digit;
 | |
| 	int base = _prefix_()_GET_OPTION_BASE(option);
 | |
| 
 | |
| 	p = str; 
 | |
| 	end = str + len;
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_LTRIM(option))
 | |
| 	{
 | |
| 		/* strip off leading spaces */
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 	}
 | |
| 
 | |
| 	/* check for a sign */
 | |
| 	while (p < end)
 | |
| 	{
 | |
| 		if (*p == '+') p++;
 | |
| 		else break;
 | |
| 	}
 | |
| 
 | |
| 	/* check for a binary/octal/hexadecimal notation */
 | |
| 	rem = end - p;
 | |
| 	if (base == 0) 
 | |
| 	{
 | |
| 		if (rem >= 1 && *p == '0') 
 | |
| 		{
 | |
| 			p++;
 | |
| 
 | |
| 			if (rem == 1) base = 8;
 | |
| 			else if (*p == 'x' || *p == 'X')
 | |
| 			{
 | |
| 				p++; base = 16;
 | |
| 			} 
 | |
| 			else if (*p == 'b' || *p == 'B')
 | |
| 			{
 | |
| 				p++; base = 2;
 | |
| 			}
 | |
| 			else base = 8;
 | |
| 		}
 | |
| 		else base = 10;
 | |
| 	} 
 | |
| 	else if (rem >= 2 && base == 16)
 | |
| 	{
 | |
| 		if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; 
 | |
| 	}
 | |
| 	else if (rem >= 2 && base == 2)
 | |
| 	{
 | |
| 		if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; 
 | |
| 	}
 | |
| 
 | |
| 	/* process the digits */
 | |
| 	pp = p;
 | |
| 	while (p < end)
 | |
| 	{
 | |
| 		digit = HAWK_ZDIGIT_TO_NUM(*p, base);
 | |
| 		if (digit >= base) break;
 | |
| 		n = n * base + digit;
 | |
| 		p++;
 | |
| 	}
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_E(option))
 | |
| 	{
 | |
| 		if (*p == 'E' || *p == 'e')
 | |
| 		{
 | |
| 			_int_type_ e = 0, i;
 | |
| 			int e_neg = 0;
 | |
| 			p++;
 | |
| 			if (*p == '+')
 | |
| 			{
 | |
| 				p++;
 | |
| 			}
 | |
| 			else if (*p == '-')
 | |
| 			{
 | |
| 				p++; e_neg = 1;
 | |
| 			}
 | |
| 			while (p < end)
 | |
| 			{
 | |
| 				digit = HAWK_ZDIGIT_TO_NUM(*p, base);
 | |
| 				if (digit >= base) break;
 | |
| 				e = e * base + digit;
 | |
| 				p++;
 | |
| 			}
 | |
| 			if (e_neg)
 | |
| 				for (i = 0; i < e; i++) n /= 10;
 | |
| 			else
 | |
| 				for (i = 0; i < e; i++) n *= 10;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* base 8: at least a zero digit has been seen.
 | |
| 	 * other case: p > pp to be able to have at least 1 meaningful digit. */
 | |
| 	if (is_sober) *is_sober = (base == 8 || p > pp); 
 | |
| 
 | |
| 	if (_prefix_()_GET_OPTION_RTRIM(option))
 | |
| 	{
 | |
| 		/* consume trailing spaces */
 | |
| 		while (p < end && _is_space_()(*p)) p++;
 | |
| 	}
 | |
| 
 | |
| 	if (endptr) *endptr = p;
 | |
| 	return n;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl
 | |
| ]])
 | |
| dnl ---------------------------------------------------------------------------
 | |
| define([[fn_fnmat]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)pushdef([[_match_ch_class_]], $4)dnl
 | |
| int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn, hawk_oow_t plen, int flags, int no_first_period)
 | |
| {
 | |
| 	const _char_type_* sp = str;
 | |
| 	const _char_type_* pp = ptn;
 | |
| 	const _char_type_* se = str + slen;
 | |
| 	const _char_type_* pe = ptn + plen;
 | |
| 	_char_type_ sc, pc, pc2;
 | |
| 
 | |
| 	while (1) 
 | |
| 	{
 | |
| 		if (pp < pe && HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) 
 | |
| 		{
 | |
| 			/* pattern is escaped and escaping is allowed. */
 | |
| 
 | |
| 			if ((++pp) >= pe) 
 | |
| 			{
 | |
| 				/* 
 | |
| 				 * the last character of the pattern is an WCS_ESC. 
 | |
| 				 * matching is performed as if the end of the pattern is
 | |
| 				 * reached just without an WCS_ESC.
 | |
| 				 */
 | |
| 				if (sp < se) return 0;
 | |
| 				return 1;
 | |
| 			}
 | |
| 
 | |
| 			if (sp >= se) return 0; /* premature string termination */
 | |
| 
 | |
| 			sc = *sp; pc = *pp; /* pc is just a normal character */
 | |
| 			if ((flags & HAWK_FNMAT_IGNORECASE) != 0) 
 | |
| 			{
 | |
| 				/* make characters to lower-case */
 | |
| 				sc = _to_lower_()(sc);
 | |
| 				pc = _to_lower_()(pc); 
 | |
| 			}
 | |
| 
 | |
| 			if (sc != pc) return 0;
 | |
| 			sp++; pp++; 
 | |
| 			continue;
 | |
| 		}
 | |
| 		if (pp >= pe) 
 | |
| 		{
 | |
| 			/* 
 | |
| 			 * the end of the pattern has been reached. 
 | |
| 			 * the string must terminate too.
 | |
| 			 */
 | |
| 			return sp >= se;
 | |
| 		}
 | |
| 
 | |
| 		if (sp >= se) 
 | |
| 		{
 | |
| 			/* the string terminats prematurely */
 | |
| 			while (pp < pe && *pp == '*') pp++;
 | |
| 			return pp >= pe;
 | |
| 		}
 | |
| 
 | |
| 		sc = *sp; pc = *pp;
 | |
| 
 | |
| 		if (sc == '.' && (flags & HAWK_FNMAT_PERIOD)) 
 | |
| 		{
 | |
| 			/* 
 | |
| 			 * a leading period in the staring must match 
 | |
| 			 * a period in the pattern explicitly 
 | |
| 			 */
 | |
| 			if ((!no_first_period && sp == str) || 
 | |
| 			    (HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME))) 
 | |
| 			{
 | |
| 				if (pc != '.') return 0;
 | |
| 				sp++; pp++;
 | |
| 				continue;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME)) 
 | |
| 		{
 | |
| 			while (pc == '*') 
 | |
| 			{
 | |
| 				if ((++pp) >= pe) return 0;
 | |
| 				pc = *pp;
 | |
| 			}
 | |
| 
 | |
| 			/* a path separator must be matched explicitly */
 | |
| 			if (!HAWK_FNMAT_IS_SEP(pc)) return 0;
 | |
| 			sp++; pp++;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		/* the handling of special pattern characters begins here */
 | |
| 		if (pc == '?') 
 | |
| 		{
 | |
| 			/* match any single character */
 | |
| 			sp++; pp++; 
 | |
| 		} 
 | |
| 		else if (pc == '*') 
 | |
| 		{ 
 | |
| 			/* match zero or more characters */
 | |
| 
 | |
| 			/* compact asterisks */
 | |
| 			do { pp++; } while (pp < pe && *pp == '*');
 | |
| 
 | |
| 			if (pp >= pe) 
 | |
| 			{
 | |
| 				/* 
 | |
| 				 * if the last character in the pattern is an asterisk,
 | |
| 				 * the string should not have any directory separators
 | |
| 				 * when HAWK_FNMAT_PATHNAME is set.
 | |
| 				 */
 | |
| 				if (flags & HAWK_FNMAT_PATHNAME)
 | |
| 				{
 | |
| 					const _char_type_* s = sp;
 | |
| 					for (s = sp; s < se; s++)
 | |
| 					{
 | |
| 						if (HAWK_FNMAT_IS_SEP(*s)) return 0;
 | |
| 					}
 | |
| 				}
 | |
| 				return 1;
 | |
| 			}
 | |
| 			else 
 | |
| 			{
 | |
| 				do 
 | |
| 				{
 | |
| 					if (_fn_name_()(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
 | |
| 					if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
 | |
| 					sp++;
 | |
| 				} 
 | |
| 				while (sp < se);
 | |
| 
 | |
| 				return 0;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (pc == '[') 
 | |
| 		{
 | |
| 			/* match range */
 | |
| 			int negate = 0;
 | |
| 			int matched = 0;
 | |
| 
 | |
| 			if ((++pp) >= pe) return 0;
 | |
| 			if (*pp == '!') { negate = 1; pp++; } 
 | |
| 
 | |
| 			while (pp < pe && *pp != ']') 
 | |
| 			{
 | |
| 				if (*pp == '[') 
 | |
| 				{
 | |
| 					hawk_oow_t pl = pe - pp;
 | |
| 
 | |
| 					if (pl >= 9)  /* assumption that [:class:] is at least 9 in _match_ch_class_ */
 | |
| 					{
 | |
| 						int x = _match_ch_class_()(pp, sc, &matched);
 | |
| 						if (x > 0)
 | |
| 						{
 | |
| 							pp += x;
 | |
| 							continue;
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					/* 
 | |
| 					 * characters in an invalid class name are 
 | |
| 					 * just treated as normal characters 
 | |
| 					 */
 | |
| 				}
 | |
| 
 | |
| 				if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) pp++;
 | |
| 				else if (*pp == ']') break;
 | |
| 
 | |
| 				if (pp >= pe) break;
 | |
| 
 | |
| 				pc = *pp;
 | |
| 				if ((flags & HAWK_FNMAT_IGNORECASE) != 0) 
 | |
| 				{
 | |
| 					sc = _to_lower_()(sc); 
 | |
| 					pc = _to_lower_()(pc); 
 | |
| 				}
 | |
| 
 | |
| 				if (pp + 1 < pe && pp[1] == '-') 
 | |
| 				{
 | |
| 					pp += 2; /* move the a character next to a dash */
 | |
| 
 | |
| 					if (pp >= pe) 
 | |
| 					{
 | |
| 						if (sc >= pc) matched = 1;
 | |
| 						break;
 | |
| 					}
 | |
| 
 | |
| 					if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) 
 | |
| 					{
 | |
| 						if ((++pp) >= pe) 
 | |
| 						{
 | |
| 							if (sc >= pc) matched = 1;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 					else if (*pp == ']') 
 | |
| 					{
 | |
| 						if (sc >= pc) matched = 1;
 | |
| 						break;
 | |
| 					}
 | |
| 
 | |
| 					pc2 = *pp;
 | |
| 					if ((flags & HAWK_FNMAT_IGNORECASE) != 0) 
 | |
| 						pc2 = _to_lower_()(pc2); 
 | |
| 
 | |
| 					if (sc >= pc && sc <= pc2) matched = 1;
 | |
| 					pp++;
 | |
| 				}
 | |
| 				else 
 | |
| 				{
 | |
| 					if (sc == pc) matched = 1;
 | |
| 					pp++;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (negate) matched = !matched;
 | |
| 			if (!matched) return 0;
 | |
| 			sp++; if (pp < pe) pp++;
 | |
| 		}
 | |
| 		else 
 | |
| 		{
 | |
| 			/* a normal character */
 | |
| 			if ((flags & HAWK_FNMAT_IGNORECASE) != 0) 
 | |
| 			{
 | |
| 				sc = _to_lower_()(sc); 
 | |
| 				pc = _to_lower_()(pc); 
 | |
| 			}
 | |
| 
 | |
| 			if (sc != pc) return 0;
 | |
| 			sp++; pp++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* will never reach here. but make some immature compilers happy... */
 | |
| 	return 0;
 | |
| }
 | |
| popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_match_ch_class_]])dnl
 | |
| ]])
 |