[lasem] traits: do string conversion error checking.



commit b46120e8d624163bda39ec3a74dc88e834c0747a
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Tue Aug 3 18:31:17 2010 +0200

    traits: do string conversion error checking.

 src/lsmmathmlattributes.c         |    1 -
 src/lsmmathmlenums.c              |  122 +++++++++++++----------
 src/lsmmathmlenums.h              |   28 +++--
 src/lsmmathmltableelement.c       |    6 +-
 src/lsmmathmltraits.c             |  199 +++++++++++++++++++++++++------------
 src/lsmmathmltraits.h             |    2 +-
 src/lsmsvgenums.c                 |   98 ++++++++++--------
 src/lsmsvgenums.h                 |   17 +++-
 src/lsmsvglength.c                |    2 +-
 src/lsmsvgradialgradientelement.c |    2 +-
 src/lsmsvgrectelement.c           |    2 +-
 src/lsmsvgtraits.c                |   79 +++++++++++----
 src/lsmtraits.c                   |   29 +++++-
 src/lsmtraits.h                   |    4 +-
 14 files changed, 382 insertions(+), 209 deletions(-)
---
diff --git a/src/lsmmathmlattributes.c b/src/lsmmathmlattributes.c
index 4156291..a8cd2b0 100644
--- a/src/lsmmathmlattributes.c
+++ b/src/lsmmathmlattributes.c
@@ -147,7 +147,6 @@ lsm_mathml_space_attribute_normalize (LsmMathmlSpaceAttribute *attribute,
 		case LSM_MATHML_SPACE_NAME_INFINITY:
 			attribute->value = G_MAXDOUBLE;
 			break;
-		case LSM_MATHML_SPACE_NAME_ERROR:
 		default:
 			attribute->value = lsm_mathml_length_normalize (&space->length,
 									base,
diff --git a/src/lsmmathmlenums.c b/src/lsmmathmlenums.c
index 6ca7bba..f374770 100644
--- a/src/lsmmathmlenums.c
+++ b/src/lsmmathmlenums.c
@@ -22,23 +22,9 @@
  */
 
 #include <lsmmathmlenums.h>
+#include <lsmtraits.h>
 #include <string.h>
 
-static unsigned int
-lsm_mathml_value_from_string (const char *string, const char **strings, unsigned int n_strings)
-{
-	int i;
-
-	if (string == NULL)
-		return 0;
-
-	for (i = 0; i < n_strings; i++)
-		if (strcmp (string, strings[i]) == 0)
-			return i;
-
-	return 0;
-}
-
 static const char *lsm_mathml_mode_strings[] = {
 	"display",
 	"inline"
@@ -47,14 +33,17 @@ static const char *lsm_mathml_mode_strings[] = {
 const char *
 lsm_mathml_mode_to_string (LsmMathmlMode mode)
 {
-	return lsm_mathml_mode_strings[CLAMP (mode, 0, LSM_MATHML_MODE_INLINE)];
+	if (mode < 0 || mode > LSM_MATHML_MODE_INLINE)
+		return NULL;
+
+	return lsm_mathml_mode_strings[mode];
 }
 
 LsmMathmlMode
 lsm_mathml_mode_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_mode_strings,
-					  G_N_ELEMENTS (lsm_mathml_mode_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_mode_strings,
+					   G_N_ELEMENTS (lsm_mathml_mode_strings));
 }
 
 static const char *lsm_mathml_display_strings[] = {
@@ -65,18 +54,20 @@ static const char *lsm_mathml_display_strings[] = {
 const char *
 lsm_mathml_display_to_string (LsmMathmlDisplay display)
 {
-	return lsm_mathml_display_strings[CLAMP (display, 0, LSM_MATHML_DISPLAY_INLINE)];
+	if (display < 0 || display > LSM_MATHML_DISPLAY_INLINE)
+		return NULL;
+
+	return lsm_mathml_display_strings[display];
 }
 
 LsmMathmlDisplay
 lsm_mathml_display_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_display_strings,
-					  G_N_ELEMENTS (lsm_mathml_display_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_display_strings,
+					   G_N_ELEMENTS (lsm_mathml_display_strings));
 }
 
 static const char *lsm_mathml_space_name_strings[] = {
-	"errormathspace",
 	"veryverythinmathspace",
 	"verythinmathspace",
 	"thinmathspace",
@@ -90,14 +81,17 @@ static const char *lsm_mathml_space_name_strings[] = {
 const char *
 lsm_mathml_space_name_to_string (LsmMathmlSpaceName space_name)
 {
-	return lsm_mathml_space_name_strings[CLAMP (space_name, 0, LSM_MATHML_SPACE_NAME_INFINITY)];
+	if (space_name < 0 || space_name > LSM_MATHML_SPACE_NAME_INFINITY)
+		return NULL;
+
+	return lsm_mathml_space_name_strings[space_name];
 }
 
 LsmMathmlSpaceName
 lsm_mathml_space_name_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_space_name_strings,
-					  G_N_ELEMENTS (lsm_mathml_space_name_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_space_name_strings,
+					   G_N_ELEMENTS (lsm_mathml_space_name_strings));
 }
 
 static const char *lsm_mathml_unit_strings[] = {
@@ -116,52 +110,59 @@ static const char *lsm_mathml_unit_strings[] = {
 const char *
 lsm_mathml_unit_to_string (LsmMathmlUnit unit)
 {
-	return lsm_mathml_unit_strings[CLAMP (unit, 0, LSM_MATHML_UNIT_PERCENT)];
+	if (unit < 0 || unit > LSM_MATHML_UNIT_PERCENT)
+		return NULL;
+
+	return lsm_mathml_unit_strings[unit];
 }
 
 LsmMathmlUnit
 lsm_mathml_unit_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_unit_strings,
-					  G_N_ELEMENTS (lsm_mathml_unit_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_unit_strings,
+					   G_N_ELEMENTS (lsm_mathml_unit_strings));
 }
 
 static const char *lsm_mathml_font_style_strings[] = {
 	"normal",
-	"italic",
-	""
+	"italic"
 };
 
 const char *
 lsm_mathml_font_style_to_string (LsmMathmlFontStyle font_style)
 {
-	return lsm_mathml_font_style_strings[CLAMP (font_style, 0, LSM_MATHML_FONT_STYLE_ERROR)];
+	if (font_style < 0 || font_style > LSM_MATHML_FONT_STYLE_ITALIC)
+		return NULL;
+
+	return lsm_mathml_font_style_strings[font_style];
 }
 
 LsmMathmlFontStyle
 lsm_mathml_font_style_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_font_style_strings,
-					     G_N_ELEMENTS (lsm_mathml_font_style_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_font_style_strings,
+					   G_N_ELEMENTS (lsm_mathml_font_style_strings));
 }
 
 static const char *lsm_mathml_font_weight_strings[] = {
 	"normal",
-	"bold",
-	""
+	"bold"
 };
 
 const char *
 lsm_mathml_font_weight_to_string (LsmMathmlFontWeight font_weight)
 {
-	return lsm_mathml_font_weight_strings[CLAMP (font_weight, 0, LSM_MATHML_FONT_WEIGHT_ERROR)];
+	if (font_weight < 0 || font_weight > LSM_MATHML_FONT_WEIGHT_BOLD)
+		return NULL;
+
+	return lsm_mathml_font_weight_strings[font_weight];
 }
 
 LsmMathmlFontWeight
 lsm_mathml_font_weight_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_font_weight_strings,
-					     G_N_ELEMENTS (lsm_mathml_font_weight_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_font_weight_strings,
+					   G_N_ELEMENTS (lsm_mathml_font_weight_strings));
 }
 
 static const char *lsm_mathml_variant_strings[] = {
@@ -184,14 +185,17 @@ static const char *lsm_mathml_variant_strings[] = {
 const char *
 lsm_mathml_variant_to_string (LsmMathmlVariant variant)
 {
-	return lsm_mathml_variant_strings[CLAMP (variant, 0, LSM_MATHML_VARIANT_MONOSPACE)];
+	if (variant < 0 || variant > LSM_MATHML_VARIANT_MONOSPACE)
+		return NULL;
+
+	return lsm_mathml_variant_strings[variant];
 }
 
 LsmMathmlVariant
 lsm_mathml_variant_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_variant_strings,
-					  G_N_ELEMENTS (lsm_mathml_variant_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_variant_strings,
+					   G_N_ELEMENTS (lsm_mathml_variant_strings));
 }
 
 void
@@ -343,14 +347,17 @@ static const char *lsm_mathml_form_strings[] = {
 const char *
 lsm_mathml_form_to_string (LsmMathmlForm form)
 {
-	return lsm_mathml_form_strings[CLAMP (form, 0, LSM_MATHML_FORM_INFIX)];
+	if (form < 0 || form > LSM_MATHML_FORM_INFIX)
+		return NULL;
+
+	return lsm_mathml_form_strings[form];
 }
 
 LsmMathmlForm
 lsm_mathml_form_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_form_strings,
-					  G_N_ELEMENTS (lsm_mathml_form_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_form_strings,
+					   G_N_ELEMENTS (lsm_mathml_form_strings));
 }
 
 static const char *lsm_mathml_row_align_strings[] = {
@@ -364,14 +371,17 @@ static const char *lsm_mathml_row_align_strings[] = {
 const char *
 lsm_mathml_row_align_to_string (LsmMathmlRowAlign row_align)
 {
-	return lsm_mathml_row_align_strings[CLAMP (row_align, 0, LSM_MATHML_ROW_ALIGN_AXIS)];
+	if (row_align < 0 || row_align > LSM_MATHML_ROW_ALIGN_AXIS)
+		return NULL;
+
+	return lsm_mathml_row_align_strings[row_align];
 }
 
 LsmMathmlRowAlign
 lsm_mathml_row_align_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_row_align_strings,
-					  G_N_ELEMENTS (lsm_mathml_row_align_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_row_align_strings,
+					   G_N_ELEMENTS (lsm_mathml_row_align_strings));
 }
 
 static const char *lsm_mathml_column_align_strings[] = {
@@ -383,14 +393,17 @@ static const char *lsm_mathml_column_align_strings[] = {
 const char *
 lsm_mathml_column_align_to_string (LsmMathmlColumnAlign column_align)
 {
-	return lsm_mathml_column_align_strings[CLAMP (column_align, 0, LSM_MATHML_COLUMN_ALIGN_RIGHT)];
+	if (column_align < 0 || column_align > LSM_MATHML_COLUMN_ALIGN_RIGHT)
+		return NULL;
+
+	return lsm_mathml_column_align_strings[column_align];
 }
 
 LsmMathmlColumnAlign
 lsm_mathml_column_align_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_column_align_strings,
-					  G_N_ELEMENTS (lsm_mathml_column_align_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_column_align_strings,
+					   G_N_ELEMENTS (lsm_mathml_column_align_strings));
 }
 
 static const char *lsm_mathml_line_strings[] = {
@@ -402,12 +415,15 @@ static const char *lsm_mathml_line_strings[] = {
 const char *
 lsm_mathml_line_to_string (LsmMathmlLine line)
 {
-	return lsm_mathml_line_strings [CLAMP (line, 0, LSM_MATHML_LINE_DASHED)];
+	if (line < 0 || line > LSM_MATHML_LINE_DASHED)
+		return NULL;
+
+	return lsm_mathml_line_strings [line];
 }
 
 LsmMathmlLine
 lsm_mathml_line_from_string (const char *string)
 {
-	return lsm_mathml_value_from_string (string, lsm_mathml_line_strings,
-					  G_N_ELEMENTS (lsm_mathml_line_strings));
+	return lsm_enum_value_from_string (string, lsm_mathml_line_strings,
+					   G_N_ELEMENTS (lsm_mathml_line_strings));
 }
diff --git a/src/lsmmathmlenums.h b/src/lsmmathmlenums.h
index 84a8b3d..5d4e117 100644
--- a/src/lsmmathmlenums.h
+++ b/src/lsmmathmlenums.h
@@ -36,6 +36,7 @@ typedef enum {
 } LsmMathmlCssType;
 
 typedef enum {
+	LSM_MATHML_MODE_ERROR = -1,
 	LSM_MATHML_MODE_DISPLAY,
 	LSM_MATHML_MODE_INLINE
 } LsmMathmlMode;
@@ -44,6 +45,7 @@ const char *		lsm_mathml_mode_to_string		(LsmMathmlMode mode);
 LsmMathmlMode		lsm_mathml_mode_from_string		(const char *string);
 
 typedef enum {
+	LSM_MATHML_DISPLAY_ERROR = -1,
 	LSM_MATHML_DISPLAY_BLOCK,
 	LSM_MATHML_DISPLAY_INLINE
 } LsmMathmlDisplay;
@@ -52,7 +54,7 @@ const char *		lsm_mathml_display_to_string		(LsmMathmlDisplay display);
 LsmMathmlDisplay	lsm_mathml_display_from_string		(const char *string);
 
 typedef enum {
-	LSM_MATHML_SPACE_NAME_ERROR,
+	LSM_MATHML_SPACE_NAME_ERROR = -1,
 	LSM_MATHML_SPACE_NAME_VERY_VERY_THIN,
 	LSM_MATHML_SPACE_NAME_VERY_THIN,
 	LSM_MATHML_SPACE_NAME_THIN,
@@ -67,6 +69,7 @@ const char * 		lsm_mathml_space_name_to_string 		(LsmMathmlSpaceName name);
 LsmMathmlSpaceName 	lsm_mathml_space_name_from_string 		(const char *string);
 
 typedef enum {
+	LSM_MATHML_UNIT_ERROR = -1,
 	LSM_MATHML_UNIT_NONE,
 	LSM_MATHML_UNIT_EM,
 	LSM_MATHML_UNIT_EX,
@@ -83,18 +86,18 @@ const char * 		lsm_mathml_unit_to_string 		(LsmMathmlUnit unit);
 LsmMathmlUnit 		lsm_mathml_unit_from_string 		(const char *string);
 
 typedef enum {
+	LSM_MATHML_FONT_STYLE_ERROR = -1,
 	LSM_MATHML_FONT_STYLE_NORMAL,
-	LSM_MATHML_FONT_STYLE_ITALIC,
-	LSM_MATHML_FONT_STYLE_ERROR
+	LSM_MATHML_FONT_STYLE_ITALIC
 } LsmMathmlFontStyle;
 
 const char * 		lsm_mathml_font_style_to_string 	(LsmMathmlFontStyle font_style);
 LsmMathmlFontStyle 	lsm_mathml_font_style_from_string 	(const char *string);
 
 typedef enum {
+	LSM_MATHML_FONT_WEIGHT_ERROR = -1,
 	LSM_MATHML_FONT_WEIGHT_NORMAL,
-	LSM_MATHML_FONT_WEIGHT_BOLD,
-	LSM_MATHML_FONT_WEIGHT_ERROR
+	LSM_MATHML_FONT_WEIGHT_BOLD
 } LsmMathmlFontWeight;
 
 const char * 		lsm_mathml_font_weight_to_string 	(LsmMathmlFontWeight font_weight);
@@ -102,6 +105,7 @@ LsmMathmlFontWeight 	lsm_mathml_font_weight_from_string 	(const char *string);
 
 /* Keep in sync with lsm_mathml_pango_options in lsm_mathml_view */
 typedef enum {
+	LSM_MATHML_VARIANT_ERROR = -1,
 	LSM_MATHML_VARIANT_NORMAL,
 	LSM_MATHML_VARIANT_BOLD,
 	LSM_MATHML_VARIANT_ITALIC,
@@ -115,8 +119,7 @@ typedef enum {
 	LSM_MATHML_VARIANT_SANS_SERIF_BOLD,
 	LSM_MATHML_VARIANT_SANS_SERIF_ITALIC,
 	LSM_MATHML_VARIANT_SANS_SERIF_BOLD_ITALIC,
-	LSM_MATHML_VARIANT_MONOSPACE,
-	LSM_MATHML_VARIANT_ERROR
+	LSM_MATHML_VARIANT_MONOSPACE
 } LsmMathmlVariant;
 
 const char * 		lsm_mathml_variant_to_string 		(LsmMathmlVariant variant);
@@ -125,28 +128,29 @@ void	 		lsm_mathml_variant_set_font_style	(LsmMathmlVariant *variant, LsmMathmlF
 void 			lsm_mathml_variant_set_font_weight	(LsmMathmlVariant *variant, LsmMathmlFontWeight weight);
 
 typedef enum {
+	LSM_MATHML_FORM_ERROR = -1,
 	LSM_MATHML_FORM_PREFIX,
 	LSM_MATHML_FORM_POSTFIX,
-	LSM_MATHML_FORM_INFIX,
-	LSM_MATHML_FORM_ERROR
+	LSM_MATHML_FORM_INFIX
 } LsmMathmlForm;
 
 const char *		lsm_mathml_form_to_string 			(LsmMathmlForm form);
 LsmMathmlForm 		lsm_mathml_form_from_string 		(const char *string);
 
 typedef enum {
+	LSM_MATHML_ROW_ALIGN_ERROR = -1,
 	LSM_MATHML_ROW_ALIGN_BASELINE,
 	LSM_MATHML_ROW_ALIGN_TOP,
 	LSM_MATHML_ROW_ALIGN_BOTTOM,
 	LSM_MATHML_ROW_ALIGN_CENTER,
-	LSM_MATHML_ROW_ALIGN_AXIS,
-	LSM_MATHML_ROW_ALIGN_ERROR
+	LSM_MATHML_ROW_ALIGN_AXIS
 } LsmMathmlRowAlign;
 
 const char *		lsm_mathml_row_align_to_string		(LsmMathmlRowAlign row_align);
 LsmMathmlRowAlign		lsm_mathml_row_align_from_string		(const char *string);
 
 typedef enum {
+	LSM_MATHML_COLUMN_ALIGN_ERROR = -1,
 	LSM_MATHML_COLUMN_ALIGN_CENTER,
 	LSM_MATHML_COLUMN_ALIGN_LEFT,
 	LSM_MATHML_COLUMN_ALIGN_RIGHT
@@ -156,6 +160,7 @@ const char *		lsm_mathml_column_align_to_string		(LsmMathmlColumnAlign column_al
 LsmMathmlColumnAlign	lsm_mathml_column_align_from_string	(const char *string);
 
 typedef enum {
+	LSM_MATHML_LINE_ERROR = -1,
 	LSM_MATHML_LINE_NONE,
 	LSM_MATHML_LINE_SOLID,
 	LSM_MATHML_LINE_DASHED
@@ -165,6 +170,7 @@ const char *		lsm_mathml_line_to_string			(LsmMathmlLine line);
 LsmMathmlLine		lsm_mathml_line_from_string		(const char *string);
 
 typedef enum {
+	LSM_MATHML_SCRIPT_LEVEL_SIGN_ERROR = -1,
 	LSM_MATHML_SCRIPT_LEVEL_SIGN_NONE,
 	LSM_MATHML_SCRIPT_LEVEL_SIGN_PLUS,
 	LSM_MATHML_SCRIPT_LEVEL_SIGN_MINUS
diff --git a/src/lsmmathmltableelement.c b/src/lsmmathmltableelement.c
index 836d66f..99ee6eb 100644
--- a/src/lsmmathmltableelement.c
+++ b/src/lsmmathmltableelement.c
@@ -30,9 +30,9 @@
 
 static const gboolean equal_default = FALSE;
 static const LsmMathmlLine frame_default = LSM_MATHML_LINE_NONE;
-static unsigned int row_align_values[1] = {LSM_MATHML_ROW_ALIGN_BASELINE};
+static int row_align_values[1] = {LSM_MATHML_ROW_ALIGN_BASELINE};
 static const LsmMathmlEnumList row_align_default = {.n_values = 1, .values = row_align_values};
-static unsigned int column_align_values[1] = {LSM_MATHML_COLUMN_ALIGN_CENTER};
+static int column_align_values[1] = {LSM_MATHML_COLUMN_ALIGN_CENTER};
 static const LsmMathmlEnumList column_align_default = {.n_values = 1, .values = column_align_values};
 static LsmMathmlSpace row_spacing_values[1] = {
 	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EX, .value = 1.0}}
@@ -42,7 +42,7 @@ static LsmMathmlSpace column_spacing_values[1] = {
 	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EM, .value = 0.8}}
 };
 static const LsmMathmlSpaceList column_spacing_default = {.n_spaces = 1, .spaces = column_spacing_values};
-static unsigned int lines_values[1] = {LSM_MATHML_LINE_NONE};
+static int lines_values[1] = {LSM_MATHML_LINE_NONE};
 static const LsmMathmlEnumList lines_default = {.n_values = 1, .values = lines_values};
 static LsmMathmlSpace frame_spacing_values[2] = {
 	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EM, .value = 0.4}},
diff --git a/src/lsmmathmltraits.c b/src/lsmmathmltraits.c
index 433d9cb..f700287 100644
--- a/src/lsmmathmltraits.c
+++ b/src/lsmmathmltraits.c
@@ -26,12 +26,21 @@
 #include <string.h>
 #include <stdlib.h>
 
-static void
+static gboolean
 lsm_mathml_boolean_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	gboolean *value = (gboolean *) abstract_trait;
 
-	*value = (g_strcmp0 (string, "true") == 0);
+	if (g_strcmp0 (string, "true") == 0) {
+		*value = TRUE;
+		return TRUE;
+	} else if (g_strcmp0 (string, "false") == 0) {
+		*value = FALSE;
+		return TRUE;
+	}
+
+	*value = FALSE;
+	return FALSE;
 }
 
 static char *
@@ -48,12 +57,15 @@ const LsmTraitClass lsm_mathml_boolean_trait_class = {
 	.to_string = lsm_mathml_boolean_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_unsigned_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	unsigned int *value = (unsigned int *) abstract_trait;
+	char *end_ptr;
 
-	*value = atoi (string);
+	*value = strtol (string, &end_ptr, 10);
+
+	return end_ptr != string;
 }
 
 static char *
@@ -70,12 +82,14 @@ const LsmTraitClass lsm_mathml_unsigned_trait_class = {
 	.to_string = lsm_mathml_unsigned_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_display_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlDisplay *value = (LsmMathmlDisplay *) abstract_trait;
 
 	*value = lsm_mathml_display_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -87,17 +101,19 @@ lsm_mathml_display_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_display_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_display_trait_from_string,
 	.to_string = lsm_mathml_display_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_mode_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlMode *value = (LsmMathmlMode *) abstract_trait;
 
 	*value = lsm_mathml_mode_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -109,17 +125,19 @@ lsm_mathml_mode_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_mode_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_mode_trait_from_string,
 	.to_string = lsm_mathml_mode_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_line_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlLine *value = (LsmMathmlLine *) abstract_trait;
 
 	*value = lsm_mathml_line_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -131,17 +149,19 @@ lsm_mathml_line_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_line_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_line_trait_from_string,
 	.to_string = lsm_mathml_line_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_font_style_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlFontStyle *value = (LsmMathmlFontStyle *) abstract_trait;
 
 	*value = lsm_mathml_font_style_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -153,17 +173,19 @@ lsm_mathml_font_style_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_font_style_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_font_style_trait_from_string,
 	.to_string = lsm_mathml_font_style_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_font_weight_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlFontWeight *value = (LsmMathmlFontWeight *) abstract_trait;
 
 	*value = lsm_mathml_font_weight_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -175,17 +197,19 @@ lsm_mathml_font_weight_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_font_weight_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_font_weight_trait_from_string,
 	.to_string = lsm_mathml_font_weight_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_variant_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlVariant *value = (LsmMathmlVariant *) abstract_trait;
 
 	*value = lsm_mathml_variant_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -197,17 +221,19 @@ lsm_mathml_variant_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_variant_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_variant_trait_from_string,
 	.to_string = lsm_mathml_variant_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_form_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlForm *value = (LsmMathmlForm *) abstract_trait;
 
 	*value = lsm_mathml_form_from_string (string);
+
+	return *value >= 0;
 }
 
 static char *
@@ -219,32 +245,45 @@ lsm_mathml_form_trait_to_string (LsmTrait *abstract_trait)
 }
 
 const LsmTraitClass lsm_mathml_form_trait_class = {
-	.size = sizeof (unsigned),
+	.size = sizeof (int),
 	.from_string = lsm_mathml_form_trait_from_string,
 	.to_string = lsm_mathml_form_trait_to_string
 };
 
-typedef unsigned int (*LsmMathmlEnumFromString) (const char *string);
+typedef int (*LsmMathmlEnumFromString) (const char *string);
 typedef char * (*LsmMathmlEnumToString) (unsigned int value);
 
-static void
+static gboolean
 lsm_mathml_enum_list_trait_from_string (LsmMathmlEnumList *enum_list,
 					LsmMathmlEnumFromString from_string,
 					char *string)
 {
 	char **items;
 	unsigned int i;
+	int enum_value;
 
 	g_free (enum_list->values);
 
 	items = g_strsplit_set (string, " ", -1);
 	enum_list->n_values = g_strv_length (items);
 
-	enum_list->values = g_new (unsigned int, enum_list->n_values);
-	for (i = 0; i < enum_list->n_values; i++)
-		enum_list->values[i] = from_string (items[i]);
+	enum_list->values = g_new (int, enum_list->n_values);
+	for (i = 0; i < enum_list->n_values; i++) {
+		enum_value = from_string (items[i]);
+		if (enum_value < 0) {
+			g_free (enum_list->values);
+			enum_list->values = NULL;
+			enum_list->n_values = 0;
+			g_strfreev (items);
+
+			return FALSE;
+		}
+		enum_list->values[i] = enum_value;
+	}
 
 	g_strfreev (items);
+
+	return TRUE;
 }
 
 static char *
@@ -265,8 +304,8 @@ lsm_mathml_enum_list_trait_init (LsmTrait *abstract_trait,
 	if (enum_list->n_values == 0)
 		enum_list->values = NULL;
 	else {
-		enum_list->values = g_new (unsigned int, enum_list->n_values);
-		memcpy (enum_list->values, enum_list_defaut->values, sizeof (unsigned int) * enum_list->n_values);
+		enum_list->values = g_new (int, enum_list->n_values);
+		memcpy (enum_list->values, enum_list_defaut->values, sizeof (int) * enum_list->n_values);
 	}
 }
 
@@ -289,13 +328,13 @@ lsm_mathml_enum_list_trait_finalize (LsmTrait *abstract_trait)
 	enum_list->n_values = 0;
 }
 
-static void
+static gboolean
 lsm_mathml_row_align_list_trait_from_string (LsmTrait *abstract_trait,
 					     char *string)
 {
-	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
-						(LsmMathmlEnumFromString) lsm_mathml_row_align_from_string,
-						string);
+	return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						       (LsmMathmlEnumFromString) lsm_mathml_row_align_from_string,
+						       string);
 }
 
 static char *
@@ -313,13 +352,13 @@ const LsmTraitClass lsm_mathml_row_align_list_trait_class = {
 	.finalize = lsm_mathml_enum_list_trait_finalize
 };
 
-static void
+static gboolean
 lsm_mathml_column_align_list_trait_from_string (LsmTrait *abstract_trait,
 					     char *string)
 {
-	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
-						(LsmMathmlEnumFromString) lsm_mathml_column_align_from_string,
-						string);
+	return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						       (LsmMathmlEnumFromString) lsm_mathml_column_align_from_string,
+						       string);
 }
 
 static char *
@@ -337,13 +376,13 @@ const LsmTraitClass lsm_mathml_column_align_list_trait_class = {
 	.finalize = lsm_mathml_enum_list_trait_finalize
 };
 
-static void
+static gboolean
 lsm_mathml_line_list_trait_from_string (LsmTrait *abstract_trait,
 					     char *string)
 {
-	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
-						(LsmMathmlEnumFromString) lsm_mathml_line_from_string,
-						string);
+	return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						       (LsmMathmlEnumFromString) lsm_mathml_line_from_string,
+						       string);
 }
 
 static char *
@@ -361,18 +400,22 @@ const LsmTraitClass lsm_mathml_line_list_trait_class = {
 	.finalize = lsm_mathml_enum_list_trait_finalize
 };
 
-static void
+static gboolean
 lsm_mathml_script_level_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlScriptLevel *value = (LsmMathmlScriptLevel *) abstract_trait;
+	char *end_ptr;
+
+	value->level = strtol (string, &end_ptr, 10);
 
-	value->level = atoi (string);
 	if (string[0] == '+')
 		value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_PLUS;
 	else if (string[0] == '-')
 		value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_MINUS;
 	else
 		value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_NONE;
+
+	return end_ptr != string;
 }
 
 static char *
@@ -392,12 +435,15 @@ const LsmTraitClass lsm_mathml_script_level_trait_class = {
 	.to_string = lsm_mathml_script_level_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_double_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	double *value = (double *) abstract_trait;
+	char *end_ptr;
 
-	*value = atof (string);
+	*value = g_ascii_strtod (string, &end_ptr);
+
+	return end_ptr != string;
 }
 
 static char *
@@ -437,25 +483,29 @@ lsm_mathml_color_get_type (void)
 	return our_type;
 }
 
-static void
+static gboolean
 lsm_mathml_color_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlColor *color = (LsmMathmlColor *) abstract_trait;
+	PangoColor pango_color;
+	gboolean result;
 
 	if (strcmp (string, "transparent") == 0) {
 		color->red = 0.0;
 		color->green = 0.0;
 		color->blue = 0.0;
 		color->alpha = 0.0;
-	} else {
-		PangoColor pango_color;
-
-		pango_color_parse (&pango_color, string);
-		color->alpha = 1.0;
-		color->red = pango_color.red / 65535.0;
-		color->green = pango_color.green / 65535.0;
-		color->blue = pango_color.blue / 65535.0;
+
+		return TRUE;
 	}
+
+	result = pango_color_parse (&pango_color, string);
+	color->alpha = 1.0;
+	color->red = pango_color.red / 65535.0;
+	color->green = pango_color.green / 65535.0;
+	color->blue = pango_color.blue / 65535.0;
+
+	return result;
 }
 
 static char *
@@ -480,13 +530,15 @@ const LsmTraitClass lsm_mathml_color_trait_class = {
 	.to_string = lsm_mathml_color_trait_to_string
 };
 
-static void
+static gboolean
 lsm_mathml_string_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	char **value = (char **) abstract_trait;
 
 	g_free (*value);
 	*value = g_strdup (string);
+
+	return TRUE;
 }
 
 static char *
