static svg_status_t
_svg_style_split_nv_pair_alloc (const char	*nv_pair,
				char		**name,
				char		**value)
{
    char *colon;
    const char *v_start;

    *name = strdup (nv_pair);
    if (*name == NULL)
	return SVG_STATUS_NO_MEMORY;

    colon = strchr (*name, ':');
    if (colon == NULL) {
	free (*name);
	*name = NULL;
	*value = NULL;
	return SVG_STATUS_PARSE_ERROR;
    }

    *colon = '\0';

    v_start = nv_pair + (colon - (char *) *name) + 1;
    while (_svg_ascii_isspace (*v_start))
	v_start++;

    *value = strdup (v_start);
    if (*value == NULL)
	return SVG_STATUS_NO_MEMORY;

    return SVG_STATUS_SUCCESS;
}
Exemplo n.º 2
0
void
_svg_str_skip_space (const char **str)
{
    const char *s = *str;
    while (_svg_ascii_isspace (*s))
	s++;
    *str = s;
}
Exemplo n.º 3
0
void
_svg_str_skip_space_or_char (const char **str, char c)
{
    const char *s = *str;
    while (_svg_ascii_isspace (*s) || *s == c)
	s++;
    *str = s;
}
Exemplo n.º 4
0
/* The following parse function is:

   Copyright (C) 2000 Eazel, Inc.
   Copyright (C) 2002 Dom Lachowicz <*****@*****.**>

   Author: Raph Levien <*****@*****.**>

   Parse an SVG transform string into an affine matrix. Reference: SVG
   working draft dated 1999-07-06, section 8.5.
*/
extern svg_status_t
_svg_transform_parse_str (svg_transform_t *transform, const char *str)
{
    intptr_t idx;
    svg_status_t status;
    char keyword[32];
    double args[6];
    int n_args;
    unsigned int key_len;
    svg_transform_t tmp_transform;

    status = _svg_transform_init (transform);
    if (status)
		return status;

    idx = 0;
    while (str[idx]) {
		/* skip initial whitespace */
		while (_svg_ascii_isspace (str[idx]) || str[idx] == ',')
			idx++;

		/* parse keyword */
		for (key_len = 0; key_len < sizeof (keyword); key_len++) {
			char c;

			c = str[idx];
			if (_svg_ascii_isalpha (c) || c == '-')
				keyword[key_len] = str[idx++];
			else
				break;
		}
		/* XXX: This size limitation looks bogus */
		if (key_len >= sizeof (keyword))
			return SVG_STATUS_PARSE_ERROR;
		keyword[key_len] = '\0';

		/* skip whitespace */
		while (_svg_ascii_isspace (str[idx]))
			idx++;

		if (str[idx] != '(')
			return SVG_STATUS_PARSE_ERROR;
		idx++;
		
		for (n_args = 0; ; n_args++) {
			char c;
			const char *end_ptr;

			/* skip whitespace */
			while (_svg_ascii_isspace (str[idx]))
				idx++;
			c = str[idx];
			if (_svg_ascii_isdigit (c) || c == '+' || c == '-' || c == '.') {
				if (n_args == SVG_ARRAY_SIZE (args))
					return SVG_STATUS_PARSE_ERROR;
				args[n_args] = _svg_ascii_strtod (str + idx, &end_ptr);
				idx = end_ptr - str;

				while (_svg_ascii_isspace (str[idx]))
					idx++;

				/* skip optional comma */
				if (str[idx] == ',')
					idx++;
			} else if (c == ')')
				break;
			else
				return SVG_STATUS_PARSE_ERROR;
		}
		idx++;

		/* ok, have parsed keyword and args, now modify the transform */
		if (strcmp (keyword, "matrix") == 0) {
			if (n_args != 6)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_init_matrix (&tmp_transform,
										args[0], args[1],
										args[2], args[3],
										args[4], args[5]);
			_svg_transform_multiply_into_right (&tmp_transform, transform);
		} else if (strcmp (keyword, "translate") == 0) {
			if (n_args == 1)
				args[1] = 0;
			else if (n_args != 2)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_translate (transform, args[0], args[1]);
		} else if (strcmp (keyword, "scale") == 0) {
			if (n_args == 1)
				args[1] = args[0];
			else if (n_args != 2)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_scale (transform, args[0], args[1]);
		} else if (strcmp (keyword, "rotate") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_rotate (transform, args[0]);
		} else if (strcmp (keyword, "skewX") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_skew_x (transform, args[0]);
		} else if (strcmp (keyword, "skewY") == 0) {
			if (n_args != 1)
				return SVG_STATUS_PARSE_ERROR;
			_svg_transform_add_skew_y (transform, args[0]);
		} else
			return SVG_STATUS_PARSE_ERROR;
    }

    return SVG_STATUS_SUCCESS;
}
Exemplo n.º 5
0
/**
 * svg_ascii_strtod:
 * @nptr:    the string to convert to a numeric value.
 * @endptr:  if non-%NULL, it returns the character after
 *           the last character used in the conversion.
 * 
 * Converts a string to a #double value.
 * This function behaves like the standard strtod() function
 * does in the C locale. It does this without actually
 * changing the current locale, since that would not be
 * thread-safe.
 *
 * This function is typically used when reading configuration files or
 * other non-user input that should be locale independent.  To handle
 * input from the user you should normally use the locale-sensitive
 * system strtod() function.
 *
 * If the correct value would cause overflow, plus or minus %HUGE_VAL
 * is returned (according to the sign of the value), and %ERANGE is
 * stored in %errno. If the correct value would cause underflow,
 * zero is returned and %ERANGE is stored in %errno.
 * 
 * This function resets %errno before calling strtod() so that
 * you can reliably detect overflow and underflow.
 *
 * Return value: the #double value.
 **/
