]> vaikene.ee Git - evaf/commitdiff
Added eVaf Command Line Interface application.
authorEnar Väikene <enar.vaikene@mt.com>
Thu, 19 May 2011 12:16:28 +0000 (15:16 +0300)
committerEnar Väikene <enar.vaikene@mt.com>
Thu, 19 May 2011 12:16:28 +0000 (15:16 +0300)
src/main/CLI/CMakeLists.txt
src/main/CLI/main.cpp
src/main/CLI/main.h
src/main/CMakeLists.txt

index f27ec1fcfae795315c00fb63911d85c4862f4336..d6a5b14cb679368029eb45c0326743325f84d3f3 100644 (file)
@@ -9,19 +9,17 @@ include(${QT_USE_FILE})
 include_directories(${eVaf_INCLUDE})
 
 # Required eVaf libraries
-set(eVaf_LIBRARIES)
+set(eVaf_LIBRARIES CommonLib PluginsLib)
 
 # Source files
 set(SRCS
     main.cpp
     exithandler.cpp
-    version.cpp
 )
 
 # Header files for the meta-object compiler
 set(MOC_HDRS
     main.h
-    version_p.h
 )
 
 # Version info resource file for Windows builds
index 4c570845bafecf7aecd6fcdb36191a8b430f25c6..3c1ec3b2e032a4608d56c4314d79a411f9c1c160 100644 (file)
@@ -1,6 +1,6 @@
 /**
- * @file main/gui/main.cpp
- * @brief The main eVaf GUI application class
+ * @file main/CLI/main.cpp
+ * @brief The main eVaf CLI application class
  *
  * Copyright (c) 2011 Enar Vaikene
  *
 
 #include "main.h"
 #include "exithandler.h"
-#include "fatalerr.h"
-#include "version_p.h"
+//#include "version_p.h"
 #include "version.h"
 
-#ifdef Q_OS_WIN32
-#include "winconsole.h"
+#include <Common/Globals>
+#include <Common/iLogger>
+#include <Common/iEnv>
+#include <Common/iApp>
+
+#include <Plugins/PluginManager>
+
+#include <QtCore>
+
+#ifdef Q_OS_LINUX
+#  include <sys/types.h>
+#  include <unistd.h>
 #endif
 
-#include <QtGui>
+using namespace eVaf;
+
+//-------------------------------------------------------------------
+
+namespace eVaf {
+namespace CLI {
+namespace Internal {
+
+/**
+ * Qt message handler replacement.
+ * @param type Type of the message
+ * @param msg The message
+ *
+ * This function outputs messages to the console and to the log file.
+ */
+static void messageOutput(QtMsgType type, char const * const msg)
+{
+    static bool inHandler = false;
+
+    // Avoid recursions in case outputting a message causes another message to be output
+    if (inHandler)
+        return;
+    inHandler = true;
+
+    // Qt message type conversion to eVaf logger severity levels
+    Common::iLogger::Severity v;
+    switch (type) {
+        case QtWarningMsg:
+            v = Common::iLogger::Warning;
+            break;
+        case QtCriticalMsg:
+            v = Common::iLogger::Error;
+            break;
+        case QtFatalMsg:
+            v = Common::iLogger::Fatal;
+            break;
+        default:
+            v = Common::iLogger::Debug;
+    }
+
+    // Output to the log file and console
+    Common::iLogger::instance()->write(v, msg);
 
+    inHandler = false;
+}
+
+/**
+ * Fatal error message handler
+ * @param msg The error message
+ * @param source Source of the message
+ * @param where Where the error occurred
+ *
+ * This function shows a critical error message box on the screen if needed and then terminates
+ * the application.
+ *
+ * If the critical error message is shown, then the user has an option to ignore the error. In this
+ * case the application is not terminated.
+ */
+static void fatalMsgHandler(QString const & msg, QString const & source, QString const & where)
+{
+#ifdef Q_OS_LINUX
+    abort();
+#else
+    exit(1);
+#endif
+}
+
+} // namespace eVaf::CLI::Internal
+} // namespace eVaf::CLI
+} // namespace eVaf
 
 //-------------------------------------------------------------------
 
-using namespace eVafGUI;
+using namespace eVaf::CLI;
 
 Application::Application(int & argc, char ** argv)