@@ -548,16 +600,18 @@ lsm_mathml_length_get_type (void)
 	return our_type;
 }
 
-static void
+static gboolean
 lsm_mathml_length_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlLength *length = (LsmMathmlLength *) abstract_trait;
 	char *unit_str;
 
-	length->value = g_strtod (string, &unit_str);
+	length->value = g_ascii_strtod (string, &unit_str);
 	length->unit = lsm_mathml_unit_from_string (unit_str);
 
 	/* TODO Handle "big", "small", normal" sizes */
+
+	return unit_str != string && length->unit >= 0;
 }
 
 static char *
@@ -644,29 +698,36 @@ lsm_mathml_space_get_type (void)
 	return our_type;
 }
 
-static void
+static gboolean
 lsm_mathml_space_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlSpace *space = (LsmMathmlSpace *) abstract_trait;
 	char *unit_str;
 
 	space->name = lsm_mathml_space_name_from_string (string);
-	if (space->name == LSM_MATHML_SPACE_NAME_ERROR) {
-		space->length.value = g_strtod (string, &unit_str);
+
+	if (space->name < 0) {
+		space->length.value = g_ascii_strtod (string, &unit_str);
 		space->length.unit = lsm_mathml_unit_from_string (unit_str);
-	} else {
-		space->length.value = 0.0;
-		space->length.unit = LSM_MATHML_UNIT_PX;
+
+		return unit_str != string && space->length.unit >= 0;
 	}
+
+	space->length.value = 0.0;
+	space->length.unit = LSM_MATHML_UNIT_PX;
+
+	return TRUE;
 }
 
 static char *
 lsm_mathml_space_trait_to_string (LsmTrait *abstract_trait)
 {
 	LsmMathmlSpace *space = (LsmMathmlSpace *) abstract_trait;
+	const char *string;
 
-	if (space->name != LSM_MATHML_SPACE_NAME_ERROR)
-		return g_strdup (lsm_mathml_space_name_to_string (space->name));
+	string = lsm_mathml_space_name_to_string (space->name);
+	if (string != NULL)
+		return g_strdup (string);
 
 	return g_strdup_printf ("%g %s", space->length.value,
 				lsm_mathml_unit_to_string (space->length.unit));
@@ -678,7 +739,7 @@ const LsmTraitClass lsm_mathml_space_trait_class = {
 	.to_string = lsm_mathml_space_trait_to_string
 };
 
-void
+gboolean
 lsm_mathml_space_list_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
@@ -691,10 +752,20 @@ lsm_mathml_space_list_trait_from_string (LsmTrait *abstract_trait, char *string)
 	space_list->n_spaces = g_strv_length (items);
 
 	space_list->spaces = g_new (LsmMathmlSpace, space_list->n_spaces);
-	for (i = 0; i < space_list->n_spaces; i++)
-		lsm_mathml_space_trait_from_string (&space_list->spaces[i], items[i]);
+	for (i = 0; i < space_list->n_spaces; i++) {
+		if (!lsm_mathml_space_trait_from_string (&space_list->spaces[i], items[i])) {
+			g_free (space_list->spaces);
+			space_list->spaces = NULL;
+			space_list->n_spaces = 0;
+			g_strfreev (items);
+
+			return FALSE;
+		}
+	}
 
 	g_strfreev (items);
+
+	return TRUE;
 }
 
 static char *
