1 /* valacodegeneratorsourcefile.vala
3 * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <rasa@gmx.ch>
26 public class Vala
.CodeGenerator
{
27 private CCodeIncludeDirective
get_internal_include (string! filename
) {
28 return new
CCodeIncludeDirective (filename
, context
.library
== null);
31 public override void visit_source_file (SourceFile
! source_file
) {
32 header_begin
= new
CCodeFragment ();
33 header_type_declaration
= new
CCodeFragment ();
34 header_type_definition
= new
CCodeFragment ();
35 header_type_member_declaration
= new
CCodeFragment ();
36 source_begin
= new
CCodeFragment ();
37 source_include_directives
= new
CCodeFragment ();
38 source_type_member_declaration
= new
CCodeFragment ();
39 source_type_member_definition
= new
CCodeFragment ();
40 source_signal_marshaller_definition
= new
CCodeFragment ();
41 source_signal_marshaller_declaration
= new
CCodeFragment ();
43 user_marshal_list
= new
HashTable (str_hash
, str_equal
);
47 string_h_needed
= false;
49 header_begin
.append (new
CCodeIncludeDirective ("glib.h"));
50 header_begin
.append (new
CCodeIncludeDirective ("glib-object.h"));
51 source_include_directives
.append (new
CCodeIncludeDirective (source_file
.get_cheader_filename (), true));
53 List
<weak string> used_includes
= null;
54 used_includes
.append ("glib.h");
55 used_includes
.append ("glib-object.h");
56 used_includes
.append (source_file
.get_cheader_filename ());
58 foreach (string filename1
in source_file
.get_header_external_includes ()) {
59 if (used_includes
.find_custom (filename1
, strcmp
) == null) {
60 header_begin
.append (new
CCodeIncludeDirective (filename1
));
61 used_includes
.append (filename1
);
64 foreach (string filename2
in source_file
.get_header_internal_includes ()) {
65 if (used_includes
.find_custom (filename2
, strcmp
) == null) {
66 header_begin
.append (get_internal_include (filename2
));
67 used_includes
.append (filename2
);
70 foreach (string filename3
in source_file
.get_source_external_includes ()) {
71 if (used_includes
.find_custom (filename3
, strcmp
) == null) {
72 source_include_directives
.append (new
CCodeIncludeDirective (filename3
));
73 used_includes
.append (filename3
);
76 foreach (string filename4
in source_file
.get_source_internal_includes ()) {
77 if (used_includes
.find_custom (filename4
, strcmp
) == null) {
78 source_include_directives
.append (get_internal_include (filename4
));
79 used_includes
.append (filename4
);
82 if (source_file
.is_cycle_head
) {
83 foreach (SourceFile cycle_file
in source_file
.cycle
.files
) {
84 var namespaces
= cycle_file
.get_namespaces ();
85 foreach (Namespace ns
in namespaces
) {
86 var structs
= ns
.get_structs ();
87 foreach (Struct st
in structs
) {
88 header_type_declaration
.append (new
CCodeTypeDefinition ("struct _%s".printf (st
.get_cname ()), new
CCodeVariableDeclarator (st
.get_cname ())));
90 var classes
= ns
.get_classes ();
91 foreach (Class cl
in classes
) {
92 header_type_declaration
.append (new
CCodeTypeDefinition ("struct _%s".printf (cl
.get_cname ()), new
CCodeVariableDeclarator (cl
.get_cname ())));
93 header_type_declaration
.append (new
CCodeTypeDefinition ("struct _%sClass".printf (cl
.get_cname ()), new
CCodeVariableDeclarator ("%sClass".printf (cl
.get_cname ()))));
95 var ifaces
= ns
.get_interfaces ();
96 foreach (Interface iface
in ifaces
) {
97 header_type_declaration
.append (new
CCodeTypeDefinition ("struct _%s".printf (iface
.get_cname ()), new
CCodeVariableDeclarator (iface
.get_cname ())));
98 header_type_declaration
.append (new
CCodeTypeDefinition ("struct _%s".printf (iface
.get_type_cname ()), new
CCodeVariableDeclarator (iface
.get_type_cname ())));
104 /* generate hardcoded "well-known" macros */
105 source_begin
.append (new
CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
106 source_begin
.append (new
CCodeMacroReplacement ("VALA_FREE_UNCHECKED(o,f)", "((o) = (f (o), NULL))"));
108 source_file
.accept_children (this
);
110 var header_define
= get_define_for_filename (source_file
.get_cheader_filename ());
112 if (string_h_needed
) {
113 source_include_directives
.append (new
CCodeIncludeDirective ("string.h"));
116 CCodeComment comment
= null;
117 if (source_file
.comment
!= null) {
118 comment
= new
CCodeComment (source_file
.comment
);
121 var writer
= new
CCodeWriter (source_file
.get_cheader_filename ());
122 if (comment
!= null) {
123 comment
.write (writer
);
125 writer
.write_newline ();
126 var once
= new
CCodeOnceSection (header_define
);
127 once
.append (new
CCodeNewline ());
128 once
.append (header_begin
);
129 once
.append (new
CCodeNewline ());
130 once
.append (new
CCodeIdentifier ("G_BEGIN_DECLS"));
131 once
.append (new
CCodeNewline ());
132 once
.append (new
CCodeNewline ());
133 once
.append (header_type_declaration
);
134 once
.append (new
CCodeNewline ());
135 once
.append (header_type_definition
);
136 once
.append (new
CCodeNewline ());
137 once
.append (header_type_member_declaration
);
138 once
.append (new
CCodeNewline ());
139 once
.append (new
CCodeIdentifier ("G_END_DECLS"));
140 once
.append (new
CCodeNewline ());
141 once
.append (new
CCodeNewline ());
142 once
.write_declaration (writer
);
146 writer
= new
CCodeWriter (source_file
.get_csource_filename ());
147 if (comment
!= null) {
148 comment
.write (writer
);
150 source_begin
.write (writer
);
151 writer
.write_newline ();
152 source_include_directives
.write (writer
);
153 writer
.write_newline ();
154 source_type_member_declaration
.write_declaration (writer
);
155 source_type_member_declaration
.write (writer
);
156 writer
.write_newline ();
157 source_signal_marshaller_declaration
.write_declaration (writer
);
158 source_signal_marshaller_declaration
.write (writer
);
159 writer
.write_newline ();
160 source_type_member_definition
.write (writer
);
161 writer
.write_newline ();
162 source_signal_marshaller_definition
.write (writer
);
163 writer
.write_newline ();
167 header_type_declaration
= null;
168 header_type_definition
= null;
169 header_type_member_declaration
= null;
171 source_include_directives
= null;
172 source_type_member_declaration
= null;
173 source_type_member_definition
= null;
174 source_signal_marshaller_definition
= null;
175 source_signal_marshaller_declaration
= null;
178 private static string get_define_for_filename (string! filename
) {
179 var define
= new
String ("__");
182 while (i
.len () > 0) {
183 var c
= i
.get_char ();
184 if (c
.isalnum () && c
< 0x80) {
185 define
.append_unichar (c
.toupper ());
187 define
.append_c ('_');
193 define
.append ("__");