// // aegis - project change supervisor // Copyright (C) 2008, 2011, 2012 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or (at // your option) any later version. // // This program 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 // General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // #include #include #include #include type_structure_introspector_code::~type_structure_introspector_code() { trace(("%s\n", __PRETTY_FUNCTION__)); } type_structure_introspector_code::type_structure_introspector_code( generator *a_gen, const nstring &a_name, bool a_global) : type_structure(a_gen, a_name, a_global) { trace(("%s\n", __PRETTY_FUNCTION__)); } type::pointer type_structure_introspector_code::create(generator *a_gen, const nstring &a_name, bool a_global) { trace(("%s\n", __PRETTY_FUNCTION__)); return pointer(new type_structure_introspector_code(a_gen, a_name, a_global)); } void type_structure_introspector_code::gen_body() const { trace(("%s\n", __PRETTY_FUNCTION__)); if (is_in_include_file()) return; include_once("common/ac/assert.h"); include_once("common/trace.h"); // // the destructor // printf("\n"); printf("%s::~%s()\n", def_name().c_str(), def_name().c_str()); printf("{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("}\n"); // // the default constructor // printf("\n"); printf("%s::%s()", def_name().c_str(), def_name().c_str()); indent_more(); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; printf("%s\n", (j ? "," : " :")); ep->etype->gen_default_constructor(ep->name); } indent_less(); printf("\n{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("}\n"); // // default create // printf("\n"); printf("%s::pointer\n", def_name().c_str()); printf("%s::create()\n", def_name().c_str()); printf("{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("return pointer(new %s());\n", def_name().c_str()); printf("}\n"); // // the copy constructor // printf("\n"); printf ( "%s::%s(const %s &", def_name().c_str(), def_name().c_str(), def_name().c_str() ); if (nelements > 0) printf("rhs"); printf(")"); indent_more(); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; printf("%s\n", (j ? "," : " :")); ep->etype->gen_copy_constructor(ep->name); } indent_less(); printf("\n{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("}\n"); // // copy create // printf("\n"); printf("%s::pointer\n", def_name().c_str()); printf ( "%s::create(const %s &rhs)\n", def_name().c_str(), def_name().c_str() ); printf("{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("return pointer(new %s(rhs));\n", def_name().c_str()); printf("}\n"); // // the assignment operator // printf("\n"); printf("%s &\n", def_name().c_str()); printf ( "%s::operator=(const %s &rhs)\n", def_name().c_str(), def_name().c_str() ); printf("{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("if (this != &rhs)\n"); printf("{\n"); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; ep->etype->gen_assignment_operator(ep->name); } printf("}\n"); printf("return *this;\n"); printf("}\n"); // // Generate getters and setters for each of the instance variables. // for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; ep->etype->gen_methods(def_name(), ep->name, ep->attributes); } include_once("libaegis/introspector/structure.h"); printf("\n"); printf("introspector::pointer\n"); printf("%s::introspector_factory()\n", def_name().c_str()); printf("{\n"); printf("trace((\"%%s\\n\", __PRETTY_FUNCTION__));\n"); printf("introspector_structure::pointer ip =\n"); indent_more(); printf("introspector_structure::create(\"%s\");\n", def_name().c_str()); indent_less(); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; nstring text = "ip->register_member ( " + ep->name.quote_c() + ", introspector_structure::adapter_by_method < " + def_name() + " > ::create ( this, &" + def_name() + "::" + ep->name + "_introspector_factory, &" + def_name() + "::" + ep->name + "_is_set));" ; wrap_and_print("", text); } printf("return ip;\n"); printf("};\n"); printf("\n"); printf("void\n"); printf("%s::write(const output::pointer &fp", def_name().c_str()); if (!toplevel_flag) printf(", const nstring &name_"); printf(")\n"); indent_more(); printf("const\n"); indent_less(); printf("{\n"); printf("trace((\"%%s\\n{\\n\", __PRETTY_FUNCTION__));\n"); if (!toplevel_flag) { printf("if (name_)\n"); printf("{\n"); printf("fp->fputs(name_);\n"); printf("fp->fputs(\" =\\n\");\n"); printf("}\n"); printf("fp->fputs(\"{\\n\");\n"); } trace(("nelements = %d\n", int(nelements))); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; trace(("ep->name = %s;\n", ep->name.quote_c().c_str())); bool show_default = false; ep->etype->gen_write(ep->name, ep->name, show_default); } if (!toplevel_flag) { printf("fp->fputs(\"}\");\n"); printf("if (name_)\n"); indent_more(); printf("fp->fputs(\";\\n\");\n"); indent_less(); } else if (!nelements) { // To silence "fp unused" warning printf("(void)fp;\n"); } printf("trace((\"}\\n\"));\n"); printf("}\n"); printf("\n"); printf("void\n"); printf("%s::write_xml(const output::pointer &fp", def_name().c_str()); if (!toplevel_flag) { printf(", const nstring &name_"); } printf(")\n"); indent_more(); printf("const\n"); indent_less(); printf("{\n"); printf("trace((\"%%s\\n{\\n\", __PRETTY_FUNCTION__));\n"); if (toplevel_flag) { printf("fp->fputs(\"<%s>\\n\");\n", def_name().c_str()); } else { printf("assert(!name_.empty());\n"); printf("fp->fputc('<');\n"); printf("fp->fputs(name_);\n"); printf("fp->fputs(\">\\n\");\n"); } for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; ep->etype->gen_call_xml(ep->name, ep->name, ep->attributes); } if (toplevel_flag) { printf("fp->fputs(\"\\n\");\n", def_name().c_str()); } else { printf("fp->fputs(\"fputs(name_);\n"); printf("fp->fputs(\">\\n\");\n"); } printf("trace((\"}\\n\"));\n"); printf("}\n"); printf("\n"); printf("void\n"); printf("%s::trace_print(const char *name_)\n", def_name().c_str()); indent_more(); printf("const\n"); indent_less(); printf("{\n"); printf("if (name_ && *name_)\n"); printf("{\n"); printf("trace_printf(\"%%s = \", name_);\n"); printf("}\n"); printf("trace_printf(\"{\\n\");\n"); for (size_t j = 0; j < nelements; ++j) { element_ty *ep = &element[j]; ep->etype->gen_trace(ep->name, ep->name); } printf("trace_printf(\"}\");\n"); printf("trace_printf((name_ && *name_) ? \";\\n\" : \",\\n\");\n"); printf("}\n"); if (toplevel_flag) { include_once("libaegis/meta_context/introspector.h"); include_once("libaegis/os.h"); printf("\n"); printf("%s::pointer\n", def_name().c_str()); printf ( "%s::create_from_file(const nstring &filename)\n", def_name().c_str() ); printf("{\n"); printf("trace((\"%%s\\n{\\n\", __PRETTY_FUNCTION__));\n"); printf("pointer p = create();\n"); printf("introspector::pointer ip = p->introspector_factory();\n"); printf("meta_context_introspector meta;\n"); printf("os_become_must_be_active();\n"); printf("meta.parse_file(filename, ip);\n"); printf("trace((\"}\\n\"));\n"); printf("return p;\n"); printf("}\n"); include_once("libaegis/io.h"); include_once("libaegis/output/file.h"); include_once("libaegis/output/filter/gzip.h"); include_once("libaegis/output/filter/indent.h"); printf("\n"); printf("void\n"); printf ( "%s::write_file(const nstring &filename, bool needs_compression)\n", def_name().c_str() ); indent_more(); printf("const\n"); indent_less(); printf("{\n"); printf("trace((\"%%s\\n{\\n\", __PRETTY_FUNCTION__));\n"); printf("if (filename)\n"); indent_more(); printf("os_become_must_be_active();\n"); indent_less(); nstring text = "output::pointer fp = (needs_compression ?\n" "output_filter_gzip::create(output_file::binary_open(filename)) :\n" "output_file::text_open(filename));\n" ; wrap_and_print("", text); printf("fp = output_filter_indent::create(fp);\n"); printf("io_comment_emit(fp);\n"); printf("write(fp);\n"); printf("type_enum_option_clear();\n"); printf("trace((\"}\\n\"));\n"); printf("}\n"); printf("\n"); printf("void\n"); printf("%s::report_init(void)\n", def_name().c_str()); printf("{\n"); printf("trace((\"%%s\\n{\\n\", __PRETTY_FUNCTION__));\n"); // // find the list of types we care about. // generate report initialization for them. // type_vector unique_types; get_reachable(unique_types); unique_types.reachable_closure(); unique_types.gen_report_initializations(); printf("trace((\"}\\n\"));\n"); printf("}\n"); } } void type_structure_introspector_code::gen_declarator(const nstring &variable_name, bool, int, const nstring &cmnt) const { trace(("%s\n", __PRETTY_FUNCTION__)); printf("\n"); indent_less(); printf("private:\n"); indent_more(); if (!cmnt.empty()) { printf("/**\n%s\n */\n", cmnt.c_str()); } printf("%s::pointer %s;\n", def_name().c_str(), variable_name.c_str()); printf("\n"); indent_less(); printf("public:\n"); indent_more(); printf("/**\n"); wrap_and_print ( "* ", "The " + variable_name + "_get method is used to obtain\n" "a pointer to the contents of the " + variable_name + "\n" "instance variable. The structure will be create()ed if\n" "necessary.\n" ); printf("*/\n"); printf ( "%s::pointer %s_get();\n", def_name().c_str(), variable_name.c_str() ); printf("\n"); printf("/**\n"); wrap_and_print ( "* ", "The " + variable_name + "_is_set method may be used to\n" "determine whether or not the " + variable_name + " instance\n" "variable presently has any contents.\n" ); printf("*/\n"); printf("bool %s_is_set() const;\n", variable_name.c_str()); printf("\n"); printf("/**\n"); wrap_and_print ( "* ", "The " + variable_name + "_clear method is used to dascard\n" "contents of the " + variable_name + " instance variable.\n" ); printf("*/\n"); printf("void %s_clear();\n", variable_name.c_str()); printf("\n"); printf("/**\n"); wrap_and_print ( "* ", "The " + variable_name + "_introspector_factory method is\n" "used to create a new instrospector for manipulating the\n" "contents of the " + variable_name + " instance variable.\n" "The structure will be create()ed if necessary.\n" ); printf("*/\n"); printf ( "introspector::pointer %s_introspector_factory();\n", variable_name.c_str() ); } void type_structure_introspector_code::gen_call_xml(const nstring &form_name, const nstring &member_name, int) const { trace(("%s\n", __PRETTY_FUNCTION__)); printf ( "if (%s)\n{\n%s->write_xml(fp, \"%s\");\n}\n", member_name.c_str(), member_name.c_str(), form_name.c_str() ); } void type_structure_introspector_code::gen_default_constructor( const nstring &member_name) { trace(("%s\n", __PRETTY_FUNCTION__)); printf("%s()", member_name.c_str()); } void type_structure_introspector_code::gen_copy_constructor( const nstring &member_name) { trace(("%s\n", __PRETTY_FUNCTION__)); printf("%s(rhs.%s)", member_name.c_str(), member_name.c_str()); } void type_structure_introspector_code::gen_assignment_operator( const nstring &member_name) { trace(("%s\n", __PRETTY_FUNCTION__)); printf("%s = rhs.%s;\n", member_name.c_str(), member_name.c_str()); } void type_structure_introspector_code::gen_free_declarator(const nstring &, bool) const { trace(("%s\n", __PRETTY_FUNCTION__)); } void type_structure_introspector_code::gen_trace(const nstring &vname, const nstring &value) const { trace(("%s\n", __PRETTY_FUNCTION__)); printf("if (%s)\n", value.c_str()); printf("{\n"); printf("%s->trace_print(\"*%s\");\n", value.c_str(), vname.c_str()); printf("}\n"); printf("else\n"); printf("{\n"); printf("trace_printf(\"%s = NULL\");\n", vname.c_str()); printf("}\n"); } void type_structure_introspector_code::gen_copy(nstring const &inst_var_name) const { printf("%s(rhs.%s)", inst_var_name.c_str(), inst_var_name.c_str()); } void type_structure_introspector_code::gen_write(const nstring &form_name, const nstring &member_name, bool) const { trace(("%s\n", __PRETTY_FUNCTION__)); printf("if (%s)\n", member_name.c_str()); printf("{\n"); nstring text = member_name + "->write(fp, " + form_name.quote_c() + ");"; wrap_and_print("", text); printf("}\n"); } // vim: set ts=8 sw=4 et :