diff --git a/src/lsmmathmltraits.h b/src/lsmmathmltraits.h
index 72cbb6b..8b32298 100644
--- a/src/lsmmathmltraits.h
+++ b/src/lsmmathmltraits.h
@@ -66,7 +66,7 @@ typedef struct {
 
 typedef struct {
 	unsigned int n_values;
-	unsigned int *values;
+	int *values;
 } LsmMathmlEnumList;
 
 #define LSM_TYPE_MATHML_SPACE (lsm_mathml_space_get_type())
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index 7b5f13f..0f69572 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -21,25 +21,10 @@
  */
 
 #include <lsmsvgenums.h>
+#include <lsmtraits.h>
 #include <string.h>
 
-static unsigned int
-lsm_svg_value_from_string (const char *string, const char **strings, unsigned int n_strings)
-{
-	int i;
-
-	if (string == NULL)
-		return 0;
-
-	for (i = 0; i < n_strings; i++)
-		if (strcmp (string, strings[i]) == 0)
-			return i;
-
-	return 0;
-}
-
 static const char *lsm_svg_length_type_strings[] = {
-	"?",
 	"",
 	"%",
 	"em",
@@ -55,14 +40,17 @@ static const char *lsm_svg_length_type_strings[] = {
 const char *
 lsm_svg_length_type_to_string (LsmSvgLengthType length_type)
 {
-	return lsm_svg_length_type_strings[CLAMP (length_type, 0, LSM_SVG_LENGTH_TYPE_PC)];
+	if (length_type < 0 || length_type > LSM_SVG_LENGTH_TYPE_PC)
+		return NULL;
+
+	return lsm_svg_length_type_strings[length_type];
 }
 
 LsmSvgLengthType
 lsm_svg_length_type_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_length_type_strings,
-				       G_N_ELEMENTS (lsm_svg_length_type_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_length_type_strings,
+					   G_N_ELEMENTS (lsm_svg_length_type_strings));
 }
 
 static const char *lsm_svg_fill_rule_strings[] = {
@@ -73,14 +61,17 @@ static const char *lsm_svg_fill_rule_strings[] = {
 const char *
 lsm_svg_fill_rule_to_string (LsmSvgFillRule fill_rule)
 {
-	return lsm_svg_fill_rule_strings[CLAMP (fill_rule, 0, LSM_SVG_FILL_RULE_EVEN_ODD)];
+	if (fill_rule < 0 || fill_rule > LSM_SVG_FILL_RULE_EVEN_ODD)
+		return NULL;
+
+	return lsm_svg_fill_rule_strings[fill_rule];
 }
 
 LsmSvgFillRule
 lsm_svg_fill_rule_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_fill_rule_strings,
-					  G_N_ELEMENTS (lsm_svg_fill_rule_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_fill_rule_strings,
+					   G_N_ELEMENTS (lsm_svg_fill_rule_strings));
 }
 
 static const char *lsm_svg_line_join_strings[] = {
@@ -92,14 +83,17 @@ static const char *lsm_svg_line_join_strings[] = {
 const char *
 lsm_svg_line_join_to_string (LsmSvgLineJoin line_join)
 {
-	return lsm_svg_line_join_strings[CLAMP (line_join, 0, LSM_SVG_LINE_JOIN_BEVEL)];
+	if (line_join < 0 || line_join > LSM_SVG_LINE_JOIN_BEVEL)
+		return NULL;
+
+	return lsm_svg_line_join_strings[line_join];
 }
 
 LsmSvgLineJoin
 lsm_svg_line_join_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_line_join_strings,
-					  G_N_ELEMENTS (lsm_svg_line_join_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_line_join_strings,
+					   G_N_ELEMENTS (lsm_svg_line_join_strings));
 }
 
 static const char *lsm_svg_line_cap_strings[] = {
@@ -111,14 +105,17 @@ static const char *lsm_svg_line_cap_strings[] = {
 const char *
 lsm_svg_line_cap_to_string (LsmSvgLineCap line_cap)
 {
-	return lsm_svg_line_cap_strings[CLAMP (line_cap, 0, LSM_SVG_LINE_CAP_SQUARE)];
+	if (line_cap < 0 || line_cap > LSM_SVG_LINE_CAP_SQUARE)
+		return NULL;
+
+	return lsm_svg_line_cap_strings[line_cap];
 }
 
 LsmSvgLineCap
 lsm_svg_line_cap_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_line_cap_strings,
-					  G_N_ELEMENTS (lsm_svg_line_cap_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_line_cap_strings,
+					   G_N_ELEMENTS (lsm_svg_line_cap_strings));
 }
 
 static const char *lsm_svg_pattern_units_strings[] = {
@@ -129,14 +126,17 @@ static const char *lsm_svg_pattern_units_strings[] = {
 const char *
 lsm_svg_pattern_units_to_string (LsmSvgPatternUnits units)
 {
-	return lsm_svg_pattern_units_strings[CLAMP (units, 0, LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX)];
+	if (units < 0 || units > LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX)
+		return NULL;
+
+	return lsm_svg_pattern_units_strings[units];
 }
 
 LsmSvgPatternUnits
 lsm_svg_pattern_units_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_pattern_units_strings,
-					  G_N_ELEMENTS (lsm_svg_pattern_units_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_pattern_units_strings,
+					   G_N_ELEMENTS (lsm_svg_pattern_units_strings));
 }
 
 static const char *lsm_svg_marker_units_strings[] = {
@@ -147,14 +147,17 @@ static const char *lsm_svg_marker_units_strings[] = {
 const char *
 lsm_svg_marker_units_to_string (LsmSvgMarkerUnits units)
 {
-	return lsm_svg_marker_units_strings[CLAMP (units, 0, LSM_SVG_MARKER_UNITS_STROKE_WIDTH)];
+	if (units < 0 || units > LSM_SVG_MARKER_UNITS_STROKE_WIDTH)
+		return NULL;
+
+	return lsm_svg_marker_units_strings[units];
 }
 
 LsmSvgMarkerUnits
 lsm_svg_marker_units_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_marker_units_strings,
-					  G_N_ELEMENTS (lsm_svg_marker_units_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_marker_units_strings,
+					   G_N_ELEMENTS (lsm_svg_marker_units_strings));
 }
 
 static const char *lsm_svg_spread_method_strings[] = {
@@ -166,18 +169,20 @@ static const char *lsm_svg_spread_method_strings[] = {
 const char *
 lsm_svg_spread_method_to_string (LsmSvgSpreadMethod units)
 {
-	return lsm_svg_spread_method_strings[CLAMP (units, 0, LSM_SVG_SPREAD_METHOD_REPEAT)];
+	if (units < 0 || units > LSM_SVG_SPREAD_METHOD_REPEAT)
+		return NULL;
+
+	return lsm_svg_spread_method_strings[units];
 }
 
 LsmSvgSpreadMethod
 lsm_svg_spread_method_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_spread_method_strings,
-				       G_N_ELEMENTS (lsm_svg_spread_method_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_spread_method_strings,
+					 G_N_ELEMENTS (lsm_svg_spread_method_strings));
 }
 
 static const char *lsm_svg_align_strings[] = {
-	"",
 	"none",
 	"xMinYMin",
 	"xMidYMin",
@@ -193,18 +198,20 @@ static const char *lsm_svg_align_strings[] = {
 const char *
 lsm_svg_align_to_string (LsmSvgAlign align)
 {
-	return lsm_svg_align_strings[CLAMP (align, 0, LSM_SVG_ALIGN_X_MAX_Y_MAX)];
+	if (align < 0 || align > LSM_SVG_ALIGN_X_MAX_Y_MAX)
+		return NULL;
+
+	return lsm_svg_align_strings[align];
 }
 
 LsmSvgAlign
 lsm_svg_align_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_align_strings,
-					  G_N_ELEMENTS (lsm_svg_align_strings));
+	return lsm_enum_value_from_string (string, lsm_svg_align_strings,
+					   G_N_ELEMENTS (lsm_svg_align_strings));
 }
 
 static const char *lsm_svg_meet_or_slice_strings[] = {
-	"",
 	"meet",
 	"slice"
 };
@@ -212,12 +219,15 @@ static const char *lsm_svg_meet_or_slice_strings[] = {
 const char *
 lsm_svg_meet_or_slice_to_string (LsmSvgMeetOrSlice meet_or_slice)
 {
-	return lsm_svg_meet_or_slice_strings[CLAMP (meet_or_slice, 0, LSM_SVG_MEET_OR_SLICE_SLICE)];
+	if (meet_or_slice < 0 || meet_or_slice > LSM_SVG_MEET_OR_SLICE_SLICE)
+		return NULL;
+
+	return lsm_svg_meet_or_slice_strings[meet_or_slice];
 }
 
 LsmSvgMeetOrSlice
 lsm_svg_meet_or_slice_from_string (const char *string)
 {
-	return lsm_svg_value_from_string (string, lsm_svg_meet_or_slice_strings,
+	return lsm_enum_value_from_string (string, lsm_svg_meet_or_slice_strings,
 					  G_N_ELEMENTS (lsm_svg_meet_or_slice_strings));
 }
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index 61641af..a755e64 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -28,11 +28,13 @@
 G_BEGIN_DECLS
 
 typedef enum {
+	LSM_SVG_ANGLE_TYPE_ERROR = -1,
 	LSM_SVG_ANGLE_TYPE_AUTO,
 	LSM_SVG_ANGLE_TYPE_FIXED
 } LsmSvgAngleType;
 
 typedef enum {
+	LSM_SVG_PAINT_TYPE_ERROR = -1,
 	LSM_SVG_PAINT_TYPE_UNKNOWN = 0,
 	LSM_SVG_PAINT_TYPE_RGB_COLOR,
 	LSM_SVG_PAINT_TYPE_RGB_COLOR_ICC_COLOR,
@@ -46,13 +48,14 @@ typedef enum {
 } LsmSvgPaintType;
 
 typedef enum {
+	LSM_SVG_LENGTH_DIRECTION_ERROR = -1,
 	LSM_SVG_LENGTH_DIRECTION_HORIZONTAL,
 	LSM_SVG_LENGTH_DIRECTION_VERTICAL,
 	LSM_SVG_LENGTH_DIRECTION_DIAGONAL
 } LsmSvgLengthDirection;
 
 typedef enum {
-	LSM_SVG_LENGTH_TYPE_UNKNOWN,
+	LSM_SVG_LENGTH_TYPE_ERROR = -1,
 	LSM_SVG_LENGTH_TYPE_NUMBER,
 	LSM_SVG_LENGTH_TYPE_PERCENTAGE,
 	LSM_SVG_LENGTH_TYPE_EMS,
@@ -69,6 +72,7 @@ const char * 		lsm_svg_length_type_to_string 		(LsmSvgLengthType length_type);
 LsmSvgLengthType	lsm_svg_length_type_from_string 	(const char *string);
 
 typedef enum {
+	LSM_SVG_FILL_RULE_ERROR = -1,
 	LSM_SVG_FILL_RULE_NON_ZERO,
 	LSM_SVG_FILL_RULE_EVEN_ODD
 } LsmSvgFillRule;
@@ -77,6 +81,7 @@ const char * 		lsm_svg_fill_rule_to_string 		(LsmSvgFillRule fill_rule);
 LsmSvgFillRule 		lsm_svg_fill_rule_from_string 		(const char *string);
 
 typedef enum {
+	LSM_SVG_LINE_JOIN_ERROR = -1,
 	LSM_SVG_LINE_JOIN_MITER,
 	LSM_SVG_LINE_JOIN_ROUND,
 	LSM_SVG_LINE_JOIN_BEVEL
@@ -86,6 +91,7 @@ const char * 		lsm_svg_line_join_to_string 		(LsmSvgLineJoin line_join);
 LsmSvgLineJoin 		lsm_svg_line_join_from_string 		(const char *string);
 
 typedef enum {
+	LSM_SVG_LINE_CAP_ERROR = -1,
 	LSM_SVG_LINE_CAP_BUTT,
 	LSM_SVG_LINE_CAP_ROUND,
 	LSM_SVG_LINE_CAP_SQUARE
@@ -95,7 +101,7 @@ const char * 		lsm_svg_line_cap_to_string 		(LsmSvgLineCap line_cap);
 LsmSvgLineCap		lsm_svg_line_cap_from_string 		(const char *string);
 
 typedef enum {
-	LSM_SVG_TRANSFORM_TYPE_UNKNOWN,
+	LSM_SVG_TRANSFORM_TYPE_ERROR = -1,
 	LSM_SVG_TRANSFORM_TYPE_MATRIX,
 	LSM_SVG_TRANSFORM_TYPE_TRANSLATE,
 	LSM_SVG_TRANSFORM_TYPE_SCALE,
@@ -105,6 +111,7 @@ typedef enum {
 } LsmSvgTransformType;
 
 typedef enum {
+	LSM_SVG_PATTERN_UNITS_ERROR = -1,
 	LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE,
 	LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX
 } LsmSvgPatternUnits;
@@ -113,6 +120,7 @@ const char * 		lsm_svg_pattern_units_to_string 		(LsmSvgPatternUnits units);
 LsmSvgPatternUnits	lsm_svg_pattern_units_from_string		(const char *string);
 
 typedef enum {
+	LSM_SVG_MARKER_UNITS_ERROR = -1,
 	LSM_SVG_MARKER_UNITS_USER_SPACE_ON_USE,
 	LSM_SVG_MARKER_UNITS_STROKE_WIDTH
 } LsmSvgMarkerUnits;
@@ -121,6 +129,7 @@ const char * 		lsm_svg_marker_units_to_string 			(LsmSvgMarkerUnits units);
 LsmSvgMarkerUnits	lsm_svg_marker_units_from_string		(const char *string);
 
 typedef enum {
+	LSM_SVG_SPREAD_METHOD_ERROR = -1,
 	LSM_SVG_SPREAD_METHOD_PAD,
 	LSM_SVG_SPREAD_METHOD_REFLECT,
 	LSM_SVG_SPREAD_METHOD_REPEAT
@@ -130,7 +139,7 @@ const char * 		lsm_svg_spread_method_to_string 		(LsmSvgSpreadMethod method);
 LsmSvgSpreadMethod	lsm_svg_spread_method_from_string		(const char *string);
 
 typedef enum {
-	LSM_SVG_ALIGN_UNKNOWN,
+	LSM_SVG_ALIGN_ERROR = -1,
 	LSM_SVG_ALIGN_NONE,
 	LSM_SVG_ALIGN_X_MIN_Y_MIN,
 	LSM_SVG_ALIGN_X_MID_Y_MIN,
@@ -147,7 +156,7 @@ const char * 		lsm_svg_align_to_string 		(LsmSvgAlign align);
 LsmSvgAlign		lsm_svg_align_from_string		(const char *string);
 
 typedef enum {
-	LSM_SVG_MEET_OR_SLICE_UNKNOWN,
+	LSM_SVG_MEET_OR_SLICE_ERROR = -1,
 	LSM_SVG_MEET_OR_SLICE_MEET,
 	LSM_SVG_MEET_OR_SLICE_SLICE
 } LsmSvgMeetOrSlice;
diff --git a/src/lsmsvglength.c b/src/lsmsvglength.c
index e94cd6f..96620d9 100644
--- a/src/lsmsvglength.c
+++ b/src/lsmsvglength.c
@@ -56,7 +56,7 @@ lsm_svg_length_normalize (const LsmSvgLength *length,
 
 	switch (length->type) {
 		case LSM_SVG_LENGTH_TYPE_NUMBER:
-		case LSM_SVG_LENGTH_TYPE_UNKNOWN:
+		case LSM_SVG_LENGTH_TYPE_ERROR:
 		case LSM_SVG_LENGTH_TYPE_PX:
 			return length->value_unit;
 		case LSM_SVG_LENGTH_TYPE_PERCENTAGE:
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index 6c88980..7c7af85 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -98,7 +98,7 @@ lsm_svg_radial_gradient_element_new (void)
 }
 
 static const LsmSvgLength length_default = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
-static const LsmSvgLength unset_default  = {.value_unit =  0.0, .type = LSM_SVG_LENGTH_TYPE_UNKNOWN};
+static const LsmSvgLength unset_default  = {.value_unit =  0.0, .type = LSM_SVG_LENGTH_TYPE_ERROR};
 
 static void
 lsm_svg_radial_gradient_element_init (LsmSvgRadialGradientElement *self)
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index 1388e42..2400636 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -91,7 +91,7 @@ lsm_svg_rect_element_new (void)
 }
 
 static const LsmSvgLength length_default = 	 { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PX};
-static const LsmSvgLength unset_length_default = { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_UNKNOWN};
+static const LsmSvgLength unset_length_default = { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_ERROR};
 
 static void
 lsm_svg_rect_element_init (LsmSvgRectElement *self)
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
index 5e6790d..135c915 100644
--- a/src/lsmsvgtraits.c
+++ b/src/lsmsvgtraits.c
@@ -29,14 +29,16 @@
 const LsmSvgColor lsm_svg_color_null = {0.0, 0.0, 0.0};
 const LsmSvgDashArray lsm_svg_dash_array_null = {0, NULL};
 
-static void
+static gboolean
 lsm_svg_length_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgLength *svg_length = (LsmSvgLength *) abstract_trait;
 	char *length_type_str;
 
-	svg_length->value_unit = g_strtod (string, &length_type_str);
+	svg_length->value_unit = g_ascii_strtod (string, &length_type_str);
 	svg_length->type = lsm_svg_length_type_from_string (length_type_str);
+
+	return length_type_str != string && svg_length->type >= 0;
 }
 
 static char *
@@ -119,7 +121,7 @@ _init_matrix (LsmSvgMatrix *matrix, LsmSvgTransformType transform, unsigned int
 	lsm_svg_matrix_init_identity (matrix);
 }
 
-static void
+static gboolean
 lsm_svg_matrix_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgMatrix *matrix = (LsmSvgMatrix *) abstract_trait;
@@ -151,7 +153,7 @@ lsm_svg_matrix_trait_from_string (LsmTrait *abstract_trait, char *string)
 			transform = LSM_SVG_TRANSFORM_TYPE_SKEW_Y;
 			string += 5;
 		} else
-			break;
+			return FALSE;
 
 		lsm_str_skip_spaces (&string);
 
@@ -179,9 +181,13 @@ lsm_svg_matrix_trait_from_string (LsmTrait *abstract_trait, char *string)
 				_init_matrix (&new_matrix, transform, n_values, values);
 
 				lsm_svg_matrix_multiply (matrix, &new_matrix, matrix);
-			}
-		}
+			} else
+				return FALSE;
+		} else
+			return FALSE;
 	}
+
+	return TRUE;
 }
 
 static char *
@@ -294,7 +300,7 @@ _parse_color (char *string,
 	return string;
 }
 
-static void
+static gboolean
 lsm_svg_paint_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgPaint *paint = (LsmSvgPaint *) abstract_trait;
@@ -342,6 +348,10 @@ lsm_svg_paint_trait_from_string (LsmTrait *abstract_trait, char *string)
 		}
 
 	paint->type = paint_type;
+
+	/* TODO better syntax error check */
+
+	return TRUE;
 }
 
 char *
@@ -368,12 +378,14 @@ const LsmTraitClass lsm_svg_paint_trait_class = {
 	.to_string = lsm_svg_paint_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_fill_rule_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgFillRule *trait = (LsmSvgFillRule *) abstract_trait;
 
 	*trait = lsm_svg_fill_rule_from_string (string);
+
+	return *trait >= 0;
 }
 
 char *
@@ -390,12 +402,14 @@ const LsmTraitClass lsm_svg_fill_rule_trait_class = {
 	.to_string = lsm_svg_fill_rule_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_line_join_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgLineJoin *trait = (LsmSvgLineJoin *) abstract_trait;
 
 	*trait = lsm_svg_line_join_from_string (string);
+
+	return *trait >= 0;
 }
 
 char *
@@ -412,12 +426,14 @@ const LsmTraitClass lsm_svg_line_join_trait_class = {
 	.to_string = lsm_svg_line_join_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_line_cap_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgLineCap *trait = (LsmSvgLineCap *) abstract_trait;
 
 	*trait = lsm_svg_line_cap_from_string (string);
+
+	return *trait >= 0;
 }
 
 static char *
@@ -474,7 +490,7 @@ lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin)
 	return duplicate;
 }
 
-static void
+static gboolean
 lsm_svg_dash_array_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgDashArray *dash_array = (LsmSvgDashArray *) abstract_trait;
@@ -517,6 +533,10 @@ lsm_svg_dash_array_trait_from_string (LsmTrait *abstract_trait, char *string)
 			}
 		}
 	}
+
+	/* TODO better syntax error check */
+
+	return TRUE;
 }
 
 static char *
@@ -542,13 +562,17 @@ const LsmTraitClass lsm_svg_dash_array_trait_class = {
 	.finalize = lsm_svg_dash_array_trait_finalize
 };
 
-static void
+static gboolean
 lsm_svg_color_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgColor *color = (LsmSvgColor *) abstract_trait;
 	LsmSvgPaintType paint_type;
 
 	_parse_color (string, color, &paint_type);
+
+	/* TODO Better error check */
+
+	return TRUE;
 }
 
 static char *
