diff options
author | Johan Dahlin <johan@gnome.org> | 2010-09-19 16:37:42 -0300 |
---|---|---|
committer | Johan Dahlin <johan@gnome.org> | 2010-09-19 23:47:36 -0300 |
commit | 0d6db7114a176c2d24a19a2d6a570aab406608ac (patch) | |
tree | d72657dee7985eeb215ad054a6b9da0a92f8579f /giscanner | |
parent | 2f6638b2c15aee49b08784f13bd5f945466f97a7 (diff) | |
download | gobject-introspection-0d6db7114a176c2d24a19a2d6a570aab406608ac.tar.gz |
[sourcescanner] Rewrite linemarks parser
Rewrite the pre-processor linemark parser so we end
up with accurate filenames and linenumbers.
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/scannerlexer.l | 74 | ||||
-rw-r--r-- | giscanner/scannerparser.y | 1 |
2 files changed, 25 insertions, 50 deletions
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l index 4fa40f63..5a5058bb 100644 --- a/giscanner/scannerlexer.l +++ b/giscanner/scannerlexer.l @@ -46,7 +46,7 @@ extern int yylex (GISourceScanner *scanner); #define YY_DECL int yylex (GISourceScanner *scanner) static int yywrap (void); static void parse_comment (GISourceScanner *scanner); -static void process_directive (GISourceScanner *scanner); +static void process_linemarks (GISourceScanner *scanner); static int check_identifier (GISourceScanner *scanner, const char *); static int parse_ignored_macro (void); %} @@ -77,8 +77,8 @@ stringtext ([^\\\"])|(\\.) "#define "[a-zA-Z_][a-zA-Z_0-9]*"(" { yyless (yyleng - 1); return FUNCTION_MACRO; } "#define "[a-zA-Z_][a-zA-Z_0-9]* { return OBJECT_MACRO; } -"#" { process_directive(scanner); } - +"# "[0-9]+" ".*"\n" { process_linemarks(scanner); } +"#" { } "{" { return '{'; } "<%" { return '{'; } "}" { return '}'; } @@ -261,55 +261,29 @@ check_identifier (GISourceScanner *scanner, return IDENTIFIER; } +/* + * # linenum "filename" flags + * See http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html + **/ + static void -process_directive (GISourceScanner *scanner) +process_linemarks (GISourceScanner *scanner) { - /* extract current filename from #line directives */ - GString *filename_builder; - gboolean in_string, found_filename; - - lineno = 0; - found_filename = FALSE; - in_string = FALSE; - filename_builder = g_string_new (""); - - int c = input (); - while (c != EOF && c != '\n') { - if (!in_string) { - if (c == '\"') { - in_string = TRUE; - found_filename = TRUE; - } else if (c >= '0' && c <= '9') { - if (!found_filename) { - lineno = lineno * 10 + (c - '0'); - } - } - } else { - if (c == '\"') { - in_string = FALSE; - } else if (c == '\\') { - g_string_append_c (filename_builder, c); - c = input (); - g_string_append_c (filename_builder, c); - } else { - g_string_append_c (filename_builder, c); - } - } - c = input (); - } - - if (filename_builder->len > 0) { - char *filename = g_strcompress (filename_builder->str); - if (g_realpath (filename)) - { - g_free (scanner->current_filename); - scanner->current_filename = g_realpath (filename); - g_assert (scanner->current_filename); - g_free(filename); - } - } - - g_string_free (filename_builder, TRUE); + char filename[1025]; + char *compress; + char *real; + + sscanf(yytext, "# %d \"%1024[^\"]\"", &lineno, filename); + + compress = g_strcompress (filename); + real = g_realpath (filename); + if (real) { + g_free (scanner->current_filename); + scanner->current_filename = real; + } else { + g_free (real); + } + g_free (compress); } /* diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y index 600aee01..b4df11cc 100644 --- a/giscanner/scannerparser.y +++ b/giscanner/scannerparser.y @@ -1488,6 +1488,7 @@ gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file) gboolean gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename) { + lineno = 1; yyin = fopen (filename, "r"); while (yylex (scanner) != YYEOF) |