예제 #1
0
	void PaddingLTRBPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue width = StyleSetValue::from_length(0.0f);

		size_t pos = 0;
		StyleToken token = next_token(pos, tokens);
		if (token.type == StyleTokenType::ident && pos == tokens.size())
		{
			if (equals(token.value, "inherit"))
				width = StyleSetValue::from_keyword("inherit");
			else
				return;
		}
		else if (is_length(token) && pos == tokens.size())
		{
			if (!parse_length(token, width))
			{
				return;
			}
		}
		else if (token.type == StyleTokenType::percentage && pos == tokens.size())
		{
			width = StyleSetValue::from_percentage(StringHelp::text_to_float(token.value));
		}
		else if (token.type == StyleTokenType::delim && token.value == "-")
		{
			token = next_token(pos, tokens);
			if (is_length(token) && pos == tokens.size())
			{
				StyleSetValue length;
				if (parse_length(token, length))
				{
					length.number = -length.number;
					width = length;
				}
				else
				{
					return;
				}
			}
			else if (token.type == StyleTokenType::percentage && pos == tokens.size())
			{
				width = StyleSetValue::from_percentage(-StringHelp::text_to_float(token.value));
			}
			else
			{
				return;
			}
		}
		else
		{
			return;
		}

		setter->set_value(name, width);
	}
void CL_CSSParserBorderSpacing::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set)
{
	CL_CSSBoxLength length1, length2;

	size_t pos = 0;
	CL_CSSToken token = next_token(pos, tokens);
	if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && pos == tokens.size())
	{
		properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_inherit;
		if (out_change_set)
		{
			(*out_change_set)["border-spacing"] = &properties.border_spacing;
		}
		return;
	}
	else if (is_length(token))
	{
		if (!parse_length(token, length1))
		{
			debug_parse_error(name, tokens);
			return;
		}
	}
	else
	{
		debug_parse_error(name, tokens);
		return;
	}

	if (pos != tokens.size())
	{
		token = next_token(pos, tokens);
		if (is_length(token) && pos == tokens.size())
		{
			if (parse_length(token, length2))
			{
				properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_two_lengths;
				properties.border_spacing.length1 = length1;
				properties.border_spacing.length2 = length2;
			}
		}
	}
	else
	{
		properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_one_length;
		properties.border_spacing.length1 = length1;
	}
	if (out_change_set)
	{
		(*out_change_set)["border-spacing"] = &properties.border_spacing;
	}
}
예제 #3
0
void CL_CSSParserTop::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set)
{
	size_t pos = 0;
	CL_CSSToken token = next_token(pos, tokens);
	if (token.type == CL_CSSToken::type_ident && pos == tokens.size())
	{
		if (equals(token.value, "auto"))
			properties.top.type = CL_CSSBoxTop::type_auto;
		else if (equals(token.value, "inherit"))
			properties.top.type = CL_CSSBoxTop::type_inherit;
	}
	else if (is_length(token) && pos == tokens.size())
	{
		CL_CSSBoxLength length;
		if (parse_length(token, length))
		{
			properties.top.type = CL_CSSBoxTop::type_length;
			properties.top.length = length;
		}
	}
	else if (token.type == CL_CSSToken::type_percentage && pos == tokens.size())
	{
		properties.top.type = CL_CSSBoxTop::type_percentage;
		properties.top.percentage = CL_StringHelp::text_to_float(token.value);
	}
	else if (token.type == CL_CSSToken::type_delim && token.value == "-")
	{
		token = next_token(pos, tokens);
		if (is_length(token) && pos == tokens.size())
		{
			CL_CSSBoxLength length;
			if (parse_length(token, length))
			{
				length.value = -length.value;
				properties.top.type = CL_CSSBoxTop::type_length;
				properties.top.length = length;
			}
		}
		else if (token.type == CL_CSSToken::type_percentage && pos == tokens.size())
		{
			properties.top.type = CL_CSSBoxTop::type_percentage;
			properties.top.percentage = -CL_StringHelp::text_to_float(token.value);
		}
	}
	if (out_change_set)
	{
		(*out_change_set)["top"] = &properties.top;
	}
}
void CL_CSSParserMinHeight::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set)
{
	size_t pos = 0;
	CL_CSSToken token = next_token(pos, tokens);
	if (token.type == CL_CSSToken::type_ident && pos == tokens.size())
	{
		if (equals(token.value, "inherit"))
			properties.min_height.type = CL_CSSBoxMinHeight::type_inherit;
	}
	else if (is_length(token) && pos == tokens.size())
	{
		CL_CSSBoxLength length;
		if (parse_length(token, length))
		{
			properties.min_height.type = CL_CSSBoxMinHeight::type_length;
			properties.min_height.length = length;
		}
	}
	else if (token.type == CL_CSSToken::type_percentage && pos == tokens.size())
	{
		properties.min_height.type = CL_CSSBoxMinHeight::type_percentage;
		properties.min_height.percentage = CL_StringHelp::text_to_float(token.value);
	}
	if (out_change_set)
	{
		(*out_change_set)["min-height"] = &properties.min_height;
	}
}
예제 #5
0
HTMLStyle *
html_style_add_width (HTMLStyle *style,const gchar *len)
{
	if (!style)
		style = html_style_new ();

	g_free (style->width);

	style->width = parse_length (len);

	return style;
}
예제 #6
0
HTMLStyle *
html_style_add_height (HTMLStyle *style,const gchar *len)
{
	if (!style)
		style = html_style_new ();

	g_free (style->height);

	style->height = parse_length (len);

	return style;
}
예제 #7
0
void
html_length_array_parse (GPtrArray *array,
                         const gchar *str)
{
	HTMLLength *length;

	if (str == NULL)
		return;

	while ((length = parse_length (&str)))
	       g_ptr_array_add (array, length);
}
예제 #8
0
/* If a single value is provided, min and max are both set to the value */
static void
parse_lengths(const char *s, struct xt_length_info *info)
{
	char *buffer;
	char *cp;

	buffer = strdup(s);
	if ((cp = strchr(buffer, ':')) == NULL)
		info->min = info->max = parse_length(buffer);
	else {
		*cp = '\0';
		cp++;

		info->min = buffer[0] ? parse_length(buffer) : 0;
		info->max = cp[0] ? parse_length(cp) : 0xFFFF;
	}
	free(buffer);
	
	if (info->min > info->max)
		exit_error(PARAMETER_PROBLEM,
		           "length min. range value `%u' greater than max. "
		           "range value `%u'", info->min, info->max);
	
}
예제 #9
0
파일: content.cpp 프로젝트: rombust/UICore
	void WidthPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue width;

		size_t pos = 0;
		StyleToken token = next_token(pos, tokens);
		if (token.type == StyleTokenType::ident && pos == tokens.size())
		{
			if (equals(token.value, "auto"))
				width = StyleSetValue::from_keyword("auto");
			else if (equals(token.value, "inherit"))
				width = StyleSetValue::from_keyword("inherit");
			else
				return;
		}
		else if (is_length(token) && pos == tokens.size())
		{
			StyleSetValue length;
			if (parse_length(token, length) && length.number >= 0.0f)
			{
				width = length;
			}
			else
			{
				return;
			}
		}
		else if (token.type == StyleTokenType::percentage && pos == tokens.size())
		{
			float v = Text::parse_float(token.value);
			if (v >= 0.0f)
			{
				width = StyleSetValue::from_percentage(v);
			}
			else
			{
				return;
			}
		}
		else
		{
			return;
		}

		setter->set_value("width", width);
	}
예제 #10
0
void CSSParserLineHeight::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
    std::unique_ptr<CSSValueLineHeight> line_height(new CSSValueLineHeight());

    size_t pos = 0;
    CSSToken token = next_token(pos, tokens);
    if (token.type == CSSToken::type_ident && pos == tokens.size())
    {
        if (equals(token.value, "normal"))
            line_height->type = CSSValueLineHeight::type_normal;
        else if (equals(token.value, "inherit"))
            line_height->type = CSSValueLineHeight::type_inherit;
        else
            return;
    }
    else if (token.type == CSSToken::type_number && pos == tokens.size())
    {
        line_height->type = CSSValueLineHeight::type_number;
        line_height->number = StringHelp::text_to_float(token.value);
    }
    else if (is_length(token) && pos == tokens.size())
    {
        CSSLength length;
        if (parse_length(token, length))
        {
            line_height->type = CSSValueLineHeight::type_length;
            line_height->length = length;
        }
        else
        {
            return;
        }
    }
    else if (token.type == CSSToken::type_percentage && pos == tokens.size())
    {
        line_height->type = CSSValueLineHeight::type_percentage;
        line_height->percentage = StringHelp::text_to_float(token.value);
    }
    else
    {
        return;
    }

    inout_values.push_back(std::move(line_height));
}
예제 #11
0
	void FlexBasisPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue flex_basis;

		size_t pos = 0;
		StyleToken token = next_token(pos, tokens);
		if (token.type == StyleTokenType::ident && pos == tokens.size())
		{
			if (equals(token.value, "main-size"))
				flex_basis = StyleSetValue::from_keyword("main-size");
			else if (equals(token.value, "inherit"))
				flex_basis = StyleSetValue::from_keyword("inherit");
			else
				return;
		}
		else if (is_length(token) && pos == tokens.size())
		{
			StyleSetValue length;
			if (parse_length(token, length) && length.number >= 0.0f)
			{
				flex_basis = length;
			}
			else
			{
				return;
			}
		}
		else if (token.type == StyleTokenType::percentage && pos == tokens.size())
		{
			float v = StringHelp::text_to_float(token.value);
			if (v >= 0.0f)
			{
				flex_basis = StyleSetValue::from_percentage(v);
			}
			else
			{
				return;
			}
		}

		setter->set_value("flex-basis", flex_basis);
	}
