]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Move visit_source_file to CCodeBaseModule
authorJürg Billeter <j@bitron.ch>
Fri, 24 Oct 2008 15:02:34 +0000 (15:02 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 24 Oct 2008 15:02:34 +0000 (15:02 +0000)
2008-10-24  Jürg Billeter  <j@bitron.ch>

* gobject/Makefile.am:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodegenerator.vala:
* gobject/valaccodegeneratorsourcefile.vala:
* gobject/valaccodemodule.vala:

Move visit_source_file to CCodeBaseModule

svn path=/trunk/; revision=1900

ChangeLog
gobject/Makefile.am
gobject/valaccodebasemodule.vala
gobject/valaccodegenerator.vala
gobject/valaccodegeneratorsourcefile.vala [deleted file]
gobject/valaccodemodule.vala

index 1157bd6374af49832980e8289f7b5d68866c4745..a425844f2b417912f2c4f87fa670cbe0200cd3f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-10-24  Jürg Billeter  <j@bitron.ch>
+
+       * gobject/Makefile.am:
+       * gobject/valaccodebasemodule.vala:
+       * gobject/valaccodegenerator.vala:
+       * gobject/valaccodegeneratorsourcefile.vala:
+       * gobject/valaccodemodule.vala:
+
+       Move visit_source_file to CCodeBaseModule
+
 2008-10-24  Jürg Billeter  <j@bitron.ch>
 
        * gobject/Makefile.am:
index 993fe6406e7372a6e25de2f831252cf2e2f21eef..22aaf07020b7db615d66bb8aa6f8cf72f0d4eaa7 100644 (file)
@@ -20,7 +20,6 @@ libvala_la_VALASOURCES = \
        valaccodedynamicsignalmodule.vala \
        valaccodeelementaccessmodule.vala \
        valaccodegenerator.vala \
-       valaccodegeneratorsourcefile.vala \
        valaccodeinvocationexpressionmodule.vala \
        valaccodememberaccessmodule.vala \
        valaccodemethodmodule.vala \
index 0c0ac264de49c4ee17a1348b81d3b7c3b46bba7c..3dd4abaf5ae51448cfe1ef4487cd1f121a962854 100644 (file)
@@ -1,6 +1,6 @@
 /* valaccodebasemodule.vala
  *
- * Copyright (C) 2008  Jürg Billeter
+ * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * Author:
  *     Jürg Billeter <j@bitron.ch>
+ *     Raffaele Sandrini <raffaele@sandrini.ch>
  */
 
+using Gee;
+
 /**
  * Code visitor generating C Code.
  */
@@ -68,4 +71,383 @@ public class Vala.CCodeBaseModule : CCodeModule {
 
                return ccomma;
        }
+
+       private CCodeIncludeDirective get_internal_include (string filename) {
+               return new CCodeIncludeDirective (filename, codegen.context.library == null);
+       }
+
+       private CCodeForStatement get_vala_array_free_loop (bool have_length) {
+               var cbody = new CCodeBlock ();
+               var cptrarray = new CCodeCastExpression (new CCodeIdentifier ("array"), "gpointer*");
+               var cea = new CCodeElementAccess (cptrarray, new CCodeIdentifier ("i"));
+
+               var cfreecall = new CCodeFunctionCall (new CCodeIdentifier ("destroy_func"));
+               cfreecall.add_argument (cea);
+
+               CCodeExpression cforcond;
+
+               if (have_length) {
+                       var cfreecond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant ("NULL"));
+                       cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("array_length"));
+                       cbody.add_statement (new CCodeIfStatement (cfreecond, new CCodeExpressionStatement (cfreecall)));
+               } else {
+                       cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant ("NULL"));
+                       cbody.add_statement (new CCodeExpressionStatement (cfreecall));
+               }
+
+               var cfor = new CCodeForStatement (cforcond, cbody);
+               cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
+               cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("i"), new CCodeConstant ("1"))));
+
+               return cfor;
+       }
+
+       private void append_vala_array_free () {
+               var fun = new CCodeFunction ("_vala_array_free", "void");
+               fun.modifiers = CCodeModifiers.STATIC;
+               fun.add_parameter (new CCodeFormalParameter ("array", "gpointer"));
+               fun.add_parameter (new CCodeFormalParameter ("array_length", "gint"));
+               fun.add_parameter (new CCodeFormalParameter ("destroy_func", "GDestroyNotify"));
+               codegen.source_type_member_declaration.append (fun.copy ());
+
+               var cdofree = new CCodeBlock ();
+
+               var citdecl = new CCodeDeclaration ("int");
+               citdecl.add_declarator (new CCodeVariableDeclarator ("i"));
+               cdofree.add_statement (citdecl);
+
+               var clencheck = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN_OR_EQUAL, new CCodeIdentifier ("array_length"), new CCodeConstant ("0"));
+               var ciflen = new CCodeIfStatement (clencheck, get_vala_array_free_loop (true), get_vala_array_free_loop (false));
+               cdofree.add_statement (ciflen);
+
+               var ccondarr = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("array"), new CCodeConstant ("NULL"));
+               var ccondfunc = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("destroy_func"), new CCodeConstant ("NULL"));
+               var cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccondarr, ccondfunc), cdofree);
+               fun.block = new CCodeBlock ();
+               fun.block.add_statement (cif);
+
+               var carrfree = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+               carrfree.add_argument (new CCodeIdentifier ("array"));
+               fun.block.add_statement (new CCodeExpressionStatement (carrfree));
+
+               codegen.source_type_member_definition.append (fun);
+       }
+
+       private void append_vala_array_move () {
+               codegen.string_h_needed = true;
+
+               // assumes that overwritten array elements are null before invocation
+               // FIXME will leak memory if that's not the case
+               var fun = new CCodeFunction ("_vala_array_move", "void");
+               fun.modifiers = CCodeModifiers.STATIC;
+               fun.add_parameter (new CCodeFormalParameter ("array", "gpointer"));
+               fun.add_parameter (new CCodeFormalParameter ("element_size", "gsize"));
+               fun.add_parameter (new CCodeFormalParameter ("src", "gint"));
+               fun.add_parameter (new CCodeFormalParameter ("dest", "gint"));
+               fun.add_parameter (new CCodeFormalParameter ("length", "gint"));
+               codegen.source_type_member_declaration.append (fun.copy ());
+
+               var array = new CCodeCastExpression (new CCodeIdentifier ("array"), "char*");
+               var element_size = new CCodeIdentifier ("element_size");
+               var length = new CCodeIdentifier ("length");
+               var src = new CCodeIdentifier ("src");
+               var dest = new CCodeIdentifier ("dest");
+               var src_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, src, element_size));
+               var dest_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, dest, element_size));
+               var dest_end_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dest, length)), element_size));
+
+               fun.block = new CCodeBlock ();
+
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_memmove"));
+               ccall.add_argument (dest_address);
+               ccall.add_argument (src_address);
+               ccall.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, length, element_size));
+               fun.block.add_statement (new CCodeExpressionStatement (ccall));
+
+               var czero1 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+               czero1.add_argument (src_address);
+               czero1.add_argument (new CCodeConstant ("0"));
+               czero1.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, dest, src)), element_size));
+               var czeroblock1 = new CCodeBlock ();
+               czeroblock1.add_statement (new CCodeExpressionStatement (czero1));
+
+               var czero2 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+               czero2.add_argument (dest_end_address);
+               czero2.add_argument (new CCodeConstant ("0"));
+               czero2.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, src, dest)), element_size));
+               var czeroblock2 = new CCodeBlock ();
+               czeroblock2.add_statement (new CCodeExpressionStatement (czero2));
+
+               fun.block.add_statement (new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest), czeroblock1, czeroblock2));
+
+               codegen.source_type_member_definition.append (fun);
+       }
+
+       private void append_vala_strcmp0 () {
+               var fun = new CCodeFunction ("_vala_strcmp0", "int");
+               fun.modifiers = CCodeModifiers.STATIC;
+               fun.add_parameter (new CCodeFormalParameter ("str1", "const char *"));
+               fun.add_parameter (new CCodeFormalParameter ("str2", "const char *"));
+               codegen.source_type_member_declaration.append (fun.copy ());
+
+               // (str1 != str2)
+               var cineq = new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("str1"), new CCodeIdentifier ("str2")));
+
+               fun.block = new CCodeBlock ();
+
+               var cblock = new CCodeBlock ();
+               // if (str1 == NULL)
+               var cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("str1"), new CCodeConstant ("NULL")), cblock);
+               // return -(str1 != str2);
+               cblock.add_statement (new CCodeReturnStatement (new CCodeUnaryExpression (CCodeUnaryOperator.MINUS, cineq)));
+               fun.block.add_statement (cif);
+
+               cblock = new CCodeBlock ();
+               // if (str2 == NULL)
+               cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("str2"), new CCodeConstant ("NULL")), cblock);
+               // return (str1 != str2);
+               cblock.add_statement (new CCodeReturnStatement (cineq));
+               fun.block.add_statement (cif);
+
+               // strcmp (str1, str2)
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
+               ccall.add_argument (new CCodeIdentifier ("str1"));
+               ccall.add_argument (new CCodeIdentifier ("str2"));
+               // return strcmp (str1, str2);
+               fun.block.add_statement (new CCodeReturnStatement (ccall));
+
+               codegen.source_type_member_definition.append (fun);
+       }
+
+       public override void visit_source_file (SourceFile source_file) {
+               codegen.header_begin = new CCodeFragment ();
+               codegen.header_type_declaration = new CCodeFragment ();
+               codegen.header_type_definition = new CCodeFragment ();
+               codegen.header_type_member_declaration = new CCodeFragment ();
+               codegen.header_constant_declaration = new CCodeFragment ();
+               codegen.source_begin = new CCodeFragment ();
+               codegen.source_include_directives = new CCodeFragment ();
+               codegen.source_type_declaration = new CCodeFragment ();
+               codegen.source_type_definition = new CCodeFragment ();
+               codegen.source_type_member_declaration = new CCodeFragment ();
+               codegen.source_constant_declaration = new CCodeFragment ();
+               codegen.source_type_member_definition = new CCodeFragment ();
+               codegen.source_signal_marshaller_definition = new CCodeFragment ();
+               codegen.source_signal_marshaller_declaration = new CCodeFragment ();
+               
+               codegen.user_marshal_set = new HashSet<string> (str_hash, str_equal);
+               
+               codegen.next_temp_var_id = 0;
+               
+               codegen.string_h_needed = false;
+               codegen.gvaluecollector_h_needed = false;
+               codegen.dbus_glib_h_needed = false;
+               codegen.requires_free_checked = false;
+               codegen.requires_array_free = false;
+               codegen.requires_array_move = false;
+               codegen.requires_strcmp0 = false;
+
+               codegen.wrappers = new HashSet<string> (str_hash, str_equal);
+
+               codegen.header_begin.append (new CCodeIncludeDirective ("glib.h"));
+               codegen.header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
+               if (codegen.context.basedir != null || codegen.context.library != null) {
+                       codegen.source_include_directives.append (new CCodeIncludeDirective (source_file.get_cinclude_filename ()));
+               } else {
+                       codegen.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_cinclude_filename ());
+               
+               foreach (string filename in source_file.get_header_external_includes ()) {
+                       if (!used_includes.contains (filename)) {
+                               codegen.header_begin.append (new CCodeIncludeDirective (filename));
+                               used_includes.add (filename);
+                       }
+               }
+               foreach (string filename in source_file.get_header_internal_includes ()) {
+                       if (!used_includes.contains (filename)) {
+                               codegen.header_begin.append (get_internal_include (filename));
+                               used_includes.add (filename);
+                       }
+               }
+               foreach (string filename in source_file.get_source_external_includes ()) {
+                       if (!used_includes.contains (filename)) {
+                               codegen.source_include_directives.append (new CCodeIncludeDirective (filename));
+                               used_includes.add (filename);
+                       }
+               }
+               foreach (string filename in source_file.get_source_internal_includes ()) {
+                       if (!used_includes.contains (filename)) {
+                               codegen.source_include_directives.append (get_internal_include (filename));
+                               used_includes.add (filename);
+                       }
+               }
+               foreach (Symbol symbol in source_file.get_source_symbol_dependencies ()) {
+                       if (!symbol.external && symbol.external_package) {
+                               symbol.accept (codegen);
+                       }
+               }
+               if (source_file.is_cycle_head) {
+                       foreach (SourceFile cycle_file in source_file.cycle.files) {
+                               foreach (CodeNode node in cycle_file.get_nodes ()) {
+                                       if (node is Struct) {
+                                               var st = (Struct) node;
+                                               codegen.header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
+                                       } else if (node is Class) {
+                                               var cl = (Class) node;
+                                               if (!cl.is_static) {
+                                                       codegen.header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
+                                                       codegen.header_type_declaration.append (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
+                                               }
+                                       } else if (node is Interface) {
+                                               var iface = (Interface) node;
+                                               if (!iface.is_static) {
+                                                       codegen.header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
+                                                       codegen.header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_type_cname ()), new CCodeVariableDeclarator (iface.get_type_cname ())));
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               source_file.accept_children (codegen);
+
+               if (Report.get_errors () > 0) {
+                       return;
+               }
+
+               var header_define = get_define_for_filename (source_file.get_cinclude_filename ());
+               
+               /* generate hardcoded "well-known" macros */
+               if (codegen.requires_free_checked) {
+                       codegen.source_begin.append (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
+               }
+               if (codegen.requires_array_free) {
+                       append_vala_array_free ();
+               }
+               if (codegen.requires_array_move) {
+                       append_vala_array_move ();
+               }
+               if (codegen.requires_strcmp0) {
+                       append_vala_strcmp0 ();
+               }
+               
+               if (codegen.string_h_needed) {
+                       codegen.source_include_directives.append (new CCodeIncludeDirective ("string.h"));
+               }
+
+               if (codegen.gvaluecollector_h_needed) {
+                       codegen.source_include_directives.append (new CCodeIncludeDirective ("gobject/gvaluecollector.h"));
+               }
+
+               if (codegen.dbus_glib_h_needed) {
+                       codegen.source_include_directives.append (new CCodeIncludeDirective ("dbus/dbus-glib.h"));
+               }
+
+               CCodeComment comment = null;
+               if (source_file.comment != null) {
+                       comment = new CCodeComment (source_file.comment);
+               }
+
+               var writer = new CCodeWriter (source_file.get_cheader_filename ());
+               if (!writer.open ()) {
+                       Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
+                       return;
+               }
+               if (comment != null) {
+                       comment.write (writer);
+               }
+               writer.write_newline ();
+               var once = new CCodeOnceSection (header_define);
+               once.append (new CCodeNewline ());
+               once.append (codegen.header_begin);
+               once.append (new CCodeNewline ());
+               once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
+               once.append (new CCodeNewline ());
+               once.append (new CCodeNewline ());
+               once.append (codegen.header_type_declaration);
+               once.append (new CCodeNewline ());
+               once.append (codegen.header_type_definition);
+               once.append (new CCodeNewline ());
+               once.append (codegen.header_type_member_declaration);
+               once.append (new CCodeNewline ());
+               once.append (codegen.header_constant_declaration);
+               once.append (new CCodeNewline ());
+               once.append (new CCodeIdentifier ("G_END_DECLS"));
+               once.append (new CCodeNewline ());
+               once.append (new CCodeNewline ());
+               once.write (writer);
+               writer.close ();
+               
+               writer = new CCodeWriter (source_file.get_csource_filename ());
+               if (!writer.open ()) {
+                       Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
+                       return;
+               }
+               writer.line_directives = codegen.context.debug;
+               if (comment != null) {
+                       comment.write (writer);
+               }
+               codegen.source_begin.write (writer);
+               writer.write_newline ();
+               codegen.source_include_directives.write (writer);
+               writer.write_newline ();
+               codegen.source_type_declaration.write_combined (writer);
+               writer.write_newline ();
+               codegen.source_type_definition.write_combined (writer);
+               writer.write_newline ();
+               codegen.source_type_member_declaration.write_declaration (writer);
+               writer.write_newline ();
+               codegen.source_type_member_declaration.write (writer);
+               writer.write_newline ();
+               codegen.source_constant_declaration.write (writer);
+               writer.write_newline ();
+               codegen.source_signal_marshaller_declaration.write_declaration (writer);
+               codegen.source_signal_marshaller_declaration.write (writer);
+               writer.write_newline ();
+               codegen.source_type_member_definition.write (writer);
+               writer.write_newline ();
+               codegen.source_signal_marshaller_definition.write (writer);
+               writer.write_newline ();
+               writer.close ();
+
+               codegen.header_begin = null;
+               codegen.header_type_declaration = null;
+               codegen.header_type_definition = null;
+               codegen.header_type_member_declaration = null;
+               codegen.header_constant_declaration = null;
+               codegen.source_begin = null;
+               codegen.source_include_directives = null;
+               codegen.source_type_declaration = null;
+               codegen.source_type_definition = null;
+               codegen.source_type_member_declaration = null;
+               codegen.source_constant_declaration = null;
+               codegen.source_type_member_definition = null;
+               codegen.source_signal_marshaller_definition = null;
+               codegen.source_signal_marshaller_declaration = null;
+       }
+       
+       private static string get_define_for_filename (string filename) {
+               var define = new StringBuilder ("__");
+               
+               var i = filename;
+               while (i.len () > 0) {
+                       var c = i.get_char ();
+                       if (c.isalnum  () && c < 0x80) {
+                               define.append_unichar (c.toupper ());
+                       } else {
+                               define.append_c ('_');
+                       }
+               
+                       i = i.next_char ();
+               }
+               
+               define.append ("__");
+               
+               return define.str;
+       }
 }
index 4da2c249d63cc3c0d7bd34d2970747654eb8747a..be6b3cdd067519cbeaff870443f090d9fca521e9 100644 (file)
@@ -132,13 +132,13 @@ public class Vala.CCodeGenerator : CodeGenerator {
        
        public bool string_h_needed;
        public bool gvaluecollector_h_needed;
-       private bool requires_free_checked;
-       private bool requires_array_free;
+       public bool requires_free_checked;
+       public bool requires_array_free;
        public bool requires_array_move;
-       private bool requires_strcmp0;
+       public bool requires_strcmp0;
        public bool dbus_glib_h_needed;
 
-       private Set<string> wrappers;
+       public Set<string> wrappers;
 
        public CCodeGenerator () {
                head = new CCodeBaseModule (this, head);
@@ -301,6 +301,10 @@ public class Vala.CCodeGenerator : CodeGenerator {
                }
        }
 
+       public override void visit_source_file (SourceFile source_file) {
+               head.visit_source_file (source_file);
+       }
+
        public override void visit_class (Class cl) {
                head.visit_class (cl);
        }
diff --git a/gobject/valaccodegeneratorsourcefile.vala b/gobject/valaccodegeneratorsourcefile.vala
deleted file mode 100644 (file)
index e9c38f8..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/* valaccodegeneratorsourcefile.vala
- *
- * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
-
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
- *
- * Author:
- *     Jürg Billeter <j@bitron.ch>
- *     Raffaele Sandrini <raffaele@sandrini.ch>
- */
-
-using GLib;
-using Gee;
-
-public class Vala.CCodeGenerator {
-       private CCodeIncludeDirective get_internal_include (string filename) {
-               return new CCodeIncludeDirective (filename, context.library == null);
-       }
-
-       private CCodeForStatement get_vala_array_free_loop (bool have_length) {
-               var cbody = new CCodeBlock ();
-               var cptrarray = new CCodeCastExpression (new CCodeIdentifier ("array"), "gpointer*");
-               var cea = new CCodeElementAccess (cptrarray, new CCodeIdentifier ("i"));
-
-               var cfreecall = new CCodeFunctionCall (new CCodeIdentifier ("destroy_func"));
-               cfreecall.add_argument (cea);
-
-               CCodeExpression cforcond;
-
-               if (have_length) {
-                       var cfreecond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant ("NULL"));
-                       cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("array_length"));
-                       cbody.add_statement (new CCodeIfStatement (cfreecond, new CCodeExpressionStatement (cfreecall)));
-               } else {
-                       cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant ("NULL"));
-                       cbody.add_statement (new CCodeExpressionStatement (cfreecall));
-               }
-
-               var cfor = new CCodeForStatement (cforcond, cbody);
-               cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
-               cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("i"), new CCodeConstant ("1"))));
-
-               return cfor;
-       }
-
-       private void append_vala_array_free () {
-               var fun = new CCodeFunction ("_vala_array_free", "void");
-               fun.modifiers = CCodeModifiers.STATIC;
-               fun.add_parameter (new CCodeFormalParameter ("array", "gpointer"));
-               fun.add_parameter (new CCodeFormalParameter ("array_length", "gint"));
-               fun.add_parameter (new CCodeFormalParameter ("destroy_func", "GDestroyNotify"));
-               source_type_member_declaration.append (fun.copy ());
-
-               var cdofree = new CCodeBlock ();
-
-               var citdecl = new CCodeDeclaration ("int");
-               citdecl.add_declarator (new CCodeVariableDeclarator ("i"));
-               cdofree.add_statement (citdecl);
-
-               var clencheck = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN_OR_EQUAL, new CCodeIdentifier ("array_length"), new CCodeConstant ("0"));
-               var ciflen = new CCodeIfStatement (clencheck, get_vala_array_free_loop (true), get_vala_array_free_loop (false));
-               cdofree.add_statement (ciflen);
-
-               var ccondarr = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("array"), new CCodeConstant ("NULL"));
-               var ccondfunc = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("destroy_func"), new CCodeConstant ("NULL"));
-               var cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccondarr, ccondfunc), cdofree);
-               fun.block = new CCodeBlock ();
-               fun.block.add_statement (cif);
-
-               var carrfree = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
-               carrfree.add_argument (new CCodeIdentifier ("array"));
-               fun.block.add_statement (new CCodeExpressionStatement (carrfree));
-
-               source_type_member_definition.append (fun);
-       }
-
-       private void append_vala_array_move () {
-               string_h_needed = true;
-
-               // assumes that overwritten array elements are null before invocation
-               // FIXME will leak memory if that's not the case
-               var fun = new CCodeFunction ("_vala_array_move", "void");
-               fun.modifiers = CCodeModifiers.STATIC;
-               fun.add_parameter (new CCodeFormalParameter ("array", "gpointer"));
-               fun.add_parameter (new CCodeFormalParameter ("element_size", "gsize"));
-               fun.add_parameter (new CCodeFormalParameter ("src", "gint"));
-               fun.add_parameter (new CCodeFormalParameter ("dest", "gint"));
-               fun.add_parameter (new CCodeFormalParameter ("length", "gint"));
-               source_type_member_declaration.append (fun.copy ());
-
-               var array = new CCodeCastExpression (new CCodeIdentifier ("array"), "char*");
-               var element_size = new CCodeIdentifier ("element_size");
-               var length = new CCodeIdentifier ("length");
-               var src = new CCodeIdentifier ("src");
-               var dest = new CCodeIdentifier ("dest");
-               var src_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, src, element_size));
-               var dest_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, dest, element_size));
-               var dest_end_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dest, length)), element_size));
-
-               fun.block = new CCodeBlock ();
-
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_memmove"));
-               ccall.add_argument (dest_address);
-               ccall.add_argument (src_address);
-               ccall.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, length, element_size));
-               fun.block.add_statement (new CCodeExpressionStatement (ccall));
-
-               var czero1 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
-               czero1.add_argument (src_address);
-               czero1.add_argument (new CCodeConstant ("0"));
-               czero1.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, dest, src)), element_size));
-               var czeroblock1 = new CCodeBlock ();
-               czeroblock1.add_statement (new CCodeExpressionStatement (czero1));
-
-               var czero2 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
-               czero2.add_argument (dest_end_address);
-               czero2.add_argument (new CCodeConstant ("0"));
-               czero2.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, src, dest)), element_size));
-               var czeroblock2 = new CCodeBlock ();
-               czeroblock2.add_statement (new CCodeExpressionStatement (czero2));
-
-               fun.block.add_statement (new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest), czeroblock1, czeroblock2));
-
-               source_type_member_definition.append (fun);
-       }
-
-       private void append_vala_strcmp0 () {
-               var fun = new CCodeFunction ("_vala_strcmp0", "int");
-               fun.modifiers = CCodeModifiers.STATIC;
-               fun.add_parameter (new CCodeFormalParameter ("str1", "const char *"));
-               fun.add_parameter (new CCodeFormalParameter ("str2", "const char *"));
-               source_type_member_declaration.append (fun.copy ());
-
-               // (str1 != str2)
-               var cineq = new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("str1"), new CCodeIdentifier ("str2")));
-
-               fun.block = new CCodeBlock ();
-
-               var cblock = new CCodeBlock ();
-               // if (str1 == NULL)
-               var cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("str1"), new CCodeConstant ("NULL")), cblock);
-               // return -(str1 != str2);
-               cblock.add_statement (new CCodeReturnStatement (new CCodeUnaryExpression (CCodeUnaryOperator.MINUS, cineq)));
-               fun.block.add_statement (cif);
-
-               cblock = new CCodeBlock ();
-               // if (str2 == NULL)
-               cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("str2"), new CCodeConstant ("NULL")), cblock);
-               // return (str1 != str2);
-               cblock.add_statement (new CCodeReturnStatement (cineq));
-               fun.block.add_statement (cif);
-
-               // strcmp (str1, str2)
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
-               ccall.add_argument (new CCodeIdentifier ("str1"));
-               ccall.add_argument (new CCodeIdentifier ("str2"));
-               // return strcmp (str1, str2);
-               fun.block.add_statement (new CCodeReturnStatement (ccall));
-
-               source_type_member_definition.append (fun);
-       }
-
-       public override void visit_source_file (SourceFile source_file) {
-               header_begin = new CCodeFragment ();
-               header_type_declaration = new CCodeFragment ();
-               header_type_definition = new CCodeFragment ();
-               header_type_member_declaration = new CCodeFragment ();
-               header_constant_declaration = new CCodeFragment ();
-               source_begin = new CCodeFragment ();
-               source_include_directives = new CCodeFragment ();
-               source_type_declaration = new CCodeFragment ();
-               source_type_definition = new CCodeFragment ();
-               source_type_member_declaration = new CCodeFragment ();
-               source_constant_declaration = new CCodeFragment ();
-               source_type_member_definition = new CCodeFragment ();
-               source_signal_marshaller_definition = new CCodeFragment ();
-               source_signal_marshaller_declaration = new CCodeFragment ();
-               
-               user_marshal_set = new HashSet<string> (str_hash, str_equal);
-               
-               next_temp_var_id = 0;
-               
-               string_h_needed = false;
-               gvaluecollector_h_needed = false;
-               dbus_glib_h_needed = false;
-               requires_free_checked = false;
-               requires_array_free = false;
-               requires_array_move = false;
-               requires_strcmp0 = false;
-
-               wrappers = new HashSet<string> (str_hash, str_equal);
-
-               header_begin.append (new CCodeIncludeDirective ("glib.h"));
-               header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
-               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_cinclude_filename ());
-               
-               foreach (string filename in source_file.get_header_external_includes ()) {
-                       if (!used_includes.contains (filename)) {
-                               header_begin.append (new CCodeIncludeDirective (filename));
-                               used_includes.add (filename);
-                       }
-               }
-               foreach (string filename in source_file.get_header_internal_includes ()) {
-                       if (!used_includes.contains (filename)) {
-                               header_begin.append (get_internal_include (filename));
-                               used_includes.add (filename);
-                       }
-               }
-               foreach (string filename in source_file.get_source_external_includes ()) {
-                       if (!used_includes.contains (filename)) {
-                               source_include_directives.append (new CCodeIncludeDirective (filename));
-                               used_includes.add (filename);
-                       }
-               }
-               foreach (string filename in source_file.get_source_internal_includes ()) {
-                       if (!used_includes.contains (filename)) {
-                               source_include_directives.append (get_internal_include (filename));
-                               used_includes.add (filename);
-                       }
-               }
-               foreach (Symbol symbol in source_file.get_source_symbol_dependencies ()) {
-                       if (!symbol.external && symbol.external_package) {
-                               symbol.accept (this);
-                       }
-               }
-               if (source_file.is_cycle_head) {
-                       foreach (SourceFile cycle_file in source_file.cycle.files) {
-                               foreach (CodeNode node in cycle_file.get_nodes ()) {
-                                       if (node is Struct) {
-                                               var st = (Struct) node;
-                                               header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
-                                       } else if (node is Class) {
-                                               var cl = (Class) node;
-                                               if (!cl.is_static) {
-                                                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
-                                                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
-                                               }
-                                       } else if (node is Interface) {
-                                               var iface = (Interface) node;
-                                               if (!iface.is_static) {
-                                                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
-                                                       header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_type_cname ()), new CCodeVariableDeclarator (iface.get_type_cname ())));
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               source_file.accept_children (this);
-
-               if (Report.get_errors () > 0) {
-                       return;
-               }
-
-               var header_define = get_define_for_filename (source_file.get_cinclude_filename ());
-               
-               /* generate hardcoded "well-known" macros */
-               if (requires_free_checked) {
-                       source_begin.append (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
-               }
-               if (requires_array_free) {
-                       append_vala_array_free ();
-               }
-               if (requires_array_move) {
-                       append_vala_array_move ();
-               }
-               if (requires_strcmp0) {
-                       append_vala_strcmp0 ();
-               }
-               
-               if (string_h_needed) {
-                       source_include_directives.append (new CCodeIncludeDirective ("string.h"));
-               }
-
-               if (gvaluecollector_h_needed) {
-                       source_include_directives.append (new CCodeIncludeDirective ("gobject/gvaluecollector.h"));
-               }
-
-               if (dbus_glib_h_needed) {
-                       source_include_directives.append (new CCodeIncludeDirective ("dbus/dbus-glib.h"));
-               }
-
-               CCodeComment comment = null;
-               if (source_file.comment != null) {
-                       comment = new CCodeComment (source_file.comment);
-               }
-
-               var writer = new CCodeWriter (source_file.get_cheader_filename ());
-               if (!writer.open ()) {
-                       Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
-                       return;
-               }
-               if (comment != null) {
-                       comment.write (writer);
-               }
-               writer.write_newline ();
-               var once = new CCodeOnceSection (header_define);
-               once.append (new CCodeNewline ());
-               once.append (header_begin);
-               once.append (new CCodeNewline ());
-               once.append (new CCodeIdentifier ("G_BEGIN_DECLS"));
-               once.append (new CCodeNewline ());
-               once.append (new CCodeNewline ());
-               once.append (header_type_declaration);
-               once.append (new CCodeNewline ());
-               once.append (header_type_definition);
-               once.append (new CCodeNewline ());
-               once.append (header_type_member_declaration);
-               once.append (new CCodeNewline ());
-               once.append (header_constant_declaration);
-               once.append (new CCodeNewline ());
-               once.append (new CCodeIdentifier ("G_END_DECLS"));
-               once.append (new CCodeNewline ());
-               once.append (new CCodeNewline ());
-               once.write (writer);
-               writer.close ();
-               
-               writer = new CCodeWriter (source_file.get_csource_filename ());
-               if (!writer.open ()) {
-                       Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
-                       return;
-               }
-               writer.line_directives = context.debug;
-               if (comment != null) {
-                       comment.write (writer);
-               }
-               source_begin.write (writer);
-               writer.write_newline ();
-               source_include_directives.write (writer);
-               writer.write_newline ();
-               source_type_declaration.write_combined (writer);
-               writer.write_newline ();
-               source_type_definition.write_combined (writer);
-               writer.write_newline ();
-               source_type_member_declaration.write_declaration (writer);
-               writer.write_newline ();
-               source_type_member_declaration.write (writer);
-               writer.write_newline ();
-               source_constant_declaration.write (writer);
-               writer.write_newline ();
-               source_signal_marshaller_declaration.write_declaration (writer);
-               source_signal_marshaller_declaration.write (writer);
-               writer.write_newline ();
-               source_type_member_definition.write (writer);
-               writer.write_newline ();
-               source_signal_marshaller_definition.write (writer);
-               writer.write_newline ();
-               writer.close ();
-
-               header_begin = null;
-               header_type_declaration = null;
-               header_type_definition = null;
-               header_type_member_declaration = null;
-               header_constant_declaration = null;
-               source_begin = null;
-               source_include_directives = null;
-               source_type_declaration = null;
-               source_type_definition = null;
-               source_type_member_declaration = null;
-               source_constant_declaration = null;
-               source_type_member_definition = null;
-               source_signal_marshaller_definition = null;
-               source_signal_marshaller_declaration = null;
-       }
-       
-       private static string get_define_for_filename (string filename) {
-               var define = new StringBuilder ("__");
-               
-               var i = filename;
-               while (i.len () > 0) {
-                       var c = i.get_char ();
-                       if (c.isalnum  () && c < 0x80) {
-                               define.append_unichar (c.toupper ());
-                       } else {
-                               define.append_c ('_');
-                       }
-               
-                       i = i.next_char ();
-               }
-               
-               define.append ("__");
-               
-               return define.str;
-       }
-}
index 613b64d281c120c64e6307ceaebdecc06c8161b6..8bd8c1bf68f4d21f7e85bcf5489277edbe527817 100644 (file)
@@ -52,6 +52,10 @@ public abstract class Vala.CCodeModule {
                next.emit (context);
        }
 
+       public virtual void visit_source_file (SourceFile source_file) {
+               next.visit_source_file (source_file);
+       }
+
        public virtual void visit_class (Class cl) {
                next.visit_class (cl);
        }