UniversalIndentGUI 1.2.0
main.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006-2012 by Thomas Schweitzer                          *
00003  *   thomas-schweitzer(at)arcor.de                                         *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License version 2.0 as   *
00007  *   published by the Free Software Foundation.                            *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program in the file LICENSE.GPL; if not, write to the *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00018  ***************************************************************************/
00019 
00020 #include "MainWindow.h"
00021 
00022 #include "UiGuiIndentServer.h"
00023 #include "debugging/TSLogger.h"
00024 #include "UiGuiIniFileParser.h"
00025 #include "UiGuiSettings.h"
00026 #include "UiGuiVersion.h"
00027 #include "UiGuiSystemInfo.h"
00028 #include "IndentHandler.h"
00029 #include "SettingsPaths.h"
00030 
00031 #include <QApplication>
00032 #include <QTextCodec>
00033 #include <QDebug>
00034 
00035 #include <string>
00036 #include <iostream>
00037 #include <algorithm>
00038 #include <tclap/CmdLine.h>
00039 
00040 #ifdef _MSC_VER
00041 
00042 #include <windows.h>
00043 #include <direct.h>
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <fcntl.h>
00047 #include <io.h>
00048 #include <iostream>
00049 #include <fstream>
00050 
00059 bool attachToConsole(/*enum ATTACH_ONLY|TRY_ATTACH_ELSE_CREATE|CREATE_NEW*/)
00060 {
00061     int hConHandle;
00062     long lStdHandle;
00063     CONSOLE_SCREEN_BUFFER_INFO coninfo;
00064     FILE *fp;
00065 
00066     // Trying to attach to the console of the parent process.
00067     BOOL successful = AttachConsole(ATTACH_PARENT_PROCESS);
00068     // In case that the parent process has no console return false and do no input/output redirection.
00069     if ( !successful )
00070         return false;
00071 
00072     // Set the screen buffer to be big enough to let us scroll text
00073     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
00074     // Set maximum console lines.
00075     coninfo.dwSize.Y = 500;
00076     SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
00077 
00078     // Redirect unbuffered STDOUT to the console.
00079     lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
00080     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00081         if ( hConHandle != -1 ) {
00082             fp = _fdopen( hConHandle, "w" );
00083             *stdout = *fp;
00084             setvbuf( stdout, NULL, _IONBF, 0 );
00085         }
00086 
00087     // Redirect unbuffered STDIN to the console.
00088     lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
00089     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00090         if ( hConHandle != -1 ) {
00091             fp = _fdopen( hConHandle, "r" );
00092             *stdin = *fp;
00093             setvbuf( stdin, NULL, _IONBF, 0 );
00094         }
00095 
00096     // Redirect unbuffered STDERR to the console.
00097     lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
00098     hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
00099         if ( hConHandle != -1 ) {
00100             fp = _fdopen( hConHandle, "w" );
00101             *stderr = *fp;
00102             setvbuf( stderr, NULL, _IONBF, 0 );
00103         }
00104 
00105     // Make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well.
00106     std::ios::sync_with_stdio();
00107 
00108     return true;
00109 }
00110 #else
00111 bool attachToConsole()
00112 {
00113     return false;
00114 }
00115 
00116 #endif
00117 
00118 using namespace tschweitzer::debugging;
00119 
00131 int main(int argc, char *argv[]) {
00132     QString file2OpenOnStart = "";
00133     int verboseLevel = 1;
00134     bool startAsPlugin = false;
00135     bool startAsServer = false;
00136     bool tclapExitExceptionThrown = false;
00137     int returnValue = 0;
00138 
00139     bool attachedToConsole = false;
00140     attachedToConsole = attachToConsole();
00141 
00142 #ifdef __APPLE__
00143         // Filter out -psn_0_118813 and similar parameters.
00144         std::vector<char*> argList;
00145         for ( int i = 0; i < argc; i++ ) {
00146             QString argString(argv[i]);
00147 
00148             if ( argString.startsWith("-psn_") == false ) {
00149                 argList.push_back(argv[i]);
00150             }
00151             else {
00152 //              std::cerr << std::endl << "The parameter "<< i << " is an invalid finder parameter. Parameter was " << argv[i] << std::endl;
00153             }
00154         }
00155         for ( size_t i = 0; i < argList.size(); i++ ) {
00156             argv[i] = argList.at(i);
00157         }
00158         argc = argList.size();
00159 #endif
00160 
00161     // Wrap everything in a try block. Do this every time,
00162     // because exceptions will be thrown for problems.
00163     try {
00164         // Define the command line object.
00165         TCLAP::CmdLine cmd("If -p and -s are set, -p will be used.\nGiving no parameters starts full gui without server.", ' ', "UiGUI version " PROGRAM_VERSION_STRING " " PROGRAM_REVISION);
00166         cmd.setExceptionHandling(false);
00167 
00168         // Define a value argument and add it to the command line.
00169                 TCLAP::UnlabeledValueArg<std::string> filenameArg("file", "Opens the by filename defined file on start" , false, "", "filename");
00170         cmd.add( filenameArg );
00171 
00172         // Define a switch and add it to the command line.
00173         TCLAP::SwitchArg pluginSwitch("p", "plugin", "Run as plugin. Server will be started with a simplified gui", false);
00174         cmd.add( pluginSwitch );
00175 
00176         // Define a switch and add it to the command line.
00177         TCLAP::SwitchArg serverSwitch("s", "server", "Run as server only without gui", false);
00178         cmd.add( serverSwitch );
00179 
00180         // Define a value argument and add it to the command line.
00181         TCLAP::ValueArg<int> verboselevelArg("v", "verbose", "Sets how many info is written to the log. 0 means with debug info, 3 means critical messages only" , false, 1, "int");
00182         cmd.add( verboselevelArg );
00183 
00184         // Parse the args.
00185         cmd.parse( argc, argv );
00186 
00187         // Get the value parsed by each arg.
00188                 file2OpenOnStart = filenameArg.getValue().c_str();
00189         startAsPlugin = pluginSwitch.getValue();
00190         startAsServer = serverSwitch.getValue();
00191         verboseLevel = verboselevelArg.getValue();
00192     }
00193     catch (TCLAP::ArgException &e) { // catch arg exceptions
00194         std::cerr << std::endl << "error: " << e.error() << ". " << e.argId() << std::endl;
00195         returnValue = 1;
00196     }
00197     catch (TCLAP::ExitException &e) { // catch exit exceptions
00198         tclapExitExceptionThrown = true;
00199         returnValue = e.getExitStatus();
00200     }
00201     catch (...) { // catch any exceptions
00202         std::cerr << std::endl << "There was an error! Maybe faulty command line arguments set. See --help." << std::endl;
00203         returnValue = 1;
00204     }
00205 
00206     if ( returnValue != 0 || tclapExitExceptionThrown ) {
00207 #ifdef _MSC_VER
00208         if ( attachedToConsole ) {
00209             // Workaround for skipped command line prompt: Get the current working directory and print it to console.
00210             char* buffer;
00211             if( (buffer = _getcwd( NULL, 0 )) != NULL ) {
00212                 std::cerr << std::endl << buffer << ">";
00213                 free(buffer);
00214             }
00215             // Release the connection to the parents console.
00216             FreeConsole();
00217         }
00218 #endif
00219         return returnValue;
00220     }
00221 
00222     QApplication app(argc, argv);
00223     UiGuiIndentServer server;
00224     MainWindow *mainWindow = NULL;
00225     IndentHandler *indentHandler = NULL;
00226 
00227     // Init and install the logger function.
00228     // Setting UTF-8 as default 8-Bit encoding to ensure that qDebug does no false string conversion.
00229     QTextCodec::setCodecForCStrings( QTextCodec::codecForName("UTF-8") );
00230     QTextCodec::setCodecForLocale( QTextCodec::codecForName("UTF-8") );
00231     // Force creation of an TSLogger instance here, to avoid recursion with SettingsPaths init function.
00232 #ifdef _DEBUG
00233     TSLogger::getInstance(0);
00234 #else
00235     TSLogger::getInstance(verboseLevel);
00236 #endif
00237     qInstallMsgHandler( TSLogger::messageHandler );
00238     TSLogger::messageHandler( TSLoggerInfoMsg, QString("Starting UiGUI Version %1 %2").arg(PROGRAM_VERSION_STRING).arg(PROGRAM_REVISION).toAscii() );
00239     TSLogger::messageHandler( TSLoggerInfoMsg, QString("Running on %1").arg(UiGuiSystemInfo::getOperatingSystem()).toAscii() );
00240 
00241     // Set default values for all by UniversalIndentGUI used settings objects.
00242     QCoreApplication::setOrganizationName("UniversalIndentGUI");
00243     QCoreApplication::setOrganizationDomain("universalindent.sf.net");
00244     QCoreApplication::setApplicationName("UniversalIndentGUI");
00245 
00246     // Start normal with full gui and without server.
00247     if ( !startAsPlugin && !startAsServer ) {
00248         mainWindow = new MainWindow(file2OpenOnStart);
00249         mainWindow->show();
00250     }
00251     // Start as plugin with server.
00252     else if ( startAsPlugin ) {
00253         server.startServer();
00254         indentHandler = new IndentHandler(0);
00255         indentHandler->show();
00256     }
00257     // Start as server only without any gui.
00258     else if ( startAsServer ) {
00259         server.startServer();
00260     }
00261 
00262     try {
00263         returnValue = app.exec();
00264     }
00265     catch (std::exception &ex) {
00266         qCritical() << __LINE__ << " " << __FUNCTION__ << ": Something went terribly wrong:" << ex.what();
00267     }
00268 
00269     if ( startAsPlugin || startAsServer )
00270         server.stopServer();
00271 
00272     delete indentHandler;
00273     delete mainWindow;
00274 
00275     SettingsPaths::cleanAndRemoveTempDir();
00276     TSLogger::deleteInstance();
00277 
00278     return returnValue;
00279 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines