[gobject-introspection] giscanner: speed up SourceScanner().parse_files()



commit 65a0fa4c4e005047af7ec029c733bed4bd80292f
Author: Dieter Verfaillie <dieterv optionexplicit be>
Date:   Thu Oct 17 17:26:10 2013 +0200

    giscanner: speed up SourceScanner().parse_files()
    
    Was looking around a bit and noticed about 2/3 of
    g-ir-scanner time is spent in SourceScanner().parse_files().
    
    Some profiling quickly shows most of that 2/3 is used
    by gi_source_scanner_add_symbol() where it creates a whole
    bunch of GFile instances just to compare paths and throw
    them away again. With this a scanner instance now maintains
    a hash table of GFile instances instead of a list of file
    names, so comparing those paths can be reduced to a fast
    g_hash_table_contains() call.
    
    This makes "g-ir-scanner <whole_bunch_of_options> --output Gtk-3.0.gir"
    complete in about 10 seconds on my box instead of about
    30 seconds (both best of 3 runs).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=710320

 giscanner/giscannermodule.c |   12 +++--
 giscanner/scannerlexer.l    |   26 +++++++----
 giscanner/scannerparser.y   |  108 +++++++++++++++++++++---------------------
 giscanner/sourcescanner.c   |   45 ++++++------------
 giscanner/sourcescanner.h   |    7 ++-
 5 files changed, 96 insertions(+), 102 deletions(-)
