summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2010-09-19 16:37:42 -0300
committerJohan Dahlin <johan@gnome.org>2010-09-19 23:47:36 -0300
commit0d6db7114a176c2d24a19a2d6a570aab406608ac (patch)
treed72657dee7985eeb215ad054a6b9da0a92f8579f
parent2f6638b2c15aee49b08784f13bd5f945466f97a7 (diff)
[sourcescanner] Rewrite linemarks parser
Rewrite the pre-processor linemark parser so we end up with accurate filenames and linenumbers.
-rw-r--r--giscanner/scannerlexer.l74
-rw-r--r--giscanner/scannerparser.y1
2 files changed, 25 insertions, 50 deletions
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l
index 4fa40f6..5a5058b 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 600aee0..b4df11c 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)