stringparsing.c

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 883 行 · 第 1/2 页

C
883
字号
	return( str );}staticchar *skipSpace(unsigned char *str, unsigned char *str_end){	assert(str != 0);	assert(str_end != 0);		while( (str < str_end) && isspace(*str) )	{		str++;	}	return( str );}staticint parseString_private(parseErrorInfo *pe,			parsedString *subString,			stringScript *script,			void **values,			int op,			va_list args){	char *str, *str_end, *str_ptr = 0, *term_ptr, *new_pos = 0;	int values_pos = 0, len, retval = 1;	stringScript *script_pos = script;	parseValue pv;	parseStack ps;#ifdef VA_LIST_IS_ARRAY	/* Use temporary copy of args on platforms where va_list	 * is an array.	 *	 * We sometimes need to pass the address of a va_list to	 * another function. C Standard mandates array types in	 * prototypes to be silently coerced into pointers to base	 * objects. If va_list is an array, this results in the	 * receiving function expecting a pointer to a va_list array	 * member, but getting a pointer to a pointer instead when	 * we pass &args.	 *	 * Copying the va_list into a temporary buffer, and copying	 * it back 'undoes' the coercion.	 *	 * A longer explanation was posted by Graeme Peterson on the	 * GDB mailing list on 2002-04-15.	 */        va_list     tmp_args;        VA_LIST_COPY (tmp_args, args);#endif	assert(subString != 0);	str = subString->data;	str_end = subString->data + subString->len;	pv.type = SPO_Noop;	ps.top = &ps.frames[0];	ps.top->op = SPO_Noop;	ps.depth = 0;	if( script )	{		op = script_pos->op;	}	while( retval && (ps.depth >= 0) )	{		switch( op )		{		case SPO_End:			if( ps.top->op == SPO_Do )				VA_LIST_COPY(args, ps.top->args);			else				popFrame(&ps);			script_pos++;			break;		case SPO_Expect:			if( script )			{				str_ptr = script_pos->args[0];				script_pos = STRING_SCRIPT_NEXT(script_pos, 1);			}			else			{				str_ptr = va_arg(args, char *);			}			if( (str = strstr(str, str_ptr)) &&			    (str < str_end) )			{				retval = storeValue(pe, &pv, str, 1);				str += strlen(str_ptr);			}			else			{				pe->position = str_end;				pe->op = op;				pe->args[0] = str_ptr;				retval = 0;			}			break;		case SPO_ExpectSpace:			str = skipChars(str, str_end);			retval = storeValue(pe, &pv, str, 1);			str = skipSpace(str, str_end);			script_pos++;			break;		case SPO_Character:		case SPO_Byte:		case SPO_HexByte:		case SPO_Short:		case SPO_HexShort:		case SPO_Integer:		case SPO_LongInteger:		case SPO_HexInteger:		case SPO_HexLongInteger:		case SPO_Float:		case SPO_Double:		case SPO_Count:		case SPO_String:		case SPO_NonEmptyString:			pv.type = op;			pv.value = str;			if( values )				pv.storage.p = values[values_pos++];			else				pv.storage.p = va_arg(args, void *);			script_pos++;			break;		case SPO_OneOf:			if( script )			{				str_ptr = script_pos->args[0];				script_pos = STRING_SCRIPT_NEXT(script_pos,								1);			}			else			{				str_ptr = va_arg(args, char *);			}			if( (new_pos = strpbrk(str, str_ptr)) &&			    (new_pos < str_end) )			{				retval = storeValue(pe, &pv, new_pos, 1);				retval = retval && pushFrame(pe,							     &ps,							     op,							     script_pos,							     values_pos,							     args);				str = new_pos;			}			else			{#ifdef VA_LIST_IS_ARRAY			        VA_LIST_COPY (args, tmp_args);#endif				skipBlock(script, values,					  &script_pos, &values_pos, &args);			}			break;		case SPO_Do:			ps.top->pv = pv;			retval = pushFrame(pe,					   &ps,					   op,					   script_pos,					   values_pos,					   args);			script_pos++;			break;		case SPO_While:			if( script )			{				str_ptr = script_pos->args[0];				term_ptr = script_pos->args[1];				script_pos = STRING_SCRIPT_NEXT(script_pos,								2);			}			else			{				str_ptr = va_arg(args, char *);				term_ptr = va_arg(args, char *);			}			if( (new_pos = strstr(str, str_ptr)) &&			    (new_pos < str_end) )			{				retval = storeValue(pe,						    &ps.top->prev->pv,						    new_pos,						    0);				retval = retval && storeValue(pe,							      &pv,							      new_pos,							      1);				str = new_pos + strlen(str_ptr);			}			else if( ((term_ptr[0] == '\0') ?				  (new_pos = str_end) :				  (new_pos = strstr(str, term_ptr))) &&				 (new_pos <= str_end) )			{				retval = storeValue(pe, &pv, new_pos, 1);				str = new_pos + strlen(term_ptr);				ps.top->op = SPO_Noop;			}			else			{				pe->position = str_end;				pe->op = op;				pe->args[0] = str_ptr;				pe->args[1] = term_ptr;				retval = 0;			}			break;		case SPO_SkipSpace:			str = skipSpace(str, str_end);			break;		case SPO_WhileSpace:			new_pos = skipChars(str, str_end);			retval = storeValue(pe, &pv, new_pos, 1);			str = skipSpace(new_pos, str_end);			if( str == str_end )			{				ps.top->op = SPO_Noop;			}			script_pos++;			break;		case SPO_Cond:			if( script )			{				str_ptr = script_pos->args[0];				script_pos = STRING_SCRIPT_NEXT(script_pos,								1);			}			else			{				str_ptr = va_arg(args, char *);			}			len = strlen(str_ptr);			new_pos = str;			if( ((pv.type == SPO_Noop) &&			     !strncmp(str, str_ptr, len)) ||			    ((pv.type != SPO_Noop) &&			     (new_pos = strstr(str, str_ptr)) &&			     (new_pos < str_end)) )			{				if( ps.top->op == SPO_OneOf )				{					ps.top->op = SPO_Noop;				}				else				{					retval = storeValue(pe,							    &pv,							    new_pos,							    1);				}				retval = retval && pushFrame(pe,							     &ps,							     op,							     script_pos,							     values_pos,							     args);				str = new_pos + len;			}			else			{#ifdef VA_LIST_IS_ARRAY			        VA_LIST_COPY (args, tmp_args);#endif				skipBlock(script, values,					  &script_pos, &values_pos, &args);			}			break;		case SPO_Handle:			{				int (*handler)(void *arg);				void *v_ptr;				if( script )				{					handler = (int (*)(void *))						script_pos->args[0];					v_ptr = script_pos->args[1];					script_pos =						STRING_SCRIPT_NEXT(script_pos,								   2);				}				else				{					handler = (int (*)(void *))						va_arg(args, void *);					v_ptr = va_arg(args, void *);				}				if( !(retval = handler(v_ptr)) )				{					pe->position = str;					pe->op = op;					pe->args[0] = handler;					pe->args[1] = v_ptr;				}			}			break;		case SPO_NotEmpty:			if( str < str_end )			{				retval = pushFrame(pe,						   &ps,						   op,						   script_pos,						   values_pos,						   args);			}			else			{#ifdef VA_LIST_IS_ARRAY			        VA_LIST_COPY (args, tmp_args);#endif				skipBlock(script, values,					  &script_pos, &values_pos, &args);			}			script_pos++;			break;		default:			assert(0);			break;		}		if( script )			op = script_pos->op;		else			op = va_arg(args, int);	}	if( retval && (str < str_end) )	{		if( pv.type == SPO_Noop )		{			pe->position = str;			pe->op = SPO_Noop;			retval = 0;		}		else		{			retval = storeValue(pe, &pv, str_end, 1);		}	}	cutFrames(&ps);	return( retval );}int parseString(char *str, int op, ...){	parseErrorInfo pe;	parsedString ps;	va_list args;	int retval;	assert(str != 0);		va_start(args, op);	ps.data = str;	ps.len = strlen(str);	retval = parseString_private(&pe, &ps, NULL, NULL, op, args);	va_end(args);	return( retval );}int parseString_error(parseErrorInfo *pe, char *str, int op, ...){	parsedString ps;	va_list args;	int retval;	assert(str != 0);		va_start(args, op);	ps.data = str;	ps.len = strlen(str);	retval = parseString_private(pe, &ps, NULL, NULL, op, args);	va_end(args);	return( retval );}int parseSubString(parsedString *ps, int op, ...){	parseErrorInfo pe;	va_list args;	int retval;	assert(ps != 0);		va_start(args, op);	retval = parseString_private(&pe, ps, NULL, NULL, op, args);	va_end(args);	return( retval );}int parseString_script(char *str, stringScript *ss, ...){	parseErrorInfo pe;	parsedString ps;	va_list args;	int retval;	va_start(args, ss);	ps.data = str;	ps.len = strlen(str);	retval = parseString_private(&pe, &ps, ss, NULL, SPO_Noop, args);	va_end(args);	return( retval );}int parseString_script_values(char *str, stringScript *ss, void **values){	parseErrorInfo pe;	parsedString ps;	int retval;	va_list * args;	args = KCALLOC(1, sizeof(args));	ps.data = str;	ps.len = strlen(str);	retval = parseString_private(&pe, &ps, ss, values, SPO_Noop, *args);	KFREE(args);	return( retval );}char *promoteParsedString(parsedString *ps){	char *retval;	if( (retval = spMalloc(ps->len + 1)) )	{		strncpy(retval, ps->data, ps->len);		retval[ps->len] = '\0';	}	return( retval );}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?