-    : QApplication(argc, argv)
+    : QCoreApplication(argc, argv)
 {
-    setObjectName(QString("%1-%2").arg(VER_MODULENAME_STR).arg(__FUNCTION__));
-
-    setWindowIcon(QIcon(":/eVafGUI/Icon"));
+    setObjectName(QString("%1-%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__));
 }
 
 Application::~Application()
 {
 }
 
+bool Application::processCommandLine(int argc, char ** argv)
+{
+    Common::iLogger::Severity consoleSeverityLevel = Common::iLogger::Fatal;
+
+    QStringList args;
+    for (int i = 1; i < argc; ++i)
+        args += argv[i];
+
+    for (int i = 0; i < args.size(); ++i) {
+        // Get the argument and optional value
+        QStringList arg = args.at(i).simplified().split(QChar('='));
+
+        if (QRegExp("(-[-]?version)|([-//]V)").exactMatch(arg.at(0))) {
+            printVersion();
+            return false;
+        }
+        else if (QRegExp("(-[-]?help)|([-//][h/?])").exactMatch(arg.at(0))) {
+            printHelp();
+            return false;
+        }
+        else if (QRegExp("-[-]?verbose").exactMatch(arg.at(0)) && arg.size() > 1) {
+            QString v = arg.at(1).toLower();
+            if (v == "debug")
+                consoleSeverityLevel = Common::iLogger::Debug;
+            else if (v == "info")
+                consoleSeverityLevel = Common::iLogger::Info;
+            else if (v == "warning")
+                consoleSeverityLevel = Common::iLogger::Warning;
+            else if (v == "error")
+                consoleSeverityLevel = Common::iLogger::Error;
+            else if (v == "fatal")
+                consoleSeverityLevel = Common::iLogger::Fatal;
+            else if (v == "none") {
+                consoleSeverityLevel = Common::iLogger::None;
+            }
+            else {
+                printHelp();
+                return false;
+            }
+        }
+        else if (QRegExp("-[v]+").exactMatch(arg.at(0)) && arg.size() == 1) {
+            // The number of 'v's increases the verbosity
+            for (int j = 1; j < arg.at(0).size(); ++j) {
+                switch (consoleSeverityLevel) {
+                    case Common::iLogger::None:
+                        consoleSeverityLevel = Common::iLogger::Fatal;
+                        break;
+                    case Common::iLogger::Fatal:
+                        consoleSeverityLevel = Common::iLogger::Error;
+                        break;
+                    case Common::iLogger::Error:
+                        consoleSeverityLevel = Common::iLogger::Warning;
+                        break;
+                    case Common::iLogger::Warning:
+                        consoleSeverityLevel = Common::iLogger::Info;
+                        break;
+                    case Common::iLogger::Info:
+                        consoleSeverityLevel = Common::iLogger::Debug;
+                        break;
+                    case Common::iLogger::Debug:
+                        break;
+                }
+            }
+        }
+    }
+
+    // Set the console severity
+    Common::iLogger::instance()->setConsoleSeverity(consoleSeverityLevel);
+
+    return true;
+}
+
+void Application::printHelp()
+{
+    char const * const txt = QT_TR_NOOP(
+        "Usage: eVafCLI [options]\n"
+        "\n"
+        // General options
+        "  -help            Shows this help and quits.\n"
+        "  -version         Shows version information and quits.\n"
+        "  -verbose=LEVEL   Specifies the verbose level. LEVEL can be one of the\n"
+        "                   following: NONE, FATAL, ERROR, WARNING, INFO, DEBUG.\n"
+        "  -v               Makes the application more verbose. Can be repeated for\n"
+        "                   more verbosity.\n"
+        // Handled by the iApp interface implementation
+        "  -appl[ication]=NAME Specifies the name of the application.\n"
+        "  -lang[uage]=xx[_CC] Specifies the language, where xx is the ISO 639\n"
+        "                   language code followed by an optional ISO 3166 country\n"
+        "                   code.\n"
+        // Handled by the iEnv interface implementation
+        "  -root[dir]=DIR   Specifies the application's root directory.\n"
+        "  -dataroot[dir]=DIR Specifies the data root directory.\n"
+        "  -etc[dir]=DIR    Specifies the configuration files directory.\n"
+        "  -log[dir]=DIR    Specifies the log files directory.\n"
+        "  -doc[dir]=DIR    Specifies the documentation directory.\n"
+        "  -qtplugins[dir]=DIR Specifies the Qt plugins directory.\n"
+    );
+    ::fputs(tr(txt).toLocal8Bit().constData(), stdout);
+}
+
+void Application::printVersion()
+{
+    ::printf("%s version %s release date %s, %s version %s\n",
+             VER_PRODUCT_NAME_STR,
+             VER_PRODUCT_VERSION_STR,
+             VER_PRODUCT_DATE_STR,
+             VER_MODULE_NAME_STR,
+             VER_FILE_VERSION_STR
+             );
+}
+
 
 //-------------------------------------------------------------------
 
 int main(int argc, char ** argv)
 {
+    Common::iLogger::instance()->setSeverity(Common::iLogger::Warning);
+
+    // Install our onw message handlers
+    Common::iLogger::instance()->installFatalMsgHandler(Internal::fatalMsgHandler);
+    qInstallMsgHandler(Internal::messageOutput);
+
+    // Process command-line arguments
+    if (!Application::processCommandLine(argc, argv))
+        return 1;
+
+    EVAF_INFO("%s version %s release date %s, %s version %s",
+              VER_PRODUCT_NAME_STR,
+              VER_PRODUCT_VERSION_STR,
+              VER_PRODUCT_DATE_STR,
+              VER_MODULE_NAME_STR,
+              VER_FILE_VERSION_STR);
+
+#ifdef Q_OS_LINUX
+    EVAF_INFO("%s application pid = %d", VER_MODULE_NAME_STR, getpid());
+#endif
+
     Application app(argc, argv);
 
+    // Install the exit handler
+    if (!Internal::installExitHandler())
+        return 1;
+
+    // Plugin manager
+    Plugins::PluginManager pluginManager;
+
+    // The main run loop
+    bool quit = false;
+    int rval;
+    while (!quit) {
+
+        EVAF_INFO("%s is starting up", VER_MODULE_NAME_STR);
+
+        // Initialize the common library
+        if (!Common::init())
+            return 1;
+
+        // Initialize the plugin manager and load plugins
+        if (!pluginManager.init())
+            return 1;
+
+        // Run the application
+        EVAF_INFO("Running %s", VER_MODULE_NAME_STR);
+        rval = app.exec();
+
+        quit = rval != Common::iApp::RC_Restart;
+
+        EVAF_INFO("%s is %s", VER_MODULE_NAME_STR, quit ? "exiting" : "restarting");
+
+        // Unload plugins and finalize the plugin manager
+        pluginManager.done();
+    }
+
+    EVAF_INFO("%s exit with code %d", VER_MODULE_NAME_STR, rval);
+
     return rval;
 }
index 41ec6b504ce6b41c143b63262f51513f03992fac..97a123734eb82ccb0245c6aef1bec974716894b0 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @file main/cli/main.h
+ * @file main/CLI/main.h
  * @brief The main eVaf CLI application class
  *
  * Copyright (c) 2011 Enar Vaikene
  */
 
 #ifndef __CLI_MAIN_H
-#define __CLI_MAIN_H
+#  define __CLI_MAIN_H
 
 #include <QCoreApplication>
 
+namespace eVaf {
 
 /**
- * The main eVaf CLI application.
+ * The main eVaf command line interface (CLI) application.
  *
  * eVafGUI is the main CLI executable. It provides an empty CLI application
  * that is used to load other eVaf modules.
  */
-namespace eVafCLI {
+namespace CLI {
 
-} // namespace eVafCLI
+/**
+ * Internal implementation of the main eVaf CLI application.
+ */
+namespace Internal {
+} // namespace eVaf::CLI::Internal
+
+/**
+ * The main eVaf CLI application class
+ */
+class Application : public QCoreApplication
+{
+    Q_OBJECT
+
+public:
+
+    Application(int & argc, char ** argv);
+
+    virtual ~Application();
+
+
+public: // Static methods
+
+    /**
+     * Processes command-line arguments
+     * @param argc Number of command-line arguments
+     * @param argv List of command-line arguments
+     * @return True if ok; false if the application should terminate
+     *
+     * This function processes command-line arguments and should be called before running
+     * the application.
+     */
+    static bool processCommandLine(int argc, char ** argv);
+
+    /**
+     * Prints out help for command-line arguments.
+     */
+    static void printHelp();
+
+    /**
+     * Prints out help for Qt command-line arguments.
+     */
+    static void printQtHelp();
+
+    /**
+     * Prints out version information.
+     */
+    static void printVersion();
+
+};
+
+} // namespace eVaf::CLI
+} // namespace eVaf
 
 #endif // main.h
index a5b83052e37e3ecbecd6fecee9ce0aa5ac9f8659..362aba67abe6c27eda6eb97091396c93e03ccb56 100644 (file)
@@ -1,2 +1,2 @@
 add_subdirectory(GUI)
-#add_subdirectory(CLI)
+add_subdirectory(CLI)