/* valaccodefile.vala * * Copyright (C) 2009-2011 Jürg Billeter * * 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 */ public class Vala.CCodeFile { public CCodeFileType file_type { get; private set; } public weak SourceFile? file { get; private set; } Set features = new HashSet (str_hash, str_equal); Set declarations = new HashSet (str_hash, str_equal); Set definitions = new HashSet (str_hash, str_equal); Set includes = new HashSet (str_hash, str_equal); CCodeFragment comments = new CCodeFragment (); CCodeFragment feature_test_macros = new CCodeFragment (); CCodeFragment define_directives = new CCodeFragment (); CCodeFragment include_directives = new CCodeFragment (); CCodeFragment type_declaration = new CCodeFragment (); CCodeFragment type_definition = new CCodeFragment (); CCodeFragment type_member_declaration = new CCodeFragment (); CCodeFragment constant_declaration = new CCodeFragment (); CCodeFragment type_member_definition = new CCodeFragment (); public CCodeFile (CCodeFileType type = CCodeFileType.SOURCE, SourceFile? source_file = null) { file = source_file; file_type = type; } public bool add_declaration (string name) { if (name in declarations) { return true; } declarations.add (name); return false; } public void add_comment (CCodeComment comment) { comments.append (comment); } public void add_feature_test_macro (string feature_test_macro) { if (!(feature_test_macro in features)) { feature_test_macros.append (new CCodeDefine (feature_test_macro)); features.add (feature_test_macro); } } public void add_include (string filename, bool local = false) { if (!(filename in includes)) { include_directives.append (new CCodeIncludeDirective (filename, local)); includes.add (filename); } } public void add_define (CCodeNode node) { define_directives.append (node); } public void add_type_declaration (CCodeNode node) { type_declaration.append (node); } public void add_type_definition (CCodeNode node) { type_definition.append (node); } public void add_type_member_declaration (CCodeNode node) { type_member_declaration.append (node); } public void add_constant_declaration (CCodeNode node) { constant_declaration.append (node); } public void add_type_member_definition (CCodeNode node) { type_member_definition.append (node); } public void add_function_declaration (CCodeFunction func) { declarations.add (func.name); var decl = func.copy (); decl.is_declaration = true; type_member_declaration.append (decl); } public void add_function (CCodeFunction func) { if (!definitions.add (func.name)) { Report.error (null, "internal: Redefinition of `%s'", func.name); return; } type_member_definition.append (func); } public List get_symbols () { var symbols = new ArrayList (str_equal); get_symbols_from_fragment (symbols, type_member_declaration); return symbols; } void get_symbols_from_fragment (List symbols, CCodeFragment fragment) { foreach (CCodeNode node in fragment.get_children ()) { if (node is CCodeFragment) { get_symbols_from_fragment (symbols, (CCodeFragment) node); } else { var func = node as CCodeFunction; if (func != null) { symbols.add (func.name); } } } } static string get_define_for_filename (string filename) { var define = new StringBuilder ("__"); var i = filename; while (i.length > 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; } public bool store (string filename, string? source_filename, bool write_version, bool line_directives, string? begin_decls = null, string? end_decls = null) { var writer = new CCodeWriter (filename, source_filename); if (!writer.open (write_version)) { return false; } if (file_type == CCodeFileType.SOURCE) { writer.line_directives = line_directives; comments.write (writer); writer.write_newline (); feature_test_macros.write (writer); writer.write_newline (); include_directives.write (writer); writer.write_newline (); define_directives.write (writer); writer.write_newline (); type_declaration.write_combined (writer); writer.write_newline (); type_definition.write_combined (writer); writer.write_newline (); type_member_declaration.write_declaration (writer); writer.write_newline (); type_member_declaration.write (writer); writer.write_newline (); constant_declaration.write_combined (writer); writer.write_newline (); type_member_definition.write (writer); writer.write_newline (); } else { writer.write_newline (); var once = new CCodeOnceSection (get_define_for_filename (writer.filename)); once.append (new CCodeNewline ()); once.append (include_directives); once.append (new CCodeNewline ()); if (begin_decls != null) { once.append (new CCodeIdentifier (begin_decls)); once.append (new CCodeNewline ()); } once.append (new CCodeNewline ()); once.append (define_directives); once.append (new CCodeNewline ()); once.append (type_declaration); once.append (new CCodeNewline ()); once.append (type_definition); once.append (new CCodeNewline ()); once.append (type_member_declaration); once.append (new CCodeNewline ()); once.append (constant_declaration); once.append (new CCodeNewline ()); if (end_decls != null) { once.append (new CCodeIdentifier (end_decls)); once.append (new CCodeNewline ()); } once.append (new CCodeNewline ()); once.write (writer); } writer.close (); return true; } } [Flags] public enum CCodeFileType { SOURCE, PUBLIC_HEADER, INTERNAL_HEADER, HEADER = PUBLIC_HEADER | INTERNAL_HEADER }