commit dbc091dd8ea7c1c436d1949c5260087af0f7ab45
Author: Sam Thursfield <sam@afuera.me.uk>
Date:   Sat Apr 15 22:48:50 2017 +0100

    g-ir-scanner: Treat #line with relative path as relative to source file
    
    This fixes an issue when scanning C source code generated by Vala. Such
    code has lots of #line directives that give just the filename of the C
    source file. If the g-ir-scanner is was run from the same directory as
    the source file being scanned then it would calculate an incorrect path
    for the file, and then ignore all subsequent comments as the incorrect
    path didn't appear in the file list.
    
    (Scanning Vala generated C code isn't necessary in most cases as Vala
    can output a .gir file itself, but if a single library mixes C and Vala
    code then you can't use the .gir that Vala generates because it won't
    include the symbols from the C portion of the library).

diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l
index 21ef570..1579bc2 100644
--- a/giscanner/scannerlexer.l
+++ b/giscanner/scannerlexer.l
@@ -44,6 +44,8 @@
 #include <windows.h>
 #endif
 
+char *source_directory;
+
 int lineno;
 char linebuf[2000];
 
@@ -413,6 +415,13 @@ process_linemarks (GISourceScanner *scanner, gboolean has_line)
 
 	filename = g_strcompress (escaped_filename);
 
+        if (! g_path_is_absolute (filename))
+          {
+            char *absolute_filename = g_build_filename (source_directory, filename, NULL);
+            g_free (filename);
+            filename = absolute_filename;
+          }
+
         real = _realpath (filename);
         if (real)
           {
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y
index 6cbf36a..15d5d03 100644
--- a/giscanner/scannerparser.y
+++ b/giscanner/scannerparser.y
@@ -40,6 +40,7 @@ extern FILE *yyin;
 extern int lineno;
 extern char linebuf[2000];
 extern char *yytext;
+extern char *source_directory;
 
 extern int yylex (GISourceScanner *scanner);
 static void yyerror (GISourceScanner *scanner, const char *str);
@@ -1784,10 +1785,14 @@ gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename)
   lineno = 1;
   yyin = fopen (filename, "r");
 
+  source_directory = g_path_get_dirname (filename);
+
   while (yylex (scanner) != YYEOF)
     ;
 
   fclose (yyin);
 
+  g_free (source_directory);
+
   return TRUE;
 }
diff --git a/tests/scanner/Lines-1.0-expected.gir b/tests/scanner/Lines-1.0-expected.gir
new file mode 100644
index 0000000..8f6a6b0
--- /dev/null
+++ b/tests/scanner/Lines-1.0-expected.gir
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- This file was automatically generated from C sources - DO NOT EDIT!
+To affect the contents of this file, edit the original C definitions,
+and/or use gtk-doc annotations.  -->
+<repository version="1.2"
+            xmlns="http://www.gtk.org/introspection/core/1.0"
+            xmlns:c="http://www.gtk.org/introspection/c/1.0"
+            xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
+  <include name="GObject" version="2.0"/>
+  <package name="gobject-2.0"/>
+  <namespace name="Lines"
+             version="1.0"
+             shared-library="liblines.so"
+             c:identifier-prefixes="Lines"
+             c:symbol-prefixes="lines">
+    <function name="function" c:identifier="lines_function">
+      <return-value transfer-ownership="none">
+        <doc xml:space="preserve">5.</doc>
+        <type name="gint" c:type="int"/>
+      </return-value>
+    </function>
+  </namespace>
+</repository>
diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
index 13156c3..988fe27 100644
--- a/tests/scanner/Makefile.am
+++ b/tests/scanner/Makefile.am
@@ -17,6 +17,7 @@ EXTRA_LTLIBRARIES = \
 	libregress.la \
 	libwarnlib.la \
 	libtypedefs.la \
+	liblines.la \
 	$(NULL)
 CLEANFILES += $(EXTRA_LTLIBRARIES)
 
@@ -165,6 +166,17 @@ Bar_1_0_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS) --accept-unprefixed
 GIRS += Bar-1.0.gir
 endif
 
+liblines_la_SOURCES = $(srcdir)/subdir/lines.c $(srcdir)/subdir/lines.h
+
+Lines-1.0.gir: liblines.la
+Lines_1_0_gir_PACKAGES = gobject-2.0
+Lines_1_0_gir_LIBS = liblines.la
+Lines_1_0_gir_CFLAGS = $(GI_SCANNER_CFLAGS)
+Lines_1_0_gir_INCLUDES = GObject-2.0
+Lines_1_0_gir_FILES = $(liblines_la_SOURCES)
+Lines_1_0_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS) --identifier-prefix=Lines --symbol-prefix=lines
+GIRS += Lines-1.0.gir
+
 EXTRA_DIST += \
 	headeronly.h \
 	Headeronly-1.0-expected.gir
diff --git a/tests/scanner/subdir/lines.c b/tests/scanner/subdir/lines.c
new file mode 100644
index 0000000..075f020
--- /dev/null
+++ b/tests/scanner/subdir/lines.c
@@ -0,0 +1,28 @@
+/* This tests the code that handles #line directives.
+ *
+ * This is in a subdirectory to test that relative paths are handled
+ * correctly. Old versions of g-ir-scanner would treat such paths as being
+ * relative to its own cwd, but they should really be treated as relative
+ * to the real source file. A #line directive that refers to a file that's
+ * not in the g-ir-scanner's file list causes the subsequent comments to
+ * be ignored.
+ */
+
+#include "config.h"
+
+#include "lines.h"
+
+#line 1 "/dev/null"
+
+#line 2 "lines.c"
+
+/**
+ * lines_function:
+ *
+ * Returns: 5.
+ */
+int
+lines_function (void)
+{
+  return 5;
+}
diff --git a/tests/scanner/subdir/lines.h b/tests/scanner/subdir/lines.h
new file mode 100644
index 0000000..d823640
--- /dev/null
+++ b/tests/scanner/subdir/lines.h
@@ -0,0 +1 @@
+int lines_function (void);