@@ -571,12 +595,14 @@ const LsmTraitClass lsm_svg_color_trait_class = {
 	.to_string = lsm_svg_color_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_marker_units_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgMarkerUnits *trait = (LsmSvgMarkerUnits *) abstract_trait;
 
 	*trait = lsm_svg_marker_units_from_string (string);
+
+	return *trait >= 0;
 }
 
 char *
@@ -593,12 +619,14 @@ const LsmTraitClass lsm_svg_marker_units_trait_class = {
 	.to_string = lsm_svg_marker_units_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_pattern_units_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgPatternUnits *trait = (LsmSvgPatternUnits *) abstract_trait;
 
 	*trait = lsm_svg_pattern_units_from_string (string);
+
+	return *trait >= 0;
 }
 
 char *
@@ -615,7 +643,7 @@ const LsmTraitClass lsm_svg_pattern_units_trait_class = {
 	.to_string = lsm_svg_pattern_units_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_preserve_aspect_ratio_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgPreserveAspectRatio *trait = (LsmSvgPreserveAspectRatio *) abstract_trait;
@@ -641,6 +669,10 @@ lsm_svg_preserve_aspect_ratio_trait_from_string (LsmTrait *abstract_trait, char
 	} else trait->align = LSM_SVG_ALIGN_X_MID_Y_MID;
 
 	g_strfreev (tokens);
+
+	/* TODO Better error check */
+
+	return TRUE;
 }
 
 char *
