add --basedir option, fixes bug 483843
authorJuerg Billeter <j@bitron.ch>
Tue, 9 Oct 2007 19:30:17 +0000 (19:30 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Tue, 9 Oct 2007 19:30:17 +0000 (19:30 +0000)
2007-10-09  Juerg Billeter  <j@bitron.ch>

* vala/valacodecontext.vala, vala/valasourcefile.vala,
  gobject/valaccodecompiler.vala,
  gobject/valaccodegeneratorsourcefile.vala, compiler/valacompiler.vala,
  tests/testrunner.sh: add --basedir option, fixes bug 483843

svn path=/trunk/; revision=646

ChangeLog
compiler/valacompiler.vala
gobject/valaccodecompiler.vala
gobject/valaccodegeneratorsourcefile.vala
tests/testrunner.sh
vala/valacodecontext.vala
vala/valasourcefile.vala

index 058ed8e..17c11bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2007-10-09  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valacodecontext.vala, vala/valasourcefile.vala,
+         gobject/valaccodecompiler.vala,
+         gobject/valaccodegeneratorsourcefile.vala, compiler/valacompiler.vala,
+         tests/testrunner.sh: add --basedir option, fixes bug 483843
+
+2007-10-09  Jürg Billeter  <j@bitron.ch>
+
        * gobject/valaccodeassignmentbinding.vala: fix support for static
          methods as GObject signal handlers
 
index 8b82f0b..d08c21e 100644 (file)
@@ -1,6 +1,7 @@
 /* valacompiler.vala
  *
  * Copyright (C) 2006-2007  Jürg Billeter
+ * Copyright (C) 1996-2002, 2004, 2005, 2006 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,6 +24,7 @@
 using GLib;
 
 class Vala.Compiler : Object {
+       static string basedir;
        static string directory;
        static bool version;
        [NoArrayLength ()]
@@ -53,6 +55,7 @@ class Vala.Compiler : Object {
                { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
                { "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." },
                { "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" },
+               { "basedir", 'b', 0, OptionArg.FILENAME, out basedir, "Base source directory", "DIRECTORY" },
                { "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
                { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
                { "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
@@ -184,7 +187,14 @@ class Vala.Compiler : Object {
                context.ccode_only = ccode_only;
                context.compile_only = compile_only;
                context.output = output;
-               context.directory = directory;
+               if (basedir != null) {
+                       context.basedir = realpath (basedir);
+               }
+               if (directory != null) {
+                       context.directory = realpath (directory);
+               } else {
+                       context.directory = context.basedir;
+               }
                context.debug = debug;
                context.thread = thread;
                context.optlevel = optlevel;
@@ -212,12 +222,13 @@ class Vala.Compiler : Object {
                
                foreach (string source in sources) {
                        if (FileUtils.test (source, FileTest.EXISTS)) {
+                               var rpath = realpath (source);
                                if (source.has_suffix (".vala")) {
-                                       context.add_source_file (new SourceFile (context, source));
+                                       context.add_source_file (new SourceFile (context, rpath));
                                } else if (source.has_suffix (".vapi")) {
-                                       context.add_source_file (new SourceFile (context, source, true));
+                                       context.add_source_file (new SourceFile (context, rpath, true));
                                } else if (source.has_suffix (".c")) {
-                                       context.add_c_source_file (source);
+                                       context.add_c_source_file (rpath);
                                } else {
                                        Report.error (null, "%s is not a supported source file type. Only .vala, .vapi, and .c files are supported.".printf (source));
                                }
@@ -293,7 +304,60 @@ class Vala.Compiler : Object {
 
                return quit ();
        }
-       
+
+       /* ported from glibc */
+       private string! realpath (string! name) {
+               string rpath;
+
+               if (name.get_char () != '/') {
+                       // relative path
+                       rpath = Environment.get_current_dir ();
+               } else {
+                       rpath = "/";
+               }
+
+               weak string start;
+               weak string end;
+
+               for (start = end = name; start.get_char () != 0; start = end) {
+                       // skip sequence of multiple path-separators
+                       while (start.get_char () == '/') {
+                               start = start.next_char ();
+                       }
+
+                       // find end of path component
+                       long len = 0;
+                       for (end = start; end.get_char () != 0 && end.get_char () != '/'; end = end.next_char ()) {
+                               len++;
+                       }
+
+                       if (len == 0) {
+                               break;
+                       } else if (len == 1 && start.get_char () == '.') {
+                               // do nothing
+                       } else if (len == 2 && start.has_prefix ("..")) {
+                               // back up to previous component, ignore if at root already
+                               if (rpath.len () > 1) {
+                                       do {
+                                               rpath = rpath.substring (0, rpath.len () - 1);
+                                       } while (!rpath.has_suffix ("/"));
+                               }
+                       } else {
+                               if (!rpath.has_suffix ("/")) {
+                                       rpath += "/";
+                               }
+
+                               rpath += start.substring (0, len);
+                       }
+               }
+
+               if (rpath.len () > 1 && rpath.has_suffix ("/")) {
+                       rpath = rpath.substring (0, rpath.len () - 1);
+               }
+
+               return rpath;
+       }
+
        static int main (string[] args) {
                try {
                        var opt_context = new OptionContext ("- Vala Compiler");
index 80dba5c..b5a3931 100644 (file)
@@ -103,7 +103,7 @@ public class Vala.CCodeCompiler : Object {
 
                /* make sure include files can be found if -d is used */
                if (context.directory != null && context.directory != "") {
-                       cmdline += " -I" + Shell.quote ("%s/..".printf (context.directory));
+                       cmdline += " -I" + Shell.quote (context.directory);
                }
 
                /* we're only interested in non-pkg source files */
index 4c79f46..ce464c4 100644 (file)
@@ -159,12 +159,16 @@ public class Vala.CCodeGenerator {
                
                header_begin.append (new CCodeIncludeDirective ("glib.h"));
                header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
-               source_include_directives.append (new CCodeIncludeDirective (source_file.get_cheader_filename (), true));
+               if (context.basedir != null || context.library != null) {
+                       source_include_directives.append (new CCodeIncludeDirective (source_file.get_cinclude_filename ()));
+               } else {
+                       source_include_directives.append (new CCodeIncludeDirective (source_file.get_cinclude_filename (), true));
+               }
                
                Gee.List<string> used_includes = new ArrayList<string> (str_equal);
                used_includes.add ("glib.h");
                used_includes.add ("glib-object.h");
-               used_includes.add (source_file.get_cheader_filename ());
+               used_includes.add (source_file.get_cinclude_filename ());
                
                foreach (string filename in source_file.get_header_external_includes ()) {
                        if (!used_includes.contains (filename)) {
@@ -211,7 +215,7 @@ public class Vala.CCodeGenerator {
 
                source_file.accept_children (this);
 
-               var header_define = get_define_for_filename (source_file.get_cheader_filename ());
+               var header_define = get_define_for_filename (source_file.get_cinclude_filename ());
                
                /* generate hardcoded "well-known" macros */
                if (requires_free_checked) {
index 7e70ce3..f1c4bef 100755 (executable)
@@ -30,7 +30,7 @@ export G_DEBUG=fatal_warnings
 
 VALAC=$topbuilddir/compiler/valac
 CC="gcc -std=c99"
-CFLAGS="-O0 -g3 -I$topsrcdir"
+CFLAGS="-O0 -g3 -I$topsrcdir -I$topbuilddir"
 LDLIBS="-lm ../gee/.libs/libgee.a"
 
 CODE=0
@@ -39,7 +39,7 @@ for testcasesource in "$@"
 do
        testsrc=${testcasesource/.vala/}
        testbuild=`basename "$testsrc"`
-       if ! $VALAC --vapidir "$vapidir" --pkg gee-1.0 $testsrc.vala > $testbuild.err 2>&1
+       if ! $VALAC --vapidir "$vapidir" --pkg gee-1.0 --basedir $topsrcdir -d $topbuilddir $testsrc.vala > $testbuild.err 2>&1
        then
                CODE=1
                continue
index c0a56fc..89a3efb 100644 (file)
@@ -66,6 +66,11 @@ public class Vala.CodeContext : Object {
        public string output { get; set; }
 
        /**
+        * Base source directory.
+        */
+       public string basedir { get; set; }
+
+       /**
         * Code output directory.
         */
        public string directory { get; set; }
index b513f51..3bebc72 100644 (file)
@@ -145,6 +145,30 @@ public class Vala.SourceFile : Object {
                }
        }
 
+       private string! get_subdir () {
+               if (context.basedir == null) {
+                       return "";
+               }
+
+               // filename and basedir are already canonicalized
+               if (filename.has_prefix (context.basedir)) {
+                       var basename = Path.get_basename (filename);
+                       var subdir = filename.substring (context.basedir.len (), filename.len () - context.basedir.len () - basename.len ());
+                       while (subdir[0] == '/') {
+                               subdir = subdir.offset (1);
+                       }
+                       return subdir;
+               }
+               return "";
+       }
+
+       private string! get_destination_directory () {
+               if (context.directory == null) {
+                       return get_subdir ();
+               }
+               return "%s/%s".printf (context.directory, get_subdir ());
+       }
+
        /**
         * Returns the filename to use when generating C header files.
         *
@@ -154,11 +178,7 @@ public class Vala.SourceFile : Object {
                if (cheader_filename == null) {
                        var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
                        basename = Path.get_basename (basename);
-                       if (context.directory != null && context.directory != "") {
-                               cheader_filename = "%s/%s.h".printf (context.directory, basename);
-                       } else {
-                               cheader_filename = "%s.h".printf (basename);
-                       }
+                       cheader_filename = "%s%s.h".printf (get_destination_directory (), basename);
                }
                return cheader_filename;
        }
@@ -172,11 +192,7 @@ public class Vala.SourceFile : Object {
                if (csource_filename == null) {
                        var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
                        basename = Path.get_basename (basename);
-                       if (context.directory != null && context.directory != "") {
-                               csource_filename = "%s/%s.c".printf (context.directory, basename);
-                       } else {
-                               csource_filename = "%s.c".printf (basename);
-                       }
+                       csource_filename = "%s%s.c".printf (get_destination_directory (), basename);
                }
                return csource_filename;
        }
@@ -191,10 +207,11 @@ public class Vala.SourceFile : Object {
                if (cinclude_filename == null) {
                        var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
                        basename = Path.get_basename (basename);
-                       if (context.library != null) {
+                       if (context.basedir == null && context.library != null) {
+                               // backward-compatibility
                                cinclude_filename = "%s/%s.h".printf (context.library, basename);
                        } else {
-                               cinclude_filename = "%s.h".printf (basename);
+                               cinclude_filename = "%s%s.h".printf (get_subdir (), basename);
                        }
                }
                return cinclude_filename;