double
_svg_ascii_strtod (const char  *nptr,
				   const char **endptr)
{
	char *fail_pos;
	double val;
	struct lconv *locale_data;
	const char *decimal_point;
	long decimal_point_len;
	const char *p, *decimal_point_pos;
	const char *end = NULL; /* Silence gcc */

	if (nptr == NULL)
		return 0;

	fail_pos = NULL;

	locale_data = localeconv ();
	decimal_point = locale_data->decimal_point;
	decimal_point_len = strlen (decimal_point);

	decimal_point_pos = NULL;
	if (decimal_point[0] != '.' ||
		decimal_point[1] != 0)
    {
		p = nptr;
		/* Skip leading space */
		while (_svg_ascii_isspace (*p))
			p++;
		
		/* Skip leading optional sign */
		if (*p == '+' || *p == '-')
			p++;
		
		if (p[0] == '0' &&
			(p[1] == 'x' || p[1] == 'X'))
		{
			p += 2;
			/* HEX - find the (optional) decimal point */
			
			while (_svg_ascii_isxdigit (*p))
				p++;
			
			if (*p == '.')
			{
				decimal_point_pos = p++;
				
				while (_svg_ascii_isxdigit (*p))
					p++;
				
				if (*p == 'p' || *p == 'P')
					p++;
				if (*p == '+' || *p == '-')
					p++;
				while (_svg_ascii_isdigit (*p))
					p++;
				end = p;
			}
		}
		else
		{
			while (_svg_ascii_isdigit (*p))
				p++;
			
			if (*p == '.')
			{
				decimal_point_pos = p++;
				
				while (_svg_ascii_isdigit (*p))
					p++;
				
				if (*p == 'e' || *p == 'E')
					p++;
				if (*p == '+' || *p == '-')
					p++;
				while (_svg_ascii_isdigit (*p))
					p++;
				end = p;
			}
		}
		/* For the other cases, we need not convert the decimal point */
    }

	/* Set errno to zero, so that we can distinguish zero results
     and underflows */
	errno = 0;
	
	if (decimal_point_pos)
    {
		char *copy, *c;

		/* We need to convert the '.' to the locale specific decimal point */
		copy = malloc (end - nptr + 1 + decimal_point_len);
		
		c = copy;
		memcpy (c, nptr, decimal_point_pos - nptr);
		c += decimal_point_pos - nptr;
		memcpy (c, decimal_point, decimal_point_len);
		c += decimal_point_len;
		memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
		c += end - (decimal_point_pos + 1);
		*c = 0;

		val = strtod (copy, &fail_pos);

		if (fail_pos)
		{
			if (fail_pos > decimal_point_pos)
				fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
			else
				fail_pos = (char *)nptr + (fail_pos - copy);
		}
		
		free (copy);
		
    }
	else
		val = strtod (nptr, &fail_pos);

	if (endptr)
		*endptr = fail_pos;
	
	return val;
}