---
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c
index 182d843..2f4c0e8 100644
--- a/giscanner/giscannermodule.c
+++ b/giscanner/giscannermodule.c
@@ -356,12 +356,13 @@ pygi_source_scanner_append_filename (PyGISourceScanner *self,
                                     PyObject          *args)
 {
   char *filename;
+  GFile *file;
 
   if (!PyArg_ParseTuple (args, "s:SourceScanner.append_filename", &filename))
     return NULL;
 
-  self->scanner->filenames = g_list_append (self->scanner->filenames,
-                                           g_realpath (filename));
+  file = g_file_new_for_path (g_realpath (filename));
+  g_hash_table_add (self->scanner->files, file);
 
   Py_INCREF (Py_None);
   return Py_None;
@@ -511,18 +512,19 @@ pygi_source_scanner_lex_filename (PyGISourceScanner *self,
                                  PyObject          *args)
 {
   char *filename;
+  GFile *file;
 
   if (!PyArg_ParseTuple (args, "s:SourceScanner.lex_filename", &filename))
     return NULL;
 
-  self->scanner->current_filename = g_realpath (filename);
+  self->scanner->current_file = g_file_new_for_path ( g_realpath (filename));
   if (!gi_source_scanner_lex_filename (self->scanner, filename))
     {
       g_print ("Something went wrong during lexing.\n");
       return NULL;
     }
-  self->scanner->filenames =
-    g_list_append (self->scanner->filenames, g_strdup (filename));
+  file = g_file_new_for_path (filename);
+  g_hash_table_add (self->scanner->files, file);
 
   Py_INCREF (Py_None);
   return Py_None;
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l
index 2e3d0ab..91f50cb 100644
--- a/giscanner/scannerlexer.l
+++ b/giscanner/scannerlexer.l
@@ -51,6 +51,7 @@ static void parse_trigraph (GISourceScanner *scanner);
 static void process_linemarks (GISourceScanner *scanner);
 static int check_identifier (GISourceScanner *scanner, const char *);
 static int parse_ignored_macro (void);
+static void print_error (GISourceScanner *scanner);
 %}
 
 %option nounput
@@ -211,7 +212,7 @@ stringtext                          ([^\\\"])|(\\.)
 "\""{stringtext}*"\""                  { return STRING; }
 "L\""{stringtext}*"\""                 { return STRING; }
 
-.                                      { if (yytext[0]) fprintf(stderr, "%s:%d: unexpected character 
`%c'\n", scanner->current_filename, lineno, yytext[0]); }
+.                                      { print_error(scanner); }
 
 %%
 
@@ -238,9 +239,7 @@ parse_comment (GISourceScanner *scanner)
      * Store GTK-Doc comment blocks,
      * starts with one '/' followed by exactly two '*' and not followed by a '/'
      */
-    if (!g_list_find_custom (scanner->filenames,
-                             scanner->current_filename,
-                             (GCompareFunc)g_strcmp0)) {
+    if (!g_hash_table_contains (scanner->files, scanner->current_file)) {
         skip = TRUE;
     } else {
         string = g_string_new (yytext);
@@ -269,10 +268,9 @@ parse_comment (GISourceScanner *scanner)
     comment = g_slice_new (GISourceComment);
     comment->comment = g_string_free (string, FALSE);
     comment->line = comment_lineno;
-    comment->filename = g_strdup(scanner->current_filename);
+    comment->filename = g_file_get_parse_name (scanner->current_file);
 
-    scanner->comments = g_slist_prepend (scanner->comments,
-                                         comment);
+    scanner->comments = g_slist_prepend (scanner->comments, comment);
   } else {
     /*
      * Ignore all other comment blocks
@@ -324,8 +322,8 @@ process_linemarks (GISourceScanner *scanner)
        filename = g_strcompress (escaped_filename);
        real = g_realpath (filename);
        if (real) {
-               g_free (scanner->current_filename);
-               scanner->current_filename = real;
+               g_object_unref (scanner->current_file);
+               scanner->current_file = g_file_new_for_path (real);
        } else {
                g_free (real);
        }
@@ -399,3 +397,13 @@ parse_trigraph (GISourceScanner *scanner)
        }
        g_strfreev (items);
 }
+
+static void
+print_error (GISourceScanner *scanner)
+{
+  if (yytext[0]) {
+    char *filename = g_file_get_parse_name (scanner->current_file);
+    fprintf(stderr, "%s:%d: unexpected character `%c'\n", filename, lineno, yytext[0]);
+    g_free (filename);
+  }
+}
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y
index 3457b49..d440fd3 100644
--- a/giscanner/scannerparser.y
+++ b/giscanner/scannerparser.y
@@ -225,7 +225,7 @@ primary_expression
          {
                $$ = g_hash_table_lookup (const_table, $1);
                if ($$ == NULL) {
-                       $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+                       $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                } else {
                        $$ = gi_source_symbol_ref ($$);
                }
@@ -234,7 +234,7 @@ primary_expression
          {
                char *rest;
                guint64 value;
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
                        value = g_ascii_strtoull (yytext + 2, &rest, 16);
@@ -248,13 +248,13 @@ primary_expression
          }
        | CHARACTER
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = g_utf8_get_char(yytext + 1);
          }
        | FLOATING
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_double_set = TRUE;
                $$->const_double = 0.0;
         sscanf (yytext, "%lf", &($$->const_double));
@@ -266,7 +266,7 @@ primary_expression
          }
        | EXTENSION '(' '{' block_item_list '}' ')'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        ;
 
@@ -274,7 +274,7 @@ primary_expression
 strings
        : STRING
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                yytext[strlen (yytext) - 1] = '\0';
                $$->const_string = parse_c_string_literal (yytext + 1);
                 if (!g_utf8_validate ($$->const_string, -1, NULL))
@@ -316,31 +316,31 @@ postfix_expression
        : primary_expression
        | postfix_expression '[' expression ']'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression '(' argument_expression_list ')'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression '(' ')'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression '.' identifier_or_typedef_name
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression ARROW identifier_or_typedef_name
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression PLUSPLUS
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | postfix_expression MINUSMINUS
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        ;
 
@@ -353,11 +353,11 @@ unary_expression
        : postfix_expression
        | PLUSPLUS unary_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | MINUSMINUS unary_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | unary_operator cast_expression
          {
@@ -378,7 +378,7 @@ unary_expression
                        $$->const_int = !gi_source_symbol_get_const_boolean ($2);
                        break;
                default:
-                       $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+                       $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                        break;
                }
          }
@@ -398,12 +398,12 @@ unary_expression
          }
        | SIZEOF unary_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | SIZEOF '(' type_name ')'
          {
                ctype_free ($3);
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        ;
 
@@ -451,13 +451,13 @@ multiplicative_expression
        : cast_expression
        | multiplicative_expression '*' cast_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int * $3->const_int;
          }
        | multiplicative_expression '/' cast_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                if ($3->const_int != 0) {
                        $$->const_int = $1->const_int / $3->const_int;
@@ -465,7 +465,7 @@ multiplicative_expression
          }
        | multiplicative_expression '%' cast_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                if ($3->const_int != 0) {
                        $$->const_int = $1->const_int % $3->const_int;
@@ -477,13 +477,13 @@ additive_expression
        : multiplicative_expression
        | additive_expression '+' multiplicative_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int + $3->const_int;
          }
        | additive_expression '-' multiplicative_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int - $3->const_int;
          }
