// // aegis - project change supervisor // Copyright (C) 2008 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 . // #ifndef FMTGEN_GENERATOR_H #define FMTGEN_GENERATOR_H #include #include #include #include /** * The generator abstract base class is used to represent a generic * code generator driven from fmtgen .def files. */ class generator { public: typedef aegis_shared_ptr pointer; /** * The destructor. */ virtual ~generator(); protected: /** * The constructor. * Only derived classes may use this constructor. * * @param filename * The name of the file to be written. */ generator(const nstring &filename); public: /** * The factory class method may be used to create a new generator * by name. * * @param name * The name of the generator to use (arglex token number). * @param filename * The name of the file to be written. * @returns * pointer to instance */ static pointer factory(int name, const nstring &filename); /** * The type_boolean_factory method is used to create new instances * of boolean type. We don't go direct, as different generator * will use diffent type classes, depending on the code to be * generated. * * @returns * pointer to new type instance */ virtual type::pointer type_boolean_factory() = 0; /** * The type_enum_factory method is used to create new * instances of enumerated types. We don't go direct, as different * generator will use diffent type classes, depending on the code * to be generated. * * @param name * the name of the enum * @returns * pointer to new type instance */ virtual type::pointer type_enum_factory(const nstring &name, bool global) = 0; /** * The type_integer_factory method is used to create new instances * of integer type. We don't go direct, as different generator * will use diffent type classes, depending on the code to be * generated. * * @returns * pointer to new type instance */ virtual type::pointer type_integer_factory() = 0; /** * The type_list_factory method is used to create new * instances of list types. We don't go direct, as different * generator will use diffent type classes, depending on the code * to be generated. * * @param name * the name of the list type * @param subtype * the type of the list members * @returns * pointer to new type instance */ virtual type::pointer type_list_factory(const nstring &name, bool global, const type::pointer &subtype) = 0; /** * The type_real_factory method is used to create new instances of * real type. We don't go direct, as different generator will use * diffent type classes, depending on the code to be generated. * * @returns * pointer to new type instance */ virtual type::pointer type_real_factory() = 0; /** * The type_string_factory method is used to create new instances * of string type. We don't go direct, as different generator will * use diffent type classes, depending on the code to be generated. * * @returns * pointer to new type instance */ virtual type::pointer type_string_factory() = 0; /** * The type_structure_factory method is used to create new * instances of struct types. We don't go direct, as different * generator will use diffent type classes, depending on the code * to be generated. * * @param name * the name of the structure * @returns * pointer to new type instance */ virtual type::pointer type_structure_factory(const nstring &name, bool global) = 0; /** * The type_time_factory method is used to create new instances of * time type. We don't go direct, as different generator will use * diffent type classes, depending on the code to be generated. * * @returns * pointer to new type instance */ virtual type::pointer type_time_factory() = 0; /** * The top_level_factory method is used to create new instances of * the top level type (this writes the code to read and write files * of the top level struct). We don't go direct, as different * generator will use diffent type classes, depending on the code * to be generated. */ virtual type::pointer top_level_factory(const type::pointer &subtype) = 0; /** * The generate_file method is used to create the output file for * whatever purpose this generator serves. */ virtual void generate_file() = 0; static nstring base_name(const nstring &path); /** * The printf method is used to print formatted output. * * @param fmt * The format string, ehich controls the number and types * of the remaining arguments. See printf(3) for more * information. */ void printf(const char *fmt, ...) ATTR_PRINTF(2, 3); /** * The vprintf method is used to print formatted output. * * @param fmt * The format string, ehich controls the number and types * of the remaining arguments. See vprintf(3) for more * information. * @param ap * where to find the remaining arguments */ void vprintf(const char *fmt, va_list ap) ATTR_VPRINTF(2); /** * The wrap_and_print method is used to wrap the given text, and * emit the wrapped lines. * * @param text * The text to pe wrapped and emitted. */ void wrap_and_print(const nstring &text); /** * The wrap_and_print method is used to wrap the given text, and * emit the wrapped lines, adding the given prefix. * * @param prefix * The constant string to add to the start of each wrapped line. * @param text * The text to pe wrapped and emitted. */ void wrap_and_print(const nstring &prefix, const nstring &text); void indent_more() { ip->more(); } void indent_less() { ip->less(); } /** * The include_once method is used to insert include lines into the * output. Each include file will only ever be included once. * * @param filename * the name of the file ot be included. */ void include_once(const nstring &filename); protected: /** * The this_file_is_generated method is used to insert a consistent * file header into the generated files. */ void this_file_is_generated(void); /** * The get_file_name method may be used to obtain the name of the * file being written. */ nstring get_file_name() const { return ip->get_file_name(); } /** * The calculate_include_file_name method may be used to calculate * the include file name (.h) when given the code file name (.cc). * * @param code_file-name * the name of the code file (.cc) * @returns * the name of the include file (.h) */ nstring calculate_include_file_name(const nstring &code_file_name); private: /** * The ip instance variable is used to remember when to write the output. */ indent::pointer ip; /** * The default constructor. Do not use. */ generator(); /** * The copy constructor. Do not use. */ generator(const generator &); /** * The assignment operator. Do not use. */ generator &operator=(const generator &); }; #endif // FMTGEN_GENERATOR_H