Line data Source code
1 : /* valaccodefile.vala
2 : *
3 : * Copyright (C) 2009-2011 Jürg Billeter
4 : *
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.
9 :
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.
14 :
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
18 : *
19 : * Author:
20 : * Jürg Billeter <j@bitron.ch>
21 : */
22 :
23 :
24 9795 : public class Vala.CCodeFile {
25 60500 : public CCodeFileType file_type { get; private set; }
26 :
27 2797 : public weak SourceFile? file { get; private set; }
28 :
29 5592 : Set<string> features = new HashSet<string> (str_hash, str_equal);
30 5592 : Set<string> declarations = new HashSet<string> (str_hash, str_equal);
31 5592 : Set<string> definitions = new HashSet<string> (str_hash, str_equal);
32 5592 : Set<string> includes = new HashSet<string> (str_hash, str_equal);
33 5592 : CCodeFragment comments = new CCodeFragment ();
34 5592 : CCodeFragment feature_test_macros = new CCodeFragment ();
35 5592 : CCodeFragment define_directives = new CCodeFragment ();
36 5592 : CCodeFragment include_directives = new CCodeFragment ();
37 5592 : CCodeFragment type_declaration = new CCodeFragment ();
38 5592 : CCodeFragment type_definition = new CCodeFragment ();
39 5592 : CCodeFragment type_member_declaration = new CCodeFragment ();
40 5592 : CCodeFragment constant_declaration = new CCodeFragment ();
41 5592 : CCodeFragment type_member_definition = new CCodeFragment ();
42 :
43 5592 : public CCodeFile (CCodeFileType type = CCodeFileType.SOURCE, SourceFile? source_file = null) {
44 2796 : file = source_file;
45 2796 : file_type = type;
46 : }
47 :
48 172209 : public bool add_declaration (string name) {
49 172209 : if (name in declarations) {
50 172209 : return true;
51 : }
52 32862 : declarations.add (name);
53 32862 : return false;
54 : }
55 :
56 155 : public void add_comment (CCodeComment comment) {
57 155 : comments.append (comment);
58 : }
59 :
60 1 : public void add_feature_test_macro (string feature_test_macro) {
61 1 : if (!(feature_test_macro in features)) {
62 1 : feature_test_macros.append (new CCodeDefine (feature_test_macro));
63 1 : features.add (feature_test_macro);
64 : }
65 : }
66 :
67 43265 : public void add_include (string filename, bool local = false) {
68 43265 : if (!(filename in includes)) {
69 6169 : include_directives.append (new CCodeIncludeDirective (filename, local));
70 6169 : includes.add (filename);
71 : }
72 : }
73 :
74 2512 : public void add_define (CCodeNode node) {
75 2512 : define_directives.append (node);
76 : }
77 :
78 26191 : public void add_type_declaration (CCodeNode node) {
79 26191 : type_declaration.append (node);
80 : }
81 :
82 4692 : public void add_type_definition (CCodeNode node) {
83 4692 : type_definition.append (node);
84 : }
85 :
86 8823 : public void add_type_member_declaration (CCodeNode node) {
87 8823 : type_member_declaration.append (node);
88 : }
89 :
90 825 : public void add_constant_declaration (CCodeNode node) {
91 825 : constant_declaration.append (node);
92 : }
93 :
94 1527 : public void add_type_member_definition (CCodeNode node) {
95 1527 : type_member_definition.append (node);
96 : }
97 :
98 39960 : public void add_function_declaration (CCodeFunction func) {
99 19980 : declarations.add (func.name);
100 :
101 19980 : var decl = func.copy ();
102 19980 : decl.is_declaration = true;
103 19980 : type_member_declaration.append (decl);
104 : }
105 :
106 17215 : public void add_function (CCodeFunction func) {
107 17215 : if (!definitions.add (func.name)) {
108 0 : Report.error (null, "internal: Redefinition of `%s'", func.name);
109 0 : return;
110 : }
111 :
112 17215 : type_member_definition.append (func);
113 : }
114 :
115 0 : public List<string> get_symbols () {
116 0 : var symbols = new ArrayList<string> (str_equal);
117 0 : get_symbols_from_fragment (symbols, type_member_declaration);
118 0 : return symbols;
119 : }
120 :
121 0 : void get_symbols_from_fragment (List<string> symbols, CCodeFragment fragment) {
122 0 : foreach (CCodeNode node in fragment.get_children ()) {
123 0 : if (node is CCodeFragment) {
124 0 : get_symbols_from_fragment (symbols, (CCodeFragment) node);
125 : } else {
126 0 : var func = node as CCodeFunction;
127 0 : if (func != null) {
128 0 : symbols.add (func.name);
129 : }
130 : }
131 : }
132 : }
133 :
134 4 : static string get_define_for_filename (string filename) {
135 4 : var define = new StringBuilder ("__");
136 :
137 4 : var i = filename;
138 31 : while (i.length > 0) {
139 27 : var c = i.get_char ();
140 27 : if (c.isalnum () && c < 0x80) {
141 23 : define.append_unichar (c.toupper ());
142 : } else {
143 4 : define.append_c ('_');
144 : }
145 :
146 54 : i = i.next_char ();
147 : }
148 :
149 4 : define.append ("__");
150 :
151 8 : return define.str;
152 : }
153 :
154 991 : public bool store (string filename, string? source_filename, bool write_version, bool line_directives, string? begin_decls = null, string? end_decls = null) {
155 991 : var writer = new CCodeWriter (filename, source_filename);
156 991 : if (!writer.open (write_version)) {
157 0 : return false;
158 : }
159 :
160 995 : if (file_type == CCodeFileType.SOURCE) {
161 987 : writer.line_directives = line_directives;
162 :
163 987 : comments.write (writer);
164 987 : writer.write_newline ();
165 987 : feature_test_macros.write (writer);
166 987 : writer.write_newline ();
167 987 : include_directives.write (writer);
168 987 : writer.write_newline ();
169 987 : define_directives.write (writer);
170 987 : writer.write_newline ();
171 987 : type_declaration.write_combined (writer);
172 987 : writer.write_newline ();
173 987 : type_definition.write_combined (writer);
174 987 : writer.write_newline ();
175 987 : type_member_declaration.write_declaration (writer);
176 987 : writer.write_newline ();
177 987 : type_member_declaration.write (writer);
178 987 : writer.write_newline ();
179 987 : constant_declaration.write_combined (writer);
180 987 : writer.write_newline ();
181 987 : type_member_definition.write (writer);
182 987 : writer.write_newline ();
183 : } else {
184 4 : writer.write_newline ();
185 :
186 4 : var once = new CCodeOnceSection (get_define_for_filename (writer.filename));
187 4 : once.append (new CCodeNewline ());
188 4 : once.append (include_directives);
189 4 : once.append (new CCodeNewline ());
190 :
191 4 : if (begin_decls != null) {
192 4 : once.append (new CCodeIdentifier (begin_decls));
193 4 : once.append (new CCodeNewline ());
194 : }
195 :
196 4 : once.append (new CCodeNewline ());
197 4 : once.append (define_directives);
198 4 : once.append (new CCodeNewline ());
199 4 : once.append (type_declaration);
200 4 : once.append (new CCodeNewline ());
201 4 : once.append (type_definition);
202 4 : once.append (new CCodeNewline ());
203 4 : once.append (type_member_declaration);
204 4 : once.append (new CCodeNewline ());
205 4 : once.append (constant_declaration);
206 4 : once.append (new CCodeNewline ());
207 :
208 4 : if (end_decls != null) {
209 4 : once.append (new CCodeIdentifier (end_decls));
210 4 : once.append (new CCodeNewline ());
211 : }
212 :
213 4 : once.append (new CCodeNewline ());
214 4 : once.write (writer);
215 : }
216 :
217 991 : writer.close ();
218 :
219 991 : return true;
220 : }
221 : }
222 :
223 : [Flags]
224 : public enum CCodeFileType {
225 : SOURCE,
226 : PUBLIC_HEADER,
227 : INTERNAL_HEADER,
228 : HEADER = PUBLIC_HEADER | INTERNAL_HEADER
229 : }
|