@@ -493,7 +493,7 @@ shift_expression
        : additive_expression
        | shift_expression SL additive_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int << $3->const_int;
 
@@ -505,7 +505,7 @@ shift_expression
          }
        | shift_expression SR additive_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int >> $3->const_int;
          }
@@ -515,25 +515,25 @@ relational_expression
        : shift_expression
        | relational_expression '<' shift_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int < $3->const_int;
          }
        | relational_expression '>' shift_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int > $3->const_int;
          }
        | relational_expression LTEQ shift_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int <= $3->const_int;
          }
        | relational_expression GTEQ shift_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int >= $3->const_int;
          }
@@ -543,13 +543,13 @@ equality_expression
        : relational_expression
        | equality_expression EQ relational_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int == $3->const_int;
          }
        | equality_expression NOTEQ relational_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int != $3->const_int;
          }
@@ -559,7 +559,7 @@ and_expression
        : equality_expression
        | and_expression '&' equality_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int & $3->const_int;
          }
@@ -569,7 +569,7 @@ exclusive_or_expression
        : and_expression
        | exclusive_or_expression '^' and_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int ^ $3->const_int;
          }
@@ -579,7 +579,7 @@ inclusive_or_expression
        : exclusive_or_expression
        | inclusive_or_expression '|' exclusive_or_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int = $1->const_int | $3->const_int;
          }
@@ -589,7 +589,7 @@ logical_and_expression
        : inclusive_or_expression
        | logical_and_expression ANDAND inclusive_or_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int =
                  gi_source_symbol_get_const_boolean ($1) &&
@@ -601,7 +601,7 @@ logical_or_expression
        : logical_and_expression
        | logical_or_expression OROR logical_and_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_file, lineno);
                $$->const_int_set = TRUE;
                $$->const_int =
                  gi_source_symbol_get_const_boolean ($1) ||
@@ -621,7 +621,7 @@ assignment_expression
        : conditional_expression
        | unary_expression assignment_operator assignment_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        ;
 
@@ -644,7 +644,7 @@ expression
        | expression ',' assignment_expression
        | EXTENSION expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        ;
 
@@ -823,7 +823,7 @@ struct_or_union_specifier
                $$->name = $2;
                $$->child_list = $4;
 
-               sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                if ($$->type == CTYPE_STRUCT) {
                        sym->type = CSYMBOL_TYPE_STRUCT;
                } else if ($$->type == CTYPE_UNION) {
@@ -922,12 +922,12 @@ struct_declarator_list
 struct_declarator
        : /* empty, support for anonymous structs and unions */
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | declarator
        | ':' constant_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
          }
        | declarator ':' constant_expression
          {
@@ -1003,7 +1003,7 @@ enumerator_list
 enumerator
        : identifier
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, scanner->current_file, lineno);
                $$->ident = $1;
                $$->const_int_set = TRUE;
                $$->const_int = ++last_enum_value;
@@ -1011,7 +1011,7 @@ enumerator
          }
        | identifier '=' constant_expression
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, scanner->current_file, lineno);
                $$->ident = $1;
                $$->const_int_set = TRUE;
                $$->const_int = $3->const_int;