void CL_CSSParserFontSize::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens)
{
	size_t pos = 0;
	CL_CSSToken token = next_token(pos, tokens);
	if (token.type == CL_CSSToken::type_ident && pos == tokens.size())
	{
		if (token.value == "xx-small")
			properties.font_size.type = CL_CSSBoxFontSize::type_xx_small;
		else if (token.value == "x-small")
			properties.font_size.type = CL_CSSBoxFontSize::type_x_small;
		else if (token.value == "small")
			properties.font_size.type = CL_CSSBoxFontSize::type_small;
		else if (token.value == "medium")
			properties.font_size.type = CL_CSSBoxFontSize::type_medium;
		else if (token.value == "large")
			properties.font_size.type = CL_CSSBoxFontSize::type_large;
		else if (token.value == "x-large")
			properties.font_size.type = CL_CSSBoxFontSize::type_x_large;
		else if (token.value == "xx-large")
			properties.font_size.type = CL_CSSBoxFontSize::type_xx_large;
		else if (token.value == "smaller")
			properties.font_size.type = CL_CSSBoxFontSize::type_smaller;
		else if (token.value == "larger")
			properties.font_size.type = CL_CSSBoxFontSize::type_larger;
		else if (token.value == "inherit")
			properties.font_size.type = CL_CSSBoxFontSize::type_inherit;
	}
	else if (is_length(token) && pos == tokens.size())
	{
		CL_CSSBoxLength length;
		if (parse_length(token, length))
		{
			properties.font_size.type = CL_CSSBoxFontSize::type_length;
			properties.font_size.length = length;
		}
	}
	else if (token.type == CL_CSSToken::type_percentage && pos == tokens.size())
	{
		properties.font_size.type = CL_CSSBoxFontSize::type_percentage;
		properties.font_size.percentage = CL_StringHelp::text_to_float(token.value);
	}
}
예제 #13
0
파일: content.cpp 프로젝트: rombust/UICore
	void MaxHeightPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue max_height;

		size_t pos = 0;
		StyleToken token = next_token(pos, tokens);
		if (token.type == StyleTokenType::ident && pos == tokens.size())
		{
			if (equals(token.value, "none"))
				max_height = StyleSetValue::from_keyword("none");
			else if (equals(token.value, "inherit"))
				max_height = StyleSetValue::from_keyword("inherit");
			else
				return;
		}
		else if (is_length(token) && pos == tokens.size())
		{
			StyleSetValue length;
			if (parse_length(token, length))
			{
				max_height = length;
			}
			else
			{
				return;
			}
		}
		else if (token.type == StyleTokenType::percentage && pos == tokens.size())
		{
			max_height = StyleSetValue::from_percentage(Text::parse_float(token.value));
		}
		else
		{
			return;
		}

		setter->set_value("max-height", max_height);
	}
예제 #14
0
void CSSParserOutlineWidth::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	std::unique_ptr<CSSValueOutlineWidth> outline_width(new CSSValueOutlineWidth());

	size_t pos = 0;
	CSSToken token = next_token(pos, tokens);
	if (token.type == CSSToken::type_ident && pos == tokens.size())
	{
		if (equals(token.value, "thin"))
			outline_width->type = CSSValueOutlineWidth::type_thin;
		else if (equals(token.value, "medium"))
			outline_width->type = CSSValueOutlineWidth::type_medium;
		else if (equals(token.value, "thick"))
			outline_width->type = CSSValueOutlineWidth::type_thick;
		else if (equals(token.value, "inherit"))
			outline_width->type = CSSValueOutlineWidth::type_inherit;
		else
			return;
	}
	else if (is_length(token) && pos == tokens.size())
	{
		CSSLength length;
		if (parse_length(token, length))
		{
			outline_width->type = CSSValueOutlineWidth::type_length;
			outline_width->length = length;
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}

	inout_values.push_back(std::move(outline_width));
}
void CL_CSSParserPaddingLTRB::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens)
{
	CL_CSSBoxPaddingWidth *width = 0;
	if (name == "padding-top")
		width = &properties.padding_width_top;
	else if (name == "padding-right")
		width = &properties.padding_width_right;
	else if (name == "padding-bottom")
		width = &properties.padding_width_bottom;
	else if (name == "padding-left")
		width = &properties.padding_width_left;

	if (width)
	{
		size_t pos = 0;
		CL_CSSToken token = next_token(pos, tokens);
		if (token.type == CL_CSSToken::type_ident && pos == tokens.size())
		{
			if (token.value == "inherit")
				width->type = CL_CSSBoxPaddingWidth::type_inherit;
		}
		else if (is_length(token) && pos == tokens.size())
		{
			CL_CSSBoxLength length;
			if (parse_length(token, length))
			{
				width->type = CL_CSSBoxPaddingWidth::type_length;
				width->length = length;
			}
		}
		else if (token.type == CL_CSSToken::type_percentage && pos == tokens.size())
		{
			width->type = CL_CSSBoxPaddingWidth::type_percentage;
			width->percentage = CL_StringHelp::text_to_float(token.value);
		}
	}
}
예제 #16
0
	bool FlexPropertyParser::parse_basis(StyleSetValue &basis, size_t &parse_pos, const std::vector<StyleToken> &tokens)
	{
		size_t pos = parse_pos;
		StyleToken token = next_token(pos, tokens);

		if (token.type == StyleTokenType::ident)
		{
			if (equals(token.value, "main-size"))
				basis = StyleSetValue::from_keyword("main-size");
			else
				return false;
		}
		else if (is_length(token))
		{
			StyleSetValue length;
			if (parse_length(token, length) && length.number >= 0.0f)
			{
				basis = length;
			}
		}
		else if (token.type == StyleTokenType::percentage)
		{
			float v = StringHelp::text_to_float(token.value);
			if (v >= 0.0f)
			{
				basis = StyleSetValue::from_percentage(v);
			}
		}
		else
		{
			return false;
		}

		parse_pos = pos;
		return true;
	}
