static GTokenType gimp_config_deserialize_enum (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { GEnumClass *enum_class; GEnumValue *enum_value; enum_class = g_type_class_peek (G_VALUE_TYPE (value)); switch (g_scanner_peek_next_token (scanner)) { case G_TOKEN_IDENTIFIER: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value_by_nick (enum_class, scanner->value.v_identifier); if (!enum_value) enum_value = g_enum_get_value_by_name (enum_class, scanner->value.v_identifier); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%s' for token %s"), scanner->value.v_identifier, prop_spec->name); return G_TOKEN_NONE; } break; case G_TOKEN_INT: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value (enum_class, (gint) scanner->value.v_int64); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%ld' for token %s"), (glong) scanner->value.v_int64, prop_spec->name); return G_TOKEN_NONE; } break; default: return G_TOKEN_IDENTIFIER; } g_value_set_enum (value, enum_value->value); return G_TOKEN_RIGHT_PAREN; }
/** * gimp_scanner_parse_boolean: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @dest: Return location for the parsed boolean * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_boolean (GScanner *scanner, gboolean *dest) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER) return FALSE; g_scanner_get_next_token (scanner); if (! g_ascii_strcasecmp (scanner->value.v_identifier, "yes") || ! g_ascii_strcasecmp (scanner->value.v_identifier, "true")) { *dest = TRUE; } else if (! g_ascii_strcasecmp (scanner->value.v_identifier, "no") || ! g_ascii_strcasecmp (scanner->value.v_identifier, "false")) { *dest = FALSE; } else { g_scanner_error (scanner, /* please don't translate 'yes' and 'no' */ _("expected 'yes' or 'no' for boolean token, got '%s'"), scanner->value.v_identifier); return FALSE; } return TRUE; }
static inline gboolean scanner_string_utf8_valid (GScanner *scanner, const gchar *token_name) { if (g_utf8_validate (scanner->value.v_string, -1, NULL)) return TRUE; g_scanner_error (scanner, _("value for token %s is not a valid UTF-8 string"), token_name); return FALSE; }
static GTokenType gimp_config_deserialize_path (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { GError *error = NULL; if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) return G_TOKEN_STRING; g_scanner_get_next_token (scanner); if (!scanner_string_utf8_valid (scanner, prop_spec->name)) return G_TOKEN_NONE; if (scanner->value.v_string) { /* Check if the string can be expanded * and converted to the filesystem encoding. */ gchar *expand = gimp_config_path_expand (scanner->value.v_string, TRUE, &error); if (!expand) { g_scanner_error (scanner, _("while parsing token '%s': %s"), prop_spec->name, error->message); g_error_free (error); return G_TOKEN_NONE; } g_free (expand); g_value_set_static_string (value, scanner->value.v_string); } return G_TOKEN_RIGHT_PAREN; }
static GTokenType plug_in_icon_deserialize (GScanner *scanner, GimpPlugInProcedure *proc) { GEnumClass *enum_class; GEnumValue *enum_value; GimpIconType icon_type; gint icon_data_length; gchar *icon_name; guint8 *icon_data; if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN)) return G_TOKEN_LEFT_PAREN; if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) || GPOINTER_TO_INT (scanner->value.v_symbol) != ICON) return G_TOKEN_SYMBOL; enum_class = g_type_class_peek (GIMP_TYPE_ICON_TYPE); switch (g_scanner_peek_next_token (scanner)) { case G_TOKEN_IDENTIFIER: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class), scanner->value.v_identifier); if (!enum_value) enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class), scanner->value.v_identifier); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%s' for icon type"), scanner->value.v_identifier); return G_TOKEN_NONE; } break; case G_TOKEN_INT: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value (enum_class, (gint) scanner->value.v_int64); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%ld' for icon type"), (glong) scanner->value.v_int64); return G_TOKEN_NONE; } break; default: return G_TOKEN_IDENTIFIER; } icon_type = enum_value->value; if (! gimp_scanner_parse_int (scanner, &icon_data_length)) return G_TOKEN_INT; switch (icon_type) { case GIMP_ICON_TYPE_ICON_NAME: case GIMP_ICON_TYPE_IMAGE_FILE: icon_data_length = -1; if (! gimp_scanner_parse_string_no_validate (scanner, &icon_name)) return G_TOKEN_STRING; icon_data = (guint8 *) icon_name; break; case GIMP_ICON_TYPE_INLINE_PIXBUF: if (icon_data_length < 0) return G_TOKEN_STRING; if (! gimp_scanner_parse_data (scanner, icon_data_length, &icon_data)) return G_TOKEN_STRING; break; } gimp_plug_in_procedure_take_icon (proc, icon_type, icon_data, icon_data_length); if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) return G_TOKEN_RIGHT_PAREN; return G_TOKEN_LEFT_PAREN; }
static GTokenType gimp_config_deserialize_fundamental (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { GTokenType token; GType value_type; gboolean negate = FALSE; value_type = G_TYPE_FUNDAMENTAL (prop_spec->value_type); switch (value_type) { case G_TYPE_STRING: token = G_TOKEN_STRING; break; case G_TYPE_BOOLEAN: token = G_TOKEN_IDENTIFIER; break; case G_TYPE_INT: case G_TYPE_LONG: case G_TYPE_INT64: if (g_scanner_peek_next_token (scanner) == '-') { negate = TRUE; g_scanner_get_next_token (scanner); } /* fallthrough */ case G_TYPE_UINT: case G_TYPE_ULONG: case G_TYPE_UINT64: token = G_TOKEN_INT; break; case G_TYPE_FLOAT: case G_TYPE_DOUBLE: if (g_scanner_peek_next_token (scanner) == '-') { negate = TRUE; g_scanner_get_next_token (scanner); } token = G_TOKEN_FLOAT; break; default: token = G_TOKEN_NONE; g_assert_not_reached (); break; } if (g_scanner_peek_next_token (scanner) != token) { return token; } g_scanner_get_next_token (scanner); switch (value_type) { case G_TYPE_STRING: if (scanner_string_utf8_valid (scanner, prop_spec->name)) g_value_set_static_string (value, scanner->value.v_string); else return G_TOKEN_NONE; break; case G_TYPE_BOOLEAN: if (! g_ascii_strcasecmp (scanner->value.v_identifier, "yes") || ! g_ascii_strcasecmp (scanner->value.v_identifier, "true")) g_value_set_boolean (value, TRUE); else if (! g_ascii_strcasecmp (scanner->value.v_identifier, "no") || ! g_ascii_strcasecmp (scanner->value.v_identifier, "false")) g_value_set_boolean (value, FALSE); else { g_scanner_error (scanner, /* please don't translate 'yes' and 'no' */ _("expected 'yes' or 'no' for boolean token %s, got '%s'"), prop_spec->name, scanner->value.v_identifier); return G_TOKEN_NONE; } break; case G_TYPE_INT: g_value_set_int (value, (negate ? - scanner->value.v_int64 : scanner->value.v_int64)); break; case G_TYPE_UINT: g_value_set_uint (value, scanner->value.v_int64); break; case G_TYPE_LONG: g_value_set_long (value, (negate ? - scanner->value.v_int64 : scanner->value.v_int64)); break; case G_TYPE_ULONG: g_value_set_ulong (value, scanner->value.v_int64); break; case G_TYPE_INT64: g_value_set_int64 (value, (negate ? - scanner->value.v_int64 : scanner->value.v_int64)); break; case G_TYPE_UINT64: g_value_set_uint64 (value, scanner->value.v_int64); break; case G_TYPE_FLOAT: g_value_set_float (value, negate ? - scanner->value.v_float : scanner->value.v_float); break; case G_TYPE_DOUBLE: g_value_set_double (value, negate ? - scanner->value.v_float: scanner->value.v_float); break; default: g_assert_not_reached (); break; } return G_TOKEN_RIGHT_PAREN; }
static gboolean gimp_tool_preset_deserialize_property (GimpConfig *config, guint property_id, GValue *value, GParamSpec *pspec, GScanner *scanner, GTokenType *expected) { GimpToolPreset *tool_preset = GIMP_TOOL_PRESET (config); switch (property_id) { case PROP_TOOL_OPTIONS: { GObject *options; gchar *type_name; GType type; GimpContextPropMask serialize_props; if (! gimp_scanner_parse_string (scanner, &type_name)) { *expected = G_TOKEN_STRING; break; } type = g_type_from_name (type_name); if (! type) { g_scanner_error (scanner, "unable to determine type of '%s'", type_name); *expected = G_TOKEN_STRING; g_free (type_name); break; } if (! g_type_is_a (type, GIMP_TYPE_TOOL_OPTIONS)) { g_scanner_error (scanner, "'%s' is not a subclass of GimpToolOptions", type_name); *expected = G_TOKEN_STRING; g_free (type_name); break; } g_free (type_name); options = g_object_new (type, "gimp", tool_preset->gimp, NULL); /* Initialize all GimpContext object properties that can be * used by presets with some non-NULL object, so loading a * broken preset won't leave us with NULL objects that have * bad effects. See bug #742159. */ gimp_context_copy_properties (gimp_get_user_context (tool_preset->gimp), GIMP_CONTEXT (options), GIMP_CONTEXT_BRUSH_MASK | GIMP_CONTEXT_DYNAMICS_MASK | GIMP_CONTEXT_PATTERN_MASK | GIMP_CONTEXT_GRADIENT_MASK | GIMP_CONTEXT_PALETTE_MASK | GIMP_CONTEXT_FONT_MASK); if (! GIMP_CONFIG_GET_INTERFACE (options)->deserialize (GIMP_CONFIG (options), scanner, 1, NULL)) { g_object_unref (options); break; } /* we need both tool and tool-info on the options */ if (gimp_context_get_tool (GIMP_CONTEXT (options))) { g_object_set (options, "tool-info", gimp_context_get_tool (GIMP_CONTEXT (options)), NULL); } else if (GIMP_TOOL_OPTIONS (options)->tool_info) { g_object_set (options, "tool", GIMP_TOOL_OPTIONS (options)->tool_info, NULL); } else { /* if we have none, the options set_property() logic will * replace the NULL with its best guess */ g_object_set (options, "tool", NULL, "tool-info", NULL, NULL); } serialize_props = gimp_context_get_serialize_properties (GIMP_CONTEXT (options)); gimp_context_set_serialize_properties (GIMP_CONTEXT (options), serialize_props | GIMP_CONTEXT_TOOL_MASK); g_value_take_object (value, options); } break; default: return FALSE; } return TRUE; }
static guint gslwave_parse_wave_dsc (GScanner *scanner, WaveDsc *dsc, const gchar *wave_name) { parse_or_return (scanner, '{'); do switch (g_scanner_get_next_token (scanner)) { guint i, token; case '}': return G_TOKEN_NONE; default: return '}'; case GSL_WAVE_TOKEN_NAME: if (dsc->wdsc.name) return '}'; parse_or_return (scanner, '='); parse_or_return (scanner, G_TOKEN_STRING); if (wave_name) { if (strcmp (wave_name, scanner->value.v_string) == 0) dsc->wdsc.name = g_strdup (scanner->value.v_string); else return gslwave_skip_rest_statement (scanner, 1); } else dsc->wdsc.name = g_strdup (scanner->value.v_string); break; case GSL_WAVE_TOKEN_CHUNK: if (g_scanner_peek_next_token (scanner) != '{') parse_or_return (scanner, '{'); i = dsc->wdsc.n_chunks++; dsc->wdsc.chunks = g_realloc (dsc->wdsc.chunks, sizeof (dsc->wdsc.chunks[0]) * dsc->wdsc.n_chunks); memset (dsc->wdsc.chunks + i, 0, sizeof (dsc->wdsc.chunks[0]) * 1); dsc->wdsc.chunks[i].mix_freq = dsc->dfl_mix_freq; dsc->wdsc.chunks[i].osc_freq = dsc->dfl_mix_freq; /* we check this later */ dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_JUMP; dsc->wdsc.chunks[i].loop_start = GSL_MAXLONG; dsc->wdsc.chunks[i].loop_end = -1; dsc->wdsc.chunks[i].loop_count = 1000000; /* FIXME */ dsc->wdsc.chunks[i].loader_offset = 0; /* offset in bytes */ dsc->wdsc.chunks[i].loader_length = 0; /* length in n_values */ dsc->wdsc.chunks[i].loader_data1 = NULL; /* file_name */ dsc->wdsc.chunks[i].loader_data2 = NULL; /* wave_name */ token = gslwave_parse_chunk_dsc (scanner, dsc->wdsc.chunks + i); if (token != G_TOKEN_NONE) return token; if (dsc->wdsc.chunks[i].loop_end < dsc->wdsc.chunks[i].loop_start) { dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_NONE; dsc->wdsc.chunks[i].loop_start = 0; dsc->wdsc.chunks[i].loop_end = 0; dsc->wdsc.chunks[i].loop_count = 0; } if (dsc->wdsc.chunks[i].osc_freq >= dsc->wdsc.chunks[i].mix_freq / 2.) g_scanner_error (scanner, "wave chunk \"%s\" mixing frequency is invalid: mix_freq=%f osc_freq=%f", dsc->wdsc.chunks[i].loader_data1 ? (gchar*) dsc->wdsc.chunks[i].loader_data1 : "", dsc->wdsc.chunks[i].mix_freq, dsc->wdsc.chunks[i].osc_freq); break; case GSL_WAVE_TOKEN_BYTE_ORDER: parse_or_return (scanner, '='); token = g_scanner_get_next_token (scanner); switch (token) { case GSL_WAVE_TOKEN_LITTLE_ENDIAN: case GSL_WAVE_TOKEN_LITTLE: dsc->byte_order = G_LITTLE_ENDIAN; break; case GSL_WAVE_TOKEN_BIG_ENDIAN: case GSL_WAVE_TOKEN_BIG: dsc->byte_order = G_BIG_ENDIAN; break; default: return GSL_WAVE_TOKEN_LITTLE_ENDIAN; } break; case GSL_WAVE_TOKEN_FORMAT: parse_or_return (scanner, '='); token = g_scanner_get_next_token (scanner); switch (token) { case GSL_WAVE_TOKEN_SIGNED_8: dsc->format = GSL_WAVE_FORMAT_SIGNED_8; break; case GSL_WAVE_TOKEN_SIGNED_12: dsc->format = GSL_WAVE_FORMAT_SIGNED_12; break; case GSL_WAVE_TOKEN_SIGNED_16: dsc->format = GSL_WAVE_FORMAT_SIGNED_16; break; case GSL_WAVE_TOKEN_UNSIGNED_8: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_8; break; case GSL_WAVE_TOKEN_UNSIGNED_12: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_12; break; case GSL_WAVE_TOKEN_UNSIGNED_16: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_16; break; case GSL_WAVE_TOKEN_FLOAT: dsc->format = GSL_WAVE_FORMAT_FLOAT; break; default: return GSL_WAVE_TOKEN_SIGNED_16; } break; case GSL_WAVE_TOKEN_N_CHANNELS: parse_or_return (scanner, '='); parse_or_return (scanner, G_TOKEN_INT); dsc->wdsc.n_channels = scanner->value.v_int; if (dsc->wdsc.n_channels < 1) return G_TOKEN_INT; break; case GSL_WAVE_TOKEN_MIX_FREQ: parse_or_return (scanner, '='); switch (g_scanner_get_next_token (scanner)) { case G_TOKEN_FLOAT: dsc->dfl_mix_freq = scanner->value.v_float; break; case G_TOKEN_INT: dsc->dfl_mix_freq = scanner->value.v_int; break; default: return G_TOKEN_FLOAT; } break; } while (TRUE); }