@@ -659,12 +691,14 @@ const LsmTraitClass lsm_svg_preserve_aspect_ratio_trait_class = {
 	.to_string = lsm_svg_preserve_aspect_ratio_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_spread_method_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgSpreadMethod *trait = (LsmSvgSpreadMethod *) abstract_trait;
 
 	*trait = lsm_svg_spread_method_from_string (string);
+
+	return *trait >= 0;
 }
 
 static char *
@@ -681,18 +715,23 @@ const LsmTraitClass lsm_svg_spread_method_trait_class = {
 	.to_string = lsm_svg_spread_method_trait_to_string
 };
 
-static void
+static gboolean
 lsm_svg_angle_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgAngle *trait = (LsmSvgAngle *) abstract_trait;
+	char *end_ptr;
 
 	if (g_strcmp0 (string, "auto") == 0) {
 		trait->type = LSM_SVG_ANGLE_TYPE_AUTO;
 		trait->angle = 0.0;
-	} else {
-		trait->type = LSM_SVG_ANGLE_TYPE_FIXED;
-		trait->angle = g_strtod (string, NULL);
+
+		return TRUE;
 	}
+
+	trait->type = LSM_SVG_ANGLE_TYPE_FIXED;
+	trait->angle = g_ascii_strtod (string, &end_ptr);
+
+	return end_ptr != string;
 }
 
 static char *