예제 #17
0
파일: parse.c 프로젝트: Meai1/libpsyc
static inline
#endif
PsycParseIndexRC
psyc_parse_index (PsycParseIndexState *state, PsycString *idx)
{
    ParseRC ret;

    if (state->cursor >= state->buffer.length)
	return PSYC_PARSE_INDEX_END;

    state->startc = state->cursor;

    switch (state->part) {
    case PSYC_INDEX_PART_START:
    case PSYC_INDEX_PART_TYPE:
	idx->length = 0;
	idx->data = NULL;

	switch (state->buffer.data[state->cursor]) {
	case '#':
	    state->part = PSYC_INDEX_PART_LIST;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
	    goto PSYC_INDEX_PART_LIST;
	case '.':
	    state->part = PSYC_INDEX_PART_DICT;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
	    goto PSYC_INDEX_PART_STRUCT;
	case '{':
	    state->part = PSYC_INDEX_PART_DICT;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
	    goto PSYC_INDEX_PART_DICT_LENGTH;
	default:
	    return PSYC_PARSE_INDEX_ERROR_TYPE;
	}

    case PSYC_INDEX_PART_LIST:
    PSYC_INDEX_PART_LIST:
	switch (parse_length((ParseState*)state, &idx->length)) {
	case PARSE_SUCCESS: // list index is complete
	    state->part = PSYC_INDEX_PART_TYPE;
	    return PSYC_PARSE_INDEX_LIST;
	case PARSE_INSUFFICIENT: // list index at the end of buffer
	    return PSYC_PARSE_INDEX_LIST_LAST;
	case PARSE_ERROR: // no index
	    return PSYC_PARSE_INDEX_ERROR_LIST;
	default: // should not be reached
	    return PSYC_PARSE_INDEX_ERROR;
	}

    case PSYC_INDEX_PART_STRUCT:
    PSYC_INDEX_PART_STRUCT:
	switch (parse_keyword((ParseState*)state, idx)) {
	case PARSE_SUCCESS: // end of keyword
	    state->part = PSYC_INDEX_PART_TYPE;
	    return PSYC_PARSE_INDEX_STRUCT;
	case PARSE_INSUFFICIENT: // end of buffer
	    return PSYC_PARSE_INDEX_STRUCT_LAST;
	case PARSE_ERROR: // no keyword
	    return PSYC_PARSE_INDEX_ERROR_STRUCT;
	default: // should not be reached
	    return PSYC_PARSE_INDEX_ERROR;
	}

    case PSYC_INDEX_PART_DICT_LENGTH:
    PSYC_INDEX_PART_DICT_LENGTH:
	switch (parse_length((ParseState*)state, &state->elemlen)) {
	case PARSE_SUCCESS: // length is complete
	    state->elemlen_found = 1;
	    state->elem_parsed = 0;
	    idx->length = state->elemlen;
	    idx->data = NULL;

	    if (state->buffer.data[state->cursor] != ' ')
		return PSYC_PARSE_INDEX_ERROR_DICT_LENGTH;

	    state->part = PSYC_INDEX_PART_DICT;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
	    break;
	case PARSE_INSUFFICIENT: // length is incomplete
	    return PSYC_PARSE_DICT_INSUFFICIENT;
	case PARSE_ERROR: // no length
	    state->part = PSYC_INDEX_PART_DICT;
	    break;
	default: // should not be reached
	    return PSYC_PARSE_INDEX_ERROR;
	}
	// fall thru

    case PSYC_INDEX_PART_DICT:
	if (state->elemlen_found) {
	    switch (parse_binary((ParseState*)state, state->elemlen, idx,
				 &state->elem_parsed)) {
	    case PARSE_SUCCESS:
		if (idx->length == state->elem_parsed)
		    ret = PSYC_PARSE_INDEX_DICT;
		else
		    ret = PSYC_PARSE_INDEX_DICT_END;
		break;
	    case PARSE_INCOMPLETE:
		if (idx->length == state->elem_parsed)
		    ret = PSYC_PARSE_INDEX_DICT_START;
		else
		    ret = PSYC_PARSE_INDEX_DICT_CONT;
		break;
	    default: // should not be reached
		return PSYC_PARSE_INDEX_ERROR_DICT;
	    }
	} else {
	    switch (parse_until((ParseState*)state, '}', idx)) {
	    case PARSE_SUCCESS:
		ret = PSYC_PARSE_INDEX_DICT;
		break;
	    case PARSE_INSUFFICIENT:
		return PSYC_PARSE_INDEX_INSUFFICIENT;
	    default: // should not be reached
		return PSYC_PARSE_INDEX_ERROR_DICT;
	    }
	}

	state->part = PSYC_INDEX_PART_TYPE;
	state->cursor++;
	return ret;
    }

    return PSYC_PARSE_INDEX_ERROR; // should not be reached
}
예제 #18
0
파일: client.c 프로젝트: kulhos/pip
/*
*	   ClConnect:
*
*	   Description:
*	   $ZCall to allow a PROFILE MUMPS client process to connect to a
*	   UNIX Message Transport Monitor on a remote host.
*
*/
void
ClConnect(int count,char *addr,SLONG *return_code)
{
	RETURNSTATUS		rc = SUCCESS;
	struct sockaddr_in	client_addr;
	char			server_ip_address[IP_ADDR_LEN+1];
	short			server_port;
	char			cLength[32];
	int			iSize = 0, iOffset = 0;
	char			cFormat = '\0';
	char			cHeader = '\0';

	*return_code = SUCCESS;

#ifdef DEBUG
	(void)fprintf(stdout,"CLIENT CONNECT:\n");
	(void)fflush(stdout);
#endif

	/*
	*	Set up timer functions
	*/
	ClTimeout.type = sca_AlarmSetup(1);

	/*
	*	Check if client is already connected. If so, disconnect then
	*	re-connect.
	*/
	if(MTMClientSd != DISCONNECTED)
	{
		MTM_LOG(EISCONN);
		(void)close(MTMClientSd);
	}

	/*
	*	   Initialize to defaults.
	*/
	MTMClientSd = DISCONNECTED;
	memset(cLength,0,sizeof(cLength));
	sscanf(addr, "%[^/]/%hd/%s", server_ip_address, &server_port, cLength);

	/*
	*	Parse the length
	*/
	if (parse_length(cLength,&ClLength) == FAILURE)
	{
		*return_code = EINVAL;
		MTM_LOG(*return_code);
		return;
	} 
	
	memset((char *)&client_addr, 0, sizeof(client_addr));
	client_addr.sin_family = AF_INET;
	client_addr.sin_port = htons(server_port);
	client_addr.sin_addr.s_addr = inet_addr(server_ip_address);
	memset(client_addr.sin_zero,0,8);

#ifdef DEBUG
	(void)fprintf(stdout,"\tPort %d\n",client_addr.sin_port);
	(void)fprintf(stdout,"\tIP Address %s\n",server_ip_address);
	(void)fprintf(stdout,"\tLength Format: %c\n",ClLength.format);
	(void)fprintf(stdout,"\tLength Header: %c\n",ClLength.header);
	(void)fprintf(stdout,"\tLength Size: %d\n",ClLength.lsize);
	(void)fprintf(stdout,"\tHeader Size: %d\n",ClLength.hsize);
	(void)fprintf(stdout,"\tLeading Count: %d\n",ClLength.lcount);
	(void)fprintf(stdout,"\tTrailing Count: %d\n",ClLength.tcount);
	(void)fflush(stdout);
#endif

	/*
 	*	Allocate memory for client message buffer
 	*/
	if (ClMsgBuffer == NULL)
		ClMsgBuffer = (char *) malloc (MAX_MSG_SIZE);
	if (ClMsgBuffer == NULL)
	{
		MTM_LOG (errno);
		*return_code = errno;
		return;
	}

	/*
	*	Get a properly connected socket
	*/
	ClTimeout.value = 10;

	sca_SetupTimer((void *)ClConnect, &ClTimeout, (void *)cl_signal_catcher);

	MTMClientSd = sca_connect((void *)&client_addr,
				sizeof(struct sockaddr_in),
				&ClTimeout,
				return_code);

	sca_CancelTimer((void *)ClConnect, &ClTimeout);

	/*
	*	Close socket and release memory if there were any errors.
	*/
	if (*return_code != SUCCESS)
	{
		MTM_LOG(*return_code);

		if (MTMClientSd != DISCONNECTED)
		{
			close(MTMClientSd);
			MTMClientSd = DISCONNECTED;
		}
		if (ClMsgBuffer)
		{
			free(ClMsgBuffer);
			ClMsgBuffer = NULL;
		}
	}

#ifdef DEBUG
	(void)fprintf(stdout,"ClConnect: Socket Descriptor = %d\n",MTMClientSd);
	(void)fflush(stdout);
#endif

	return;
}
예제 #19
0
font_size::font_size(type t)
    : type_(t)
{
}


font_size::font_size(length size)
    : type_(type::length)
    , size_(size)
{
}


font_size::font_size(Platform::String^ str)
    : type_(parse_type(str))
    , size_(parse_length(str, length{}))
{
}


