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; }
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); }