@@ -1058,7 +1058,7 @@ declarator
 direct_declarator
        : identifier
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                $$->ident = $1;
          }
        | '(' declarator ')'
@@ -1165,25 +1165,25 @@ parameter_declaration
          }
        | declaration_specifiers
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                $$->base_type = $1;
          }
        | ELLIPSIS
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_ELLIPSIS, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_ELLIPSIS, scanner->current_file, lineno);
          }
        ;
 
 identifier_list
        : identifier
          {
-               GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, 
lineno);
+               GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, 
lineno);
                sym->ident = $1;
                $$ = g_list_append (NULL, sym);
          }
        | identifier_list ',' identifier
          {
-               GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, 
lineno);
+               GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, 
lineno);
                sym->ident = $3;
                $$ = g_list_append ($1, sym);
          }
@@ -1197,7 +1197,7 @@ type_name
 abstract_declarator
        : pointer
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                gi_source_symbol_merge_type ($$, $1);
          }
        | direct_abstract_declarator
@@ -1215,12 +1215,12 @@ direct_abstract_declarator
          }
        | '[' ']'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
          }
        | '[' assignment_expression ']'
          {
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                gi_source_symbol_merge_type ($$, gi_source_array_new ($2));
          }
        | direct_abstract_declarator '[' ']'
@@ -1236,7 +1236,7 @@ direct_abstract_declarator
        | '(' ')'
          {
                GISourceType *func = gi_source_function_new ();
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                gi_source_symbol_merge_type ($$, func);
          }
        | '(' parameter_list ')'
@@ -1246,7 +1246,7 @@ direct_abstract_declarator
                if ($2 != NULL && ($2->next != NULL || ((GISourceSymbol *) $2->data)->base_type->type != 
CTYPE_VOID)) {
                        func->child_list = $2;
                }
-               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_filename, lineno);
+               $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, scanner->current_file, lineno);
                gi_source_symbol_merge_type ($$, func);
          }
        | direct_abstract_declarator '(' ')'
@@ -1418,7 +1418,7 @@ yyerror (GISourceScanner *scanner, const char *s)
   if (!scanner->macro_scan)
     {
       fprintf(stderr, "%s:%d: %s in '%s' at '%s'\n",
-             scanner->current_filename, lineno, s, linebuf, yytext);
+             g_file_get_parse_name (scanner->current_file), lineno, s, linebuf, yytext);
     }
 }
 
diff --git a/giscanner/sourcescanner.c b/giscanner/sourcescanner.c
index 90db294..70eca8d 100644
--- a/giscanner/sourcescanner.c
+++ b/giscanner/sourcescanner.c
@@ -25,11 +25,11 @@
 #include <gio/gio.h>
 
 GISourceSymbol *
-gi_source_symbol_new (GISourceSymbolType type, const gchar *filename, int line)
+gi_source_symbol_new (GISourceSymbolType type, GFile *file, int line)
 {
   GISourceSymbol *s = g_slice_new0 (GISourceSymbol);
   s->ref_count = 1;
-  s->source_filename = g_strdup (filename);
+  s->source_filename = g_file_get_parse_name (file);
   s->type = type;
   s->line = line;
   return s;
@@ -47,8 +47,9 @@ ctype_free (GISourceType * type)
 GISourceSymbol *
 gi_source_symbol_copy (GISourceSymbol * symbol)
 {
+  GFile *source_file = g_file_new_for_path (symbol->source_filename);
   GISourceSymbol *new_symbol = gi_source_symbol_new (symbol->type,
-                                                     symbol->source_filename,
+                                                     source_file,
                                                      symbol->line);
   new_symbol->ident = g_strdup (symbol->ident);
 
@@ -213,11 +214,13 @@ gi_source_scanner_new (void)
 
   scanner = g_slice_new0 (GISourceScanner);
   scanner->typedef_table = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                 g_free, NULL);
+                                                  g_free, NULL);
   scanner->struct_or_union_or_enum_table =
     g_hash_table_new_full (g_str_hash, g_str_equal,
-                          g_free, (GDestroyNotify)gi_source_symbol_unref);
+                           g_free, (GDestroyNotify)gi_source_symbol_unref);
 
