/* * This function is just like gimp_scanner_parse_int(), but it is allows * to detect the special value '-0'. This is used as in X geometry strings. */ static gboolean gimp_session_info_parse_offset (GScanner *scanner, gint *dest, gboolean *negative) { if (g_scanner_peek_next_token (scanner) == '-') { *negative = TRUE; g_scanner_get_next_token (scanner); } else { *negative = FALSE; } if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT) return FALSE; g_scanner_get_next_token (scanner); if (*negative) *dest = -scanner->value.v_int64; else *dest = scanner->value.v_int64; return TRUE; }
/* Function to parse the body of a class. Current token is '{'. CBODY:= '}' //This is an empty class body | CLASSMETHODS '}' */ static void parseCBody(void) { PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data; while(g_scanner_peek_next_token(gScanner)!= G_TOKEN_EOF && g_scanner_peek_next_token(gScanner)!='}') { PSYMBOL pCurSymbol; GTokenValue value; /* Method implementations must start with "public" which is registered as a symbol. Here we check if the token is a symbol. */ exitIfNotMatchNext(G_TOKEN_SYMBOL, "Method implementation must start with 'public'."); value=gScanner->value; pCurSymbol=value.v_symbol; /* Check if token is "public". */ if(!pCurSymbol || pCurSymbol->uiSymbolToken!=NOMC_SYMBOL_PUBLIC) { g_scanner_unexp_token(gScanner, G_TOKEN_SYMBOL, NULL, NULL, NULL, "'impl'.", TRUE); /* is_error */ cleanupAndExit(1); } /* Get name, parameters and stuff. Print the body. */ parseClassMethod(); }; exitIfNotMatchNext('}', "No closing of 'class' section."); }
//______________________________________________________________________ guint RCStyle::parse( GtkRcStyle* rc_style, GtkSettings* settings, GScanner* scanner ) { static GQuark scope_id = 0; guint old_scope; guint token; if( !scope_id ) { scope_id = g_quark_from_string( "oxygen_engine" ); } old_scope = g_scanner_set_scope( scanner, scope_id ); token = g_scanner_peek_next_token( scanner ); while( token != G_TOKEN_RIGHT_CURLY ) { token = g_scanner_peek_next_token( scanner ); if( token != G_TOKEN_NONE ) return token; } g_scanner_get_next_token( scanner ); g_scanner_set_scope( scanner, old_scope ); return G_TOKEN_NONE; }
static void do_parseCodeBlock(void) { GTokenValue value; PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data; do { if('{'==g_scanner_peek_next_token(gScanner)) parseCodeBlock(); else { getNextToken(); } } while(g_scanner_peek_next_token(gScanner)!= EOF && g_scanner_peek_next_token(gScanner)!='}'); }
static GTokenType gimp_config_deserialize_any (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { GValue src = { 0, }; if (!g_value_type_transformable (G_TYPE_STRING, prop_spec->value_type)) { g_warning ("%s: %s can not be transformed from a string", G_STRFUNC, g_type_name (prop_spec->value_type)); return G_TOKEN_NONE; } if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER) return G_TOKEN_IDENTIFIER; g_scanner_get_next_token (scanner); g_value_init (&src, G_TYPE_STRING); g_value_set_static_string (&src, scanner->value.v_identifier); g_value_transform (&src, value); g_value_unset (&src); return G_TOKEN_RIGHT_PAREN; }
static GTokenType gimp_config_skip_unknown_property (GScanner *scanner) { gint open_paren = 0; while (TRUE) { GTokenType token = g_scanner_peek_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: open_paren++; g_scanner_get_next_token (scanner); break; case G_TOKEN_RIGHT_PAREN: if (open_paren == 0) return token; open_paren--; g_scanner_get_next_token (scanner); break; case G_TOKEN_EOF: return token; default: g_scanner_get_next_token (scanner); break; } } }
/** * gimp_scanner_parse_string: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @dest: Return location for the parsed string * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_string (GScanner *scanner, gchar **dest) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) return FALSE; g_scanner_get_next_token (scanner); if (*scanner->value.v_string) { if (! g_utf8_validate (scanner->value.v_string, -1, NULL)) { g_scanner_warn (scanner, _("invalid UTF-8 string")); return FALSE; } *dest = g_strdup (scanner->value.v_string); } else { *dest = NULL; } return TRUE; }
/** * 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; }
/* This token is not necessarily the current token! */ static guint getKindOfNextToken() { /* Load info into gScanner */ g_scanner_peek_next_token(gScanner); if(gScanner->next_token==G_TOKEN_SYMBOL) { GTokenValue value; PSYMBOL pCurSymbol; value=gScanner->next_value; pCurSymbol=value.v_symbol; return pCurSymbol->uiKind; } switch(gScanner->next_token) { case G_TOKEN_IDENTIFIER: { /* Compare strings here. Yes, that's slow... */ break; } default: break; } return KIND_UNKNOWN; }
/** * gimp_config_deserialize_return: * @scanner: a #GScanner * @expected_token: the expected token * @nest_level: the nest level * * Returns: * * Since: 2.4 **/ gboolean gimp_config_deserialize_return (GScanner *scanner, GTokenType expected_token, gint nest_level) { GTokenType next_token; g_return_val_if_fail (scanner != NULL, FALSE); next_token = g_scanner_peek_next_token (scanner); if (expected_token != G_TOKEN_LEFT_PAREN) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL, _("fatal parse error"), TRUE); return FALSE; } else { if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN) { return TRUE; } else if (next_token != G_TOKEN_EOF) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL, _("fatal parse error"), TRUE); return FALSE; } } return TRUE; }
/* return a glist with the cats read from file */ static GList *read_star_list(GScanner *scan) { GTokenType tok; GList *sl = NULL; struct cat_star *cats; tok = g_scanner_peek_next_token(scan); if (tok != '(') return NULL; tok = g_scanner_get_next_token(scan); do { tok = g_scanner_get_next_token(scan); if (tok == '(') { cats = cat_star_new(); if (!parse_star(scan, cats)) { sl = g_list_prepend(sl, cats); } else { cat_star_release(cats); } continue; } else if (tok == ')') { sl = g_list_reverse(sl); return sl; } } while (tok != G_TOKEN_EOF); sl = g_list_reverse(sl); return sl; }
static GTokenType gimp_config_deserialize_memsize (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { gchar *orig_cset_first = scanner->config->cset_identifier_first; gchar *orig_cset_nth = scanner->config->cset_identifier_nth; guint64 memsize; scanner->config->cset_identifier_first = G_CSET_DIGITS; scanner->config->cset_identifier_nth = G_CSET_DIGITS "gGmMkKbB"; if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER) return G_TOKEN_IDENTIFIER; g_scanner_get_next_token (scanner); scanner->config->cset_identifier_first = orig_cset_first; scanner->config->cset_identifier_nth = orig_cset_nth; if (! gimp_memsize_deserialize (scanner->value.v_identifier, &memsize)) return G_TOKEN_NONE; g_value_set_uint64 (value, memsize); return G_TOKEN_RIGHT_PAREN; }
static gboolean _xfdashboard_css_selector_parse(XfdashboardCssSelector *self, GScanner *ioScanner) { GScannerConfig *oldScannerConfig; GScannerConfig *scannerConfig; gboolean success; GTokenType token; g_return_val_if_fail(XFDASHBOARD_IS_CSS_SELECTOR(self), FALSE); g_return_val_if_fail(ioScanner, FALSE); success=TRUE; /* Set up scanner configuration for parsing css selectors: * - Identifiers are allowed to contain '-' (minus sign) as non-first characters * - Disallow scanning float values as we need '.' for identifiers * - Set up single comment line not to include '#' as this character is need for identifiers * - Disable parsing HEX values * - Identifiers cannot be single quoted * - Identifiers cannot be double quoted */ scannerConfig=(GScannerConfig*)g_memdup(ioScanner->config, sizeof(GScannerConfig)); scannerConfig->cset_skip_characters=" \n\r\t"; scannerConfig->cset_identifier_nth=G_CSET_a_2_z "-_0123456789" G_CSET_A_2_Z G_CSET_LATINS G_CSET_LATINC; scannerConfig->scan_float=FALSE; scannerConfig->cpair_comment_single="\1\n"; scannerConfig->scan_hex=FALSE; scannerConfig->scan_string_sq=FALSE; scannerConfig->scan_string_dq=FALSE; /* Set new scanner configuration but remember old one to restore it later */ oldScannerConfig=ioScanner->config; ioScanner->config=scannerConfig; /* Parse input stream */ token=g_scanner_peek_next_token(ioScanner); if(token!=G_TOKEN_EOF) { token=_xfdashboard_css_selector_parse_css_rule(self, ioScanner); if(token==G_TOKEN_ERROR) { g_warning(_("Failed to parse css selector.")); success=FALSE; } } else { g_warning(_("Failed to parse css selector because stream is empty.")); success=FALSE; } /* Restore old scanner configuration */ ioScanner->config=oldScannerConfig; /* Release allocated resources */ g_free(scannerConfig); /* Return success result */ return(success); }
/* Well, the name says all... Note that this function advances to the next token if the tokens match. */ gboolean matchNext(GTokenType token) { if(token==g_scanner_peek_next_token(gScanner)) { getNextToken(); return TRUE; } return FALSE; }
/** * gimp_scanner_parse_token: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @token: Return location for the parsed token * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_token (GScanner *scanner, GTokenType token) { if (g_scanner_peek_next_token (scanner) != token) return FALSE; g_scanner_get_next_token (scanner); return TRUE; }
/* * static void j_config_parse_white_start(GScanner *scanner, * JConfigCtxt *cfc) * * If a line starts with whitespace, it is either a blank line, or an * attribute line. We skip whitespace lines. * If it looks like an attribute line, we call the proper function. */ static void j_config_parse_white_start(GScanner *scanner, JConfigCtxt *cfc) { gboolean done; GTokenType token; GTokenValue *value; value = &scanner->value; token = g_scanner_get_next_token(scanner); g_assert(token == G_TOKEN_CHAR); g_assert(strchr(CF_SCAN_WHITESPACE, value->v_char) != NULL); done = FALSE; while (done == FALSE) { token = g_scanner_peek_next_token(scanner); switch (token) { case G_TOKEN_EOF: done = TRUE; break; case G_TOKEN_IDENTIFIER: j_config_parse_stanza_attr(scanner, cfc); done = TRUE; break; case G_TOKEN_CHAR: token = g_scanner_get_next_token(scanner); if (value->v_char == '\n') { #ifdef DEBUG g_print("Skipped whitespace line\n"); #endif /* DEBUG */ if (cfc->cfs != NULL) cfc->cfs = NULL; done = TRUE; } else if (strchr(CF_SCAN_WHITESPACE, value->v_char) == NULL) { if (cfc->verbose) { g_warning("Invalid character in attribute name: %c\n", value->v_char); } cfc->error = TRUE; j_config_parse_to_eol(scanner); done = TRUE; } break; default: break; } } } /* j_config_parse_white_start() */
/** * gtk_accel_map_load_scanner: * @scanner: a #GScanner which has already been provided with an input file * * #GScanner variant of gtk_accel_map_load(). */ void gtk_accel_map_load_scanner (GScanner *scanner) { gboolean skip_comment_single; gboolean symbol_2_token; gchar *cpair_comment_single; gpointer saved_symbol; g_return_if_fail (scanner != NULL); /* configure scanner */ skip_comment_single = scanner->config->skip_comment_single; scanner->config->skip_comment_single = TRUE; cpair_comment_single = scanner->config->cpair_comment_single; scanner->config->cpair_comment_single = ";\n"; symbol_2_token = scanner->config->symbol_2_token; scanner->config->symbol_2_token = FALSE; saved_symbol = g_scanner_lookup_symbol (scanner, "gtk_accel_path"); g_scanner_scope_add_symbol (scanner, 0, "gtk_accel_path", accel_map_parse_accel_path); /* outer parsing loop */ g_scanner_peek_next_token (scanner); while (scanner->next_token == '(') { g_scanner_get_next_token (scanner); accel_map_parse_statement (scanner); g_scanner_peek_next_token (scanner); } /* restore config */ scanner->config->skip_comment_single = skip_comment_single; scanner->config->cpair_comment_single = cpair_comment_single; scanner->config->symbol_2_token = symbol_2_token; g_scanner_scope_remove_symbol (scanner, 0, "gtk_accel_path"); if (saved_symbol) g_scanner_scope_add_symbol (scanner, 0, "gtk_accel_path", saved_symbol); }
XfdashboardCssSelector* xfdashboard_css_selector_new_from_scanner_with_priority(GScanner *ioScanner, gint inPriority, XfdashboardCssSelectorParseFinishCallback inFinishCallback, gpointer inUserData) { GObject *selector; g_return_val_if_fail(ioScanner, NULL); g_return_val_if_fail(!g_scanner_eof(ioScanner), NULL); /* Create selector instance */ selector=g_object_new(XFDASHBOARD_TYPE_CSS_SELECTOR, "priority", inPriority, NULL); if(!selector) { g_warning(_("Could not create seleector.")); return(NULL); } /* Parse selector from scanner provided */ if(!_xfdashboard_css_selector_parse(XFDASHBOARD_CSS_SELECTOR(selector), ioScanner)) { g_object_unref(selector); return(NULL); } /* If a callback is given to call after parsing finished so call it now * to determine if scanner is still in good state. If it is in bad state * then return NULL. */ if(inFinishCallback) { gboolean goodState; goodState=(inFinishCallback)(XFDASHBOARD_CSS_SELECTOR(selector), ioScanner, g_scanner_peek_next_token(ioScanner), inUserData); if(!goodState) { g_scanner_unexp_token(ioScanner, G_TOKEN_ERROR, NULL, NULL, NULL, _("Unexpected state of CSS scanner."), TRUE); g_object_unref(selector); return(NULL); } } /* Return created selector which may be NULL in case of error */ return(XFDASHBOARD_CSS_SELECTOR(selector)); }
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; }
static guint mist_rc_style_parse (GtkRcStyle *rc_style, GtkSettings *settings, GScanner *scanner) { static GQuark scope_id = 0; guint old_scope; guint token; /* Set up a new scope in this scanner. */ if (!scope_id) scope_id = g_quark_from_string("theme_engine"); /* If we bail out due to errors, we *don't* reset the scope, so the * error messaging code can make sense of our tokens. */ old_scope = g_scanner_set_scope(scanner, scope_id); /* We're ready to go, now parse the top level */ token = g_scanner_peek_next_token(scanner); while (token != G_TOKEN_RIGHT_CURLY) { switch (token) { default : token = G_TOKEN_RIGHT_CURLY; } token = g_scanner_peek_next_token (scanner); if (token != G_TOKEN_NONE) { return token; } } g_scanner_get_next_token(scanner); g_scanner_set_scope(scanner, old_scope); return G_TOKEN_NONE; }
/** * gimp_scanner_parse_float: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @dest: Return location for the parsed float * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_float (GScanner *scanner, gdouble *dest) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_FLOAT) return FALSE; g_scanner_get_next_token (scanner); *dest = scanner->value.v_float; return TRUE; }
static gboolean gimp_color_profile_store_load (GimpColorProfileStore *store, const gchar *filename, GError **error) { GScanner *scanner; GTokenType token; gint i = 0; scanner = gimp_scanner_new_file (filename, error); if (! scanner) return FALSE; g_scanner_scope_add_symbol (scanner, 0, "color-profile", NULL); token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: token = gimp_color_profile_store_load_profile (store, scanner, i++); break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } if (token != G_TOKEN_LEFT_PAREN) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } gimp_scanner_destroy (scanner); return TRUE; }
guint theme_parse_rc_style (GScanner *scanner, GtkRcStyle *rc_style) { ThemeRcData *theme_data; guint scope_id; guint old_scope; guint token; if (!scope_id) scope_id = g_quark_from_string("theme_engine"); old_scope = g_scanner_set_scope (scanner, scope_id); #if 0 if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name)) { g_scanner_freeze_symbol_table(scanner); for (i = 0; i < n_theme_symbols; i++) { g_scanner_scope_add_symbol(scanner, scope_id, theme_symbols[i].name, GINT_TO_POINTER(theme_symbols[i].token)); } g_scanner_thaw_symbol_table(scanner); } #endif token = g_scanner_peek_next_token (scanner); while (token != G_TOKEN_RIGHT_CURLY) { token = g_scanner_peek_next_token (scanner); } g_scanner_get_next_token (scanner); g_scanner_set_scope (scanner, old_scope); theme_data = g_new0 (ThemeRcData, 1); rc_style->engine_data = theme_data; return G_TOKEN_NONE; }
/** * gimp_scanner_parse_identifier: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @identifier: Return location for the parsed identifier * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_identifier (GScanner *scanner, const gchar *identifier) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER) return FALSE; g_scanner_get_next_token (scanner); if (strcmp (scanner->value.v_identifier, identifier)) return FALSE; return TRUE; }
/** * gimp_scanner_parse_int64: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @dest: Return location for the parsed integer * * Return value: %TRUE on success * * Since: 2.8 **/ gboolean gimp_scanner_parse_int64 (GScanner *scanner, gint64 *dest) { gboolean negate = FALSE; if (g_scanner_peek_next_token (scanner) == '-') { negate = TRUE; g_scanner_get_next_token (scanner); } if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT) return FALSE; g_scanner_get_next_token (scanner); if (negate) *dest = -scanner->value.v_int64; else *dest = scanner->value.v_int64; return TRUE; }
/** * gimp_scanner_parse_string_no_validate: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @dest: Return location for the parsed string * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, gchar **dest) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) return FALSE; g_scanner_get_next_token (scanner); if (*scanner->value.v_string) *dest = g_strdup (scanner->value.v_string); else *dest = NULL; return TRUE; }
static guint dawati_get_token (GScanner *scanner, guint expected) { guint token; token = g_scanner_peek_next_token (scanner); if (token != expected) { return expected; } else { g_scanner_get_next_token (scanner); return G_TOKEN_NONE; } }
/** * gimp_scanner_parse_data: * @scanner: A #GScanner created by gimp_scanner_new_file() or * gimp_scanner_new_string() * @length: Length of tha data to parse * @dest: Return location for the parsed data * * Return value: %TRUE on success * * Since: 2.4 **/ gboolean gimp_scanner_parse_data (GScanner *scanner, gint length, guint8 **dest) { if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) return FALSE; g_scanner_get_next_token (scanner); if (scanner->value.v_string) *dest = g_memdup (scanner->value.v_string, length); else *dest = NULL; return TRUE; }
static guint accel_map_parse_accel_path (GScanner *scanner) { guint accel_key = 0; GdkModifierType accel_mods = 0; gchar *path, *accel; /* parse accel path */ g_scanner_get_next_token (scanner); if (scanner->token != G_TOKEN_STRING) return G_TOKEN_STRING; /* test if the next token is an accelerator */ g_scanner_peek_next_token (scanner); if (scanner->next_token != G_TOKEN_STRING) { /* if not so, eat that token and error out */ g_scanner_get_next_token (scanner); return G_TOKEN_STRING; } /* get the full accelerator specification */ path = g_strdup (scanner->value.v_string); g_scanner_get_next_token (scanner); accel = g_strdup (scanner->value.v_string); /* ensure the entry is present */ gtk_accel_map_add_entry (path, 0, 0); /* and propagate it */ gtk_accelerator_parse (accel, &accel_key, &accel_mods); gtk_accel_map_change_entry (path, accel_key, accel_mods, TRUE); g_free (accel); g_free (path); /* check correct statement end */ g_scanner_get_next_token (scanner); if (scanner->token != ')') return ')'; else return G_TOKEN_NONE; }
static GTokenType gimp_config_deserialize_file_value (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { GTokenType token; token = g_scanner_peek_next_token (scanner); if (token != G_TOKEN_IDENTIFIER && token != G_TOKEN_STRING) { return G_TOKEN_STRING; } g_scanner_get_next_token (scanner); if (token == G_TOKEN_IDENTIFIER) { /* this is supposed to parse a literal "NULL" only, but so what... */ g_value_set_object (value, NULL); } else { gchar *path = gimp_config_path_expand (scanner->value.v_string, TRUE, NULL); if (path) { GFile *file = g_file_new_for_path (path); g_value_take_object (value, file); g_free (path); } else { g_value_set_object (value, NULL); } } return G_TOKEN_RIGHT_PAREN; }