static GtkCssValue * gtk_css_win32_size_value_parse_size (GtkCssValue *value, GtkCssParser *parser) { char *name; name = _gtk_css_parser_try_ident (parser, TRUE); if (name) { value->val.size.id = gtk_win32_get_sys_metric_id_for_name (name); if (value->val.size.id == -1) { _gtk_css_parser_error (parser, "'%s' is not a name for a win32 metric.", name); _gtk_css_value_unref (value); g_free (name); return NULL; } g_free (name); } else if (!_gtk_css_parser_try_int (parser, &value->val.size.id)) { _gtk_css_value_unref (value); _gtk_css_parser_error (parser, "Expected an integer ID"); return NULL; } return value; }
static gboolean enum_value_parse (GtkCssParser *parser, GFile *base, GValue *value) { GEnumClass *enum_class; GEnumValue *enum_value; char *str; str = _gtk_css_parser_try_ident (parser, TRUE); if (str == NULL) { _gtk_css_parser_error (parser, "Expected an identifier"); return FALSE; } enum_class = g_type_class_ref (G_VALUE_TYPE (value)); enum_value = g_enum_get_value_by_nick (enum_class, str); if (enum_value) g_value_set_enum (value, enum_value->value); else _gtk_css_parser_error (parser, "Unknown value '%s' for enum type '%s'", str, g_type_name (G_VALUE_TYPE (value))); g_type_class_unref (enum_class); g_free (str); return enum_value != NULL; }
static gboolean theming_engine_value_parse (GtkCssParser *parser, GFile *base, GValue *value) { GtkThemingEngine *engine; char *str; str = _gtk_css_parser_try_ident (parser, TRUE); if (str == NULL) { _gtk_css_parser_error (parser, "Expected a valid theme name"); return FALSE; } engine = gtk_theming_engine_load (str); if (engine == NULL) { _gtk_css_parser_error (parser, "Themeing engine '%s' not found", str); g_free (str); return FALSE; } g_value_set_object (value, engine); g_free (str); return TRUE; }
gboolean _gtk_css_parser_try_enum (GtkCssParser *parser, GType enum_type, int *value) { GEnumClass *enum_class; gboolean result; const char *start; char *str; g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE); g_return_val_if_fail (value != NULL, FALSE); result = FALSE; enum_class = g_type_class_ref (enum_type); start = parser->data; str = _gtk_css_parser_try_ident (parser, TRUE); if (str == NULL) return FALSE; if (enum_class->n_values) { GEnumValue *enum_value; for (enum_value = enum_class->values; enum_value->value_name; enum_value++) { if (enum_value->value_nick && g_ascii_strcasecmp (str, enum_value->value_nick) == 0) { *value = enum_value->value; result = TRUE; break; } } } g_free (str); g_type_class_unref (enum_class); if (!result) parser->data = start; return result; }
static gboolean flags_value_parse (GtkCssParser *parser, GFile *base, GValue *value) { GFlagsClass *flags_class; GFlagsValue *flag_value; guint flags = 0; char *str; flags_class = g_type_class_ref (G_VALUE_TYPE (value)); do { str = _gtk_css_parser_try_ident (parser, TRUE); if (str == NULL) { _gtk_css_parser_error (parser, "Expected an identifier"); g_type_class_unref (flags_class); return FALSE; } flag_value = g_flags_get_value_by_nick (flags_class, str); if (!flag_value) { _gtk_css_parser_error (parser, "Unknown flag value '%s' for type '%s'", str, g_type_name (G_VALUE_TYPE (value))); /* XXX Do we want to return FALSE here? We can get * forward-compatibility for new values this way */ g_free (str); g_type_class_unref (flags_class); return FALSE; } g_free (str); } while (_gtk_css_parser_try (parser, ",", FALSE)); g_type_class_unref (flags_class); g_value_set_enum (value, flags); return TRUE; }
static gboolean bindings_value_parse (GtkCssParser *parser, GFile *base, GValue *value) { GPtrArray *array; GtkBindingSet *binding_set; char *name; array = g_ptr_array_new (); do { name = _gtk_css_parser_try_ident (parser, TRUE); if (name == NULL) { _gtk_css_parser_error (parser, "Not a valid binding name"); g_ptr_array_free (array, TRUE); return FALSE; } binding_set = gtk_binding_set_find (name); if (!binding_set) { _gtk_css_parser_error (parser, "No binding set named '%s'", name); g_free (name); continue; } g_ptr_array_add (array, binding_set); g_free (name); } while (_gtk_css_parser_try (parser, ",", TRUE)); g_value_take_boxed (value, array); return TRUE; }
static gboolean enum_parse (GtkCssParser *parser, GType type, int *res) { char *str; if (_gtk_css_parser_try_enum (parser, type, res)) return TRUE; str = _gtk_css_parser_try_ident (parser, TRUE); if (str == NULL) { _gtk_css_parser_error (parser, "Expected an identifier"); return FALSE; } _gtk_css_parser_error (parser, "Unknown value '%s' for enum type '%s'", str, g_type_name (type)); g_free (str); return FALSE; }
GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags) { static const struct { const char *name; GtkCssUnit unit; GtkCssNumberParseFlags required_flags; } units[] = { { "px", GTK_CSS_PX, GTK_CSS_PARSE_LENGTH }, { "pt", GTK_CSS_PT, GTK_CSS_PARSE_LENGTH }, { "em", GTK_CSS_EM, GTK_CSS_PARSE_LENGTH }, { "ex", GTK_CSS_EX, GTK_CSS_PARSE_LENGTH }, { "pc", GTK_CSS_PC, GTK_CSS_PARSE_LENGTH }, { "in", GTK_CSS_IN, GTK_CSS_PARSE_LENGTH }, { "cm", GTK_CSS_CM, GTK_CSS_PARSE_LENGTH }, { "mm", GTK_CSS_MM, GTK_CSS_PARSE_LENGTH }, { "rad", GTK_CSS_RAD, GTK_CSS_PARSE_ANGLE }, { "deg", GTK_CSS_DEG, GTK_CSS_PARSE_ANGLE }, { "grad", GTK_CSS_GRAD, GTK_CSS_PARSE_ANGLE }, { "turn", GTK_CSS_TURN, GTK_CSS_PARSE_ANGLE }, { "s", GTK_CSS_S, GTK_CSS_PARSE_TIME }, { "ms", GTK_CSS_MS, GTK_CSS_PARSE_TIME } }; char *end, *unit_name; double value; GtkCssUnit unit; g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL); errno = 0; value = g_ascii_strtod (parser->data, &end); if (errno) { _gtk_css_parser_error (parser, "not a number: %s", g_strerror (errno)); return NULL; } if (parser->data == end) { _gtk_css_parser_error (parser, "not a number"); return NULL; } parser->data = end; if (flags & GTK_CSS_POSITIVE_ONLY && value < 0) { _gtk_css_parser_error (parser, "negative values are not allowed."); return NULL; } unit_name = _gtk_css_parser_try_ident (parser, FALSE); if (unit_name) { guint i; for (i = 0; i < G_N_ELEMENTS (units); i++) { if (flags & units[i].required_flags && g_ascii_strcasecmp (unit_name, units[i].name) == 0) break; } if (i >= G_N_ELEMENTS (units)) { _gtk_css_parser_error (parser, "`%s' is not a valid unit.", unit_name); g_free (unit_name); return NULL; } unit = units[i].unit; g_free (unit_name); } else { if ((flags & GTK_CSS_PARSE_PERCENT) && _gtk_css_parser_try (parser, "%", FALSE)) { unit = GTK_CSS_PERCENT; } else if (value == 0.0) { if (flags & GTK_CSS_PARSE_NUMBER) unit = GTK_CSS_NUMBER; else if (flags & GTK_CSS_PARSE_LENGTH) unit = GTK_CSS_PX; else if (flags & GTK_CSS_PARSE_ANGLE) unit = GTK_CSS_DEG; else if (flags & GTK_CSS_PARSE_TIME) unit = GTK_CSS_S; else unit = GTK_CSS_PERCENT; } else if (flags & GTK_CSS_NUMBER_AS_PIXELS) { _gtk_css_parser_error_full (parser, GTK_CSS_PROVIDER_ERROR_DEPRECATED, "Not using units is deprecated. Assuming 'px'."); unit = GTK_CSS_PX; } else if (flags & GTK_CSS_PARSE_NUMBER) { unit = GTK_CSS_NUMBER; } else { _gtk_css_parser_error (parser, "Unit is missing."); return NULL; } } _gtk_css_parser_skip_whitespace (parser); return _gtk_css_number_value_new (value, unit); }