+  scanner->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
+                                          g_object_unref, NULL);
   return scanner;
 }
 
@@ -232,7 +235,7 @@ gi_source_comment_free (GISourceComment *comment)
 void
 gi_source_scanner_free (GISourceScanner *scanner)
 {
-  g_free (scanner->current_filename);
+  g_object_unref (scanner->current_file);
 
   g_hash_table_destroy (scanner->typedef_table);
   g_hash_table_destroy (scanner->struct_or_union_or_enum_table);
@@ -242,8 +245,7 @@ gi_source_scanner_free (GISourceScanner *scanner)
   g_slist_foreach (scanner->symbols, (GFunc)gi_source_symbol_unref, NULL);
   g_slist_free (scanner->symbols);
 
-  g_list_foreach (scanner->filenames, (GFunc)g_free, NULL);
-  g_list_free (scanner->filenames);
+  g_hash_table_unref (scanner->files);
 
 }
 
@@ -266,29 +268,12 @@ void
 gi_source_scanner_add_symbol (GISourceScanner  *scanner,
                              GISourceSymbol   *symbol)
 {
-  gboolean found_filename = FALSE;
-  GList *l;
-  GFile *current_file;
-
-  g_assert (scanner->current_filename);
-  current_file = g_file_new_for_path (scanner->current_filename);
+  g_assert (scanner->current_file);
 
-  for (l = scanner->filenames; l != NULL; l = l->next)
-    {
-      GFile *file = g_file_new_for_path (l->data);
-
-      if (g_file_equal (file, current_file))
-       {
-         found_filename = TRUE;
-          g_object_unref (file);
-         break;
-       }
-      g_object_unref (file);
-    }
-
-  if (found_filename || scanner->macro_scan)
+  if (scanner->macro_scan || g_hash_table_contains (scanner->files, scanner->current_file))
     scanner->symbols = g_slist_prepend (scanner->symbols,
-                                       gi_source_symbol_ref (symbol));
+                                        gi_source_symbol_ref (symbol));
+
   g_assert (symbol->source_filename != NULL);
 
   switch (symbol->type)
@@ -308,8 +293,6 @@ gi_source_scanner_add_symbol (GISourceScanner  *scanner,
     default:
       break;
     }
-
-    g_object_unref (current_file);
 }
 
 GSList *
diff --git a/giscanner/sourcescanner.h b/giscanner/sourcescanner.h
index f67ae6b..2db9bdf 100644
--- a/giscanner/sourcescanner.h
+++ b/giscanner/sourcescanner.h
@@ -25,6 +25,7 @@
 
 #include <glib.h>
 #include <stdio.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -105,12 +106,12 @@ struct _GISourceComment
 
 struct _GISourceScanner
 {
-  char *current_filename;
+  GFile *current_file;
   gboolean macro_scan;
   gboolean private; /* set by gtk-doc comment <private>/<public> */
   gboolean flags; /* set by gtk-doc comment <flags> */
   GSList *symbols;
-  GList *filenames;
+  GHashTable *files;
   GSList *comments; /* _GIComment */
   GHashTable *typedef_table;
   GHashTable *struct_or_union_or_enum_table;
@@ -158,7 +159,7 @@ GSList *            gi_source_scanner_get_symbols      (GISourceScanner  *scanne
 GSList *            gi_source_scanner_get_comments     (GISourceScanner  *scanner);
 void                gi_source_scanner_free             (GISourceScanner  *scanner);
 
-GISourceSymbol *    gi_source_symbol_new               (GISourceSymbolType  type, const gchar *filename, int 
line);
+GISourceSymbol *    gi_source_symbol_new               (GISourceSymbolType  type, GFile *file, int line);
 gboolean            gi_source_symbol_get_const_boolean (GISourceSymbol     *symbol);
 GISourceSymbol *    gi_source_symbol_ref               (GISourceSymbol     *symbol);
 void                gi_source_symbol_unref             (GISourceSymbol     *symbol);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]