]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcssparser.c
Use gdk_threads_add_timeout to popup the selection window
[~andy/gtk] / gtk / gtkcssparser.c
index 62d911324c5f449874a2d3eb0ca485671df71cdb..ab38fc9d93560a279dc025aeb925ff48b7c3c3f0 100644 (file)
 
 struct _GtkCssParser
 {
-  const char *data;
-  GtkCssParserErrorFunc error_func;
-  gpointer              user_data;
+  const char            *data;
+  GFile                 *file;
+  GtkCssParserErrorFunc  error_func;
+  gpointer               user_data;
 
-  const char *line_start;
-  guint line;
+  const char            *line_start;
+  guint                  line;
 };
 
 GtkCssParser *
 _gtk_css_parser_new (const char            *data,
+                     GFile                 *file,
                      GtkCssParserErrorFunc  error_func,
                      gpointer               user_data)
 {
   GtkCssParser *parser;
 
   g_return_val_if_fail (data != NULL, NULL);
+  g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
 
   parser = g_slice_new0 (GtkCssParser);
 
   parser->data = data;
+  if (file)
+    parser->file = g_object_ref (file);
   parser->error_func = error_func;
   parser->user_data = user_data;
 
@@ -72,6 +77,9 @@ _gtk_css_parser_free (GtkCssParser *parser)
 {
   g_return_if_fail (GTK_IS_CSS_PARSER (parser));
 
+  if (parser->file)
+    g_object_unref (parser->file);
+
   g_slice_free (GtkCssParser, parser);
 }
 
@@ -117,6 +125,49 @@ _gtk_css_parser_get_position (GtkCssParser *parser)
   return parser->data - parser->line_start;
 }
 
+static GFile *
+gtk_css_parser_get_base_file (GtkCssParser *parser)
+{
+  GFile *base;
+
+  if (parser->file)
+    {
+      base = g_file_get_parent (parser->file);
+    }
+  else
+    {
+      char *dir = g_get_current_dir ();
+      base = g_file_new_for_path (dir);
+      g_free (dir);
+    }
+
+  return base;
+}
+
+GFile *
+_gtk_css_parser_get_file_for_path (GtkCssParser *parser,
+                                   const char   *path)
+{
+  GFile *base, *file;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+  g_return_val_if_fail (path != NULL, NULL);
+
+  base = gtk_css_parser_get_base_file (parser);
+  file = g_file_resolve_relative_path (base, path);
+  g_object_unref (base);
+
+  return file;
+}
+
+GFile *
+_gtk_css_parser_get_file (GtkCssParser *parser)
+{
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  return parser->file;
+}
+
 void
 _gtk_css_parser_take_error (GtkCssParser *parser,
                             GError       *error)
@@ -206,7 +257,7 @@ gtk_css_parser_skip_comment (GtkCssParser *parser)
 
       parser->data++;
 
-      if (parser->data[-2] == '*')
+      if (len > 0 && parser->data[-2] == '*')
         return TRUE;
       if (parser->data[0] == '*')
         _gtk_css_parser_error (parser, "'/*' in comment block");
@@ -618,15 +669,16 @@ _gtk_css_number_value_parse (GtkCssParser           *parser,
             break;
         }
 
-      g_free (unit_name);
-
       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
     {
@@ -773,8 +825,7 @@ _gtk_css_parser_try_hash_color (GtkCssParser *parser,
 }
 
 GFile *
-_gtk_css_parser_read_url (GtkCssParser *parser,
-                          GFile        *base)
+_gtk_css_parser_read_url (GtkCssParser *parser)
 {
   gchar *path;
   char *scheme;
@@ -828,17 +879,17 @@ _gtk_css_parser_read_url (GtkCssParser *parser,
         }
     }
 
-  file = g_file_resolve_relative_path (base, path);
+  file = _gtk_css_parser_get_file_for_path (parser, path);
   g_free (path);
 
   return file;
 }
 
-void
-_gtk_css_parser_resync_internal (GtkCssParser *parser,
-                                 gboolean      sync_at_semicolon,
-                                 gboolean      read_sync_token,
-                                 char          terminator)
+static void
+gtk_css_parser_resync_internal (GtkCssParser *parser,
+                                gboolean      sync_at_semicolon,
+                                gboolean      read_sync_token,
+                                char          terminator)
 {
   gsize len;
 
@@ -933,7 +984,7 @@ _gtk_css_parser_read_value (GtkCssParser *parser)
   start = parser->data;
 
   /* This needs to be done better */
-  _gtk_css_parser_resync_internal (parser, TRUE, FALSE, '}');
+  gtk_css_parser_resync_internal (parser, TRUE, FALSE, '}');
 
   result = g_strndup (start, parser->data - start);
   if (result)
@@ -959,5 +1010,5 @@ _gtk_css_parser_resync (GtkCssParser *parser,
 {
   g_return_if_fail (GTK_IS_CSS_PARSER (parser));
 
-  _gtk_css_parser_resync_internal (parser, sync_at_semicolon, TRUE, terminator);
+  gtk_css_parser_resync_internal (parser, sync_at_semicolon, TRUE, terminator);
 }