diff options
Diffstat (limited to 'Build/source/libs/graphite/engine-2.3.1/test/RegressionTest/RegressionTest.cpp')
-rw-r--r-- | Build/source/libs/graphite/engine-2.3.1/test/RegressionTest/RegressionTest.cpp | 748 |
1 files changed, 748 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/engine-2.3.1/test/RegressionTest/RegressionTest.cpp b/Build/source/libs/graphite/engine-2.3.1/test/RegressionTest/RegressionTest.cpp new file mode 100644 index 00000000000..1d361a4f3cd --- /dev/null +++ b/Build/source/libs/graphite/engine-2.3.1/test/RegressionTest/RegressionTest.cpp @@ -0,0 +1,748 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2004 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: RegressionTest.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Main file for the Graphite regression test program. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +#include "main.h" +#include "MemoryUsage.h" +#include <cstring> + +//:>******************************************************************************************** +//:> Global variables +//:>******************************************************************************************** +std::ofstream g_strmLog; // log file output stream +std::ofstream g_strmTrace; // debugger trace for selected tests +std::ofstream g_strmMemUsage; + +int g_errorCount; + +// HDC g_hdc; // device-context for bogus window on which to do drawing + +bool g_debugMode = false; +bool g_silentMode = false; + +int g_itcaseStart = 0; // adjust to skip to a certain test + +SegmentMemoryUsage g_smu; +FontMemoryUsage g_fmu; + +std::string g_fontPath = "."; +#ifdef _WIN32 +#define PATH_SEP "\\" +#else +#define PATH_SEP "/" +#endif + +// Forward defintions. +int WriteLog(int); +void CopyWstringToUtf16(std::wstring textStr, gr::utf16 * utf16Buf, int bufSize); + +//:>******************************************************************************************** +//:> Functions +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Main function. +----------------------------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ +#ifdef _WIN32 + _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); +#endif // WIN32 + + int iargc = 1; + while (iargc < argc) + { + if ((strcmp(argv[iargc], "/d") == 0) || (strcmp(argv[iargc], "-d") == 0)) + { + g_debugMode = true; + } + if ((strcmp(argv[iargc], "/s") == 0) || (strcmp(argv[iargc], "-s") == 0)) + { + g_silentMode = true; + } + if ((strcmp(argv[iargc], "/p") == 0) || (strcmp(argv[iargc], "-p") == 0)) + { + iargc++; + if (iargc < argc) + { + g_fontPath = argv[iargc]; + } + } + iargc++; + } + + if (!g_silentMode) + { + std::cout << "Graphite Regression Test\n"; + std::cout << "Files path is " << g_fontPath << "\n\n"; + if (g_debugMode) + std::cout << "In debug mode\n"; + } + + // Start a new log. + g_strmLog.open("grregtest.log"); + if (g_strmLog.fail()) + { + std::cout << "Unable to open log file."; + return -1; + } + + g_errorCount = 0; + +// g_hdc = ::GetDC(NULL); + + WriteToLog("Graphite Regression Test\n\n"); + + // Initialize the tracelog file. + g_strmTrace.open("tracelog.txt"); + g_strmTrace.close(); + + TestCase * ptcaseList = NULL; + int numberOfTests = TestCase::SetupTests(&ptcaseList); + + RunTests(numberOfTests, ptcaseList); + + WriteToLog("\n==============================================\n"); + g_strmLog << "\n\nTOTAL NUMBER OF ERRORS: " << g_errorCount << "\n"; + if (!g_silentMode) + std::cout << "\n\nTOTAL NUMBER OF ERRORS: " << g_errorCount << "\n"; + + g_strmLog.close(); + + ////EngineInstance::DeleteEngines(); + TestCase::DeleteTests(); + +// ::ReleaseDC(NULL, g_hdc); + + // Output segment memory usage information. + //g_strmMemUsage.open("SegMemoryUsage.log"); + //g_smu.prettyPrint(g_strmMemUsage); + //g_strmMemUsage.close(); + + return g_errorCount; +} + +/*---------------------------------------------------------------------------------------------- + Run the tests. +----------------------------------------------------------------------------------------------*/ +void RunTests(int numberOfTests, TestCase * ptcaseList) +{ + Segment * psegPrev = NULL; + RtTextSrc * ptsrcPrev = NULL; + Segment * psegRet = NULL; + RtTextSrc * ptsrcRet = NULL; + + for (int itcase = g_itcaseStart; itcase < numberOfTests; itcase++) + { + TestCase * ptcase = ptcaseList + itcase; + WriteToLog("\n----------------------------------------------\n"); + WriteToLog("Test: "); + + if (!g_silentMode) + std::cout << "Test " << ptcase->TestName() << "..."; + WriteToLog(ptcase->TestName()); + WriteToLog("\n"); + + RunOneTestCase(ptcase, psegPrev, &psegRet, &ptsrcRet); + + delete psegPrev; + delete ptsrcPrev; + psegPrev = psegRet; + ptsrcPrev = ptsrcRet; + psegRet = NULL; + ptsrcRet = NULL; + } + + delete psegPrev; + delete ptsrcPrev; +} + +/*---------------------------------------------------------------------------------------------- + Run a single test case. +----------------------------------------------------------------------------------------------*/ +int RunOneTestCase(TestCase * ptcase, Segment * psegPrev, Segment ** ppsegRet, RtTextSrc ** pptsrcRet) +{ + if (ptcase->Skip()) + { + std::cout << "\nskipped\n"; + g_strmLog << "skipping\n"; + *ppsegRet = NULL; + return 0; + } + +#ifdef _WIN32 + // Break into the debugger if requested. + if (ptcase->RunDebugger() && ::IsDebuggerPresent()) + { + ::DebugBreak(); + } +#endif + + int errorCount = 0; + + gr::utf16 text[1024]; + CopyWstringToUtf16(ptcase->Text(), text, 1024); + + *ppsegRet = NULL; + SegmentPainter * ppainter = NULL; + std::pair<GlyphIterator, GlyphIterator> iterPair; + GlyphIterator gitBegin; + GlyphIterator gitEnd; + + //LOGFONT lf; + //memset(&lf, '\0', sizeof(LOGFONT)); + //lf.lfCharSet = DEFAULT_CHARSET; + //lf.lfHeight = (signed(ptcase->FontSize()) * -96) / 72; // 96 = resolution, 72 = points per inch + //lf.lfWeight = 400; + //lf.lfItalic = FALSE; + //wcscpy(lf.lfFaceName, ptcase->FontName().data()); + //HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + //HFONT hfont = CreateFontIndirect(&lf); + //HFONT hfontOld = (HFONT)::SelectObject(hdc, hfont); // restore before destroying the DC. + //WinFont winfont(hdc); + + FileFont font(g_fontPath + PATH_SEP + ptcase->FontFile(), float(signed(ptcase->FontSize())), 96, 96); + + if (!font.isValid()) + { + OutputError(ptcase, std::string("ERROR: reading font file: \"") + ptcase->FontFile() + "\" at path \"" + g_fontPath + "\"; remaining tests skipped"); + *ppsegRet = NULL; + errorCount++; + return WriteLog(errorCount); + } + + // Set up the text source. + *pptsrcRet = new RtTextSrc(&(text[0])); + RtTextSrc * ptsrc = *pptsrcRet; + (*pptsrcRet)->setFeatures(ptcase->Features()); + (*pptsrcRet)->setRightToLeft(ptcase->Rtl()); + + // Generate a segment. + LayoutEnvironment layout; + layout.setDumbFallback(ptcase->DumbFallback()); + layout.setStartOfLine(true); + layout.setRightToLeft(ptcase->ParaRtl()); + if (ptcase->InitWithPrevSeg()) + layout.setPrevSegment(psegPrev); + + if (ptcase->TraceLog()) + { + g_strmTrace.open("tracelog.txt", std::ios::app); + g_strmTrace << "Test: " << ptcase->TestName() << "\n\n"; + layout.setLoggingStream(&g_strmTrace); + } + + try + { + if (ptcase->AvailWidth() < 10000) + { + layout.setBestBreak(ptcase->PrefBreak()); + layout.setWorstBreak(ptcase->WorstBreak()); + layout.setTrailingWs(ptcase->Twsh()); + *ppsegRet = new LineFillSegment(&font, ptsrc, &layout, + ptcase->FirstChar(), ptsrc->getLength(), + (float)ptcase->AvailWidth(), + ptcase->Backtrack()); + } + else + { + *ppsegRet = new RangeSegment(&font, ptsrc, &layout); + } + } + catch (...) + { + if (!ptcase->NoSegment()) + { + if (ptcase->BadFont() && !ptcase->DumbFallback()) + // Weird situation. + OutputError(ptcase, "ERROR: bad font with no fallback, yet a segment was expected???"); + else + OutputError(ptcase, "ERROR: generating segment; remaining tests skipped"); + errorCount++; + } + // else segment creation failed as expected + + // NB: failure to create a segment due to throwing an exception seems to result in a memory + // leak--the FontCache object FontFace::s_pFontCache does not get deleted. + + *ppsegRet = NULL; + return WriteLog(errorCount); + } + + if (ptcase->TraceLog()) + { + g_strmTrace << "\n\n*********************************************************************************************************************\n\n"; + g_strmTrace.close(); + } + + if ((*ppsegRet) && (*ppsegRet)->segmentTermination() == kestNothingFit) + { + delete *ppsegRet; + *ppsegRet = NULL; + } + + if ((*ppsegRet) == NULL && !ptcase->NoSegment()) + { + OutputError(ptcase, "ERROR: segment not created; remaining tests skipped"); + errorCount++; + return WriteLog(errorCount); + } + else if (ptcase->NoSegment()) + { + if (*ppsegRet) + { + OutputError(ptcase, "ERROR: segment created when none expected"); + errorCount++; + } + delete *ppsegRet; + *ppsegRet = NULL; + return WriteLog(errorCount); + } + + Segment * pseg = *ppsegRet; + + pseg->calculateMemoryUsage(g_smu); + + // Calculate and output font memory usage. + //g_fmu = Font::calculateMemoryUsage(); + //g_strmMemUsage.open("fontMemoryUsage.log"); + //g_fmu.prettyPrint(g_strmMemUsage); + //g_strmMemUsage.close(); + + // Test results. + int segMin = pseg->startCharacter(); + int segLim = pseg->stopCharacter(); + if ((segLim - segMin) != ptcase->CharCount()) + { + OutputErrorWithValues(ptcase, "ERROR: number of characters in segment", -1, + (segLim - segMin), ptcase->CharCount()); + errorCount++; + } + + int segWidth = (int)pseg->advanceWidth(); + if (segWidth != ptcase->SegWidth()) + { + OutputErrorWithValues(ptcase, "ERROR: width of segment", -1, + segWidth, ptcase->SegWidth()); + errorCount++; + } + + iterPair = pseg->glyphs(); + gitBegin = iterPair.first; + gitEnd = iterPair.second; + int cGlyphs = gitEnd - gitBegin; + if (cGlyphs != ptcase->GlyphCount()) + { + OutputErrorWithValues(ptcase, "ERROR: number of glyphs", -1, + cGlyphs, ptcase->GlyphCount()); + errorCount++; + } + else + { + GlyphIterator gitThis = gitBegin; + for (int iglyph = 0; gitThis != gitEnd; ++gitThis, iglyph++) + { + if ((*gitThis).glyphID() != ptcase->GlyphID(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph id ", iglyph, + (*gitThis).glyphID(), ptcase->GlyphID(iglyph)); + errorCount++; + } + if (int((*gitThis).origin()) != ptcase->XPos(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph x-position ", iglyph, + int((*gitThis).origin()), ptcase->XPos(iglyph)); + errorCount++; + } + if (int((*gitThis).yOffset()) != ptcase->YPos(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph y-position ", iglyph, + int((*gitThis).yOffset()), ptcase->YPos(iglyph)); + errorCount++; + } + if (int((*gitThis).advanceWidth()) != ptcase->AdvWidth(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: advance width ", iglyph, + int((*gitThis).advanceWidth()), ptcase->AdvWidth(iglyph)); + errorCount++; + } + if (ptcase->BbTests()) + { + gr::Rect rectBb = (*gitThis).bb(); + if (int(rectBb.left) != ptcase->BbLeft(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb left ", iglyph, + int(rectBb.left), ptcase->BbLeft(iglyph)); + errorCount++; + } + if (int(rectBb.right) != ptcase->BbRight(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb right ", iglyph, + int(rectBb.right), ptcase->BbRight(iglyph)); + errorCount++; + } + if (int(rectBb.top) != ptcase->BbTop(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb top ", iglyph, + int(rectBb.top), ptcase->BbTop(iglyph)); + errorCount++; + } + if (int(rectBb.bottom) != ptcase->BbBottom(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb bottom ", iglyph, + int(rectBb.bottom), ptcase->BbBottom(iglyph)); + errorCount++; + } + } + } + } + + ppainter = new SegmentNonPainter(pseg); + + if (segLim == ptcase->CharCount()) + { + for (int ichar = 0; ichar < segLim; ichar++) + { + LgIpValidResult ipvr = ppainter->isValidInsertionPoint(ichar); + if ((ipvr == kipvrOK && !ptcase->InsPtFlag(ichar)) // TODO: handle kipvrUnknown + || (ipvr != kipvrOK && ptcase->InsPtFlag(ichar))) + { + OutputErrorWithValues(ptcase, "ERROR: valid insertion point ", ichar, + (ipvr == kipvrOK), ptcase->InsPtFlag(ichar)); + errorCount++; + } + } + } + + int c2gi = 0; + while (c2gi < ptcase->CharToGlyphCount()) + { + int ichar = ptcase->CharToGlyphItem(c2gi++); + int glyphCount = ptcase->CharToGlyphItem(c2gi++); + std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyphSet = pseg->charToGlyphs(ichar); + gr::GlyphSetIterator gitStart = glyphSet.first; + gr::GlyphSetIterator gitStop = glyphSet.second; + if ((gitStop - gitStart) != glyphCount) + { + OutputErrorWithValues(ptcase, "ERROR: number of glyphs for char ", ichar, + gitStop - gitStart, glyphCount); + errorCount++; + c2gi += glyphCount; + } + else + { + GlyphSetIterator glyphLp = glyphSet.first; + for (int ig = 0; ig < glyphCount; ig++) + { + if (static_cast<int>((*glyphLp).logicalIndex()) != ptcase->CharToGlyphItem(c2gi)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph for char ", ichar, + (*glyphLp).logicalIndex(), ptcase->CharToGlyphItem(c2gi)); + errorCount++; + } + c2gi++; + glyphLp++; + } + } + } + + int att = 0; + while (att < ptcase->AttachedGlyphCount()) + { + int iglyph = ptcase->AttachedGlyphItem(att++); + if (iglyph > cGlyphs) + { + OutputError(ptcase, "ERROR: non-existent glyph in attachment test ", iglyph); + errorCount++; + att++; + att += ptcase->AttachedGlyphItem(att) + 1; + continue; + } + + GlyphIterator gitThis = gitBegin + iglyph; + GlyphIterator gitBase = gitThis->attachedClusterBase(); + int ibase = gitBase->logicalIndex(); + if (ibase != ptcase->AttachedGlyphItem(att)) + { + OutputErrorWithValues(ptcase, "ERROR: attachment base for glyph ", iglyph, + ibase, ptcase->AttachedGlyphItem(att)); + errorCount++; + } + att++; + std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyphSet = gitThis->attachedClusterGlyphs(); + gr::GlyphSetIterator gitStart = glyphSet.first; + gr::GlyphSetIterator gitStop = glyphSet.second; + int glyphCount = ptcase->AttachedGlyphItem(att++); + if ((gitStop - gitStart) != glyphCount) + { + OutputErrorWithValues(ptcase, "ERROR: number of attachments for glyph ", iglyph, + gitStop - gitStart, glyphCount); + errorCount++; + att += glyphCount; + } + else + { + GlyphSetIterator glyphLp = glyphSet.first; + for (int ig = 0; ig < glyphCount; ig++) + { + if (static_cast<int>((*glyphLp).logicalIndex()) != ptcase->AttachedGlyphItem(att)) + { + OutputErrorWithValues(ptcase, "ERROR: attachment for glyph ", iglyph, + (*glyphLp).logicalIndex(), ptcase->AttachedGlyphItem(att)); + errorCount++; + } + att++; + glyphLp++; + } + } + } + + for (int iclicktest = 0; iclicktest < ptcase->NumberOfClickTests(); iclicktest++) + { + gr::Point ptClick; + ptClick.x = static_cast<float>(ptcase->XClick(iclicktest)); + ptClick.y = static_cast<float>(ptcase->YClick(iclicktest)); + int charIndex; + bool assocPrev; + ppainter->pointToChar(ptClick, &charIndex, &assocPrev); + if (charIndex != ptcase->ClickCharIndex(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: char index from click ", iclicktest, + charIndex, ptcase->ClickCharIndex(iclicktest)); + errorCount++; + continue; + } + if (assocPrev != ptcase->ClickAssocPrev(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: assoc-prev from click ", iclicktest, + assocPrev, ptcase->ClickAssocPrev(iclicktest)); + errorCount++; + } + gr::Rect rect1, rect2; + ppainter->positionsOfIP(charIndex, assocPrev, + false, &rect1, &rect2); + if (ptcase->Sel1Top(iclicktest) == TestCase::kAbsent) + { + if (rect1.top != 0 || rect1.bottom != 0 || rect1.left != 0 || rect1.right != 0) + { + OutputError(ptcase, "ERROR: IP prim rect found ", iclicktest); + errorCount++; + } + } + else if (rect1.top == 0 && rect1.bottom == 0 && rect1.left == 0 && rect1.right == 0) + { + OutputError(ptcase, "ERROR: IP prim rect not found ", iclicktest); + errorCount++; + } + else + { + if ((int)rect1.top != ptcase->Sel1Top(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect top ", iclicktest, + int(rect1.top), ptcase->Sel1Top(iclicktest)); + errorCount++; + } + if ((int)rect1.bottom != ptcase->Sel1Bottom(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect bottom ", iclicktest, + int(rect1.bottom), ptcase->Sel1Bottom(iclicktest)); + errorCount++; + } + if ((int)rect1.left != ptcase->Sel1Left(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect left ", iclicktest, + int(rect1.left), ptcase->Sel1Left(iclicktest)); + errorCount++; + } + } + + if (ptcase->Sel2Top(iclicktest) == TestCase::kAbsent) + { + if (rect2.top != 0 || rect2.bottom != 0 || rect2.left != 0 || rect2.right != 0) + { + OutputError(ptcase, "ERROR: IP sec rect found when not expected ", iclicktest); + errorCount++; + } + } + else if (rect2.top == 0 && rect2.bottom == 0 && rect2.left == 0 && rect2.right == 0) + { + OutputError(ptcase, "ERROR: IP sec rect not found ", iclicktest); + errorCount++; + } + else + { + if ((int)rect2.top != ptcase->Sel2Top(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect top ", iclicktest, + int(rect2.top), ptcase->Sel2Top(iclicktest)); + errorCount++; + } + if ((int)rect2.bottom != ptcase->Sel2Bottom(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect bottom ", iclicktest, + int(rect2.bottom), ptcase->Sel2Bottom(iclicktest)); + errorCount++; + } + if ((int)rect2.left != ptcase->Sel2Left(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect left ", iclicktest, + int(rect2.left), ptcase->Sel2Left(iclicktest)); + errorCount++; + } + } + } + + ////if (contextBlockOut != ptcase->OutputContextBlockSize()) + ////{ + //// OutputErrorWithValues(ptcase, "ERROR: output context block size ", -1, + //// (int)contextBlockOut, (int)ptcase->OutputContextBlockSize()); + //// errorCount++; + ////} + ////else if (!ptcase->CompareContextBlock(pContextBlockOut)) + ////{ + //// OutputError(ptcase, "ERROR: output context block"); + //// errorCount++; + ////} + delete ppainter; + + return WriteLog(errorCount); +} + + +/*---------------------------------------------------------------------------------------------- + Write the error count to the log. +----------------------------------------------------------------------------------------------*/ +int WriteLog(int errorCount) +{ + WriteToLog("\nError count = "); + WriteToLog(errorCount); + WriteToLog("\n"); + + if (!g_silentMode) + { + if (errorCount == 0) + std::cout << "ok\n"; + else + std::cout << "FAILED\n"; + } + + + //delete pseg; // don't delete these; they are passed back to the calling method + //delete ptsrc; + + // Delete device context + //DeleteObject(SelectObject(hdc, hfontOld)); + //DeleteDC(hdc); + + g_errorCount += errorCount; + return errorCount; +} + +/*---------------------------------------------------------------------------------------------- + Copy a std::wstring (whose bytes can be of various sizes on different platforms) + to a buffer of UTF16. +----------------------------------------------------------------------------------------------*/ +void CopyWstringToUtf16(std::wstring textStr, gr::utf16 * utf16Buf, int bufSize) +{ + std::fill_n(utf16Buf, bufSize, 0); + int cc = textStr.length(); + for (int i = 0; i < cc; i++) + utf16Buf[i] = textStr[i]; +} + +/*---------------------------------------------------------------------------------------------- + Output information about an error. +----------------------------------------------------------------------------------------------*/ +void OutputError(TestCase * ptcase, std::string strErr, int i) +{ + OutputErrorAux(ptcase, strErr, i, false, 0, 0); +} + +void OutputErrorWithValues(TestCase * ptcase, std::string strErr, int i, + int valueFound, int valueExpected) +{ + OutputErrorAux(ptcase, strErr, i, true, valueFound, valueExpected); +} + +void OutputErrorAux(TestCase * ptcase, std::string strErr, int i, + bool showValues, int valueFound, int valueExpected) +{ +// if (g_debugMode) +// ::DebugBreak(); + + if (!g_silentMode) + { + //std::cout << ptcase->TestName() << ": "; + std::cout << strErr; + if (i > -1) + { + std::cout << "[" << i << "]"; + } + std::cout << "\n "; + } + + WriteToLog(strErr, i, showValues, valueFound, valueExpected); + + WriteToLog("\n"); +} + +/*---------------------------------------------------------------------------------------------- + Write some text to the log file. +----------------------------------------------------------------------------------------------*/ +bool WriteToLog(std::string str, int i) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << str; + if (i > -1) + g_strmLog << "[" << i << "]"; + g_strmLog.flush(); + return true; +} + +bool WriteToLog(std::string str, int i, + bool showValues, int valueFound, int valueExpected) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << str; + if (i > -1) + g_strmLog << "[" << i << "]"; + if (showValues) + { + g_strmLog << "; found " << valueFound << " not " << valueExpected; + } + g_strmLog.flush(); + return true; +} + + +bool WriteToLog(int n) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << n; + g_strmLog.flush(); + return true; +} + |