main.cpp
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #include "support.h"
15 
16 #ifdef WITH_KDE
17  #include <kcmdlineargs.h>
18  #include <kaboutdata.h>
19  #include <kapplication.h>
20  #include <kstandarddirs.h>
21 #else
22  #include <QCommandLineParser>
23  #include <QCommandLineOption>
24  #include <QApplication>
25  #include <QMainWindow>
26 #endif
27 
28 #include "kame.h"
29 #include "xsignal.h"
30 #include "icons/icon.h"
31 #include "messagebox.h"
32 #include <QFile>
33 #include <QTextCodec>
34 #include <QTranslator>
35 #include <QLibraryInfo>
36 #ifndef WITH_KDE
37  #include <QStandardPaths>
38 #endif
39 #include <errno.h>
40 
41 #if defined __WIN32__ || defined WINDOWS || defined _WIN32
42  #define NOMINMAX
43  #include <windows.h>
44  #include <QDir>
45  #define USE_LOADLIBRARY
46 #else
47  #define USE_LIBTOOL
48  #include <ltdl.h>
49 #endif
50 
51 #include <gsl/gsl_errno.h>
52 
53 void
54 my_gsl_err_handler (const char *reason, const char *file, int line, int gsl_errno) {
55 // gErrPrint_redirected(formatString("GSL emitted an error for a reason:%s; %s", reason, gsl_strerror(gsl_errno)), file, line);
56  fprintf(stderr, "GSL emitted an error for a reason:%s; %s, at %s:%d\n", reason, gsl_strerror(gsl_errno), file, line);
57 }
58 
59 #ifdef USE_LIBTOOL
60 int load_module(const char *filename, lt_ptr data) {
61  static_cast<std::deque<XString> *>(data)->push_back(QString::fromLocal8Bit(filename));
62  return 0;
63 }
64 #endif
65 
66 int main(int argc, char *argv[]) {
67  char dummy_for_mlock[8192];
68 #ifdef HAVE_LIBGCCPP
69  //initialize GC
70  GC_INIT();
71  // GC_find_leak = 1;
72  //GC_dont_gc
73 #endif
74 
75  Q_INIT_RESOURCE(kame);
76 
77 #ifdef WITH_KDE
78  const char *description =
79  I18N_NOOP("KAME");
80  // INSERT A DESCRIPTION FOR YOUR APPLICATION HERE
81 
82  KAboutData aboutData( "kame", "", ki18n("KAME"),
83  VERSION, ki18n(description), KAboutData::License_GPL,
84  ki18n("(c) 2003-2014"), ki18n(""), "", "kitagawa@phys.s.u-tokyo.ac.jp");
85  KCmdLineArgs::init( argc, argv, &aboutData );
86 
87  KCmdLineOptions options;
88  options.add("logging", ki18n("log debugging info."));
89  options.add("mlockall", ki18n("never cause swapping, perhaps you need 'ulimit -l <MB>'"));
90  options.add("nomlock", ki18n("never use mlock"));
91  options.add("nodr");
92  options.add("moduledir <path>", ki18n("search modules in <path> instead of the standard dirs"));
93  options.add("+[File]", ki18n("measurement file to open"));
94 
95  KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
96 
97  KApplication app;
98 
99  KGlobal::dirs()->addPrefix(".");
100 
101  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
102  g_bLogDbgPrint = args->isSet("logging");
103  g_bMLockAlways = args->isSet("mlockall");
104  g_bUseMLock = args->isSet("mlock");
105  QStringList module_dir = args->getOptionList("moduledir");
106  if(module_dir.isEmpty())
107  module_dir = KGlobal::dirs()->resourceDirs("lib");
108 
109  XString mesfile = args->count() ? args->arg(0) : "";
110  args->clear();
111 #else
112  QApplication app(argc, argv);
113  QApplication::setApplicationName("kame");
114  QApplication::setApplicationVersion(VERSION);
115 
116  QCommandLineParser parser;
117  parser.setApplicationDescription("KAME");
118  parser.addHelpOption();
119  parser.addVersionOption();
120 
121  parser.addPositionalArgument("file", QCoreApplication::translate("main", "Measurement file to open"));
122 
123  QCommandLineOption logOption(QStringList() << "l" << "logging", "Log debugging info.");
124  parser.addOption(logOption);
125  QCommandLineOption mlockAllOption(QStringList() << "m" << "mlockall",
126  "Never cause swapping, perhaps you need 'ulimit -l <MB>'");
127  parser.addOption(mlockAllOption);
128  QCommandLineOption noMLockOption(QStringList() << "n" << "nomlock", "Never use mlock");
129  parser.addOption(noMLockOption);
130 
131  QCommandLineOption moduleDirectoryOption("moduledir",
132  QCoreApplication::translate("main", "search modules in <path> instead of the standard dirs"),
133  QCoreApplication::translate("main", "path"));
134  parser.addOption(moduleDirectoryOption);
135 
136  parser.process(app); //processes args.
137 
138  QStringList args = parser.positionalArguments();
139 
140  g_bLogDbgPrint = parser.isSet(logOption);
141  g_bMLockAlways = parser.isSet(mlockAllOption);
142  g_bUseMLock = !parser.isSet(noMLockOption);
143  QStringList module_dir = parser.values(moduleDirectoryOption);
144 
145  XString mesfile = args.count() ? args.at(0) : "";
146  args.clear();
147 
148 
149  QTranslator qtTranslator;
150  qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
151  app.installTranslator(&qtTranslator); //transaltions for QT.
152 
153  QTranslator appTranslator;
154  if( !appTranslator.load("kame_" + QLocale::system().name())) {
155  appTranslator.load("kame_" + QLocale::system().name(), app.applicationDirPath());
156  }
157  app.installTranslator(&appTranslator); //translations for KAME.
158 #endif
159 
160 //#if defined __WIN32__ || defined WINDOWS || defined _WIN32
161 // if(AllocConsole()) {
162 // freopen("CONOUT$", "w", stdout);
163 // freopen("CONOUT$", "w", stderr);
164 // }
165 //#endif
166 
167  {
168  makeIcons(); //loads icon pixmaps.
169  {
170 
171 #if !defined __WIN32__ && !defined WINDOWS && !defined _WIN32
172  if(g_bMLockAlways) {
173  if(( mlockall(MCL_CURRENT) == 0)) {
174  dbgPrint("MLOCKALL succeeded.");
175  }
176  else{
177  dbgPrint(formatString("MLOCKALL failed errno=%d.", errno));
178  }
179  }
180 #endif
181  if(isMemLockAvailable())
182  mlock(dummy_for_mlock, sizeof(dummy_for_mlock)); //reserve stack of main thread.
183 
184  // Use UTF8 conversion from std::string to QString.
185 // QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf8") );
186 
187 #ifdef __SSE2__
188  // Check CPU specs.
189  if(cg_cpuSpec.verSSE < 2) {
190  fprintf(stderr, "SSE2 is needed. Aborting.");
191  return -1;
192  }
193 #endif
194 
195  FrmKameMain *form;
196  form = new FrmKameMain();
197 
198  if(mesfile.length()) {
199  form->openMes(mesfile);
200  }
201  }
202  }
203 
204  //Overrides GSL's error handler.
205  gsl_set_error_handler(&my_gsl_err_handler);
206 
207  fprintf(stderr, "Start processing events.\n");
208 
209  app.processEvents(); //displays a main window.
210 
211 #ifdef USE_LIBTOOL
212  fprintf(stderr, "Initializing LTDL.\n");
213  lt_dlinit();
214  #ifdef __linux__
215  LTDL_SET_PRELOADED_SYMBOLS();
216  #endif
217 #endif
218  if(module_dir.isEmpty())
219  module_dir = app.libraryPaths();
220  std::deque<XString> modules;
221  for(auto it = module_dir.begin(); it != module_dir.end(); it++) {
222  QStringList paths;
223 #if defined KAME_COREMODULE_DIR_SURFIX
224  paths += *it + KAME_COREMODULE_DIR_SURFIX;
225 #endif
226 #if defined KAME_COREMODULE2_DIR_SURFIX
227  paths += *it + KAME_COREMODULE2_DIR_SURFIX; //modules that depend on core ones
228 #endif
229  paths += *it + KAME_MODULE_DIR_SURFIX; //modules that depend on core/core2
230 
231  //searches module directories
232  for(auto sit = paths.begin(); sit != paths.end(); sit++) {
233 #ifdef USE_LIBTOOL
234  lt_dladdsearchdir(sit->toLocal8Bit().data());
235 #endif
236  XMessageBox::post("Searching for modules in " + *sit, *g_pIconInfo);
237 #ifdef USE_LIBTOOL
238  lt_dlforeachfile(sit->toLocal8Bit().data(), &load_module, &modules);
239 #endif
240 #ifdef USE_LOADLIBRARY
241  QFileInfoList files = QDir(*sit).entryInfoList(QStringList("*.dll"), QDir::Files);
242  for(QFileInfoList::const_iterator it = files.constBegin(); it != files.constEnd(); ++it) {
243  modules.push_back(it->filePath());
244  }
245 #endif
246  }
247  }
248  //loads modules.
249  for(auto it = modules.begin(); it != modules.end(); it++) {
250  app.processEvents(); //displays message.
251 #ifdef USE_LIBTOOL
252  lt_dlhandle handle = lt_dlopenext(QString( *it).toLocal8Bit().data());
253 #endif
254 #ifdef USE_LOADLIBRARY
255  DWORD currerrmode = GetThreadErrorMode();
256  SetThreadErrorMode(currerrmode | SEM_FAILCRITICALERRORS, NULL); //suppresses an error dialog on loading.
257  HANDLE handle = LoadLibraryA(QString( *it).toLocal8Bit().data());
258  DWORD lasterr = GetLastError();
259  SetThreadErrorMode(currerrmode, NULL);
260  SetLastError(lasterr);
261 #endif
262  if(handle) {
263  XMessageBox::post("Module \"" + *it + "\" loaded", *g_pIconKame);
264  }
265  else {
266  XMessageBox::post("Failure during loading module \"" + *it + "\"", *g_pIconError);
267  }
268 
269  }
270 
271  const char *greeting = "KAME ver:" VERSION ", built at " __DATE__ " " __TIME__;
272  fprintf(stderr, "%s\n", greeting);
273  gMessagePrint(greeting);
274 
275  int ret = app.exec();
276 
277 //#if defined __WIN32__ || defined WINDOWS || defined _WIN32
278 // FreeConsole();
279 //#endif
280 
281  return ret;
282 }

Generated for KAME4 by  doxygen 1.8.3