/*static*/
font_size::type font_size::parse_type(Platform::String^ str)
{
    if (str == L"xx-small") return type::xx_small;
    if (str == L"x-small") return type::x_small;
    if (str == L"small") return type::small;
    if (str == L"medium") return type::medium;
    if (str == L"large") return type::large;
    if (str == L"x-large") return type::x_large;
    if (str == L"xx-large") return type::xx_large;
    if (str == L"larger") return type::larger;
void CL_CSSParserBackgroundPosition::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set)
{
	size_t pos = 0;
	CL_CSSToken token = next_token(pos, tokens);

	if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && tokens.size() == 1)
	{
		properties.background_position.type = CL_CSSBoxBackgroundPosition::type_inherit;
		if (out_change_set)
		{
			(*out_change_set)["background-position"] = &properties.background_position;
		}
		return;
	}

	CL_CSSBoxBackgroundPosition position;
	position.type = CL_CSSBoxBackgroundPosition::type_value;
	position.positions.clear();
	bool done = false;
	while (!done)
	{
		CL_CSSBoxBackgroundPosition::Position bg_pos;
		bool x_specified = false;
		bool y_specified = false;
		bool center_specified = false;

		while (true)
		{
			if (token.type == CL_CSSToken::type_ident)
			{
				if (!y_specified && equals(token.value, "top"))
				{
					bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_top;
					y_specified = true;

					if (center_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}
				}
				else if (!y_specified && equals(token.value, "bottom"))
				{
					bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_bottom;
					y_specified = true;

					if (center_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}
				}
				else if (!x_specified && equals(token.value, "left"))
				{
					bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_left;
					x_specified = true;

					if (center_specified)
					{
						bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center;
						y_specified = true;
						center_specified = false;
					}
				}
				else if (!x_specified && equals(token.value, "right"))
				{
					bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_right;
					x_specified = true;

					if (center_specified)
					{
						bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center;
						y_specified = true;
						center_specified = false;
					}
				}
				else if (equals(token.value, "center"))
				{
					if (center_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (x_specified && !y_specified)
					{
						bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center;
						y_specified = true;
					}
					else if (y_specified && !x_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
					}
					else if (!x_specified && !y_specified)
					{
						center_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
			}
			else if (is_length(token))
			{
				CL_CSSBoxLength length;
				if (parse_length(token, length))
				{
					if (center_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (!x_specified && !y_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_length;
						bg_pos.length_x = length;
						x_specified = true;
					}
					else if (x_specified && !y_specified)
					{
						bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_length;
						bg_pos.length_y = length;
						y_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == CL_CSSToken::type_percentage)
			{
				if (center_specified)
				{
					bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
					x_specified = true;
					center_specified = false;
				}

				if (!x_specified && !y_specified)
				{
					bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_percentage;
					bg_pos.percentage_x = CL_StringHelp::text_to_float(token.value);
					x_specified = true;
				}
				else if (x_specified && !y_specified)
				{
					bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_percentage;
					bg_pos.percentage_y = CL_StringHelp::text_to_float(token.value);
					y_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == CL_CSSToken::type_delim && token.value == "-")
			{
				token = next_token(pos, tokens);
				if (is_length(token))
				{
					CL_CSSBoxLength length;
					if (parse_length(token, length))
					{
						length.value = -length.value;
						if (center_specified)
						{
							bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
							x_specified = true;
							center_specified = false;
						}

						if (!x_specified && !y_specified)
						{
							bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_length;
							bg_pos.length_x = length;
							x_specified = true;
						}
						else if (x_specified && !y_specified)
						{
							bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_length;
							bg_pos.length_y = length;
							y_specified = true;
						}
						else
						{
							debug_parse_error(name, tokens);
							return;
						}
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else if (token.type == CL_CSSToken::type_percentage)
				{
					if (center_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (!x_specified && !y_specified)
					{
						bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_percentage;
						bg_pos.percentage_x = -CL_StringHelp::text_to_float(token.value);
						x_specified = true;
					}
					else if (x_specified && !y_specified)
					{
						bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_percentage;
						bg_pos.percentage_y = -CL_StringHelp::text_to_float(token.value);
						y_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}

			if (pos == tokens.size())
			{
				done = true;
				break;
			}
			else
			{
				token = next_token(pos, tokens);
				if (token.type == CL_CSSToken::type_delim && token.value == ",")
					break;
			}
		}

		if (!x_specified)
			bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center;
		else if (!y_specified)
			bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center;

		position.positions.push_back(bg_pos);
	}

	properties.background_position = position;
	if (out_change_set)
	{
		(*out_change_set)["background-position"] = &properties.background_position;
	}
}
void CSSParserBackgroundPosition::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	std::unique_ptr<CSSValueBackgroundPosition> position(new CSSValueBackgroundPosition());

	size_t pos = 0;
	CSSToken token = next_token(pos, tokens);

	if (token.type == CSSToken::type_ident && equals(token.value, "inherit") && tokens.size() == 1)
	{
		position->type = CSSValueBackgroundPosition::type_inherit;
		inout_values.push_back(std::move(position));
		return;
	}

	position->type = CSSValueBackgroundPosition::type_value;
	position->positions.clear();
	bool done = false;
	while (!done)
	{
		CSSValueBackgroundPosition::Position bg_pos;
		bool x_specified = false;
		bool y_specified = false;
		bool center_specified = false;

		while (true)
		{
			if (token.type == CSSToken::type_ident)
			{
				if (!y_specified && equals(token.value, "top"))
				{
					bg_pos.type_y = CSSValueBackgroundPosition::type2_top;
					y_specified = true;

					if (center_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}
				}
				else if (!y_specified && equals(token.value, "bottom"))
				{
					bg_pos.type_y = CSSValueBackgroundPosition::type2_bottom;
					y_specified = true;

					if (center_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}
				}
				else if (!x_specified && equals(token.value, "left"))
				{
					bg_pos.type_x = CSSValueBackgroundPosition::type1_left;
					x_specified = true;

					if (center_specified)
					{
						bg_pos.type_y = CSSValueBackgroundPosition::type2_center;
						y_specified = true;
						center_specified = false;
					}
				}
				else if (!x_specified && equals(token.value, "right"))
				{
					bg_pos.type_x = CSSValueBackgroundPosition::type1_right;
					x_specified = true;

					if (center_specified)
					{
						bg_pos.type_y = CSSValueBackgroundPosition::type2_center;
						y_specified = true;
						center_specified = false;
					}
				}
				else if (equals(token.value, "center"))
				{
					if (center_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (x_specified && !y_specified)
					{
						bg_pos.type_y = CSSValueBackgroundPosition::type2_center;
						y_specified = true;
					}
					else if (y_specified && !x_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
					}
					else if (!x_specified && !y_specified)
					{
						center_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
			}
			else if (is_length(token))
			{
				CSSLength length;
				if (parse_length(token, length))
				{
					if (center_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (!x_specified && !y_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_length;
						bg_pos.length_x = length;
						x_specified = true;
					}
					else if (x_specified && !y_specified)
					{
						bg_pos.type_y = CSSValueBackgroundPosition::type2_length;
						bg_pos.length_y = length;
						y_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == CSSToken::type_percentage)
			{
				if (center_specified)
				{
					bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
					x_specified = true;
					center_specified = false;
				}

				if (!x_specified && !y_specified)
				{
					bg_pos.type_x = CSSValueBackgroundPosition::type1_percentage;
					bg_pos.percentage_x = StringHelp::text_to_float(token.value);
					x_specified = true;
				}
				else if (x_specified && !y_specified)
				{
					bg_pos.type_y = CSSValueBackgroundPosition::type2_percentage;
					bg_pos.percentage_y = StringHelp::text_to_float(token.value);
					y_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == CSSToken::type_delim && token.value == "-")
			{
				token = next_token(pos, tokens);
				if (is_length(token))
				{
					CSSLength length;
					if (parse_length(token, length))
					{
						length.value = -length.value;
						if (center_specified)
						{
							bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
							x_specified = true;
							center_specified = false;
						}

						if (!x_specified && !y_specified)
						{
							bg_pos.type_x = CSSValueBackgroundPosition::type1_length;
							bg_pos.length_x = length;
							x_specified = true;
						}
						else if (x_specified && !y_specified)
						{
							bg_pos.type_y = CSSValueBackgroundPosition::type2_length;
							bg_pos.length_y = length;
							y_specified = true;
						}
						else
						{
							debug_parse_error(name, tokens);
							return;
						}
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else if (token.type == CSSToken::type_percentage)
				{
					if (center_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
						x_specified = true;
						center_specified = false;
					}

					if (!x_specified && !y_specified)
					{
						bg_pos.type_x = CSSValueBackgroundPosition::type1_percentage;
						bg_pos.percentage_x = -StringHelp::text_to_float(token.value);
						x_specified = true;
					}
					else if (x_specified && !y_specified)
					{
						bg_pos.type_y = CSSValueBackgroundPosition::type2_percentage;
						bg_pos.percentage_y = -StringHelp::text_to_float(token.value);
						y_specified = true;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}

			if (pos == tokens.size())
			{
				done = true;
				break;
			}
			else
			{
				token = next_token(pos, tokens);
				if (token.type == CSSToken::type_delim && token.value == ",")
					break;
			}
		}

		if (!x_specified)
			bg_pos.type_x = CSSValueBackgroundPosition::type1_center;
		else if (!y_specified)
			bg_pos.type_y = CSSValueBackgroundPosition::type2_center;

		position->positions.push_back(bg_pos);
	}

	inout_values.push_back(std::move(position));
}
void CSSParserBorderImageWidth::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	std::unique_ptr<CSSValueBorderImageWidth> border_image_width(new CSSValueBorderImageWidth());

	size_t pos = 0;
	CSSToken token = next_token(pos, tokens);

	if (token.type == CSSToken::type_ident && pos == tokens.size() && equals(token.value, "inherit"))
	{
		border_image_width->type = CSSValueBorderImageWidth::type_inherit;
		inout_values.push_back(std::move(border_image_width));
	}
	else
	{
		int num_lengths;
		CSSValueBorderImageWidth::ValueType value_types[4];
		CSSLength lengths[4];
		float percentages[4] = { 0, 0, 0, 0 };
		float numbers[4] = { 0, 0, 0, 0 };
		for (num_lengths = 0; num_lengths < 4; num_lengths++)
		{
			if (is_length(token))
			{
				value_types[num_lengths] = CSSValueBorderImageWidth::value_type_length;
				if (!parse_length(token, lengths[num_lengths]))
					return;
			}
			else if (token.type == CSSToken::type_number)
			{
				value_types[num_lengths] = CSSValueBorderImageWidth::value_type_number;
				numbers[num_lengths] = StringHelp::text_to_float(token.value);
			}
			else if (token.type == CSSToken::type_percentage)
			{
				value_types[num_lengths] = CSSValueBorderImageWidth::value_type_percentage;
				percentages[num_lengths] = StringHelp::text_to_float(token.value);
			}
			else if (token.type == CSSToken::type_ident && equals(token.value, "auto"))
			{
				value_types[num_lengths] = CSSValueBorderImageWidth::value_type_auto;
			}
			else
			{
				break;
			}

			token = next_token(pos, tokens);
		}
		if (num_lengths < 1 || pos != tokens.size())
			return;

		border_image_width->type = CSSValueBorderImageWidth::type_values;

		if (num_lengths == 1)
		{
			for (int i = 1; i < 4; i++)
			{
				value_types[i] = value_types[0];
				lengths[i] = lengths[0];
				numbers[i] = numbers[0];
				percentages[i] = percentages[0];
			}
		}
		else if (num_lengths == 2)
		{
			value_types[2] = value_types[0];
			lengths[2] = lengths[0];
			numbers[2] = numbers[0];
			percentages[2] = percentages[0];
			value_types[3] = value_types[1];
			lengths[3] = lengths[1];
			numbers[3] = numbers[1];
			percentages[3] = percentages[1];
		}
		else if (num_lengths == 3)
		{
			value_types[3] = value_types[1];
			lengths[3] = lengths[1];
			numbers[3] = numbers[1];
			percentages[3] = percentages[1];
		}

		border_image_width->value_top = value_types[0];
		border_image_width->value_right = value_types[1];
		border_image_width->value_bottom = value_types[2];
		border_image_width->value_left = value_types[3];
		border_image_width->length_top = lengths[0];
		border_image_width->length_right = lengths[1];
		border_image_width->length_bottom = lengths[2];
		border_image_width->length_left = lengths[3];
		border_image_width->number_top = numbers[0];
		border_image_width->number_right = numbers[1];
		border_image_width->number_bottom = numbers[2];
		border_image_width->number_left = numbers[3];
		border_image_width->percentage_top = percentages[0];
		border_image_width->percentage_right = percentages[1];
		border_image_width->percentage_bottom = percentages[2];
		border_image_width->percentage_left = percentages[3];

		inout_values.push_back(std::move(border_image_width));
	}
}
예제 #23
0
void CSSParserBottom::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	std::unique_ptr<CSSValueBottom> bottom(new CSSValueBottom());

	size_t pos = 0;
	CSSToken token = next_token(pos, tokens);
	if (token.type == CSSToken::type_ident && pos == tokens.size())
	{
		if (equals(token.value, "auto"))
			bottom->type = CSSValueBottom::type_auto;
		else if (equals(token.value, "inherit"))
			bottom->type = CSSValueBottom::type_inherit;
		else
			return;
	}
	else if (is_length(token) && pos == tokens.size())
	{
		CSSLength length;
		if (parse_length(token, length))
		{
			bottom->type = CSSValueBottom::type_length;
			bottom->length = length;
		}
		else
		{
			return;
		}
	}
	else if (token.type == CSSToken::type_percentage && pos == tokens.size())
	{
		bottom->type = CSSValueBottom::type_percentage;
		bottom->percentage = StringHelp::text_to_float(token.value);
	}
	else if (token.type == CSSToken::type_delim && token.value == "-")
	{
		token = next_token(pos, tokens);
		if (is_length(token) && pos == tokens.size())
		{
			CSSLength length;
			if (parse_length(token, length))
			{
				length.value = -length.value;
				bottom->type = CSSValueBottom::type_length;
				bottom->length = length;
			}
			else
			{
				return;
			}
		}
		else if (token.type == CSSToken::type_percentage && pos == tokens.size())
		{
			bottom->type = CSSValueBottom::type_percentage;
			bottom->percentage = -StringHelp::text_to_float(token.value);
		}
		else
		{
			return;
		}
	}

	inout_values.push_back(std::move(bottom));
}
예제 #24
0
void CSSParserOutline::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	std::unique_ptr<CSSValueOutlineWidth> outline_width(new CSSValueOutlineWidth());
	std::unique_ptr<CSSValueOutlineStyle> outline_style(new CSSValueOutlineStyle());
	std::unique_ptr<CSSValueOutlineColor> outline_color(new CSSValueOutlineColor());
	bool width_specified = false;
	bool style_specified = false;
	bool color_specified = false;

	size_t pos = 0;
	while (pos != tokens.size())
	{
		Colorf color;
		if (!color_specified && parse_color(tokens, pos, color))
		{
			outline_color->type = CSSValueOutlineColor::type_color;
			outline_color->color = color;
			color_specified = true;
		}
		else
		{
			CSSToken token = next_token(pos, tokens);
			if (token.type == CSSToken::type_ident)
			{
				if (equals(token.value, "inherit") && tokens.size() == 1)
				{
					outline_width->type = CSSValueOutlineWidth::type_inherit;
					outline_style->type = CSSValueOutlineStyle::type_inherit;
					outline_color->type = CSSValueOutlineColor::type_inherit;
					inout_values.push_back(std::move(outline_width));
					inout_values.push_back(std::move(outline_style));
					inout_values.push_back(std::move(outline_color));
					return;
				}
				else if (!width_specified && equals(token.value, "thin"))
				{
					outline_width->type = CSSValueOutlineWidth::type_thin;
					width_specified = true;
				}
				else if (!width_specified && equals(token.value, "medium"))
				{
					outline_width->type = CSSValueOutlineWidth::type_medium;
					width_specified = true;
				}
				else if (!width_specified && equals(token.value, "thick"))
				{
					outline_width->type = CSSValueOutlineWidth::type_thick;
					width_specified = true;
				}
				else if (!style_specified && equals(token.value, "none"))
				{
					outline_style->type = CSSValueOutlineStyle::type_none;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "hidden"))
				{
					outline_style->type = CSSValueOutlineStyle::type_hidden;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "dotted"))
				{
					outline_style->type = CSSValueOutlineStyle::type_dotted;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "dashed"))
				{
					outline_style->type = CSSValueOutlineStyle::type_dashed;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "solid"))
				{
					outline_style->type = CSSValueOutlineStyle::type_solid;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "double"))
				{
					outline_style->type = CSSValueOutlineStyle::type_double;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "groove"))
				{
					outline_style->type = CSSValueOutlineStyle::type_groove;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "ridge"))
				{
					outline_style->type = CSSValueOutlineStyle::type_ridge;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "inset"))
				{
					outline_style->type = CSSValueOutlineStyle::type_inset;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "outset"))
				{
					outline_style->type = CSSValueOutlineStyle::type_outset;
					style_specified = true;
				}
				else if (!color_specified && equals(token.value, "invert"))
				{
					outline_color->type = CSSValueOutlineColor::type_invert;
					color_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (is_length(token))
			{
				CSSLength length;
				if (!width_specified && parse_length(token, length))
				{
					outline_width->type = CSSValueOutlineWidth::type_length;
					outline_width->length = length;
					width_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}
		}
	}

	inout_values.push_back(std::move(outline_width));
	inout_values.push_back(std::move(outline_style));
	inout_values.push_back(std::move(outline_color));
}
예제 #25
0
	void MarginPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		StyleSetValue margin_widths[4];
		int count;
		size_t pos = 0;
		for (count = 0; count < 4; count++)
		{
			StyleToken token = next_token(pos, tokens);
			if (token.type == StyleTokenType::ident && equals(token.value, "auto"))
			{
				margin_widths[count] = StyleSetValue::from_keyword("auto");
			}
			else if (token.type == StyleTokenType::ident && equals(token.value, "inherit") && count == 0 && pos == tokens.size())
			{
				margin_widths[0] = StyleSetValue::from_keyword("inherit");
				setter->set_value("margin-left", margin_widths[0]);
				setter->set_value("margin-top", margin_widths[0]);
				setter->set_value("margin-right", margin_widths[0]);
				setter->set_value("margin-bottom", margin_widths[0]);
				return;
			}
			else if (is_length(token))
			{
				StyleSetValue length;
				if (parse_length(token, length))
				{
					margin_widths[count] = length;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == StyleTokenType::percentage)
			{
				margin_widths[count] = StyleSetValue::from_percentage(StringHelp::text_to_float(token.value));
			}
			else if (token.type == StyleTokenType::delim && token.value == "-")
			{
				token = next_token(pos, tokens);
				if (is_length(token))
				{
					StyleSetValue length;
					if (parse_length(token, length))
					{
						length.number = -length.number;
						margin_widths[count] = length;
					}
					else
					{
						debug_parse_error(name, tokens);
						return;
					}
				}
				else if (token.type == StyleTokenType::percentage)
				{
					margin_widths[count] = StyleSetValue::from_percentage(-StringHelp::text_to_float(token.value));
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == StyleTokenType::null)
			{
				break;
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}
		}

		if (pos == tokens.size())
		{
			switch (count)
			{
			case 1:
				setter->set_value("margin-left", margin_widths[0]);
				setter->set_value("margin-top", margin_widths[0]);
				setter->set_value("margin-right", margin_widths[0]);
				setter->set_value("margin-bottom", margin_widths[0]);
				break;
			case 2:
				setter->set_value("margin-top", margin_widths[0]);
				setter->set_value("margin-bottom", margin_widths[0]);
				setter->set_value("margin-left", margin_widths[1]);
				setter->set_value("margin-right", margin_widths[1]);
				break;
			case 3:
				setter->set_value("margin-top", margin_widths[0]);
				setter->set_value("margin-left", margin_widths[1]);
				setter->set_value("margin-right", margin_widths[1]);
				setter->set_value("margin-bottom", margin_widths[2]);
				break;
			case 4:
				setter->set_value("margin-top", margin_widths[0]);
				setter->set_value("margin-right", margin_widths[1]);
				setter->set_value("margin-bottom", margin_widths[2]);
				setter->set_value("margin-left", margin_widths[3]);
				break;
			default:
				break;
			}
		}
	}
예제 #26
0
파일: parse.c 프로젝트: Meai1/libpsyc
/**
 * Parse dictionary.
 *
 * dict		= [ type ] *dict-item
 * dict-item	= "{" ( dict-key / length SP OCTET) "}"
 *                ( type [ SP dict-value ] / [ length ] [ ":" type ] [ SP *OCTET ] )
 * dict-key	= %x00-7C / %x7E-FF	; any byte except "{"
 * dict-value	= %x00-7A / %x7C-FF	; any byte except "}"
 */
PsycParseDictRC
psyc_parse_dict (PsycParseDictState *state, PsycString *type, PsycString *elem)
{
    ParseRC ret;

    if (state->cursor >= state->buffer.length)
	return PSYC_PARSE_DICT_END;

    state->startc = state->cursor;

    switch (state->part) {
    case PSYC_DICT_PART_START:
	type->length = elem->length = 0;
	type->data = elem->data = NULL;

	state->part = PSYC_DICT_PART_TYPE;
	// fall thru

    case PSYC_DICT_PART_TYPE:
	switch (parse_keyword((ParseState*)state, type)) {
	case PARSE_SUCCESS: // end of keyword
	    state->part = PSYC_DICT_PART_KEY_START;
	    return PSYC_PARSE_DICT_TYPE;
	case PARSE_INSUFFICIENT: // end of buffer
	    return PSYC_PARSE_DICT_END;
	case PARSE_ERROR: // no keyword
	    state->part = PSYC_DICT_PART_KEY_START;
	    break;
	default: // should not be reached
	    return PSYC_PARSE_DICT_ERROR;
	}
	// fall thru

    case PSYC_DICT_PART_KEY_START:
	if (state->buffer.data[state->cursor] != '{')
	    return PSYC_PARSE_DICT_ERROR_KEY_START;

	type->length = elem->length = 0;
	type->data = elem->data = NULL;

	state->elem_parsed = 0;
	state->elemlen_found = 0;

	state->part = PSYC_DICT_PART_KEY_LENGTH;
	ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_INSUFFICIENT);
	// fall thru

    case PSYC_DICT_PART_KEY_LENGTH:
	switch (parse_length((ParseState*)state, &state->elemlen)) {
	case PARSE_SUCCESS: // length is complete
	    state->elemlen_found = 1;
	    state->elem_parsed = 0;
	    elem->length = state->elemlen;
	    elem->data = NULL;

	    if (state->buffer.data[state->cursor] != ' ')
		return PSYC_PARSE_DICT_ERROR_KEY_LENGTH;

	    state->part = PSYC_DICT_PART_KEY;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
	    break;
	case PARSE_INSUFFICIENT: // length is incomplete
	    return PSYC_PARSE_DICT_INSUFFICIENT;
	case PARSE_ERROR: // no length
	    state->part = PSYC_DICT_PART_KEY;
	    break;
	default: // should not be reached
	    return PSYC_PARSE_DICT_ERROR;
	}
	// fall thru

    case PSYC_DICT_PART_KEY:
	if (state->elemlen_found) {
	    switch (parse_binary((ParseState*)state, state->elemlen, elem,
				 &state->elem_parsed)) {
	    case PARSE_SUCCESS:
		if (elem->length == state->elem_parsed)
		    ret = PSYC_PARSE_DICT_KEY;
		else
		    ret = PSYC_PARSE_DICT_KEY_END;
		break;
	    case PARSE_INCOMPLETE:
		if (elem->length == state->elem_parsed)
		    ret = PSYC_PARSE_DICT_KEY_START;
		else
		    ret = PSYC_PARSE_DICT_KEY_CONT;
		break;
	    default: // should not be reached
		return PSYC_PARSE_DICT_ERROR;
	    }
	} else {
	    switch (parse_until((ParseState*)state, '}', elem)) {
	    case PARSE_SUCCESS:
		ret = PSYC_PARSE_DICT_KEY;
		break;
	    case PARSE_INSUFFICIENT:
		return PSYC_PARSE_DICT_INSUFFICIENT;
	    default: // should not be reached
		return PSYC_PARSE_DICT_ERROR;
	    }
	}

	state->part = PSYC_DICT_PART_VALUE_START;
	state->startc = state->cursor;
	return ret;

    case PSYC_DICT_PART_VALUE_START:
	switch (state->buffer.data[state->cursor] != '}')
	    return PSYC_PARSE_DICT_ERROR_VALUE_START;

	type->length = elem->length = 0;
	type->data = elem->data = NULL;

	state->elem_parsed = 0;
	state->elemlen_found = 0;

	state->part = PSYC_DICT_PART_VALUE_TYPE;
	ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST);
	// fall thru

    case PSYC_DICT_PART_VALUE_TYPE:
	if (state->buffer.data[state->cursor] == '=') {
	    ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);

	    switch (parse_keyword((ParseState*)state, type)) {
	    case PARSE_SUCCESS:
		switch (state->buffer.data[state->cursor]) {
		case ':':
		    state->part = PSYC_DICT_PART_VALUE_LENGTH;
		    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST);
		    break;
		case ' ':
		    state->part = PSYC_DICT_PART_VALUE;
		    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST);
		    goto PSYC_DICT_PART_VALUE;
		case '{':
		    state->part = PSYC_DICT_PART_KEY_START;
		    return PSYC_PARSE_DICT_VALUE;
		    break;
		default:
		    return PSYC_PARSE_DICT_ERROR_VALUE_TYPE;
		}
		break;
	    case PARSE_INSUFFICIENT: // end of buffer
		return PSYC_PARSE_DICT_VALUE_LAST;
	    case PARSE_ERROR:
		return PSYC_PARSE_DICT_ERROR_VALUE_TYPE;
	    default: // should not be reached
		return PSYC_PARSE_DICT_ERROR;
	    }
	}
	// fall thru

    case PSYC_DICT_PART_VALUE_LENGTH:
	switch (parse_length((ParseState*)state, &state->elemlen)) {
	case PARSE_SUCCESS: // length is complete
	    state->elemlen_found = 1;
	    state->elem_parsed = 0;
	    elem->length = state->elemlen;
	    elem->data = NULL;
	    break;
	case PARSE_INSUFFICIENT: // length is incomplete
	    return PSYC_PARSE_DICT_INSUFFICIENT;
	case PARSE_ERROR: // no length
	    break;
	default: // should not be reached
	    return PSYC_PARSE_DICT_ERROR;
	}

	switch (state->buffer.data[state->cursor]) {
	case ' ':
	    state->part = PSYC_DICT_PART_VALUE;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST);
	    break;
	case '{':
	    state->part = PSYC_DICT_PART_KEY_START;
	    return PSYC_PARSE_DICT_VALUE;
	default:
	    return PSYC_PARSE_DICT_ERROR_VALUE_LENGTH;
	}
	// fall thru

    case PSYC_DICT_PART_VALUE:
    PSYC_DICT_PART_VALUE:
	if (state->elemlen_found) {
	    switch (parse_binary((ParseState*)state, state->elemlen, elem,
				 &state->elem_parsed)) {
	    case PARSE_SUCCESS:
		if (elem->length == state->elem_parsed)
		    ret = PSYC_PARSE_DICT_VALUE;
		else
		    ret = PSYC_PARSE_DICT_VALUE_END;
		break;
	    case PARSE_INCOMPLETE:
		if (elem->length == state->elem_parsed)
		    ret = PSYC_PARSE_DICT_VALUE_START;
		else
		    ret = PSYC_PARSE_DICT_VALUE_CONT;
		break;
	    default: // should not be reached
		return PSYC_PARSE_DICT_ERROR;
	    }
	} else {
	    switch (parse_until((ParseState*)state, '{', elem)) {
	    case PARSE_SUCCESS:
		ret = PSYC_PARSE_DICT_VALUE;
		break;
	    case PARSE_INSUFFICIENT:
		return PSYC_PARSE_DICT_VALUE_LAST;
	    default: // should not be reached
		return PSYC_PARSE_DICT_ERROR;
	    }
	}

	state->part = PSYC_DICT_PART_KEY_START;
	return ret;
    }

    return PSYC_PARSE_DICT_ERROR; // should not be reached
}
예제 #27
0
void CL_CSSParserPadding::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set)
{
	CL_CSSBoxPaddingWidth padding_widths[4];
	int count;
	size_t pos = 0;
	for (count = 0; count < 4; count++)
	{
		CL_CSSToken token = next_token(pos, tokens);
		if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && count == 0 && pos == tokens.size())
		{
			properties.padding_width_left.type = CL_CSSBoxPaddingWidth::type_inherit;
			properties.padding_width_top.type = CL_CSSBoxPaddingWidth::type_inherit;
			properties.padding_width_right.type = CL_CSSBoxPaddingWidth::type_inherit;
			properties.padding_width_bottom.type = CL_CSSBoxPaddingWidth::type_inherit;
			return;
		}
		else if (is_length(token))
		{
			CL_CSSBoxLength length;
			if (parse_length(token, length))
			{
				padding_widths[count].type = CL_CSSBoxPaddingWidth::type_length;
				padding_widths[count].length = length;
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}
		}
		else if (token.type == CL_CSSToken::type_percentage)
		{
			padding_widths[count].type = CL_CSSBoxPaddingWidth::type_percentage;
			padding_widths[count].percentage = CL_StringHelp::text_to_float(token.value);
		}
		else if (token.type == CL_CSSToken::type_delim && token.value == "-")
		{
			token = next_token(pos, tokens);
			if (is_length(token))
			{
				CL_CSSBoxLength length;
				if (parse_length(token, length))
				{
					length.value = -length.value;
					padding_widths[count].type = CL_CSSBoxPaddingWidth::type_length;
					padding_widths[count].length = length;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (token.type == CL_CSSToken::type_percentage)
			{
				padding_widths[count].type = CL_CSSBoxPaddingWidth::type_percentage;
				padding_widths[count].percentage = -CL_StringHelp::text_to_float(token.value);
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}
		}
		else if (token.type == CL_CSSToken::type_null)
		{
			break;
		}
		else
		{
			debug_parse_error(name, tokens);
			return;
		}
	}

	if (pos == tokens.size())
	{
		switch (count)
		{
		case 1:
			properties.padding_width_left = padding_widths[0];
			properties.padding_width_top = padding_widths[0];
			properties.padding_width_right = padding_widths[0];
			properties.padding_width_bottom = padding_widths[0];
			break;
		case 2:
			properties.padding_width_top = padding_widths[0];
			properties.padding_width_bottom = padding_widths[0];
			properties.padding_width_left = padding_widths[1];
			properties.padding_width_right = padding_widths[1];
			break;
		case 3:
			properties.padding_width_top = padding_widths[0];
			properties.padding_width_left = padding_widths[1];
			properties.padding_width_right = padding_widths[1];
			properties.padding_width_bottom = padding_widths[2];
			break;
		case 4:
			properties.padding_width_top = padding_widths[0];
			properties.padding_width_right = padding_widths[1];
			properties.padding_width_bottom = padding_widths[2];
			properties.padding_width_left = padding_widths[3];
			break;
		default:
			break;
		}
	}
	if (out_change_set)
	{
		(*out_change_set)["padding-left"] = &properties.padding_width_left;
		(*out_change_set)["padding-right"] = &properties.padding_width_right;
		(*out_change_set)["padding-top"] = &properties.padding_width_top;
		(*out_change_set)["padding-bottom"] = &properties.padding_width_bottom;
	}
}
예제 #28
0
파일: parse.c 프로젝트: Meai1/libpsyc
static inline
#endif
PsycParseUpdateRC
psyc_parse_update (PsycParseUpdateState *state, char *oper, PsycString *value)
{
    PsycParseIndexRC ret;

    if (state->cursor >= state->buffer.length)
	return PSYC_PARSE_UPDATE_END;

    state->startc = state->cursor;

    switch (state->part) {
    case PSYC_UPDATE_PART_START:
	value->length = 0;
	value->data = NULL;
	// fall thru

    case PSYC_INDEX_PART_TYPE:
    case PSYC_INDEX_PART_LIST:
    case PSYC_INDEX_PART_STRUCT:
    case PSYC_INDEX_PART_DICT_LENGTH:
    case PSYC_INDEX_PART_DICT:
	ret = psyc_parse_index((PsycParseIndexState*)state, value);

	switch (ret) {
	case PSYC_PARSE_INDEX_INSUFFICIENT:
	case PSYC_PARSE_INDEX_LIST_LAST:
	case PSYC_PARSE_INDEX_STRUCT_LAST:
	case PSYC_PARSE_INDEX_END:
	    return PSYC_PARSE_UPDATE_INSUFFICIENT;
	case PSYC_PARSE_INDEX_ERROR_TYPE:
	    if (state->buffer.data[state->cursor] != ' ')
		return ret;
	    state->part = PSYC_PARSE_UPDATE_TYPE;
	    value->length = 0;
	    value->data = NULL;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT);
	    break;
	default:
	    return ret;
	}
    case PSYC_UPDATE_PART_TYPE:
	if (!psyc_is_oper(state->buffer.data[state->cursor]))
	    return PSYC_PARSE_UPDATE_ERROR_OPER;

	*oper = state->buffer.data[state->cursor];
	ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_UPDATE_END);

	switch (parse_keyword((ParseState*)state, value)) {
	case PARSE_SUCCESS: // end of keyword
	case PARSE_ERROR: // no keyword
	    switch (state->buffer.data[state->cursor]) {
	    case ':':
		state->part = PSYC_UPDATE_PART_LENGTH;
		break;
	    case ' ':
		state->part = PSYC_UPDATE_PART_VALUE;
		break;
	    default:
		return PSYC_PARSE_UPDATE_ERROR_TYPE;
	    }

	    state->cursor++;
	    return PSYC_PARSE_UPDATE_TYPE;
	    break;
	case PARSE_INSUFFICIENT: // end of buffer
	    return PSYC_PARSE_UPDATE_TYPE_END;
	default: // should not be reached
	    return PSYC_PARSE_UPDATE_ERROR;
	}
	break;

    case PSYC_UPDATE_PART_LENGTH:
	switch (parse_length((ParseState*)state, &state->elemlen)) {
	case PARSE_SUCCESS: // length is complete
	    state->elemlen_found = 1;
	    state->elem_parsed = 0;
	    value->length = state->elemlen;
	    value->data = NULL;

	    if (state->buffer.data[state->cursor] != ' ')
		return PSYC_PARSE_UPDATE_ERROR_LENGTH;

	    state->part = PSYC_UPDATE_PART_VALUE;
	    if (value->length == 0)
		return PSYC_PARSE_UPDATE_END;
	    ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT);
	    break;
	case PARSE_INSUFFICIENT: // length is incomplete
	    if (value->length == 0)
		return PSYC_PARSE_UPDATE_END;
	    return PSYC_PARSE_UPDATE_INSUFFICIENT;
	case PARSE_ERROR: // no length after :
	    return PSYC_PARSE_UPDATE_ERROR_LENGTH;
	default: // should not be reached
	    return PSYC_PARSE_UPDATE_ERROR;
	}
	// fall thru

    case PSYC_UPDATE_PART_VALUE:
	if (state->elemlen_found) {
	    switch (parse_binary((ParseState*)state, state->elemlen, value,
				 &state->elem_parsed)) {
	    case PARSE_SUCCESS:
		if (value->length == state->elem_parsed)
		    ret = PSYC_PARSE_UPDATE_VALUE;
		else
		    ret = PSYC_PARSE_UPDATE_VALUE_END;
		break;
	    case PARSE_INCOMPLETE:
		if (value->length == state->elem_parsed)
		    ret = PSYC_PARSE_UPDATE_VALUE_START;
		else
		    ret = PSYC_PARSE_UPDATE_VALUE_CONT;
		break;
	    default: // should not be reached
		return PSYC_PARSE_UPDATE_ERROR_VALUE;
	    }
	} else {
	    value->data = state->buffer.data + state->cursor;
	    value->length = state->buffer.length - state->cursor;
	    ret = PSYC_PARSE_UPDATE_VALUE;
	}

	state->part = PSYC_INDEX_PART_TYPE;
	state->cursor++;
	return ret;
    }

    return PSYC_PARSE_INDEX_ERROR; // should not be reached
}
예제 #29
0
void CSSParserBorder::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
	CSSValueBorderWidth border_width;
	CSSValueBorderStyle border_style;
	CSSValueBorderColor border_color;
	bool width_specified = false;
	bool style_specified = false;
	bool color_specified = false;

	size_t pos = 0;
	while (pos != tokens.size())
	{
		Colorf color;
		if (!color_specified && parse_color(tokens, pos, color))
		{
			border_color.type = CSSValueBorderColor::type_color;
			border_color.color = color;
			color_specified = true;
		}
		else
		{
			CSSToken token = next_token(pos, tokens);
			if (token.type == CSSToken::type_ident)
			{
				if (equals(token.value, "inherit") && tokens.size() == 1)
				{
					border_width.type = CSSValueBorderWidth::type_inherit;
					border_style.type = CSSValueBorderStyle::type_inherit;
					border_color.type = CSSValueBorderColor::type_inherit;

					inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::left_value, border_width)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::right_value, border_width)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::top_value, border_width)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::bottom_value, border_width)));

					inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::left_value, border_style)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::right_value, border_style)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::top_value, border_style)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::bottom_value, border_style)));

					inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_color)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_color)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_color)));
					inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_color)));

					return;
				}
				else if (!width_specified && equals(token.value, "thin"))
				{
					border_width.type = CSSValueBorderWidth::type_thin;
					width_specified = true;
				}
				else if (!width_specified && equals(token.value, "medium"))
				{
					border_width.type = CSSValueBorderWidth::type_medium;
					width_specified = true;
				}
				else if (!width_specified && equals(token.value, "thick"))
				{
					border_width.type = CSSValueBorderWidth::type_thick;
					width_specified = true;
				}
				else if (!style_specified && equals(token.value, "none"))
				{
					border_style.type = CSSValueBorderStyle::type_none;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "hidden"))
				{
					border_style.type = CSSValueBorderStyle::type_hidden;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "dotted"))
				{
					border_style.type = CSSValueBorderStyle::type_dotted;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "dashed"))
				{
					border_style.type = CSSValueBorderStyle::type_dashed;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "solid"))
				{
					border_style.type = CSSValueBorderStyle::type_solid;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "double"))
				{
					border_style.type = CSSValueBorderStyle::type_double;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "groove"))
				{
					border_style.type = CSSValueBorderStyle::type_groove;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "ridge"))
				{
					border_style.type = CSSValueBorderStyle::type_ridge;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "inset"))
				{
					border_style.type = CSSValueBorderStyle::type_inset;
					style_specified = true;
				}
				else if (!style_specified && equals(token.value, "outset"))
				{
					border_style.type = CSSValueBorderStyle::type_outset;
					style_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else if (is_length(token))
			{
				CSSLength length;
				if (!width_specified && parse_length(token, length))
				{
					border_width.type = CSSValueBorderWidth::type_length;
					border_width.length = length;
					width_specified = true;
				}
				else
				{
					debug_parse_error(name, tokens);
					return;
				}
			}
			else
			{
				debug_parse_error(name, tokens);
				return;
			}
		}
	}

	inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::left_value, border_width)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::right_value, border_width)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::top_value, border_width)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::bottom_value, border_width)));

	inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::left_value, border_style)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::right_value, border_style)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::top_value, border_style)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::bottom_value, border_style)));

	inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_color)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_color)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_color)));
	inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_color)));
}
void ProcessWayTags(TagList *tags,int64_t way_id,int mode)
{
 Way way={0};
 int oneway=0,area=0;
 int roundabout=0,lanes=0;
 char *name=NULL,*ref=NULL,*refname=NULL;
 way_t id;
 int i;

 /* Convert id */

 id=(way_t)way_id;
 logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */

 /* Delete */

 if(mode==MODE_DELETE || mode==MODE_MODIFY)
   {
    way.type=WAY_DELETED;

    AppendWayList(ways,id,&way,way_nodes,way_nnodes,"");
   }

 if(mode==MODE_DELETE)
    return;

 /* Sanity check */

 if(way_nnodes==0)
   {
    logerror("Way %"Pway_t" has no nodes.\n",logerror_way(id));
    return;
   }

 if(way_nnodes==1)
   {
    logerror_node(way_nodes[0]); /* Extra logerror information since way isn't stored */
    logerror("Way %"Pway_t" has only one node.\n",logerror_way(id));
    return;
   }

 /* Parse the tags - just look for highway */

 for(i=0;i<tags->ntags;i++)
   {
    char *k=tags->k[i];
    char *v=tags->v[i];

    if(!strcmp(k,"highway"))
      {
       way.type=HighwayType(v);

       if(way.type==Highway_None)
          logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v);

       break;
      }
   }

 /* Don't continue if this is not a highway (bypass error logging) */

 if(way.type==Highway_None)
    return;

 /* Parse the tags - look for the others */

 for(i=0;i<tags->ntags;i++)
   {
    int recognised=0;
    char *k=tags->k[i];
    char *v=tags->v[i];

    switch(*k)
      {
      case 'a':
       if(!strcmp(k,"area"))
         {
          if(ISTRUE(v))
             area=1;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'area' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'b':
       if(!strcmp(k,"bicycle"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Bicycle;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'bicycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"bicycleroute"))
         {
          if(ISTRUE(v))
             way.props|=Properties_BicycleRoute;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"bridge"))
         {
          if(ISTRUE(v))
             way.props|=Properties_Bridge;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'bridge' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

	  case 'c':
       if(!strcmp(k,"cycleway"))
         {
          if(!strcmp(v,"opposite_lane"))
             way.props|=Properties_DoubleSens;
           recognised=1; break;
         }
	    break;
	   
      case 'f':
       if(!strcmp(k,"foot"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Foot;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'foot' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"footroute"))
         {
          if(ISTRUE(v))
             way.props|=Properties_FootRoute;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'footroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'g':
       if(!strcmp(k,"goods"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Goods;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'goods' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'h':
       if(!strcmp(k,"highway"))
         {recognised=1; break;}

       if(!strcmp(k,"horse"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Horse;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'horse' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"hgv"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_HGV;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'hgv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

	  case 'i':
       if(!strcmp(k,"incline"))
         {
/* logerror("Way %"Pway_t" has an 'incline' = '%s' \n",logerror_way(id),v); */
         way.incline=pourcent_to_incline(parse_incline(id,k,v));
          recognised=1; break;
		 }
	    break;


      case 'l':
       if(!strcmp(k,"lanes"))
         {
          int en=0;
          float lanesf;
          if(sscanf(v,"%f%n",&lanesf,&en)==1 && en && !v[en])
             lanes=(int)lanesf;
          else
             logerror("Way %"Pway_t" has an unrecognised tag 'lanes' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'm':
       if(!strncmp(k,"max",3))
         {
          if(!strcmp(k+3,"speed"))
            {
             way.speed=kph_to_speed(parse_speed(id,k,v));
             recognised=1; break;
            }

          if(!strcmp(k+3,"weight"))
            {
             way.weight=tonnes_to_weight(parse_weight(id,k,v));
             recognised=1; break;
            }

          if(!strcmp(k+3,"height"))
            {
             way.height=metres_to_height(parse_length(id,k,v));
             recognised=1; break;
            }

          if(!strcmp(k+3,"width"))
            {
             way.width=metres_to_height(parse_length(id,k,v));
             recognised=1; break;
            }

          if(!strcmp(k+3,"length"))
            {
             way.length=metres_to_height(parse_length(id,k,v));
             recognised=1; break;
            }
         }

       if(!strcmp(k,"moped"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Moped;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'moped' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"motorcycle"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Motorcycle;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'motorcycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"motorcar"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Motorcar;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'motorcar' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"multilane"))
         {
          if(ISTRUE(v))
             way.props|=Properties_Multilane;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'multilane' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'n':
       if(!strcmp(k,"name"))
         {
          name=v;
          recognised=1; break;
         }

       break;

      case 'o':
       if(!strcmp(k,"oneway"))
         {
          if(ISTRUE(v))
             oneway=1;
          else if(!strcmp(v,"-1"))
             oneway=-1;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'oneway' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'p':
       if(!strcmp(k,"paved"))
         {
          if(ISTRUE(v))
             way.props|=Properties_Paved;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'paved' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       if(!strcmp(k,"psv"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_PSV;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'psv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'r':
       if(!strcmp(k,"ref"))
         {
          ref=v;
          recognised=1; break;
         }

       if(!strcmp(k,"roundabout"))
         {
          if(ISTRUE(v))
             roundabout=1;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'roundabout' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 't':
       if(!strcmp(k,"tunnel"))
         {
          if(ISTRUE(v))
             way.props|=Properties_Tunnel;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'tunnel' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      case 'w':
       if(!strcmp(k,"wheelchair"))
         {
          if(ISTRUE(v))
             way.allow|=Transports_Wheelchair;
          else if(!ISFALSE(v))
             logerror("Way %"Pway_t" has an unrecognised tag 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v);
          recognised=1; break;
         }

       break;

      default:
       break;
      }

    if(!recognised)
       logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),k,v);
   }

 /* Create the way */

 if(area && oneway)
   {
    logerror("Way %"Pway_t" is an area and oneway; ignoring area tagging.\n",logerror_way(id));
    area=0;
   }

 if(!way.allow)
    return;

 if(oneway)
   {
    way.type|=Highway_OneWay;

    if(oneway==-1)
       for(i=0;i<way_nnodes/2;i++)
         {
          node_t temp;

          temp=way_nodes[i];
          way_nodes[i]=way_nodes[way_nnodes-i-1];
          way_nodes[way_nnodes-i-1]=temp;
         }
   }

 if(roundabout)
    way.type|=Highway_Roundabout;

 if(area)
   {
    way.type|=Highway_Area;

    if(way_nodes[0]!=way_nodes[way_nnodes-1])
       logerror("Way %"Pway_t" is an area but not closed.\n",logerror_way(id));
   }

 if(lanes)
   {
    if(oneway || (lanes/2)>1)
       way.props|=Properties_Multilane;

    if(oneway && lanes==1)
       way.props&=~Properties_Multilane;
   }

 if(ref && name)
   {
    refname=(char*)malloc(strlen(ref)+strlen(name)+4);
    sprintf(refname,"%s (%s)",name,ref);
   }
 else if(ref && !name)
    refname=ref;
 else if(!ref && name)
    refname=name;
 else /* if(!ref && !name) */
    refname="";

 AppendWayList(ways,id,&way,way_nodes,way_nnodes,refname);

 if(ref && name)
    free(refname);
}