codegen: Fix floating reference regression with Variants
[vala-gnome.git] / ccode / valaccodefile.vala
blobaa5be219e13a7beeaca84b6d455dc9c6eb3d6634
1 /* valaccodefile.vala
3 * Copyright (C) 2009-2011 Jürg Billeter
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.1 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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
24 public class Vala.CCodeFile {
25 public bool is_header { get; set; }
27 Set<string> features = new HashSet<string> (str_hash, str_equal);
28 Set<string> declarations = new HashSet<string> (str_hash, str_equal);
29 Set<string> includes = new HashSet<string> (str_hash, str_equal);
30 CCodeFragment comments = new CCodeFragment ();
31 CCodeFragment feature_test_macros = new CCodeFragment ();
32 CCodeFragment include_directives = new CCodeFragment ();
33 CCodeFragment type_declaration = new CCodeFragment ();
34 CCodeFragment type_definition = new CCodeFragment ();
35 CCodeFragment type_member_declaration = new CCodeFragment ();
36 CCodeFragment constant_declaration = new CCodeFragment ();
37 CCodeFragment type_member_definition = new CCodeFragment ();
39 public bool add_declaration (string name) {
40 if (name in declarations) {
41 return true;
43 declarations.add (name);
44 return false;
47 public void add_comment (CCodeComment comment) {
48 comments.append (comment);
51 public void add_feature_test_macro (string feature_test_macro) {
52 if (!(feature_test_macro in features)) {
53 feature_test_macros.append (new CCodeFeatureTestMacro (feature_test_macro));
54 features.add (feature_test_macro);
58 public void add_include (string filename, bool local = false) {
59 if (!(filename in includes)) {
60 include_directives.append (new CCodeIncludeDirective (filename, local));
61 includes.add (filename);
65 public void add_type_declaration (CCodeNode node) {
66 type_declaration.append (node);
69 public void add_type_definition (CCodeNode node) {
70 type_definition.append (node);
73 public void add_type_member_declaration (CCodeNode node) {
74 type_member_declaration.append (node);
77 public void add_constant_declaration (CCodeNode node) {
78 constant_declaration.append (node);
81 public void add_type_member_definition (CCodeNode node) {
82 type_member_definition.append (node);
85 public void add_function_declaration (CCodeFunction func) {
86 var decl = func.copy ();
87 decl.is_declaration = true;
88 type_member_declaration.append (decl);
91 public void add_function (CCodeFunction func) {
92 type_member_definition.append (func);
95 public List<string> get_symbols () {
96 var symbols = new ArrayList<string> ();
97 get_symbols_from_fragment (symbols, type_member_declaration);
98 return symbols;
101 void get_symbols_from_fragment (List<string> symbols, CCodeFragment fragment) {
102 foreach (CCodeNode node in fragment.get_children ()) {
103 if (node is CCodeFragment) {
104 get_symbols_from_fragment (symbols, (CCodeFragment) node);
105 } else {
106 var func = node as CCodeFunction;
107 if (func != null) {
108 symbols.add (func.name);
114 static string get_define_for_filename (string filename) {
115 var define = new StringBuilder ("__");
117 var i = filename;
118 while (i.length > 0) {
119 var c = i.get_char ();
120 if (c.isalnum () && c < 0x80) {
121 define.append_unichar (c.toupper ());
122 } else {
123 define.append_c ('_');
126 i = i.next_char ();
129 define.append ("__");
131 return define.str;
134 public bool store (string filename, string? source_filename, bool write_version, bool line_directives, string? begin_decls = null, string? end_decls = null) {
135 var writer = new CCodeWriter (filename, source_filename);
136 if (!writer.open (write_version)) {
137 return false;
140 if (!is_header) {
141 writer.line_directives = line_directives;
143 comments.write (writer);
144 writer.write_newline ();
145 feature_test_macros.write (writer);
146 writer.write_newline ();
147 include_directives.write (writer);
148 writer.write_newline ();
149 type_declaration.write_combined (writer);
150 writer.write_newline ();
151 type_definition.write_combined (writer);
152 writer.write_newline ();
153 type_member_declaration.write_declaration (writer);
154 writer.write_newline ();
155 type_member_declaration.write (writer);
156 writer.write_newline ();
157 constant_declaration.write_combined (writer);
158 writer.write_newline ();
159 type_member_definition.write (writer);
160 writer.write_newline ();
161 } else {
162 writer.write_newline ();
164 var once = new CCodeOnceSection (get_define_for_filename (writer.filename));
165 once.append (new CCodeNewline ());
166 once.append (include_directives);
167 once.append (new CCodeNewline ());
169 if (begin_decls != null) {
170 once.append (new CCodeIdentifier (begin_decls));
171 once.append (new CCodeNewline ());
174 once.append (new CCodeNewline ());
175 once.append (type_declaration);
176 once.append (new CCodeNewline ());
177 once.append (type_definition);
178 once.append (new CCodeNewline ());
179 once.append (type_member_declaration);
180 once.append (new CCodeNewline ());
181 once.append (constant_declaration);
182 once.append (new CCodeNewline ());
184 if (begin_decls != null) {
185 once.append (new CCodeIdentifier (end_decls));
186 once.append (new CCodeNewline ());
189 once.append (new CCodeNewline ());
190 once.write (writer);
193 writer.close ();
195 return true;