Пример #1
0
Файл: s-mold.c Проект: Oldes/r3
*/  REBSER *Prep_String(REBSER *series, REBYTE **str, REBCNT len)
/*
**		Helper function for the string related Mold functions below.
**		Creates or expands the series and provides the location to
**		copy text into.
**
***********************************************************************/
{
	REBCNT tail;

	if (!series) {
		series = Make_Binary(len);
		series->tail = len;
		*str = STR_HEAD(series);
	}
	else {
		tail = SERIES_TAIL(series);
		EXPAND_SERIES_TAIL(series, len);
		*str = STR_SKIP(series, tail);
	}
	return series;
}
Пример #2
0
x*/	REBCNT Match_2_String(REBSER *series, REBCNT index, REBYTE *str, REBCNT len, REBINT uncase)
/*
**		(Evaluate if there is another function to use. ???!!!)
**
**		Used for: PARSE function
**
***********************************************************************/
{
	REBYTE *ser = STR_SKIP(series, index);
	REBCNT tail = series->tail;

	if (uncase) {
		for (;len > 0 && index < tail; index++, len--) {
			if (*ser++ != *str++) return 0;
		}
	} else {
		for (;len > 0 && index < tail; index++, len--) {
			if (LO_CASE(*ser++) != LO_CASE(*str++)) return 0;
		}
	}
	if (len == 0) return index;
	return 0;
}
Пример #3
0
*/	static REBCNT Parse_Next_String(REBPARSE *parse, REBCNT index, REBVAL *item, REBCNT depth)
/*
**		Match the next item in the string ruleset.
**
**		If it matches, return the index just past it.
**		Otherwise return NOT_FOUND.
**
***********************************************************************/
{
	// !!! THIS CODE NEEDS CLEANUP AND REWRITE BASED ON OTHER CHANGES
	REBSER *series = parse->series;
	REBSER *ser;
	REBCNT flags = parse->flags | AM_FIND_MATCH | AM_FIND_TAIL;
	int rewrite_needed;

	if (Trace_Level) {
		Trace_Value(7, item);
		Trace_String(8, STR_SKIP(series, index), series->tail - index);
	}

	if (IS_NONE(item)) return index;

	if (index >= series->tail) return NOT_FOUND;

	switch (VAL_TYPE(item)) {

	// Do we match a single character?
	case REB_CHAR:
		if (HAS_CASE(parse))
			index = (VAL_CHAR(item) == GET_ANY_CHAR(series, index)) ? index+1 : NOT_FOUND;
		else
			index = (UP_CASE(VAL_CHAR(item)) == UP_CASE(GET_ANY_CHAR(series, index))) ? index+1 : NOT_FOUND;
		break;

	case REB_EMAIL:
	case REB_STRING:
	case REB_BINARY: 
		index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), flags);
		break;

	// Do we match to a char set?
	case REB_BITSET:
		flags = Check_Bit(VAL_SERIES(item), GET_ANY_CHAR(series, index), !HAS_CASE(parse));
		index = flags ? index + 1 : NOT_FOUND;
		break;
/*
	case REB_DATATYPE:	// Currently: integer!
		if (VAL_DATATYPE(item) == REB_INTEGER) {
			REBCNT begin = index;
			while (IS_LEX_NUMBER(*str)) str++, index++;
			if (begin == index) index = NOT_FOUND;
		}
		break;
*/
	case REB_TAG:
	case REB_FILE:
//	case REB_ISSUE:
		// !! Can be optimized (w/o COPY)
		ser = Copy_Form_Value(item, 0);
		index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, ser, 0, ser->tail, flags);
		break;

	case REB_NONE:
		break;

	// Parse a sub-rule block:
	case REB_BLOCK:
		index = Parse_Rules_Loop(parse, index, VAL_BLK_DATA(item), depth);
		break;

	// Do an expression:
	case REB_PAREN:
		item = Do_Block_Value_Throw(item); // might GC
		// old: if (IS_ERROR(item)) Throw_Error(VAL_ERR_OBJECT(item));
        index = MIN(index, series->tail); // may affect tail
		break;

	default:
		Trap1(RE_PARSE_RULE, item);
	}

	return index;
}