diff --git a/src/lsmtraits.c b/src/lsmtraits.c
index 36b217c..c5b6bf6 100644
--- a/src/lsmtraits.c
+++ b/src/lsmtraits.c
@@ -1,16 +1,20 @@
 #include <lsmtraits.h>
 #include <lsmstr.h>
+#include <string.h>
 
 const LsmTraitClass lsm_null_trait_class = {
 	.size = 0
 };
 
-static void
+static gboolean
 lsm_double_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	double *trait = (double *) abstract_trait;
+	char *end_ptr;
 
-	*trait = g_strtod (string, NULL);
+	*trait = g_ascii_strtod (string, &end_ptr);
+
+	return end_ptr != string;
 }
 
 static char *
@@ -27,7 +31,7 @@ const LsmTraitClass lsm_double_trait_class = {
 	.to_string = lsm_double_trait_to_string
 };
 
-static void
+static gboolean
 lsm_box_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmBox *trait = (LsmBox *) abstract_trait;
@@ -47,13 +51,15 @@ lsm_box_trait_from_string (LsmTrait *abstract_trait, char *string)
 		trait->width = value[2];
 		trait->height = value[3];
 
-		return;
+		return TRUE;
 	}
 
 	trait->x =
 	trait->y =
 	trait->width =
 	trait->height = 0.0;
