stringparsing.c

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

C
883
字号
/* * stringParsing.c * A handy string parsing function. * * Copyright (c) 2000, 2001, 2002, 2003 The University of Utah and the Flux Group. * All rights reserved. * * @JANOSVM_KAFFE_MISC_LICENSE@ */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <assert.h>#include "stringParsing.h"/* We use this in JSI stuff too, and we don't want to drag in kaffe goo. */#include "gtypes.h"#include "gc.h"#include "defs.h"#define spMalloc(x) gc_malloc(x, GC_ALLOC_FIXED)#define spFree(x) gc_free(x)int cmpPStrStr(parsedString *ps, char *str){	char *ps_pos, *ps_end;	int retval = 0;	assert(ps != 0);	assert(str != 0);		for( ps_pos = ps->data, ps_end = ps->data + ps->len;	     !retval && (ps_pos < ps_end) && *str;	     ps_pos++, str++ )	{		if( *ps_pos != *str )		{			/* XXX */			retval = *ps_pos - *str;		}	}	if( !retval && ((ps_pos != ps_end) || (*str != 0)) )	{		/* XXX */		retval = 1;	}	return( retval );}typedef struct _parseValue {	int type;	char *value;	union {		void *p;		char *c;		short *s;		int *i;		float *f;		double *d;		long long *ll;		parsedString *ps;	} storage;} parseValue;typedef struct _parseFrame {	struct _parseFrame *prev;	int op;	parseValue pv;	stringScript *script_pos;	int values_pos;	va_list args;} parseFrame;#define PREALLOC_FRAMES 8typedef struct _parseStack {	struct _parseFrame *top;	struct _parseFrame frames[PREALLOC_FRAMES];	int depth;} parseStack;staticint pushFrame(parseErrorInfo *pe,	      parseStack *ps,	      int op,	      stringScript *script_pos,	      int values_pos,	      va_list args){	parseFrame *pf;	int retval = 0;	assert(ps != 0);	ps->depth++;	if( ps->depth < PREALLOC_FRAMES )	{		pf = &ps->frames[ps->depth];	}	else	{		pf = spMalloc(sizeof(parseFrame));	}	if( pf )	{		pf->prev = ps->top;		pf->op = op;		pf->pv.type = SPO_Noop;		pf->script_pos = script_pos;		pf->values_pos = values_pos;		VA_LIST_COPY(pf->args, args);		ps->top = pf;		retval = 1;	}	else	{		pe->position = 0;		pe->op = op;	}	return( retval );}staticvoid popFrame(parseStack *ps){	parseFrame *prev;	assert(ps != 0);	prev = ps->top->prev;	if( ps->depth >= PREALLOC_FRAMES )		spFree(ps->top);	ps->depth--;	ps->top = prev;}staticvoid cutFrames(parseStack *ps){	assert(ps != 0);		while( ps->depth >= PREALLOC_FRAMES )	{		popFrame(ps);	}}staticint storeValue(parseErrorInfo *pe, parseValue *pv, char *str, int clear){	int retval = 1;	assert(pv != 0);	assert(str != 0);		switch( pv->type )	{	case SPO_String:		pv->storage.ps->data = pv->value;		pv->storage.ps->len = str - pv->value;		break;	case SPO_NonEmptyString:		if( (str - pv->value) > 0 )		{			pv->storage.ps->data = pv->value;			pv->storage.ps->len = str - pv->value;		}		else		{			retval = 0;		}		break;	case SPO_Character:		if( (str - pv->value) == 1 )			*pv->storage.c = pv->value[0];		else			retval = 0;		break;	case SPO_Byte:		if( strncasecmp(pv->value, "0x", 2) == 0 )		{			int c;						if( sscanf(&pv->value[2], "%x", &c) != 1 )				retval = 0;			else				*pv->storage.c = (char)(c & 0xff);		}		else		{			int c;						if( sscanf(pv->value, "%d", &c) != 1 )				retval = 0;			else				*pv->storage.c = (char)(c & 0xff);		}		break;	case SPO_HexByte:		{			int c;						if( !(((strncasecmp(pv->value, "0x", 2) == 0) &&			       (sscanf(&pv->value[2], "%x", &c) == 1)) ||			      (sscanf(pv->value, "%x", &c) == 1)) )			{				retval = 0;			}			else			{				*pv->storage.c = (char)(c & 0xff);			}		}		break;	case SPO_Short:		if( strncasecmp(pv->value, "0x", 2) == 0 )		{			if( sscanf(&pv->value[2], "%hx", pv->storage.s) != 1 )				retval = 0;		}		else		{			if( sscanf(pv->value, "%hd", pv->storage.s) != 1 )				retval = 0;		}		break;	case SPO_HexShort:		if( !(((strncasecmp(pv->value, "0x", 2) == 0) &&		       (sscanf(&pv->value[2], "%hx", pv->storage.s) == 1)) ||		      (sscanf(pv->value, "%hx", pv->storage.s) == 1)) )		{			retval = 0;		}		break;	case SPO_Integer:		if( strncasecmp(pv->value, "0x", 2) == 0 )		{			if( sscanf(&pv->value[2], "%x", pv->storage.i) != 1 )				retval = 0;		}		else		{			if( sscanf(pv->value, "%d", pv->storage.i) != 1 )				retval = 0;		}		break;	case SPO_LongInteger:		if( strncasecmp(pv->value, "0x", 2) == 0 )		{			if( sscanf(&pv->value[2], "%qx", pv->storage.ll) != 1 )				retval = 0;		}		else		{			if( sscanf(pv->value, "%qd", pv->storage.ll) != 1 )				retval = 0;		}		break;	case SPO_HexInteger:		if( !(((strncasecmp(pv->value, "0x", 2) == 0) &&		       (sscanf(&pv->value[2], "%x", pv->storage.i) == 1)) ||		      (sscanf(pv->value, "%x", pv->storage.i) == 1)) )		{			retval = 0;		}		break;	case SPO_HexLongInteger:		if( !(((strncasecmp(pv->value, "0x", 2) == 0) &&		       (sscanf(&pv->value[2], "%qx", pv->storage.ll) == 1)) ||		      (sscanf(pv->value, "%qx", pv->storage.ll) == 1)) )		{			retval = 0;		}		break;	case SPO_Float:		if( sscanf(pv->value, "%f", pv->storage.f) != 1 )		{			retval = 0;		}		break;	case SPO_Double:		if( sscanf(pv->value, "%lf", pv->storage.d) != 1 )		{			retval = 0;		}		break;	case SPO_Count:		pv->storage.i[0]++;		break;	default:		break;	}	if( clear )		pv->type = SPO_Noop;	if( retval == 0 )	{		pe->position = pv->value;		pe->op = pv->type;	}	return( retval );}staticvoid skipBlock(stringScript *script, void **values,	       stringScript **script_pos, int *values_pos, va_list *args){	int op, skip_depth = 0;	/* Used to quiet the compiler */	char *c_ptr;	void *v_ptr;	if( script )	{		op = (*script_pos)->op;	}	else	{		op = va_arg(*args, int);	}	while( skip_depth >= 0 )	{		switch( op )		{		case SPO_End:			skip_depth--;			(*script_pos)++;			break;		case SPO_Noop:			(*script_pos)++;			break;		case SPO_Cond:			if( script )			{				(*script_pos) = STRING_SCRIPT_NEXT(*script_pos,								   1);			}			else			{				c_ptr = va_arg(*args, char *);			}			skip_depth++;			break;		case SPO_Do:		case SPO_NotEmpty:			skip_depth++;			(*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_NonEmptyString:		case SPO_String:			if( values )				(*values_pos)++;			else				v_ptr = va_arg(*args, void *);			(*script_pos)++;			break;		case SPO_While:			if( script )			{				(*script_pos) = STRING_SCRIPT_NEXT(*script_pos,								   2);			}			else			{				c_ptr = va_arg(*args, char *);				c_ptr = va_arg(*args, char *);			}			break;		case SPO_Expect:			if( script )			{				(*script_pos) = STRING_SCRIPT_NEXT(*script_pos,								   1);			}			else			{				c_ptr = va_arg(*args, char *);			}			break;		case SPO_WhileSpace:		case SPO_ExpectSpace:			(*script_pos)++;			break;		case SPO_Handle:			if( script )			{				(*script_pos) = STRING_SCRIPT_NEXT(*script_pos,								   2);			}			else			{				v_ptr = va_arg(*args, void *);				v_ptr = va_arg(*args, void *);			}			break;		case SPO_OneOf:			if( script )			{				(*script_pos) = STRING_SCRIPT_NEXT(*script_pos,								   1);			}			else			{				c_ptr = va_arg(*args, char *);			}			break;		}		if( skip_depth >= 0 )		{			if( script )				op = (*script_pos)->op;			else				op = va_arg(*args, int);		}	}}staticchar *skipChars(unsigned char *str, unsigned char *str_end){	assert(str != 0);	assert(str_end != 0);		while( (str < str_end) && !isspace(*str) )	{		str++;	}

⌨️ 快捷键说明

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