// -*- c++ -*- //------------------------------------------------------------------------------ // $Id: assa-genesis.cpp,v 1.13 2006/07/23 02:26:45 vlg Exp $ //------------------------------------------------------------------------------ // assa-genesis.cpp //------------------------------------------------------------------------------ // Copyright (C) 2001,2005,2006 Vladislav Grinchenko // // 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 // 2 of the License, or (at your option) any later version. // // Creation date: Nov 1 2001 //------------------------------------------------------------------------------ static const char help_msg[]= " \n" " NAME: \n" " \n" " assa-genesis \n" " \n" " DESCRIPTION: \n" " \n" " assa-genesis generates skeleton files for rapid application \n" " development with ASSA library. \n" " \n" " See ASSA User's Guide for further details. \n" " \n" " USAGE: \n" " \n" " shell> assa-genesis [OPTIONS] \n" " \n" " Four files are generated by default: \n" " \n" " -main.h - Header file with debug tracing masks \n" " -main.cpp - 'main()' function with event loop \n" " .h - Header file for class \n" " .cpp - Implementation stubs for class \n" " \n" " In addition, if --gtk2-app options was specified, the MainWindow class \n" " is generated: \n" " \n" " MainWindow.h - Class MainWindow declaration \n" " MainWindow.cpp - Class MainWindow definition \n" " \n" " If {-t, --one-file} switch is used, everything is put in one file, \n" " .cpp. This is primarily used for writing test programs. \n" " \n" " \n" " OPTIONS: \n" " \n" " --with-example=BOOL - Add example of processing positional \n" " command-line arguments. \n" " --with-gpl-license=BOOL - (Default) Generate files with GPL license \n" " headers. \n" " --with-lgpl-license=BOOL - Generate files with LGPL license headers. \n" " --with-x11-license=BOOL - Generate files with X11-type license headers. \n" " --with-makefile=BOOL - Generate makefile. \n" " \n" " --gtk2-app=BOOL - Generate Gtk2 ready application. \n" " -o, --one-file=BOOL - Put everything in one file \n" " -e, --extension STRING - Set file extention for C++ code (C, cxx, ...) \n" " -h, --help - print help messag \n" " -v, --version - print version number \n" " \n" " NOTE: \n" " \n" " From Merriam-Webster Dictionary: \n" " 'genesis' (n) - to be born (Etymology: from Greek 'gignesthai') \n" " \n"; //------------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include "assa/Assure.h" #include "assa/TimeVal.h" #include "assa/GenServer.h" #include "assa/Singleton.h" #include using std::string; using std::cerr; using std::endl; using std::cout; using namespace ASSA; static char assa_version [32]; class Genesis : public GenServer, public Singleton { public: Genesis (); virtual void init_service (); virtual void process_events (); private: virtual void pos_arg (const char* arg_); void write_header (const char* name_, ostream& sink_); void write_onefile_header (ostream& sink_); void write_class_declaration (const char* name_, ostream& sink_); void write_class_definition (const char* name_, ostream& sink_); void write_mw_class_declaration (ostream& sink_); void write_mw_class_definition (ostream& sink_); void write_main (const char* name_, ostream& msrc_); void write_help_msg (ostream& sink_); void write_gpl_license (ostream& sink_); void write_lgpl_license (ostream& sink_); void write_x11_license (ostream& sink_); void generate_one_file (); void generate_makefile (); private: string m_app_name; string m_extension; u_int m_pos_arg_count; bool m_one_file; bool m_with_example; bool m_with_gpl_license; bool m_with_lgpl_license; bool m_with_x11_license; bool m_gtk2_app; bool m_with_makefile; }; // Static declarations mandated by Singleton class ASSA_DECL_SINGLETON(Genesis); Genesis:: Genesis () : m_extension ("cpp"), m_pos_arg_count (1), m_one_file (false), m_with_example (false), m_with_gpl_license (true), m_with_lgpl_license (false), m_with_x11_license (false), m_gtk2_app (false), m_with_makefile (false) { add_opt ('e', "extension", &m_extension); add_flag_opt ('o', "one-file", &m_one_file); add_flag_opt (0, "with-example", &m_with_example); add_flag_opt (0, "with-gpl-license", &m_with_gpl_license); add_flag_opt (0, "with-lgpl-license", &m_with_lgpl_license); add_flag_opt (0, "with-x11-license", &m_with_x11_license); add_flag_opt (0, "gtk2-app", &m_gtk2_app); add_flag_opt (0, "with-makefile", &m_with_makefile); rm_opt ('m', "mask" ); rm_opt ('d', "log-stdout" ); rm_opt ('D', "debug-file" ); rm_opt ('z', "log-size" ); rm_opt ('f', "config-file" ); rm_opt ('n', "instance" ); rm_opt ('p', "port" ); rm_opt ('s', "set-name" ); rm_opt ('t', "comm-timeout" ); rm_opt ('b', "daemon" ); rm_opt ('l', "pidfile" ); rm_opt ('L', "ommit-pidfile"); /*--- * Disable all debugging *---*/ m_mask = 0; } void Genesis:: pos_arg (const char* arg_) { switch (m_pos_arg_count) { case 1: m_app_name = arg_; break; case 2: default: cerr << "Error: unexpected arguments!" << endl; Assure_exit (false); } m_pos_arg_count++; } void Genesis:: init_service () { Log::disable_timestamp (); } void Genesis:: generate_makefile () { string mkfname ("GNUmakefile." + m_app_name); std::ofstream mkfile (mkfname.c_str ()); if (!mkfile) { cerr << "Cannot create \"" << mkfname << "\"" << endl; exit (1); } cout << "\nassa-genesis: Generating makefile ...\n"; mkfile << "## -*- makefile -*-\n" << "##\n" << "## " << mkfname << ": generated by assa-genesis\n" << "##\n" << '\n'; if (m_gtk2_app) { mkfile << "APP_CFLAGS=`pkg-config assa-" << assa_version << " --cflags` `pkg-config gtkmm-2.4 --cflags`\n" << "APP_LIBS=`pkg-config assa-" << assa_version << " --libs` `pkg-config gtkmm-2.4 --libs`\n\n"; } else { mkfile << "APP_CFLAGS=`pkg-config assa-" << assa_version << " --cflags`\n" << "APP_LIBS=`pkg-config assa-" << assa_version << " --libs`\n\n"; } mkfile << "OBJS = \\\n"; if (m_one_file) { mkfile << "\t" << m_app_name << ".o\n"; } else { mkfile << " " << m_app_name << ".o " << m_app_name << "-main.o"; if (m_gtk2_app) { mkfile << " MainWindow.o"; } mkfile << '\n'; } mkfile << '\n' << "all: " << m_app_name << "\n" << '\n' << m_app_name << ": ${OBJS}\n" << "\tg++ -g ${APP_CFLAGS} ${OBJS} -o " << m_app_name << " ${APP_LIBS}\n" << '\n' << "." << m_extension << ".o:\n" << "\tg++ -g ${APP_CFLAGS} -c $<\n" << '\n' << "clean:" << "\t-rm -f *.o *~ core core.*\n" << '\n' << "distclean: clean\n" << "\t-rm " << m_app_name << "\n" << "\t-rm *.log *.log.0\n" << '\n' << "dist:\n" << "\ttar cvfz " << m_app_name << ".tar.gz *.h *." << m_extension << " makefile\n"; mkfile << '\n' << "## Dependencies\n" << '\n'; if (m_one_file) { mkfile << m_app_name << ".o: " << m_app_name << "." << m_extension << "\n"; } else { mkfile << m_app_name << ".o: " << m_app_name << "." << m_extension << " " << m_app_name << ".h\n" << m_app_name << "-main.o: " << m_app_name << "-main." << m_extension << " " << m_app_name << "-main.h\n"; if (m_gtk2_app) { mkfile << "MainWindow.o: MainWindow." << m_extension << " MainWindow.h\n"; } } mkfile << endl; mkfile.close (); } void Genesis:: generate_one_file () { string projname (m_app_name); string fname (projname); fname += '.' + m_extension; std::ofstream onefile (fname.c_str ()); if (!onefile) { cerr << "Cannot open input file \"" << fname << "\"" << endl; exit (1); } cout << "\nassa-genesis: Generating skeleton files ...\n"; write_header (fname.c_str (), onefile); write_help_msg (onefile); write_onefile_header (onefile); write_class_declaration (projname.c_str (), onefile); if (m_gtk2_app) { write_mw_class_declaration (onefile); } write_class_definition (projname.c_str (), onefile); if (m_gtk2_app) { write_mw_class_definition (onefile); } write_main (projname.c_str (), onefile); onefile << endl; onefile.close (); cout << "\nCreated: \"" << fname << "\"\n\n"; } void Genesis:: write_gpl_license (ostream& sink_) { sink_ << "// This program is free software; you can redistribute it and/or \n" << "// modify it under the terms of the GNU General Public License \n" << "// as published by the Free Software Foundation; either version \n" << "// 2 of the License, or (at your option) any later version. \n"; } void Genesis:: write_lgpl_license (ostream& sink_) { sink_ << "// This library is free software; you can redistribute it and/or \n" << "// modify it under the terms of the GNU Library General Public \n" << "// License as published by the Free Software Foundation; either \n" << "// version 2 of the License, or (at your option) any later version. \n"; } void Genesis:: write_x11_license (ostream& sink_) { sink_ << "// Permission to use, copy, modify, and distribute this software \n" << "// and its documentation for any purpose and without fee is hereby \n" << "// granted, provided that the above copyright notice appear in all \n" << "// copies. The author makes no representations about the suitability \n" << "// of this software for any purpose. It is provided \"as is\" without \n" << "// express or implied warranty. \n"; } void Genesis:: process_events () { string projname (m_app_name); string fname; if (m_pos_arg_count == 1) { /*--- * We haven't seen expected position argument *---*/ cerr << endl << endl << "Missing argument" << endl << "Try `assa-genesis --help` for details" << endl << endl; exit (1); } if (m_with_makefile) { generate_makefile (); } if (m_one_file) { generate_one_file (); return; } cout << "\nassa-genesis: Generating skeleton files ...\n"; /*-----------------------------------------------------*/ /*--- Create 'main.h' ---*/ /*-----------------------------------------------------*/ string header_name (projname); header_name += "-main.h"; std::ofstream mheader (header_name.c_str ()); if (!mheader) { cerr << "Cannot open \"" << header_name << "\"\n"; exit (1); } write_header (header_name.c_str (), mheader); mheader << "#ifndef MAIN_H\n" << "#define MAIN_H\n"; mheader << endl << "#include \n"; if (m_gtk2_app) { mheader << endl << "enum { GUITRACE = ASSA::USR1 };\n"; } mheader << endl << "#endif /* MAIN_H */\n" << endl; mheader.close (); cout << "\nCreated: \"" << header_name << "\"\n"; /*-----------------------------------------------------*/ /*--- Creating 'main.cpp' ---*/ /*-----------------------------------------------------*/ fname = projname + "-main." + m_extension; std::ofstream msrc (fname.c_str ()); if (!msrc) { cerr << "Cannot open \"" << fname << "\"\n"; exit (1); } write_header (fname.c_str (), msrc); write_help_msg (msrc); msrc << endl << "#include \"" << header_name << "\"\n" << "#include \"" << projname << ".h\"\n" << endl; write_main (projname.c_str (), msrc); msrc.close (); cout << "\nCreated: \"" << fname << "\"\n"; /*-----------------------------------------------------*/ /*--- Create Project's header file ---*/ /*-----------------------------------------------------*/ string hdr_fname = projname + string (".h"); std::ofstream hdr (hdr_fname.c_str ()); if (!hdr) { cerr << "Cannot open file " << hdr_fname << endl; exit (1); } write_header (hdr_fname.c_str (), hdr); hdr << endl << "#ifndef " << projname << "_H\n" << "#define " << projname << "_H\n" << endl; write_class_declaration (projname.c_str (), hdr); hdr << endl << "#endif // " << projname << "_H\n" << endl; hdr.close (); cout << "\nCreated: \"" << hdr_fname << "\"\n"; /*-----------------------------------------------------*/ /*--- Create Project's source file ---*/ /*-----------------------------------------------------*/ fname = projname + string (".") + m_extension; std::ofstream source (fname.c_str ()); if (!source) { cerr << "Cannot open input file \"" << fname << "\"" << endl; exit (1); } write_header (fname.c_str (), source); source << endl << "#include \"" << header_name << "\"\n" << "#include \"" << projname << ".h\"\n"; if (m_gtk2_app) { source << endl << "#include \"MainWindow.h\"\n"; } write_class_definition (projname.c_str (), source); source << endl; source.close (); cout << "\nCreated: \"" << fname << "\"\n\n"; /** Bail out here if we are not generating GTK2 application */ if (!m_gtk2_app) { return; } /*-----------------------------------------------------*/ /*--- Create MainWindow header file ---*/ /*-----------------------------------------------------*/ std::ofstream mwh ("MainWindow.h"); if (!mwh) { cerr << "Cannot open file MainWindow.h" << endl; exit (1); } write_header ("MainWindow.h", mwh); mwh << endl << "#ifndef MAIN_WINDOW_H\n" << "#define MAIN_WINDOW_H\n" << endl; write_mw_class_declaration (mwh); mwh << endl << "#endif // MAIN_WINDOW_H\n" << endl; mwh.close (); cout << "\nCreated: \"MainWindow.h\"\n"; /*-----------------------------------------------------*/ /*--- Create MainWindow source file ---*/ /*-----------------------------------------------------*/ fname = string ("MainWindow.") + m_extension; std::ofstream mw_source (fname.c_str ()); if (!mw_source) { cerr << "Cannot open input file \"" << fname << "\"" << endl; exit (1); } write_header (fname.c_str (), mw_source); write_mw_class_definition (mw_source); mw_source << endl; mw_source.close (); cout << "\nCreated: \"" << fname << "\"\n\n"; } void Genesis:: write_header (const char* name_, ostream& sink_) { TimeVal tv (TimeVal::gettimeofday ()); sink_ << "// -*- c++ -*-\n" << "// Generated by assa-genesis\n" << "//------------------------------------------------------------------------------\n" << "// $" << "Id" << "$\n" << "//------------------------------------------------------------------------------\n" << "// " << name_ << "\n" << "//------------------------------------------------------------------------------\n" << "// Copyright (c) YEAR by YOUR-NAME \n" << "//\n"; if (m_with_lgpl_license) { write_lgpl_license (sink_); } else if (m_with_x11_license) { write_x11_license (sink_); } else if (m_with_gpl_license) { write_gpl_license (sink_); } else { write_gpl_license (sink_); } sink_ << "//------------------------------------------------------------------------------\n" << "//\n" << "// Date : " << tv.fmtString ("%c") << "\n" << "//\n" << "//------------------------------------------------------------------------------\n"; sink_ << endl; } void Genesis:: write_help_msg (ostream& sink_) { sink_ << "static const char help_msg[]=\n" << "\" \\n\"\n" << "\" NAME: \\n\"\n" << "\" \\n\"\n" << "\" Your application program name \\n\"\n" << "\" \\n\"\n" << "\" DESCRIPTION: \\n\"\n" << "\" \\n\"\n" << "\" Short description to give general feeling \\n\"\n" << "\" of what its main purpose is. \\n\"\n" << "\" \\n\"\n" << "\" USAGE: \\n\"\n" << "\" \\n\"\n" << "\" shell> app_name [OPTIONS] \\n\"\n" << "\" \\n\"\n" << "\" OPTIONS: \\n\"\n" << "\" \\n\"\n" << "\" -b, --daemon BOOL - Run process as true UNIX daemon \\n\"\n" << "\" -l, --pidfile PATH - The process ID is written to the lockfile PATH \\n\"\n" << "\" instead of default ~/.{procname}.pid \\n\"\n" << "\" -L, --ommit-pidfile BOOL- Do not create PID lockfile \\n\"\n" << "\" \\n\"\n" << "\" -D, --log-file NAME - Write debug to NAME file \\n\"\n" << "\" -d, --log-stdout BOOL - Write debug to standard output \\n\"\n" << "\" -z, --log-size NUM - Maximum size debug file can reach (dfl: is 10Mb) \\n\"\n" << "\" \\n\"\n" << "\" -c, --log-level NUM - Log verbosity \\n\"\n" << "\" -s, --with-log-server BOOL - Redirect log messages to the log server \\n\"\n" << "\" -S, --log-server NAME - Define assa-logd server address \\n\"\n" << "\" \\n\"\n" << "\" -m, --mask MASK - Mask (default: ALL = 0x7fffffff) \\n\"\n" << "\" -p, --port NAME - The tcp/ip port NAME (default - procname) \\n\"\n" << "\" -n, --instance NUM - Process instance NUM (default - none) \\n\"\n" << "\" -f, --config-file NAME - Alternative configuration file NAME \\n\"\n" << "\" \\n\"\n" << "\" -h, --help - Print this messag \\n\"\n" << "\" -v, --version - Print version number \\n\";\n" << "//------------------------------------------------------------------------------\n"; } void Genesis:: write_mw_class_declaration (ostream& sink_) { sink_ << endl << "#ifdef HAVE_CONFIG_H\n" << "# include \"config.h\"\n" << "#endif\n" << "\n" << "#include \n" << "#include \n" << "#include \n" << "#include \n" << "\n" << "class MainWindow : public Gtk::Window\n" << "{\n" << "public:\n" << " MainWindow ();\n" << " ~MainWindow ();\n" << "\n" << "protected:\n" << " void on_menu_file_quit ();\n" << " void on_menu_help ();\n" << "\n" << "private:\n" << " Gtk::MenuBar m_menu_bar;\n" << " Gtk::Menu m_menu_file;\n" << " Gtk::Menu m_menu_help;\n" << " Gtk::VBox m_box;\n" << "};\n" << "\n" << endl; } void Genesis:: write_mw_class_definition (ostream& sink_) { /** Included */ sink_ << endl << "#include \n"; if (!m_one_file) { sink_ << "#include \"MainWindow.h\"\n" << "#include \"" << m_app_name << "-main.h\"\n" << "\n"; } /** Constructor */ sink_ << endl << "MainWindow::\n" << "MainWindow ()\n" << "{\n" << " trace_with_mask(\"MainWindow::MainWindow\",GUITRACE);\n" << "\n" << " set_title (\"" << m_app_name << "\");\n" << " set_default_size (200, 300);\n" << "\n" << " add (m_box);\n" << "\n" << " /** menu\n" << " */\n" << " {\n" << " Gtk::Menu::MenuList& menulist = m_menu_file.items ();\n" << " menulist.push_back (\n" << " Gtk::Menu_Helpers::MenuElem (\"_Quit\",\n" << " Gtk::AccelKey (\"q\"),\n" << " sigc::mem_fun (*this, &MainWindow::on_menu_file_quit)));\n" << " }\n" << "\n" << " /** menu\n" << " */\n" << " {\n" << " Gtk::Menu::MenuList& menulist = m_menu_help.items ();\n" << " menulist.push_back (\n" << " Gtk::Menu_Helpers::MenuElem (\"_Help\",\n" << " Gtk::AccelKey (\"h\"),\n" << " sigc::mem_fun (*this, &MainWindow::on_menu_help)));\n" << " menulist.back ().set_right_justified ();\n" << " }\n" << "\n" << " /** Add menus to the MenuBar\n" << " */\n" << " m_menu_bar.items ().push_back (\n" << " Gtk::Menu_Helpers::MenuElem (\"_File\", m_menu_file));\n" << "\n" << " m_menu_bar.items ().push_back (\n" << " Gtk::Menu_Helpers::StockMenuElem (Gtk::Stock::HELP, m_menu_help));\n" << "\n" << " /** Add the MenuBar to the Window\n" << " */\n" << " m_box.pack_start (m_menu_bar, Gtk::PACK_SHRINK);\n" << "\n" << " show_all ();\n" << "}\n" << "\n"; /** Destructor */ sink_ << "\n" << "MainWindow::\n" << "~MainWindow ()\n" << "{\n" << " trace_with_mask(\"MainWindow::~MainWindow\",GUITRACE);\n" << " /* no-op */\n" << "}\n"; /** Callbacks */ sink_ << "\n" << "void\n" << "MainWindow::\n" << "on_menu_file_quit ()\n" << "{\n" << " trace_with_mask(\"MainWindow::on_menu_file_quit\",GUITRACE);\n" << "\n" << " hide (); // Close the MainWindow to stop Gtk::Main::run ()\n" << "}\n"; sink_ << "\n" << "void\n" << "MainWindow::\n" << "on_menu_help ()\n" << "{\n" << " trace_with_mask(\"MainWindow::on_menu_help\",GUITRACE);\n" << "\n" << " // Do your help here\n" << "}\n" << "\n" << endl; } void Genesis:: write_class_declaration (const char* projname_, ostream& sink_) { string PROJNAME (projname_); for (int i = 0; i < PROJNAME.length (); i++) { PROJNAME [i] = toupper (PROJNAME [i]); } sink_ << endl << "#ifdef HAVE_CONFIG_H\n" << "# include \"config.h\"\n" << "#endif" << endl << "#include \n" << "using std::string;\n"; if (m_gtk2_app) { sink_ << "#include \n"; } sink_ << endl << "#include \n" << "#include \n" << "#include \n"; if (m_gtk2_app) { sink_ << endl << "class MainWindow;\n"; } sink_ << endl /** Class declaration */ << "class " << projname_ << " :\n"; if (m_gtk2_app) { sink_ << " public virtual sigc::trackable,\n"; } sink_ << " public ASSA::GenServer,\n" << " public ASSA::Singleton<" << projname_ << ">\n" << "{\n" << "public:\n" << " " << projname_ << " ();\n"; if (m_gtk2_app) { sink_ << " ~" << projname_ << " ();\n"; } sink_ << "\n" << " virtual void init_service ();\n" << " virtual void process_events ();\n" << "\n"; if (m_gtk2_app) { sink_ << " bool timer_cb ();\n"; } if (m_with_example) { sink_ << '\n' << "private:\n" << " // An example of processing positional arguments\n" << " virtual void pos_arg (const char* arg_);\n"; } sink_ << '\n' << "private:\n"; if (m_with_example) { sink_ << " string m_pos_arg1; // An example of positional argument\n" << " float m_cmd_loop; // An example of optional argument\n" << " u_int m_pos_arg_count; // Number of pos. arguments processed\n"; } if (m_gtk2_app) { sink_ << " static const int IDLE_TIMEOUT = 500;\n" << '\n' << " std::string m_gtk_options;\n" << " Gtk::Main* m_kit;\n" << " MainWindow* m_main_window;\n" << " ASSA::TimeVal m_timeout;\n" << " sigc::connection m_tconn;\n"; } sink_ << "};\n" << '\n' << '\n' << "/* Useful definitions */\n" << '\n' << "#define " << PROJNAME << " " << projname_ << "::get_instance()\n" << "#define REACTOR " << PROJNAME << "->get_reactor()\n" << '\n'; } void Genesis:: write_class_definition (const char* projname_, ostream& sink_) { /** Static declarations */ sink_ << endl << "// Static declarations mandated by Singleton class\n" << "ASSA_DECL_SINGLETON(" << projname_ << ");\n"; /** Constructor */ sink_ << endl << projname_ << "::\n" << projname_ << " ()"; if (m_with_example || m_gtk2_app) { sink_ << " :\n"; } if (m_with_example) { sink_ << " m_pos_arg1 (\"VLG\"),\n" << " m_cmd_loop (34.2),\n" << " m_pos_arg_count (0)"; if (m_gtk2_app) { sink_ << ",\n"; } } if (m_gtk2_app) { sink_ << " m_kit (NULL),\n" << " m_main_window (NULL)"; } sink_ << "{\n"; if (m_with_example) { sink_ << " // An example of adding a command-line option\n" << " // {-l, --loop}\n" << " //\n" << "\n" << " add_opt ('l', \"loop\", &m_cmd_loop);\n"; } if (m_gtk2_app) { sink_ << " add_opt ('g', \"gtk-options\", &m_gtk_options);\n"; } sink_ << "\n" << " // Following list removes all predefined options.\n" << " // Remove only those that you won't use.\n" << " // Don't forget to update your help message in 'main.cpp'!\n" << " //\n" << "\n" << " // ---General---\n" << " // rm_opt ('h', \"help\" );\n" << " // rm_opt ('v', \"version\" );\n" << "\n" << " // ---Debugging---\n" << " // rm_opt ('m', \"mask\" );\n" << " // rm_opt ('d', \"log-stdout\" );\n" << " // rm_opt ('D', \"log-file\" );\n" << " // rm_opt ('z', \"log-size\" );\n" << "\n" << " // ---Configuration---\n" << " // rm_opt ('f', \"config-file\" );\n" << " // rm_opt ('n', \"instance\" );\n" << " // rm_opt ('p', \"port\" );\n" << "\n" << " // ---Process bookkeeping---\n" << " // rm_opt ('b', \"daemon\" );\n" << " // rm_opt ('l', \"pidfile\" );\n" << " // rm_opt ('L', \"ommit-pidfile\");\n" << endl << " /*---\n" << " * By defauil disable all debugging\n" << " *---*/\n"; if (m_gtk2_app) { sink_ << " m_mask = ASSA::APP | GUITRACE | ASSA::ASSAERR;\n"; } else { sink_ << " m_mask = ASSA::APP | ASSA::ASSAERR;\n"; } sink_ << " m_log_file = \"" << projname_ << ".log\";\n" << "}\n" << endl; /** Optional (gtk2-app) destructor */ if (m_gtk2_app) { sink_ << projname_ << "::\n" << "~" << projname_ << " ()\n" << "{\n" << " trace_with_mask(\"" << projname_ << "::~" << projname_ << "\",GUITRACE);\n" << "\n" << " m_tconn.disconnect ();\n" << " delete m_main_window;\n" << "}\n" << endl; } /** Example of processing positional arguments */ if (m_with_example) { sink_ << "void\n" << "" << projname_ << "::\n" << "pos_arg (const char* arg_)\n" << "{\n" << " trace(\"" << projname_ << "::pos_arg\");\n" << '\n' << " switch(m_pos_arg_count) {\n" << " case 0:\n" << " m_pos_arg1 = arg_;\n" << " break;\n" << "\n" << " case 1:\n" << " default:\n" << " DL((ASSA::ASSAERR,\"Error: unexpected argument '%s'\\n\", arg_));\n" << " DL((ASSA::ASSAERR,\"Try `app-name --help` for more information.\\n\"));\n" << " Assure_exit (false);\n" << " }\n" << " m_pos_arg_count++;\n" << "}\n"; } /** Idle callback to run ASSA event loop */ if (m_gtk2_app) { sink_ << "bool\n" << projname_ << "::\n" << "timer_cb ()\n" << "{\n" << " ASSA::TimeVal timeout (m_timeout);\n" << " REACTOR->waitForEvents (&timeout);\n" << " return true;\n" << "}\n"; } /** Service initialization */ if (m_gtk2_app) { sink_ << "\n" << "void\n" << "" << projname_ << "::\n" << "init_service ()\n" << "{\n" << " trace_with_mask(\"" << projname_ << "::init_service\"" << ",GUITRACE);\n" << "\n" << " ASSA::Log::disable_timestamp ();\n" << " int gtk_argc = 0;\n" << " char** gtk_argv = NULL;\n" << "\n" << " m_gtk_options = \"" << projname_ << " --g-fatal-warnings \" + m_gtk_options;\n" << " CmdLineOpts::str_to_argv (m_gtk_options, gtk_argc, gtk_argv);\n" << "\n" << " m_kit = new Gtk::Main (>k_argc, >k_argv);\n" << "\n" << " CmdLineOpts::free_argv (gtk_argv);\n" << "\n" << " m_main_window = new MainWindow;\n" << "\n" << " sigc::slot0 tslot = sigc::mem_fun (*this, &" << projname_ << "::timer_cb);\n" << " m_tconn = Glib::signal_timeout ().connect (tslot, IDLE_TIMEOUT); \n" << "\n" << " DL((ASSA::APP,\"Service has been initialized\\n\"));\n" << "}\n" << "\n"; } else { sink_ << "\n" << "void\n" << "" << projname_ << "::\n" << "init_service ()\n" << "{\n" << " trace(\"" << projname_ << "::init_service\");\n" << "\n" << " //\n" << " // Insert initialization code here\n" << " //\n" << "\n" << " DL((ASSA::APP,\"Service has been initialized\\n\"));\n" << "}\n" << "\n"; } /** Service processing - main event loop */ if (m_gtk2_app) { sink_ << "void\n" << projname_ << "::\n" << "process_events ()\n" << "{\n" << " trace_with_mask(\"" << projname_ << "::process_events\",GUITRACE);\n" << "\n" << " m_kit->run (*m_main_window);\n" << "\n" << " DL((ASSA::APP,\"Service stopped!\\n\"));\n" << "}\n"; } else { sink_ << "void\n" << projname_ << "::\n" << "process_events ()\n" << "{\n" << " trace(\"" << projname_ << "::process_events\");\n" << "\n" << " while (service_is_active ()) {\n" << " m_reactor.waitForEvents ();\n" << " }\n" << "\n" << " // Shut the service down\n" << " m_reactor.stopReactor ();\n" << " DL((ASSA::APP,\"Service stopped!\\n\"));\n" << "}\n" << endl; } } void Genesis:: write_main (const char* projname_, ostream& msrc_) { string PROJNAME (projname_); for (int i = 0; i < PROJNAME.length (); i++) { PROJNAME [i] = toupper (PROJNAME [i]); } msrc_ << endl << endl << "int\n" << "main (int argc, char* argv[])\n" << "{\n" << " static const char release[] = \"VERSION\";\n" << " int patch_level = 0;\n" << "\n" << " " << PROJNAME << "->set_version (release, patch_level);\n" << " " << PROJNAME << "->set_author (\"YOUR-NAME\");\n" << " " << PROJNAME << "->set_flags (ASSA::GenServer::RMLOG);\n" << "\n" << " " << PROJNAME << "->init (&argc, argv, help_msg);\n" << " \n" << " " << PROJNAME << "->init_service ();\n" << " " << PROJNAME << "->process_events ();\n" << "\n" << "\n" << " return " << PROJNAME << "->get_exit_value ();\n" << "}\n"; } /*-----------------------------------------------------------------*/ /* MAIN */ /*-----------------------------------------------------------------*/ int main (int argc, char* argv[]) { static const char release[] = VERSION; // follows library version int patch_level = 0; sprintf (assa_version, "%d.%d", ASSA_MAJOR_VERSION, ASSA_MINOR_VERSION); Genesis& server = *Genesis::get_instance (); server.set_version (release, patch_level); server.set_author ("Vladislav Grinchenko"); server.init (&argc, argv, help_msg); server.init_service (); server.process_events (); return 0; } void Genesis:: write_onefile_header (ostream& sink_) { sink_ << endl << "#include \n"; if (m_gtk2_app) { sink_ << endl << "enum { GUITRACE = ASSA::USR1 };\n"; } sink_ << endl; }