GFile * _gtk_css_parser_read_url (GtkCssParser *parser) { gchar *path; char *scheme; GFile *file; if (_gtk_css_parser_try (parser, "url", FALSE)) { if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_skip_whitespace (parser); if (_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error_full (parser, GTK_CSS_PROVIDER_ERROR_DEPRECATED, "Whitespace between 'url' and '(' is deprecated"); } else { _gtk_css_parser_error (parser, "Expected '(' after 'url'"); return NULL; } } path = _gtk_css_parser_read_string (parser); if (path == NULL) return NULL; if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "No closing ')' found for 'url'"); g_free (path); return NULL; } scheme = g_uri_parse_scheme (path); if (scheme != NULL) { file = g_file_new_for_uri (path); g_free (path); g_free (scheme); return file; } } else { path = _gtk_css_parser_try_name (parser, TRUE); if (path == NULL) { _gtk_css_parser_error (parser, "Not a valid url"); return NULL; } } file = _gtk_css_parser_get_file_for_path (parser, path); g_free (path); return file; }
GFile * _gtk_css_parse_url (GtkCssParser *parser, GFile *base) { gchar *path; GFile *file; if (_gtk_css_parser_try (parser, "url", FALSE)) { if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_skip_whitespace (parser); if (_gtk_css_parser_try (parser, "(", TRUE)) { GError *error; error = g_error_new_literal (GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED, "Whitespace between 'url' and '(' is not allowed"); _gtk_css_parser_take_error (parser, error); } else { _gtk_css_parser_error (parser, "Expected '(' after 'url'"); return NULL; } } path = _gtk_css_parser_read_string (parser); if (path == NULL) return NULL; if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "No closing ')' found for 'url'"); g_free (path); return NULL; } } else { path = _gtk_css_parser_try_name (parser, TRUE); if (path == NULL) { _gtk_css_parser_error (parser, "Not a valid url"); return NULL; } } file = g_file_resolve_relative_path (base, path); g_free (path); return file; }
static gboolean string_value_parse (GtkCssParser *parser, GValue *value) { char *str = _gtk_css_parser_read_string (parser); if (str == NULL) return FALSE; g_value_take_string (value, str); return TRUE; }
char * _gtk_css_parser_read_uri (GtkCssParser *parser) { char *result; g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL); if (!_gtk_css_parser_try (parser, "url(", TRUE)) { _gtk_css_parser_error (parser, "expected 'url('"); return NULL; } _gtk_css_parser_skip_whitespace (parser); if (_gtk_css_parser_is_string (parser)) { result = _gtk_css_parser_read_string (parser); } else { GString *str = g_string_new (NULL); while (_gtk_css_parser_read_char (parser, str, URLCHAR)) ; result = g_string_free (str, FALSE); if (result == NULL) _gtk_css_parser_error (parser, "not a url"); } if (result == NULL) return NULL; _gtk_css_parser_skip_whitespace (parser); if (*parser->data != ')') { _gtk_css_parser_error (parser, "missing ')' for url"); g_free (result); return NULL; } parser->data++; _gtk_css_parser_skip_whitespace (parser); return result; }
GtkCssValue * gtk_css_icon_theme_value_parse (GtkCssParser *parser) { GtkIconTheme *icontheme; GtkCssValue *result; char *s; s = _gtk_css_parser_read_string (parser); if (s == NULL) return NULL; icontheme = gtk_icon_theme_new (); gtk_icon_theme_set_custom_theme (icontheme, s); result = gtk_css_icon_theme_value_new (icontheme); g_object_unref (icontheme); g_free (s); return result; }
static gboolean gtk_css_image_icon_theme_parse (GtkCssImage *image, GtkCssParser *parser) { GtkCssImageIconTheme *icon_theme = GTK_CSS_IMAGE_ICON_THEME (image); if (!_gtk_css_parser_try (parser, "-gtk-icontheme(", TRUE)) { _gtk_css_parser_error (parser, "Expected '-gtk-icontheme('"); return FALSE; } icon_theme->name = _gtk_css_parser_read_string (parser); if (icon_theme->name == NULL) return FALSE; if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Missing closing bracket at end of '-gtk-icontheme'"); return FALSE; } return TRUE; }
static void gtk_css_parser_resync_internal (GtkCssParser *parser, gboolean sync_at_semicolon, gboolean read_sync_token, char terminator) { gsize len; do { len = strcspn (parser->data, "\\\"'/()[]{};" NEWLINE_CHARS); parser->data += len; if (gtk_css_parser_new_line (parser)) continue; if (_gtk_css_parser_is_string (parser)) { /* Hrm, this emits errors, and i suspect it shouldn't... */ char *free_me = _gtk_css_parser_read_string (parser); g_free (free_me); continue; } if (gtk_css_parser_skip_comment (parser)) continue; switch (*parser->data) { case '\\': { GString *ignore = g_string_new (NULL); _gtk_css_parser_unescape (parser, ignore); g_string_free (ignore, TRUE); } break; case ';': if (sync_at_semicolon && !read_sync_token) return; parser->data++; if (sync_at_semicolon) { _gtk_css_parser_skip_whitespace (parser); return; } break; case '(': parser->data++; _gtk_css_parser_resync (parser, FALSE, ')'); if (*parser->data) parser->data++; break; case '[': parser->data++; _gtk_css_parser_resync (parser, FALSE, ']'); if (*parser->data) parser->data++; break; case '{': parser->data++; _gtk_css_parser_resync (parser, FALSE, '}'); if (*parser->data) parser->data++; if (sync_at_semicolon || !terminator) { _gtk_css_parser_skip_whitespace (parser); return; } break; case '}': case ')': case ']': if (terminator == *parser->data) { _gtk_css_parser_skip_whitespace (parser); return; } parser->data++; continue; case '\0': break; case '/': default: parser->data++; break; } } while (*parser->data); }