| 
									
										
										
										
											2006-07-17 06:21:39 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  |  * $Id: rex.c,v 1.33 2006-10-04 10:11:04 bacon Exp $ | 
					
						
							| 
									
										
										
										
											2006-07-17 06:21:39 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <xp/awk/awk_i.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	CT_EOF, | 
					
						
							|  |  |  | 	CT_SPECIAL, | 
					
						
							|  |  |  | 	CT_NORMAL | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	LEVEL_TOP, | 
					
						
							|  |  |  | 	LEVEL_CHARSET, | 
					
						
							|  |  |  | 	LEVEL_RANGE, | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-17 14:27:09 +00:00
										 |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	CMD_BOL, | 
					
						
							|  |  |  | 	CMD_EOL, | 
					
						
							| 
									
										
										
										
											2006-07-17 14:27:09 +00:00
										 |  |  | 	CMD_ANY_CHAR, | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	CMD_ORD_CHAR, | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	CMD_CHARSET, | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	CMD_GROUP | 
					
						
							| 
									
										
										
										
											2006-07-17 14:27:09 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	CHARSET_ONE, | 
					
						
							|  |  |  | 	CHARSET_RANGE, | 
					
						
							|  |  |  | 	CHARSET_CLASS | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CHARSET_CLASS_PUNCT, | 
					
						
							|  |  |  | 	CHARSET_CLASS_SPACE, | 
					
						
							|  |  |  | 	CHARSET_CLASS_DIGIT, | 
					
						
							|  |  |  | 	CHARSET_CLASS_ALNUM | 
					
						
							| 
									
										
										
										
											2006-07-17 14:27:09 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 09:35:21 +00:00
										 |  |  | #ifdef _MSC_VER
 | 
					
						
							|  |  |  | #pragma warning (disable: 4296)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 15:21:17 +00:00
										 |  |  | #define DEF_CODE_CAPA 512
 | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | #define BOUND_MIN 0
 | 
					
						
							|  |  |  | #define BOUND_MAX (XP_TYPE_MAX(xp_size_t))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | typedef struct __builder_t __builder_t; | 
					
						
							|  |  |  | typedef struct __matcher_t __matcher_t; | 
					
						
							|  |  |  | typedef struct __match_t __match_t; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | struct __code_t | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	//xp_byte_t cmd;
 | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	short cmd; | 
					
						
							|  |  |  | 	short negate; /* only for CMD_CHARSET */ | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	xp_size_t lbound; | 
					
						
							|  |  |  | 	xp_size_t ubound; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | struct __builder_t | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	xp_awk_t* awk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		const xp_char_t* ptr; | 
					
						
							|  |  |  | 		const xp_char_t* end; | 
					
						
							|  |  |  | 		const xp_char_t* curp; | 
					
						
							|  |  |  | 		struct | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int type; | 
					
						
							|  |  |  | 			xp_char_t value; | 
					
						
							|  |  |  | 		} curc; | 
					
						
							|  |  |  | 	} ptn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_byte_t* buf; | 
					
						
							|  |  |  | 		xp_size_t  size; | 
					
						
							|  |  |  | 		xp_size_t  capa; | 
					
						
							|  |  |  | 	} code;	 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int max; | 
					
						
							|  |  |  | 		int cur; | 
					
						
							|  |  |  | 	} depth; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	int errnum; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | struct __matcher_t | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	xp_awk_t* awk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		struct | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			const xp_char_t* ptr; | 
					
						
							|  |  |  | 			const xp_char_t* end; | 
					
						
							|  |  |  | 		} str; | 
					
						
							|  |  |  | 	} match; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int max; | 
					
						
							|  |  |  | 		int cur; | 
					
						
							|  |  |  | 	} depth; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	int ignorecase; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	int errnum; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | struct __match_t | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	const xp_char_t* match_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	xp_bool_t matched; | 
					
						
							|  |  |  | 	xp_size_t match_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const xp_byte_t* branch; | 
					
						
							|  |  |  | 	const xp_byte_t* branch_end; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | typedef const xp_byte_t* (*atom_matcher_t) ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | #define NCHARS_REMAINING(rex) ((rex)->ptn.end - (rex)->ptn.curp)
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | #define NEXT_CHAR(rex,level) \
 | 
					
						
							|  |  |  | 	do { if (__next_char(rex,level) == -1) return -1; } while (0) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define ADD_CODE(rex,data,len) \
 | 
					
						
							|  |  |  | 	do { if (__add_code(rex,data,len) == -1) return -1; } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | #if defined(__sparc) || defined(__sparc__)
 | 
					
						
							|  |  |  | 	#define GET_CODE(rex,pos,type) __get_code(rex,pos)
 | 
					
						
							|  |  |  | 	#define SET_CODE(rex,pos,type,code) __set_code(rex,pos,code)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	#define GET_CODE(rex,pos,type) (*((type*)&(rex)->code.buf[pos]))
 | 
					
						
							|  |  |  | 	#define SET_CODE(rex,pos,type,code) (GET_CODE(rex,pos,type) = (code))
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_pattern (__builder_t* rex); | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | static int __build_pattern0 (__builder_t* rex); | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_branch (__builder_t* rex); | 
					
						
							|  |  |  | static int __build_atom (__builder_t* rex); | 
					
						
							|  |  |  | static int __build_charset (__builder_t* rex, struct __code_t* cmd); | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | static int __build_occurrences (__builder_t* rex, struct __code_t* cmd); | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_cclass (__builder_t* rex, xp_char_t* cc); | 
					
						
							|  |  |  | static int __build_range (__builder_t* rex, struct __code_t* cmd); | 
					
						
							|  |  |  | static int __next_char (__builder_t* rex, int level); | 
					
						
							|  |  |  | static int __add_code (__builder_t* rex, void* data, xp_size_t len); | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | #if defined(__sparc) || defined(__sparc__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static xp_size_t __get_code (__builder_t* builder, xp_size_t pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xp_size_t code; | 
					
						
							|  |  |  | 	XP_AWK_MEMCPY (builder->awk,  | 
					
						
							|  |  |  | 		&code, &builder->code.buf[pos], xp_sizeof(code)); | 
					
						
							|  |  |  | 	return code; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __set_code (__builder_t* builder, xp_size_t pos, xp_size_t code) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	XP_AWK_MEMCPY (builder->awk,  | 
					
						
							|  |  |  | 		&builder->code.buf[pos], &code, xp_sizeof(code)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | static xp_bool_t __begin_with ( | 
					
						
							|  |  |  | 	const xp_char_t* str, xp_size_t len, const xp_char_t* what); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | static const xp_byte_t* __match_pattern ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_branch ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_branch_body ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | static const xp_byte_t* __match_branch_body0 ( | 
					
						
							|  |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_atom ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_bol ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_eol ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_any_char ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_ord_char ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_charset ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_group ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | static const xp_byte_t* __match_occurrences ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, xp_size_t si, const xp_byte_t* p, | 
					
						
							|  |  |  | 	xp_size_t lbound, xp_size_t ubound, __match_t* mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static xp_bool_t __test_charset ( | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* p, xp_size_t csc, xp_char_t c); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isalnum (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isalpha (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isblank (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_iscntrl (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isdigit (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isgraph (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_islower (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isprint (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_ispunct (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isspace (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isupper (xp_awk_t* awk, xp_char_t c); | 
					
						
							|  |  |  | static xp_bool_t __cc_isxdigit (xp_awk_t* awk, xp_char_t c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | static const xp_byte_t* __print_pattern (const xp_byte_t* p); | 
					
						
							|  |  |  | static const xp_byte_t* __print_branch (const xp_byte_t* p); | 
					
						
							|  |  |  | static const xp_byte_t* __print_atom (const xp_byte_t* p); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 07:18:40 +00:00
										 |  |  | struct __char_class_t | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_char_t* name; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	xp_size_t name_len; | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	xp_bool_t (*func) (xp_awk_t* awk, xp_char_t c); | 
					
						
							| 
									
										
										
										
											2006-09-01 07:18:40 +00:00
										 |  |  | };  | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 07:18:40 +00:00
										 |  |  | static struct __char_class_t __char_class[] = | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	{ XP_T("alnum"),  5, __cc_isalnum }, | 
					
						
							|  |  |  | 	{ XP_T("alpha"),  5, __cc_isalpha }, | 
					
						
							|  |  |  | 	{ XP_T("blank"),  5, __cc_isblank }, | 
					
						
							|  |  |  | 	{ XP_T("cntrl"),  5, __cc_iscntrl }, | 
					
						
							|  |  |  | 	{ XP_T("digit"),  5, __cc_isdigit }, | 
					
						
							|  |  |  | 	{ XP_T("graph"),  5, __cc_isgraph }, | 
					
						
							|  |  |  | 	{ XP_T("lower"),  5, __cc_islower }, | 
					
						
							|  |  |  | 	{ XP_T("print"),  5, __cc_isprint }, | 
					
						
							|  |  |  | 	{ XP_T("punct"),  5, __cc_ispunct }, | 
					
						
							|  |  |  | 	{ XP_T("space"),  5, __cc_isspace }, | 
					
						
							|  |  |  | 	{ XP_T("upper"),  5, __cc_isupper }, | 
					
						
							|  |  |  | 	{ XP_T("xdigit"), 6, __cc_isxdigit }, | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	{ XP_T("arabic"),   6, __cc_isarabic }, | 
					
						
							|  |  |  | 	{ XP_T("chinese"),  7, __cc_ischinese }, | 
					
						
							|  |  |  | 	{ XP_T("english"),  7, __cc_isenglish }, | 
					
						
							|  |  |  | 	{ XP_T("japanese"), 8, __cc_isjapanese }, | 
					
						
							|  |  |  | 	{ XP_T("korean"),   6, __cc_iskorean },  | 
					
						
							|  |  |  | 	{ XP_T("thai"),     4, __cc_isthai },  | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	{ XP_NULL,        0, XP_NULL } | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | void* xp_awk_buildrex ( | 
					
						
							|  |  |  | 	xp_awk_t* awk, const xp_char_t* ptn, xp_size_t len, int* errnum) | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__builder_t builder; | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	builder.awk = awk; | 
					
						
							| 
									
										
										
										
											2006-08-16 15:21:17 +00:00
										 |  |  | 	builder.code.capa = DEF_CODE_CAPA; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder.code.size = 0; | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	builder.code.buf = (xp_byte_t*)  | 
					
						
							|  |  |  | 		XP_AWK_MALLOC (builder.awk, builder.code.capa); | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 	if (builder.code.buf == XP_NULL)  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		*errnum = XP_AWK_ENOMEM; | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 		return XP_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder.ptn.ptr = ptn; | 
					
						
							|  |  |  | 	builder.ptn.end = builder.ptn.ptr + len; | 
					
						
							|  |  |  | 	builder.ptn.curp = builder.ptn.ptr; | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder.ptn.curc.type = CT_EOF; | 
					
						
							|  |  |  | 	builder.ptn.curc.value = XP_T('\0'); | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | /* TODO: implement the maximum depth 
 | 
					
						
							|  |  |  | 	builder.depth.max = awk->max_depth; */ | 
					
						
							|  |  |  | 	builder.depth.max = 0; | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 	builder.depth.cur = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 15:00:01 +00:00
										 |  |  | 	if (__next_char (&builder, LEVEL_TOP) == -1)  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 		if (errnum != XP_NULL) *errnum = builder.errnum; | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 		XP_AWK_FREE (builder.awk, builder.code.buf); | 
					
						
							| 
									
										
										
										
											2006-07-26 15:00:01 +00:00
										 |  |  | 		return XP_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (__build_pattern (&builder) == -1)  | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 		if (errnum != XP_NULL) *errnum = builder.errnum; | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 		XP_AWK_FREE (builder.awk, builder.code.buf); | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 		return XP_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder.ptn.curc.type != CT_EOF) | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		if (errnum != XP_NULL) *errnum = XP_AWK_EREXGARBAGE; | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 		XP_AWK_FREE (builder.awk, builder.code.buf); | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 		return XP_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	return builder.code.buf; | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | int xp_awk_matchrex ( | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	xp_awk_t* awk, void* code, int option, | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	const xp_char_t* str, xp_size_t len,  | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 	const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum) | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t matcher; | 
					
						
							|  |  |  | 	__match_t mat; | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	xp_size_t offset = 0; | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 	/*const xp_char_t* match_ptr_zero = XP_NULL;*/ | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	matcher.awk = awk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	/* store the source string */ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	matcher.match.str.ptr = str; | 
					
						
							|  |  |  | 	matcher.match.str.end = str + len; | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | /* TODO: implement the maximum depth 
 | 
					
						
							|  |  |  | 	matcher.depth.max = awk->max_depth; */ | 
					
						
							|  |  |  | 	matcher.depth.max = 0; | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 	matcher.depth.cur = 0; | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | // TODO: set it to a good value
 | 
					
						
							|  |  |  | 	matcher.ignorecase = (option & XP_AWK_REX_IGNORECASE)? 1: 0; | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mat.matched = xp_false; | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | /* TODO: should it allow an offset here??? */ | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	mat.match_ptr = str + offset; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	while (mat.match_ptr < matcher.match.str.end) | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 16:43:35 +00:00
										 |  |  | 		if (__match_pattern (&matcher, code, &mat) == XP_NULL)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (errnum != XP_NULL) *errnum = matcher.errnum; | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (mat.matched) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 			/*
 | 
					
						
							|  |  |  | 			if (mat.match_len == 0) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (match_ptr_zero == XP_NULL) | 
					
						
							|  |  |  | 					match_ptr_zero = mat.match_ptr; | 
					
						
							|  |  |  | 				mat.match_ptr++; | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 			if (match_ptr != XP_NULL) *match_ptr = mat.match_ptr; | 
					
						
							|  |  |  | 			if (match_len != XP_NULL) *match_len = mat.match_len; | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/*match_ptr_zero = XP_NULL;*/ | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mat.match_ptr++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	if (match_ptr_zero != XP_NULL)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (match_ptr != XP_NULL) *match_ptr = match_ptr_zero; | 
					
						
							|  |  |  | 		if (match_len != XP_NULL) *match_len = 0; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | 	return (mat.matched)? 1: 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | void xp_awk_freerex (xp_awk_t* awk, void* code) | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-08-30 07:15:14 +00:00
										 |  |  | 	xp_assert (code != XP_NULL); | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	XP_AWK_FREE (awk, code); | 
					
						
							| 
									
										
										
										
											2006-07-26 02:25:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-30 07:15:14 +00:00
										 |  |  | xp_bool_t xp_awk_isemptyrex (void* code) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p = code; | 
					
						
							|  |  |  | 	xp_size_t nb, el; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xp_assert (p != XP_NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nb = *(xp_size_t*)p; p += xp_sizeof(nb); | 
					
						
							|  |  |  | 	el = *(xp_size_t*)p; p += xp_sizeof(el); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* an empty regular expression look like:
 | 
					
						
							|  |  |  | 	 *  | expression                     |  | 
					
						
							|  |  |  | 	 *  | header         | branch        | | 
					
						
							|  |  |  | 	 *  |                | branch header | | 
					
						
							|  |  |  | 	 *  | NB(1) | EL(16) | NA(1) | BL(8) | */ | 
					
						
							|  |  |  | 	return (nb == 1 && el == xp_sizeof(xp_size_t)*4)? xp_true: xp_false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_pattern (__builder_t* builder) | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (builder->depth.max > 0 && builder->depth.cur >= builder->depth.max) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		builder->errnum = XP_AWK_ERECURSION; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	builder->depth.cur++; | 
					
						
							|  |  |  | 	n = __build_pattern0 (builder); | 
					
						
							|  |  |  | 	builder->depth.cur--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __build_pattern0 (__builder_t* builder) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 	xp_size_t zero = 0; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	xp_size_t old_size; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	xp_size_t pos_nb, pos_el; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	old_size = builder->code.size; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	/* secure space for header and set the header fields to zero */ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_nb = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_el = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	/* handle the first branch */ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	n = __build_branch (builder); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	if (n == -1) return -1; | 
					
						
							|  |  |  | 	if (n == 0)  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 		/* if the pattern is empty, the control reaches here */ | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 	/*CODEAT(builder,pos_nb,xp_size_t) += 1;*/ | 
					
						
							|  |  |  | 	SET_CODE (builder, pos_nb, xp_size_t, | 
					
						
							|  |  |  | 		GET_CODE (builder, pos_nb, xp_size_t) + 1); | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	/* handle subsequent branches if any */ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	while (builder->ptn.curc.type == CT_SPECIAL &&  | 
					
						
							|  |  |  | 	       builder->ptn.curc.value == XP_T('|')) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		NEXT_CHAR (builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		n = __build_branch(builder); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		if (n == -1) return -1; | 
					
						
							|  |  |  | 		if (n == 0)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* if the pattern ends with a vertical bar(|),
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			 * this block can be reached. however, such a  | 
					
						
							|  |  |  | 			 * pattern is highly discouraged */ | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 		/*CODEAT(builder,pos_nb,xp_size_t) += 1;*/ | 
					
						
							|  |  |  | 		SET_CODE (builder, pos_nb, xp_size_t,  | 
					
						
							|  |  |  | 			GET_CODE (builder, pos_nb, xp_size_t) + 1); | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 	/*CODEAT(builder,pos_el,xp_size_t) = builder->code.size - old_size;*/ | 
					
						
							|  |  |  | 	SET_CODE (builder, pos_el, xp_size_t, builder->code.size - old_size); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_branch (__builder_t* builder) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	xp_size_t zero = 0; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	xp_size_t old_size; | 
					
						
							|  |  |  | 	xp_size_t pos_na, pos_bl; | 
					
						
							|  |  |  | 	struct __code_t* cmd; | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	old_size = builder->code.size; | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_na = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_bl = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	while (1) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		cmd = (struct __code_t*)&builder->code.buf[builder->code.size]; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		n = __build_atom (builder); | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 		if (n == -1)  | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			builder->code.size = old_size; | 
					
						
							| 
									
										
										
										
											2006-07-19 15:58:01 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		if (n == 0) break; /* no atom */ | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		n = __build_occurrences (builder, cmd); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		if (n == -1) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			builder->code.size = old_size; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* n == 0  no bound character. just continue */ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		/* n == 1  bound has been applied by build_occurrences */ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 		/*CODEAT(builder,pos_na,xp_size_t) += 1;*/ | 
					
						
							|  |  |  | 		SET_CODE (builder, pos_na, xp_size_t, | 
					
						
							|  |  |  | 			GET_CODE (builder, pos_na, xp_size_t) + 1); | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 	/*CODEAT(builder,pos_bl,xp_size_t) = builder->code.size - old_size;*/ | 
					
						
							|  |  |  | 	SET_CODE (builder, pos_bl, xp_size_t, builder->code.size - old_size); | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	return (builder->code.size == old_size)? 0: 1; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_atom (__builder_t* builder) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	struct __code_t tmp; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type == CT_EOF) return 0; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type == CT_SPECIAL) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (builder->ptn.curc.value == XP_T('(')) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			tmp.cmd = CMD_GROUP; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			tmp.negate = 0; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			tmp.lbound = 1; | 
					
						
							|  |  |  | 			tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR (builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			n = __build_pattern (builder); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			if (n == -1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.type != CT_SPECIAL ||  | 
					
						
							|  |  |  | 			    builder->ptn.curc.value != XP_T(')'))  | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 				builder->errnum = XP_AWK_EREXRPAREN; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		else if (builder->ptn.curc.value == XP_T('^')) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			tmp.cmd = CMD_BOL; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			tmp.negate = 0; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 			tmp.lbound = 1; | 
					
						
							|  |  |  | 			tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		else if (builder->ptn.curc.value == XP_T('$')) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			tmp.cmd = CMD_EOL; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			tmp.negate = 0; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 			tmp.lbound = 1; | 
					
						
							|  |  |  | 			tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		else if (builder->ptn.curc.value == XP_T('.')) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 			tmp.cmd = CMD_ANY_CHAR; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			tmp.negate = 0; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 			tmp.lbound = 1; | 
					
						
							|  |  |  | 			tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		else if (builder->ptn.curc.value == XP_T('[')) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			struct __code_t* cmd; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			cmd = (struct __code_t*)&builder->code.buf[builder->code.size]; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			tmp.cmd = CMD_CHARSET; | 
					
						
							|  |  |  | 			tmp.negate = 0; | 
					
						
							|  |  |  | 			tmp.lbound = 1; | 
					
						
							|  |  |  | 			tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			n = __build_charset (builder, cmd); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			if (n == -1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			xp_assert (n != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.type != CT_SPECIAL || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value != XP_T(']')) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 				builder->errnum = XP_AWK_EREXRBRACKET; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 		else return 0; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		NEXT_CHAR (builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		xp_assert (builder->ptn.curc.type == CT_NORMAL); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		tmp.cmd = CMD_ORD_CHAR; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		tmp.negate = 0; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		tmp.lbound = 1; | 
					
						
							|  |  |  | 		tmp.ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		ADD_CODE (builder, &tmp, xp_sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		ADD_CODE (builder, &builder->ptn.curc.value, xp_sizeof(builder->ptn.curc.value)); | 
					
						
							|  |  |  | 		NEXT_CHAR (builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		return 1; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_charset (__builder_t* builder, struct __code_t* cmd) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	xp_size_t zero = 0; | 
					
						
							|  |  |  | 	xp_size_t old_size; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	xp_size_t pos_csc, pos_csl; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	old_size = builder->code.size; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_csc = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	pos_csl = builder->code.size; | 
					
						
							|  |  |  | 	ADD_CODE (builder, &zero, xp_sizeof(zero)); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type == CT_NORMAL && | 
					
						
							|  |  |  | 	    builder->ptn.curc.value == XP_T('^'))  | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		cmd->negate = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	while (builder->ptn.curc.type == CT_NORMAL) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		xp_char_t c0, c1, c2; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		int cc = 0; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		c1 = builder->ptn.curc.value; | 
					
						
							|  |  |  | 		NEXT_CHAR(builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (c1 == XP_T('[') && | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		    builder->ptn.curc.type == CT_NORMAL && | 
					
						
							|  |  |  | 		    builder->ptn.curc.value == XP_T(':')) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (__build_cclass (builder, &c1) == -1) return -1; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			cc = cc | 1; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		c2 = c1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (builder->ptn.curc.type == CT_NORMAL && | 
					
						
							|  |  |  | 		    builder->ptn.curc.value == XP_T('-')) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.type == CT_NORMAL) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				c2 = builder->ptn.curc.value; | 
					
						
							|  |  |  | 				NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (c2 == XP_T('[') && | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				    builder->ptn.curc.type == CT_NORMAL && | 
					
						
							|  |  |  | 				    builder->ptn.curc.value == XP_T(':')) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 					if (__build_cclass (builder, &c2) == -1) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 					{ | 
					
						
							|  |  |  | 						return -1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					cc = cc | 2; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}	 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			else cc = cc | 4; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		if (cc == 0 || cc == 4) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (c1 == c2) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c0 = CHARSET_ONE; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				ADD_CODE (builder, &c0, xp_sizeof(c0)); | 
					
						
							|  |  |  | 				ADD_CODE (builder, &c1, xp_sizeof(c1)); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c0 = CHARSET_RANGE; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				ADD_CODE (builder, &c0, xp_sizeof(c0)); | 
					
						
							|  |  |  | 				ADD_CODE (builder, &c1, xp_sizeof(c1)); | 
					
						
							|  |  |  | 				ADD_CODE (builder, &c2, xp_sizeof(c2)); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (cc == 1) | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			c0 = CHARSET_CLASS; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			ADD_CODE (builder, &c0, xp_sizeof(c0)); | 
					
						
							|  |  |  | 			ADD_CODE (builder, &c1, xp_sizeof(c1)); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			/* invalid range */ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("invalid character set range\n"));
 | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 			builder->errnum = XP_AWK_EREXCRANGE; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 		/*CODEAT(builder,pos_csc,xp_size_t) += 1;*/ | 
					
						
							|  |  |  | 		SET_CODE (builder, pos_csc, xp_size_t, | 
					
						
							|  |  |  | 			GET_CODE (builder, pos_csc, xp_size_t) + 1); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | 	/*CODEAT(builder,pos_csl,xp_size_t) = builder->code.size - old_size;*/ | 
					
						
							|  |  |  | 	SET_CODE (builder, pos_csl, xp_size_t, builder->code.size - old_size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_cclass (__builder_t* builder, xp_char_t* cc) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const struct __char_class_t* ccp = __char_class; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	xp_size_t len = builder->ptn.end - builder->ptn.curp; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (ccp->name != XP_NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (__begin_with (builder->ptn.curp, len, ccp->name)) break; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		ccp++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ccp->name == XP_NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* wrong class name */ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("wrong class name\n"));
 | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		builder->errnum = XP_AWK_EREXCCLASS; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder->ptn.curp += ccp->name_len; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							|  |  |  | 	if (builder->ptn.curc.type != CT_NORMAL || | 
					
						
							|  |  |  | 	    builder->ptn.curc.value != XP_T(':')) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T(": expected\n"));
 | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		builder->errnum = XP_AWK_EREXCOLON; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	NEXT_CHAR (builder, LEVEL_CHARSET);  | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* ] happens to be the charset ender ] */ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type != CT_SPECIAL || | 
					
						
							|  |  |  | 	    builder->ptn.curc.value != XP_T(']')) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("] expected\n"));
 | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		builder->errnum = XP_AWK_EREXRBRACKET;	 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	NEXT_CHAR (builder, LEVEL_CHARSET); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*cc = (xp_char_t)(ccp - __char_class); | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | static int __build_occurrences (__builder_t* builder, struct __code_t* cmd) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type != CT_SPECIAL) return 0; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	switch (builder->ptn.curc.value) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		case XP_T('+'): | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			cmd->lbound = 1; | 
					
						
							|  |  |  | 			cmd->ubound = BOUND_MAX; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR(builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case XP_T('*'): | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			cmd->lbound = 0; | 
					
						
							|  |  |  | 			cmd->ubound = BOUND_MAX; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR(builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case XP_T('?'): | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			cmd->lbound = 0; | 
					
						
							|  |  |  | 			cmd->ubound = 1; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR(builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case XP_T('{'): | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR (builder, LEVEL_RANGE); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (__build_range(builder, cmd) == -1) return -1; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.type != CT_SPECIAL ||  | 
					
						
							|  |  |  | 			    builder->ptn.curc.value != XP_T('}'))  | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 				builder->errnum = XP_AWK_EREXRBRACE; | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			NEXT_CHAR (builder, LEVEL_TOP); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __build_range (__builder_t* builder, struct __code_t* cmd) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	xp_size_t bound; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TODO: should allow white spaces in the range???
 | 
					
						
							|  |  |  | //  what if it is not in the raight format? convert it to ordinary characters??
 | 
					
						
							|  |  |  | 	bound = 0; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	while (builder->ptn.curc.type == CT_NORMAL && | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 	       (builder->ptn.curc.value >= XP_T('0') &&  | 
					
						
							|  |  |  | 	        builder->ptn.curc.value <= XP_T('9'))) | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		bound = bound * 10 + builder->ptn.curc.value - XP_T('0'); | 
					
						
							|  |  |  | 		NEXT_CHAR (builder, LEVEL_RANGE); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd->lbound = bound; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.type == CT_SPECIAL && | 
					
						
							|  |  |  | 	    builder->ptn.curc.value == XP_T(','))  | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		NEXT_CHAR (builder, LEVEL_RANGE); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		bound = 0; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		while (builder->ptn.curc.type == CT_NORMAL && | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 		       (builder->ptn.curc.value >= XP_T('0') &&  | 
					
						
							|  |  |  | 		        builder->ptn.curc.value <= XP_T('9'))) | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			bound = bound * 10 + builder->ptn.curc.value - XP_T('0'); | 
					
						
							|  |  |  | 			NEXT_CHAR (builder, LEVEL_RANGE); | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cmd->ubound = bound; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else cmd->ubound = BOUND_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	if (cmd->lbound > cmd->ubound) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		/* invalid occurrences range */ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 		builder->errnum = XP_AWK_EREXBRANGE; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __next_char (__builder_t* builder, int level) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curp >= builder->ptn.end) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		builder->ptn.curc.type = CT_EOF; | 
					
						
							|  |  |  | 		builder->ptn.curc.value = XP_T('\0'); | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder->ptn.curc.type = CT_NORMAL; | 
					
						
							|  |  |  | 	builder->ptn.curc.value = *builder->ptn.curp++; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (builder->ptn.curc.value == XP_T('\\')) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	{	        | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (builder->ptn.curp >= builder->ptn.end) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 			builder->errnum = XP_AWK_EREXEND; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 			return -1;	 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		builder->ptn.curc.value = *builder->ptn.curp++; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		if (level == LEVEL_TOP) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.value == XP_T('[') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('|') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('^') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('$') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('{') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('+') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('?') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('*') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('.') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('(') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T(')'))  | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				builder->ptn.curc.type = CT_SPECIAL; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		else if (level == LEVEL_CHARSET) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.value == XP_T(']'))  | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				builder->ptn.curc.type = CT_SPECIAL; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-21 05:05:03 +00:00
										 |  |  | 		else if (level == LEVEL_RANGE) | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			if (builder->ptn.curc.value == XP_T(',') || | 
					
						
							|  |  |  | 			    builder->ptn.curc.value == XP_T('}'))  | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				builder->ptn.curc.type = CT_SPECIAL; | 
					
						
							| 
									
										
										
										
											2006-07-20 03:41:00 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | static int __add_code (__builder_t* builder, void* data, xp_size_t len) | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	if (len > builder->code.capa - builder->code.size) | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		xp_size_t capa = builder->code.capa * 2; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 		xp_byte_t* tmp; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2006-08-16 15:21:17 +00:00
										 |  |  | 		if (capa == 0) capa = DEF_CODE_CAPA; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		while (len > capa - builder->code.size) { capa = capa * 2; } | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 06:17:19 +00:00
										 |  |  | 		if (builder->awk->syscas->realloc != XP_NULL) | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 			tmp = (xp_byte_t*) XP_AWK_REALLOC ( | 
					
						
							|  |  |  | 				builder->awk, builder->code.buf, capa); | 
					
						
							|  |  |  | 			if (tmp == XP_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				builder->errnum = XP_AWK_ENOMEM; | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 			tmp = (xp_byte_t*) XP_AWK_MALLOC (builder->awk, capa); | 
					
						
							|  |  |  | 			if (tmp == XP_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				builder->errnum = XP_AWK_ENOMEM; | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (builder->code.buf != XP_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-09-25 06:17:19 +00:00
										 |  |  | 				XP_AWK_MEMCPY (builder->awk, tmp,  | 
					
						
							|  |  |  | 					builder->code.buf, builder->code.capa); | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 				XP_AWK_FREE (builder->awk, builder->code.buf); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		builder->code.buf = tmp; | 
					
						
							|  |  |  | 		builder->code.capa = capa; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 06:17:19 +00:00
										 |  |  | 	XP_AWK_MEMCPY (builder->awk,  | 
					
						
							|  |  |  | 		&builder->code.buf[builder->code.size], data, len); | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	builder->code.size += len; | 
					
						
							| 
									
										
										
										
											2006-07-19 11:45:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-07-18 15:28:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-07-20 16:21:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | static xp_bool_t __begin_with ( | 
					
						
							|  |  |  | 	const xp_char_t* str, xp_size_t len, const xp_char_t* what) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const xp_char_t* end = str + len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (str < end) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (*what == XP_T('\0')) return xp_true; | 
					
						
							|  |  |  | 		if (*what != *str) return xp_false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		str++; what++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*what == XP_T('\0')) return xp_true; | 
					
						
							|  |  |  | 	return xp_false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | static const xp_byte_t* __match_pattern ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	const xp_byte_t* p; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__match_t mat2; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	xp_size_t nb, el, i; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	p = base; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	nb = *(xp_size_t*)p; p += xp_sizeof(nb); | 
					
						
							|  |  |  | 	el = *(xp_size_t*)p; p += xp_sizeof(el); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("NB = %u, EL = %u\n"), (unsigned)nb, (unsigned)el);
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	for (i = 0; i < nb; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		mat2.match_ptr = mat->match_ptr; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		p = __match_branch (matcher, p, &mat2); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		if (p == XP_NULL) return XP_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		if (mat2.matched) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			mat->matched = xp_true; | 
					
						
							|  |  |  | 			mat->match_len = mat2.match_len; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	return base + el; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | static const xp_byte_t* __match_branch ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * branch body (base+sizeof(NA)+sizeof(BL)---+ | 
					
						
							|  |  |  | 	 * BL=base+sizeof(NA) ---------+             | | 
					
						
							|  |  |  | 	 * base=NA ------+             |             | | 
					
						
							|  |  |  | 	 *               |             |             | | 
					
						
							|  |  |  | 	 *               |NA(xp_size_t)|BL(xp_size_t)|ATOMS.........| | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	mat->branch = base; | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	mat->branch_end = base + *((xp_size_t*)(base+xp_sizeof(xp_size_t))); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	return __match_branch_body ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		matcher, base+xp_sizeof(xp_size_t)*2, mat); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_branch_body ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-08-16 08:55:43 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (matcher->depth.max > 0 && matcher->depth.cur >= matcher->depth.max) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		matcher->errnum = XP_AWK_ERECURSION; | 
					
						
							|  |  |  | 		return XP_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	matcher->depth.cur++; | 
					
						
							|  |  |  | 	n = __match_branch_body0 (matcher, base, mat); | 
					
						
							|  |  |  | 	matcher->depth.cur--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_branch_body0 ( | 
					
						
							|  |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | //	__match_t mat2;
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	xp_size_t match_len = 0; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | /* TODO: is mat2 necessary here ? */ | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	mat2.match_ptr = mat->match_ptr; | 
					
						
							|  |  |  | 	mat2.branch = mat->branch; | 
					
						
							|  |  |  | 	mat2.branch_end = mat->branch_end; | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	p = base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (p < mat->branch_end) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		p = __match_atom (matcher, p, mat); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		if (p == XP_NULL) return XP_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!mat->matched) break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mat->match_ptr = &mat->match_ptr[mat->match_len]; | 
					
						
							|  |  |  | 		match_len += mat->match_len; | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		p = __match_atom (matcher, p, &mat2); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		if (p == XP_NULL) return XP_NULL; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!mat2.matched)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			mat->matched = xp_false; | 
					
						
							|  |  |  | 			break; /* stop matching */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mat->matched = xp_true; | 
					
						
							|  |  |  | 		mat->match_len += mat2.match_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		mat2.match_ptr = &mat2.match_ptr[mat2.match_len]; | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	if (mat->matched) mat->match_len = match_len; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	return mat->branch_end; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | static const xp_byte_t* __match_atom ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	static atom_matcher_t matchers[] = | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		__match_bol, | 
					
						
							|  |  |  | 		__match_eol, | 
					
						
							|  |  |  | 		__match_any_char, | 
					
						
							|  |  |  | 		__match_ord_char, | 
					
						
							|  |  |  | 		__match_charset, | 
					
						
							|  |  |  | 		__match_group | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  |         | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	xp_assert (((struct __code_t*)base)->cmd >= 0 &&  | 
					
						
							|  |  |  | 	           ((struct __code_t*)base)->cmd < xp_countof(matchers)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	return matchers[((struct __code_t*)base)->cmd] (matcher, base, mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_bol ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p = base; | 
					
						
							|  |  |  | 	const struct __code_t* cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_BOL); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	mat->matched = (mat->match_ptr == matcher->match.str.ptr || | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	               (cp->lbound == cp->ubound && cp->lbound == 0)); | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_eol ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p = base; | 
					
						
							|  |  |  | 	const struct __code_t* cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_EOL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	mat->matched = (mat->match_ptr == matcher->match.str.end || | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	               (cp->lbound == cp->ubound && cp->lbound == 0)); | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_any_char ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p = base; | 
					
						
							|  |  |  | 	const struct __code_t* cp; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	xp_size_t si = 0, lbound, ubound; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_ANY_CHAR); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	lbound = cp->lbound; | 
					
						
							|  |  |  | 	ubound = cp->ubound; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	/* merge the same consecutive codes */ | 
					
						
							|  |  |  | 	while (p < mat->branch_end && | 
					
						
							|  |  |  | 	       cp->cmd == ((const struct __code_t*)p)->cmd) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		lbound += ((const struct __code_t*)p)->lbound; | 
					
						
							|  |  |  | 		ubound += ((const struct __code_t*)p)->ubound; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //xp_printf (XP_T("lbound = %u, ubound = %u\n"), 
 | 
					
						
							|  |  |  | //(unsigned int)lbound, (unsigned int)ubound);
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	/* find the longest match */ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	while (si < ubound) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (&mat->match_ptr[si] >= matcher->match.str.end) break; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		si++; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("max si = %d\n"), si);
 | 
					
						
							|  |  |  | 	if (si >= lbound && si <= ubound) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		p = __match_occurrences (matcher, si, p, lbound, ubound, mat); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | static const xp_byte_t* __match_ord_char ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	const xp_byte_t* p = base; | 
					
						
							|  |  |  | 	const struct __code_t* cp; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	xp_size_t si = 0, lbound, ubound; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	xp_char_t cc; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_ORD_CHAR); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	lbound = cp->lbound;  | 
					
						
							|  |  |  | 	ubound = cp->ubound; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	cc = *(xp_char_t*)p; p += xp_sizeof(cc); | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	if (matcher->ignorecase) cc = XP_AWK_TOUPPER(matcher->awk, cc); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	/* merge the same consecutive codes 
 | 
					
						
							|  |  |  | 	 * for example, a{1,10}a{0,10} is shortened to a{1,20}  | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	if (matcher->ignorecase)  | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 		while (p < mat->branch_end && | 
					
						
							|  |  |  | 		       cp->cmd == ((const struct __code_t*)p)->cmd) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (XP_AWK_TOUPPER (matcher->awk, *(xp_char_t*)(p+xp_sizeof(*cp))) != cc) break; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 			lbound += ((const struct __code_t*)p)->lbound; | 
					
						
							|  |  |  | 			ubound += ((const struct __code_t*)p)->ubound; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 			p += xp_sizeof(*cp) + xp_sizeof(cc); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		while (p < mat->branch_end && | 
					
						
							|  |  |  | 		       cp->cmd == ((const struct __code_t*)p)->cmd) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (*(xp_char_t*)(p+xp_sizeof(*cp)) != cc) break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lbound += ((const struct __code_t*)p)->lbound; | 
					
						
							|  |  |  | 			ubound += ((const struct __code_t*)p)->ubound; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			p += xp_sizeof(*cp) + xp_sizeof(cc); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | //xp_printf (XP_T("lbound = %u, ubound = %u\n"), 
 | 
					
						
							|  |  |  | //(unsigned int)lbound, (unsigned int)ubound);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* find the longest match */ | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	if (matcher->ignorecase)  | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 		while (si < ubound) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (&mat->match_ptr[si] >= matcher->match.str.end) break; | 
					
						
							|  |  |  | 			if (cc != XP_AWK_TOUPPER (matcher->awk, mat->match_ptr[si])) break; | 
					
						
							|  |  |  | 			si++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		while (si < ubound) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (&mat->match_ptr[si] >= matcher->match.str.end) break; | 
					
						
							|  |  |  | 			if (cc != mat->match_ptr[si]) break; | 
					
						
							|  |  |  | 			si++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | //xp_printf (XP_T("max si = %d, lbound = %u, ubound = %u\n"), si, lbound, ubound);
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	if (si >= lbound && si <= ubound) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		p = __match_occurrences (matcher, si, p, lbound, ubound, mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_charset ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const xp_byte_t* p = base; | 
					
						
							|  |  |  | 	const struct __code_t* cp; | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	xp_size_t si = 0, lbound, ubound, csc, csl; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	xp_bool_t n; | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 	xp_char_t c; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_CHARSET); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	lbound = cp->lbound; | 
					
						
							|  |  |  | 	ubound = cp->ubound; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	csc = *(xp_size_t*)p; p += xp_sizeof(csc); | 
					
						
							|  |  |  | 	csl = *(xp_size_t*)p; p += xp_sizeof(csl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	while (si < ubound) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (&mat->match_ptr[si] >= matcher->match.str.end) break; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 		c = mat->match_ptr[si]; | 
					
						
							|  |  |  | 		if (matcher->ignorecase) c = XP_AWK_TOUPPER(matcher->awk, c); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		n = __test_charset (matcher, p, csc, c); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		if (cp->negate) n = !n; | 
					
						
							|  |  |  | 		if (!n) break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		si++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	p = p + csl - (xp_sizeof(csc) + xp_sizeof(csl)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	if (si >= lbound && si <= ubound) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 		p = __match_occurrences (matcher, si, p, lbound, ubound, mat); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __match_group ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, const xp_byte_t* base, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	const xp_byte_t* p = base; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	const struct __code_t* cp; | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__match_t mat2; | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	xp_size_t si = 0, grp_len_static[16], * grp_len; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cp = (const struct __code_t*)p; p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	xp_assert (cp->cmd == CMD_GROUP); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	mat->matched = xp_false; | 
					
						
							|  |  |  | 	mat->match_len = 0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	 * A grouped pattern, unlike other atoms, can match one or more  | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	 * characters. When it is requested with a variable occurrences,  | 
					
						
							|  |  |  | 	 * the number of characters that have matched at each occurrence  | 
					
						
							|  |  |  | 	 * needs to be remembered for the backtracking purpose. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * An array "grp_len" is used to store the accumulated number of  | 
					
						
							|  |  |  | 	 * characters. grp_len[0] is set to zero always for convenience. | 
					
						
							|  |  |  | 	 * grp_len[1] holds the number of characters that have matched | 
					
						
							|  |  |  | 	 * at the first occurrence, grp_len[2] at the second occurrence,  | 
					
						
							|  |  |  | 	 * and so on. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Look at the following example | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 *   pattern: (abc){1,3}x   string: abcabcabcxyz | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 *  grp_len[3] => 9 -----------+ | 
					
						
							|  |  |  | 	 *  grp_len[2] => 6 --------+  | | 
					
						
							|  |  |  | 	 *  grp_len[1] => 3 -----+  |  | | 
					
						
							|  |  |  | 	 *  grp_len[0] => 0 --+  |  |  | | 
					
						
							|  |  |  | 	 *                    |  |  |  | | 
					
						
							|  |  |  | 	 *                     abcabcabcxyz | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	if (cp->ubound < xp_countof(grp_len_static)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		grp_len = grp_len_static; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 		grp_len = (xp_size_t*) XP_AWK_MALLOC ( | 
					
						
							|  |  |  | 			matcher->awk, xp_sizeof(xp_size_t) * cp->ubound); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		if (grp_len == XP_NULL) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-08-10 16:02:15 +00:00
										 |  |  | 			matcher->errnum = XP_AWK_ENOMEM; | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 			return XP_NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	grp_len[si] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mat2.match_ptr = mat->match_ptr; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	while (si < cp->ubound) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (mat2.match_ptr >= matcher->match.str.end) break; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 		if (__match_pattern (matcher, p, &mat2) == XP_NULL)  | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 			if (grp_len != grp_len_static)  | 
					
						
							|  |  |  | 				XP_AWK_FREE (matcher->awk, grp_len); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 			return XP_NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		if (!mat2.matched) break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 		grp_len[si+1] = grp_len[si] + mat2.match_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		mat2.match_ptr += mat2.match_len; | 
					
						
							|  |  |  | 		mat2.match_len = 0; | 
					
						
							|  |  |  | 		mat2.matched = xp_false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		si++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 	/* increment p by the length of the subpattern */ | 
					
						
							|  |  |  | 	p += *(xp_size_t*)(p+xp_sizeof(xp_size_t)); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | 	/* check the occurrences */ | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	if (si >= cp->lbound && si <= cp->ubound) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (cp->lbound == cp->ubound || p >= mat->branch_end) | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			mat->matched = xp_true; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			mat->match_len = grp_len[si]; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		else  | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			xp_assert (cp->ubound > cp->lbound); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			do | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				const xp_byte_t* tmp; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 				mat2.match_ptr = &mat->match_ptr[grp_len[si]]; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 				mat2.branch = mat->branch; | 
					
						
							|  |  |  | 				mat2.branch_end = mat->branch_end; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("GROUP si = %d [%s]\n"), si, mat->match_ptr);
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 				tmp = __match_branch_body (matcher, p, &mat2); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 				if (tmp == XP_NULL) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (grp_len != grp_len_static)  | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 						XP_AWK_FREE (matcher->awk, grp_len); | 
					
						
							| 
									
										
										
										
											2006-07-25 16:41:40 +00:00
										 |  |  | 					return XP_NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (mat2.matched) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					mat->matched = xp_true; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 					mat->match_len = grp_len[si] + mat2.match_len; | 
					
						
							|  |  |  | 					p = tmp; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 				if (si <= cp->lbound) break; | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 				si--; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			}  | 
					
						
							|  |  |  | 			while (1); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 03:44:51 +00:00
										 |  |  | 	if (grp_len != grp_len_static) XP_AWK_FREE (matcher->awk, grp_len); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-05 15:18:36 +00:00
										 |  |  | static const xp_byte_t* __match_occurrences ( | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 	__matcher_t* matcher, xp_size_t si, const xp_byte_t* p, | 
					
						
							|  |  |  | 	xp_size_t lbound, xp_size_t ubound, __match_t* mat) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	xp_assert (si >= lbound && si <= ubound); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	/* the match has been found */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 	if (lbound == ubound || p >= mat->branch_end) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		/* if the match for fixed occurrences was 
 | 
					
						
							|  |  |  | 		 * requested or no atoms remain unchecked in  | 
					
						
							|  |  |  | 		 * the branch, the match is returned. */ | 
					
						
							|  |  |  | 		mat->matched = xp_true; | 
					
						
							|  |  |  | 		mat->match_len = si; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* Otherwise, it checks if the remaining atoms 
 | 
					
						
							|  |  |  | 		 * match the rest of the string  | 
					
						
							|  |  |  | 		 *  | 
					
						
							|  |  |  | 		 * Let's say the caller of this function was processing | 
					
						
							|  |  |  | 		 * the first period character in the following example. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 *     pattern: .{1,3}xx   string: xxxyy | 
					
						
							|  |  |  | 		 *  | 
					
						
							|  |  |  | 		 * It scans up to the third "x" in the string. si is set  | 
					
						
							|  |  |  | 		 * to 3 and p points to the first "x" in the pattern.  | 
					
						
							|  |  |  | 		 * It doesn't change mat.match_ptr so mat.match_ptr remains | 
					
						
							|  |  |  | 		 * the same. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 *     si = 3    p -----+    mat.match_ptr ---+ | 
					
						
							|  |  |  | 		 *                      |                     | | 
					
						
							|  |  |  | 		 *                .{1,3}xx                    xxxyy | 
					
						
							|  |  |  | 		 *                      | 
					
						
							|  |  |  | 		 *  When the code reaches here, the string pointed at by | 
					
						
							|  |  |  | 		 *  &mat.match_ptr[si] is tried to match against the remaining | 
					
						
							|  |  |  | 		 *  pattern pointed at p. | 
					
						
							|  |  |  | 		 *   | 
					
						
							|  |  |  | 		 *     &mat.match_ptr[si] ---+ | 
					
						
							|  |  |  | 		 *                           | | 
					
						
							|  |  |  | 		 *                        xxxyy | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * If a match is found, the match and the previous match are | 
					
						
							|  |  |  | 		 * merged and returned. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * If not, si is decremented by one and the match is performed | 
					
						
							|  |  |  | 		 * from the string pointed at by &mat.match_ptr[si]. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 *     &mat.match_ptr[si] --+ | 
					
						
							|  |  |  | 		 *                          | | 
					
						
							|  |  |  | 		 *                        xxxyy | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * This process is repeated until a match is found or si  | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 		 * becomes less than lbound. (si never becomes less than | 
					
						
							|  |  |  | 		 * lbound in the implementation below, though) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 		xp_assert (ubound > lbound); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		do | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			__match_t mat2; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			const xp_byte_t* tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mat2.match_ptr = &mat->match_ptr[si]; | 
					
						
							|  |  |  | 			mat2.branch = mat->branch; | 
					
						
							|  |  |  | 			mat2.branch_end = mat->branch_end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | //xp_printf (XP_T("si = %d [%s]\n"), si, mat->match_ptr);
 | 
					
						
							| 
									
										
										
										
											2006-07-26 05:19:46 +00:00
										 |  |  | 			tmp = __match_branch_body (matcher, p, &mat2); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (mat2.matched) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				mat->matched = xp_true; | 
					
						
							|  |  |  | 				mat->match_len = si + mat2.match_len; | 
					
						
							|  |  |  | 				p = tmp; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 			if (si <= lbound) break; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			si--; | 
					
						
							|  |  |  | 		}  | 
					
						
							|  |  |  | 		while (1); | 
					
						
							| 
									
										
										
										
											2006-07-23 16:31:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | xp_bool_t __test_charset ( | 
					
						
							|  |  |  | 	__matcher_t* matcher, const xp_byte_t* p, xp_size_t csc, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	xp_size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < csc; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_char_t c0, c1, c2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		c0 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 		p += xp_sizeof(c0); | 
					
						
							|  |  |  | 		if (c0 == CHARSET_ONE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			c1 = *(xp_char_t*)p; | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 			if (matcher->ignorecase)  | 
					
						
							|  |  |  | 				c1 = XP_AWK_TOUPPER(matcher->awk, c1); | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			if (c == c1) return xp_true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c0 == CHARSET_RANGE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			c1 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 			p += xp_sizeof(c1); | 
					
						
							|  |  |  | 			c2 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-10 15:50:34 +00:00
										 |  |  | 			if (matcher->ignorecase)  | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c1 = XP_AWK_TOUPPER(matcher->awk, c1); | 
					
						
							|  |  |  | 				c2 = XP_AWK_TOUPPER(matcher->awk, c2); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 			if (c >= c1 && c <= c2) return xp_true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c0 == CHARSET_CLASS) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			c1 = *(xp_char_t*)p; | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 			if (__char_class[c1].func ( | 
					
						
							|  |  |  | 				matcher->awk, c)) return xp_true; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 			xp_assert (!"should never happen - invalid charset code"); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-07-24 11:58:55 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		p += xp_sizeof(c1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return xp_false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isalnum (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISALNUM (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isalpha (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISALPHA (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isblank (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return c == XP_T(' ') || c == XP_T('\t'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_iscntrl (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISCNTRL (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isdigit (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISDIGIT (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isgraph (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISGRAPH (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_islower (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISLOWER (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isprint (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISPRINT (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_ispunct (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISPUNCT (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isspace (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISSPACE (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isupper (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISUPPER (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | static xp_bool_t __cc_isxdigit (xp_awk_t* awk, xp_char_t c) | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-01 06:45:05 +00:00
										 |  |  | 	return XP_AWK_ISXDIGIT (awk, c); | 
					
						
							| 
									
										
										
										
											2006-07-22 16:40:39 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | void xp_awk_printrex (void* rex) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	__print_pattern (rex); | 
					
						
							|  |  |  | 	xp_printf (XP_T("\n")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | static const xp_byte_t* __print_pattern (const xp_byte_t* p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xp_size_t nb, el, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nb = *(xp_size_t*)p; p += xp_sizeof(nb); | 
					
						
							|  |  |  | 	el = *(xp_size_t*)p; p += xp_sizeof(el); | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | //xp_printf (XP_T("NB = %u, EL = %u\n"), (unsigned int)nb, (unsigned int)el);
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < nb; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (i != 0) xp_printf (XP_T("|")); | 
					
						
							|  |  |  | 		p = __print_branch (p); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __print_branch (const xp_byte_t* p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xp_size_t na, bl, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	na = *(xp_size_t*)p; p += xp_sizeof(na); | 
					
						
							|  |  |  | 	bl = *(xp_size_t*)p; p += xp_sizeof(bl); | 
					
						
							| 
									
										
										
										
											2006-10-04 10:11:04 +00:00
										 |  |  | //xp_printf (XP_T("NA = %u, BL = %u\n"), (unsigned int) na, (unsigned int)bl);
 | 
					
						
							| 
									
										
										
										
											2006-07-24 16:23:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < na; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		p = __print_atom (p); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const xp_byte_t* __print_atom (const xp_byte_t* p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct __code_t* cp = (const struct __code_t*)p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cp->cmd == CMD_BOL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_printf (XP_T("^")); | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cp->cmd == CMD_EOL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_printf (XP_T("$")); | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cp->cmd == CMD_ANY_CHAR)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_printf (XP_T(".")); | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cp->cmd == CMD_ORD_CHAR)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 		xp_printf (XP_T("%c"), *(xp_char_t*)p); | 
					
						
							|  |  |  | 		p += xp_sizeof(xp_char_t); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cp->cmd == CMD_CHARSET) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_size_t csc, csl, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 		xp_printf (XP_T("[")); | 
					
						
							|  |  |  | 		if (cp->negate) xp_printf (XP_T("^")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		csc = *(xp_size_t*)p; p += xp_sizeof(csc); | 
					
						
							|  |  |  | 		csl = *(xp_size_t*)p; p += xp_sizeof(csl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0; i < csc; i++) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xp_char_t c0, c1, c2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			c0 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 			p += xp_sizeof(c0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (c0 == CHARSET_ONE) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c1 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 				xp_printf (XP_T("%c"), c1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (c0 == CHARSET_RANGE) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c1 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 				p += xp_sizeof(c1); | 
					
						
							|  |  |  | 				c2 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 				xp_printf (XP_T("%c-%c"), c1, c2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (c0 == CHARSET_CLASS) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				c1 = *(xp_char_t*)p; | 
					
						
							|  |  |  | 				xp_printf (XP_T("[:%s:]"), __char_class[c1].name); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				xp_assert (!"should never happen - invalid charset code"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			p += xp_sizeof(c1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		xp_printf (XP_T("]")); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (cp->cmd == CMD_GROUP) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		p += xp_sizeof(*cp); | 
					
						
							|  |  |  | 		xp_printf (XP_T("(")); | 
					
						
							|  |  |  | 		p = __print_pattern (p); | 
					
						
							|  |  |  | 		xp_printf (XP_T(")")); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_assert (!"should never happen - invalid atom code"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cp->lbound == 0 && cp->ubound == BOUND_MAX) | 
					
						
							|  |  |  | 		xp_printf (XP_T("*")); | 
					
						
							|  |  |  | 	else if (cp->lbound == 1 && cp->ubound == BOUND_MAX) | 
					
						
							|  |  |  | 		xp_printf (XP_T("+")); | 
					
						
							|  |  |  | 	else if (cp->lbound == 0 && cp->ubound == 1) | 
					
						
							|  |  |  | 		xp_printf (XP_T("?")); | 
					
						
							|  |  |  | 	else if (cp->lbound != 1 || cp->ubound != 1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xp_printf (XP_T("{%lu,%lu}"),  | 
					
						
							|  |  |  | 			(unsigned long)cp->lbound, (unsigned long)cp->ubound); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-08-16 11:35:54 +00:00
										 |  |  | 
 |