+
+	return FALSE;
 }
 
 char *
@@ -72,3 +78,18 @@ const LsmTraitClass lsm_box_trait_class = {
 	.to_string = lsm_box_trait_to_string
 };
 
+int
+lsm_enum_value_from_string (const char *string, const char **strings, unsigned int n_strings)
+{
+	int i;
+
+	if (string == NULL)
+		return -1;
+
+	for (i = 0; i < n_strings; i++)
+		if (strcmp (string, strings[i]) == 0)
+			return i;
+
+	return -1;
+}
+
diff --git a/src/lsmtraits.h b/src/lsmtraits.h
index 892a7a9..c452aef 100644
--- a/src/lsmtraits.h
+++ b/src/lsmtraits.h
@@ -33,7 +33,7 @@ typedef struct {
 	size_t		size;
 	void 		(*init)			(LsmTrait *abstract_trait, const LsmTrait *trait_default);
 	void 		(*finalize)		(LsmTrait *abstract_trait);
-	void		(*from_string)		(LsmTrait *abstract_trait, char *string);
+	gboolean	(*from_string)		(LsmTrait *abstract_trait, char *string);
 	char * 		(*to_string)		(LsmTrait *abstract_trait);
 } LsmTraitClass;
 
@@ -41,6 +41,8 @@ extern const LsmTraitClass lsm_null_trait_class;
 extern const LsmTraitClass lsm_double_trait_class;
 extern const LsmTraitClass lsm_box_trait_class;
 
+int 	lsm_enum_value_from_string 	(const char *string, const char **strings, unsigned int n_strings);
+
 G_END_DECLS
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]