diff --git a/dic/compdic.cpp b/dic/compdic.cpp index f1a054e..b067d6b 100644 --- a/dic/compdic.cpp +++ b/dic/compdic.cpp @@ -60,6 +60,8 @@ # define _(String) String #endif +#define MAX_STRING_LENGTH 200 + // Useful shortcut #define fmt(a) boost::format(a) @@ -76,6 +78,15 @@ CompDic::CompDic() m_headerInfo.edgesused = 1; m_headerInfo.nodessaved = 0; m_headerInfo.edgessaved = 0; + + m_stringBuf = new wchar_t[MAX_STRING_LENGTH]; + m_endString = m_stringBuf; +} + + +CompDic::~CompDic() +{ + delete[] m_stringBuf; } diff --git a/dic/compdic.h b/dic/compdic.h index f26f723..efbf48a 100644 --- a/dic/compdic.h +++ b/dic/compdic.h @@ -48,6 +48,7 @@ class CompDic public: CompDic(); + ~CompDic(); /** * Define a new letter. The letter must be alphabetic (i.e. iswalpha() @@ -93,12 +94,10 @@ private: HashMap m_hashMap; -#define MAX_STRING_LENGTH 200 - /// Space for the current string - wchar_t m_stringBuf[MAX_STRING_LENGTH]; + wchar_t *m_stringBuf; /// Point to the end of the string - wchar_t* m_endString; + wchar_t *m_endString; #ifdef CHECK_RECURSION map > m_mapForDepth; int m_currentRec; diff --git a/dic/compdicmain.cpp b/dic/compdicmain.cpp index 991b300..f54eb6f 100644 --- a/dic/compdicmain.cpp +++ b/dic/compdicmain.cpp @@ -260,10 +260,14 @@ int main(int argc, char* argv[]) #endif return 0; } + catch (const BaseException &e) + { + cerr << "Exception caught: " << e.what() << "\n" << e.getStackTrace(); + } catch (std::exception &e) { - cerr << fmt(_("Exception caught: %1%")) % e.what() << endl; - return 1; + cerr << "Exception caught: " << e.what() << endl; } + return 1; } diff --git a/dic/regexp.cpp b/dic/regexp.cpp index f838f0f..07330b7 100644 --- a/dic/regexp.cpp +++ b/dic/regexp.cpp @@ -26,6 +26,7 @@ #include "dic.h" #include "regexp.h" +#include "debug.h" using boost::format; @@ -68,24 +69,30 @@ void Node::traverse(int &p, int &n, int ptl[]) m_DP = 1 << (m_position - 1); break; case NODE_OR: + ASSERT(m_fg, "The left child node should not be NULL"); + ASSERT(m_fd, "The right child node should not be NULL"); m_position = 0; m_annulable = m_fg->m_annulable || m_fd->m_annulable; m_PP = m_fg->m_PP | m_fd->m_PP; m_DP = m_fg->m_DP | m_fd->m_DP; break; case NODE_AND: + ASSERT(m_fg, "The left child node should not be NULL"); + ASSERT(m_fd, "The right child node should not be NULL"); m_position = 0; m_annulable = m_fg->m_annulable && m_fd->m_annulable; m_PP = (m_fg->m_annulable) ? (m_fg->m_PP | m_fd->m_PP) : m_fg->m_PP; m_DP = (m_fd->m_annulable) ? (m_fg->m_DP | m_fd->m_DP) : m_fd->m_DP; break; case NODE_PLUS: + ASSERT(m_fg, "The left child node should not be NULL"); m_position = 0; m_annulable = false; m_PP = m_fg->m_PP; m_DP = m_fg->m_DP; break; case NODE_STAR: + ASSERT(m_fg, "The left child node should not be NULL"); m_position = 0; m_annulable = true; m_PP = m_fg->m_PP; @@ -109,6 +116,8 @@ void Node::nextPos(uint64_t PS[]) /* \forall p \in DP(left) */ /* PS[p] = PS[p] \cup PP(right) */ /************************************/ + ASSERT(m_fg, "The left child node should not be NULL"); + ASSERT(m_fd, "The right child node should not be NULL"); for (uint32_t pos = 1; pos <= PS[0]; pos++) { if (m_fg->m_DP & (1 << (pos-1))) diff --git a/qt/main.cpp b/qt/main.cpp index 878762a..5688172 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -20,6 +20,7 @@ #include "config.h" +#include #include #include #include @@ -162,9 +163,25 @@ int main(int argc, char **argv) app.installTranslator(&translator); #endif - MainWindow qmain; - qmain.show(); - return app.exec(); + try + { + MainWindow qmain; + qmain.show(); + return app.exec(); + } + catch (const BaseException &e) + { + cerr << "Exception caught: " << e.what() << "\n" << e.getStackTrace(); + } + catch (const std::exception &e) + { + cerr << "Exception caught: " << e.what(); + } + catch (...) + { + cerr << "Unknown exception caught"; + } + return 1; } #ifdef HAVE_EXECINFO_H diff --git a/qt/main_window.cpp b/qt/main_window.cpp index 935d027..fb31f83 100644 --- a/qt/main_window.cpp +++ b/qt/main_window.cpp @@ -188,7 +188,7 @@ MainWindow::MainWindow(QWidget *iParent) { m_dic = new Dictionary(lfq(dicPath)); } - catch (DicException &e) + catch (const std::exception &e) { displayErrorMsg(_q("Cannot load dictionary '%1' indicated in the " "preferences.\nReason: %2").arg(dicPath).arg(e.what())); @@ -272,7 +272,7 @@ void MainWindow::refresh() { m_game->save(m_autoSaveGame); } - catch (std::exception &e) + catch (const std::exception &e) { LOG_ERROR("Error during auto-save: " << e.what()); displayErrorMsg(_q("Error during auto-save of the game: %1").arg(e.what())); @@ -615,7 +615,7 @@ void MainWindow::changeDictionary(QString iFileName) QSettings qs; qs.setValue(PrefsDialog::kINTF_DIC_PATH, iFileName); } - catch (std::exception &e) + catch (const std::exception &e) { displayErrorMsg(e.what()); } @@ -829,7 +829,7 @@ void MainWindow::loadGame(QString fileName) destroyCurrentGame(); m_game = tmpGame; } - catch (std::exception &e) + catch (const std::exception &e) { displayErrorMsg(_q("Error while loading the game:\n") + e.what()); return; @@ -856,7 +856,7 @@ void MainWindow::onGameSaveAs() m_game->save(lfq(fileName)); displayInfoMsg(_q("Game saved")); } - catch (std::exception &e) + catch (const std::exception &e) { displayErrorMsg(_q("Error saving game: %1").arg(e.what())); } diff --git a/qt/qtcommon.cpp b/qt/qtcommon.cpp index 836bc06..418d4e9 100644 --- a/qt/qtcommon.cpp +++ b/qt/qtcommon.cpp @@ -31,9 +31,11 @@ #include #include -#include "qtcommon.h" #include +#include "qtcommon.h" +#include "debug.h" + using namespace std; @@ -60,11 +62,13 @@ QString qfw(const wstring &wstr) #endif } -static void logFailedTest(const string &testName) +static void logFailedTest(const string &testName, bool & oFailure) { cerr << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl; cerr << "@@@@@@@ Test " + testName + " failed! @@@@@@@" << endl; cerr << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl << endl; + + oFailure = true; } @@ -72,47 +76,51 @@ void QtCommon::CheckConversions() { string s = "abcdéöùßĿ"; + bool failure = false; + // Check identities if (s != lfw(wfl(s))) - logFailedTest("1"); + logFailedTest("1", failure); if (s != lfu(ufl(s))) - logFailedTest("2"); + logFailedTest("2", failure); if (s != lfq(qfl(s))) - logFailedTest("3"); + logFailedTest("3", failure); wstring w = wfl(s); if (w != wfl(lfw(w))) - logFailedTest("4"); + logFailedTest("4", failure); if (w != wfu(ufw(w))) - logFailedTest("5"); + logFailedTest("5", failure); if (w != wfq(qfw(w))) - logFailedTest("6"); + logFailedTest("6", failure); QString q = qfl(s); if (q != qfl(lfq(q))) - logFailedTest("7"); + logFailedTest("7", failure); if (q != qfu(ufq(q))) - logFailedTest("8"); + logFailedTest("8", failure); if (q != qfw(wfq(q))) - logFailedTest("9"); + logFailedTest("9", failure); // Check some cycles if (s != lfu(ufw(wfl(s)))) - logFailedTest("10"); + logFailedTest("10", failure); if (s != lfw(wfu(ufl(s)))) - logFailedTest("11"); + logFailedTest("11", failure); if (s != lfq(qfw(wfl(s)))) - logFailedTest("12"); + logFailedTest("12", failure); if (s != lfw(wfq(qfl(s)))) - logFailedTest("13"); + logFailedTest("13", failure); if (s != lfu(ufw(wfq(qfl(s))))) - logFailedTest("14"); + logFailedTest("14", failure); if (s != lfq(qfw(wfu(ufl(s))))) - logFailedTest("15"); + logFailedTest("15", failure); if (s != lfu(ufq(qfw(wfl(s))))) - logFailedTest("16"); + logFailedTest("16", failure); if (s != lfw(wfq(qfu(ufl(s))))) - logFailedTest("17"); + logFailedTest("17", failure); + + ASSERT(!failure, "Some string conversions failed"); } diff --git a/utils/ncurses.cpp b/utils/ncurses.cpp index f81017d..2fcbbae 100644 --- a/utils/ncurses.cpp +++ b/utils/ncurses.cpp @@ -31,6 +31,7 @@ # include #endif +#include #include #include // For strlen #include // For iswalnum @@ -1160,64 +1161,91 @@ int main(int argc, char ** argv) srand(time(NULL)); - Game *realGame = GameFactory::Instance()->createFromCmdLine(argc, argv); - if (realGame == NULL) + int retCode = 1; + try { - GameFactory::Destroy(); - return 1; - } - PublicGame *game = new PublicGame(*realGame); - - game->start(); - - // Initialize the ncurses library - WINDOW *wBoard = initscr(); - keypad(wBoard, true); - // Take input chars one at a time - cbreak(); - // Do not do NL -> NL/CR - nonl(); - // Hide the cursor - curs_set(0); - - if (has_colors()) - { - start_color(); - - // Simple color assignment - init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); - init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); - init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); - init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_RED); - - init_pair(COLOR_BLUE, COLOR_BLACK, COLOR_BLUE); - init_pair(COLOR_CYAN, COLOR_BLACK, COLOR_CYAN); - init_pair(COLOR_MAGENTA, COLOR_BLACK, COLOR_MAGENTA); - init_pair(COLOR_RED, COLOR_BLACK, COLOR_RED); - } - - // Do not echo - noecho(); - - // mainIntf will take care of destroying game for us - CursesIntf mainIntf(wBoard, *game); - mainIntf.redraw(wBoard); - - while (!mainIntf.isDying()) - { - int c = getch(); - if (mainIntf.handleKey(c) == 1) + Game *realGame = GameFactory::Instance()->createFromCmdLine(argc, argv); + if (realGame == NULL) { - mainIntf.redraw(wBoard); + GameFactory::Destroy(); + return 1; } + PublicGame *game = new PublicGame(*realGame); + + game->start(); + + // Initialize the ncurses library + WINDOW *wBoard = initscr(); + try + { + keypad(wBoard, true); + // Take input chars one at a time + cbreak(); + // Do not do NL -> NL/CR + nonl(); + // Hide the cursor + curs_set(0); + + if (has_colors()) + { + start_color(); + + // Simple color assignment + init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); + init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); + init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); + init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_RED); + + init_pair(COLOR_BLUE, COLOR_BLACK, COLOR_BLUE); + init_pair(COLOR_CYAN, COLOR_BLACK, COLOR_CYAN); + init_pair(COLOR_MAGENTA, COLOR_BLACK, COLOR_MAGENTA); + init_pair(COLOR_RED, COLOR_BLACK, COLOR_RED); + } + + // Do not echo + noecho(); + + // mainIntf will take care of destroying game for us + CursesIntf mainIntf(wBoard, *game); + mainIntf.redraw(wBoard); + + while (!mainIntf.isDying()) + { + int c = getch(); + if (mainIntf.handleKey(c) == 1) + { + mainIntf.redraw(wBoard); + } + } + } + catch (...) + { + // Clean up + delwin(wBoard); + + // Exit the ncurses library + endwin(); + + // Rethrow the exception + throw; + } + + retCode = 0; + } + catch (const BaseException &e) + { + cerr << "Exception caught: " << e.what() << "\n" << e.getStackTrace(); + } + catch (const std::exception &e) + { + cerr << "Exception caught: " << e.what(); + } + catch (...) + { + cerr << "Unknown exception caught"; } - - delwin(wBoard); - - // Exit the ncurses library - endwin(); GameFactory::Destroy(); - return 0; + return retCode; }