testlib.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. #ifndef _TESTLIB_H_
  2. #define _TESTLIB_H_
  3. /*
  4. *
  5. * Copyright (c) 2005-2008
  6. */
  7. #define VERSION "0.5.2"
  8. /*
  9. * Mike Mirzayanov
  10. *
  11. * This material is provided "as is", with absolutely no warranty expressed
  12. * or implied. Any use is at your own risk.
  13. *
  14. * Permission to use or copy this software for any purpose is hereby granted
  15. * without fee, provided the above notices are retained on all copies.
  16. * Permission to modify the code and to distribute modified code is granted,
  17. * provided the above notices are retained, and a notice that the code was
  18. * modified is included with the above copyright notice.
  19. *
  20. */
  21. /* NOTE: This file contains testlib library for C++.
  22. *
  23. * Program, using testlib running format:
  24. * check.exe <Input_File> <Output_File> <Answer_File> [<Result_File> [-appes]],
  25. *
  26. * If result file is specified it will contain results.
  27. */
  28. const char* latestFeatures[] = {
  29. "Added InStream::readLong() and removed InStream::readLongint()",
  30. "Now no footer added to each report by default (use directive FOOTER to switch on)",
  31. "Now every checker has a name, use setName(const char* format, ...) to set it",
  32. "Now it is compatible with TTS (by Kittens Computing)",
  33. "Added \'ensure(condition, message = \"\")\' feature, it works like assert()",
  34. "Fixed compatibility with MS C++ 7.1",
  35. "Added footer with exit code information",
  36. "Added compatibility with EJUDGE (compile with EJUDGE directive)"
  37. };
  38. #include <cstdio>
  39. #include <cctype>
  40. #include <string>
  41. #include <string.h>
  42. #include <stdarg.h>
  43. #include <cstdlib>
  44. #if ( _WIN32 || __WIN32__ )
  45. #include <windows.h>
  46. #else
  47. #define WORD unsigned short
  48. #endif
  49. #define ABS(f) ((f) < 0 ? -(f) : (f))
  50. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  51. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  52. #define OUTPUT_BUFFER_SIZE (2097152)
  53. #define LF (char)10
  54. #define CR (char)13
  55. #define TAB (char)9
  56. #define SPACE (char)' '
  57. #define EOFCHAR (EOF)
  58. #define EOFREMAP SPACE
  59. #define NUMBERBEFORE LF, CR, SPACE, TAB, EOFCHAR
  60. #define NUMBERAFTER LF, CR, TAB, EOFCHAR
  61. #define LINEAFTER LF, CR, EOFCHAR
  62. #define BLANKS LF, CR, SPACE, TAB
  63. #define EOLNCHAR LF, CR, EOFCHAR
  64. #ifndef EJUDGE
  65. #define OK_EXIT_CODE 0
  66. #define WA_EXIT_CODE 1
  67. #define PE_EXIT_CODE 2
  68. #define FAIL_EXIT_CODE 3
  69. #define DIRT_EXIT_CODE 4
  70. #else
  71. #define OK_EXIT_CODE 0
  72. #define WA_EXIT_CODE 5
  73. #define PE_EXIT_CODE 4
  74. #define FAIL_EXIT_CODE 6
  75. #define DIRT_EXIT_CODE 6
  76. #endif
  77. inline bool isEofChar(char c)
  78. {
  79. return (c == EOFCHAR);
  80. }
  81. inline bool isEofRemap(char c)
  82. {
  83. return (c == EOFREMAP);
  84. }
  85. inline bool isNumberBefore(char c)
  86. {
  87. return (c == LF || c == CR || c == SPACE || c == TAB);
  88. }
  89. inline bool isNumberAfter(char c)
  90. {
  91. return (c == LF || c == CR || c == SPACE || c == TAB || c == EOFCHAR || c == (char)26);
  92. }
  93. inline bool isLineAfter(char c)
  94. {
  95. return (c == LF || c == CR || c == EOFCHAR || c == (char)26);
  96. }
  97. inline bool isBlanks(char c)
  98. {
  99. return (c == LF || c == CR || c == SPACE || c == TAB);
  100. }
  101. inline bool isEolnChar(char c)
  102. {
  103. return (c == LF || c == CR || c == EOFCHAR || c == (char)26);
  104. }
  105. struct TCharSet
  106. {
  107. unsigned int data[64];
  108. void insert(char c)
  109. {
  110. int pc = (int)c;
  111. data[pc >> 3] |= (1 << (pc & 7));
  112. }
  113. bool count(char c)
  114. {
  115. unsigned int pc = (unsigned char)c;
  116. return (data[pc >> 3] & (1 << (pc & 7))) != 0;
  117. }
  118. void clear()
  119. {
  120. memset(data, 0, sizeof(data));
  121. }
  122. TCharSet()
  123. {
  124. clear();
  125. }
  126. TCharSet(char c0)
  127. {
  128. clear();
  129. insert(c0);
  130. }
  131. TCharSet(char c0, char c1)
  132. {
  133. clear();
  134. insert(c0); insert(c1);
  135. }
  136. TCharSet(char c0, char c1, char c2)
  137. {
  138. clear();
  139. insert(c0); insert(c1); insert(c2);
  140. }
  141. TCharSet(char c0, char c1, char c2, char c3)
  142. {
  143. clear();
  144. insert(c0); insert(c1); insert(c2); insert(c3);
  145. }
  146. TCharSet(char c0, char c1, char c2, char c3, char c4)
  147. {
  148. clear();
  149. insert(c0); insert(c1); insert(c2); insert(c3); insert(c4);
  150. }
  151. };
  152. enum TMode
  153. {
  154. _input, _output, _answer
  155. };
  156. enum TResult
  157. {
  158. _ok, _wa, _pe, _fail, _dirt
  159. };
  160. const std::string outcomes[] =
  161. {"accepted", "wrong-answer", "presentation-error", "fail", "fail"};
  162. struct InStream
  163. {
  164. InStream();
  165. std::FILE * file;
  166. std::string name;
  167. TMode mode;
  168. bool opened;
  169. void init(std::string fileName, TMode mode);
  170. char curChar();
  171. void skipChar();
  172. char nextChar();
  173. void reset();
  174. bool eof();
  175. bool seekEof();
  176. bool eoln();
  177. bool seekEoln();
  178. void nextLine();
  179. void skip(TCharSet setof);
  180. std::string readWord(TCharSet before, TCharSet after);
  181. std::string readWord();
  182. long long readLong();
  183. int readInteger();
  184. int readInt();
  185. double readReal();
  186. double readDouble();
  187. std::string readString();
  188. void quit(TResult result, const char * msg);
  189. void quits(TResult result, std::string msg);
  190. void close();
  191. const static WORD LightGray = 0x07;
  192. const static WORD LightRed = 0x0c;
  193. const static WORD LightCyan = 0x0b;
  194. const static WORD LightGreen = 0x0a;
  195. static void textColor(WORD color);
  196. static void quitscr(WORD color, const char * msg);
  197. static void quitscrS(WORD color, std::string msg);
  198. void xmlSafeWrite(std::FILE * file, const char * msg);
  199. };
  200. InStream inf;
  201. InStream ouf;
  202. InStream ans;
  203. bool appesMode;
  204. std::string resultName;
  205. std::string checkerName = "untitled checker";
  206. /* implementation
  207. */
  208. InStream::InStream()
  209. {
  210. file = NULL;
  211. name = "";
  212. mode = _input;
  213. }
  214. int resultExitCode(TResult r)
  215. {
  216. if (r == _ok)
  217. return OK_EXIT_CODE;
  218. if (r == _wa)
  219. return WA_EXIT_CODE;
  220. if (r == _pe)
  221. return PE_EXIT_CODE;
  222. if (r == _fail)
  223. return FAIL_EXIT_CODE;
  224. if (r == _dirt)
  225. return DIRT_EXIT_CODE;
  226. return FAIL_EXIT_CODE;
  227. }
  228. void InStream::textColor(WORD color)
  229. {
  230. #if ( _WIN32 || __WIN32__ )
  231. HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
  232. SetConsoleTextAttribute(handle, color);
  233. #endif
  234. }
  235. void halt(int exitCode)
  236. {
  237. #ifdef FOOTER
  238. InStream::textColor(InStream::LightGray);
  239. std::printf("Checker: \"%s\"\n", checkerName.c_str());
  240. std::printf("Exit code: %d\n", exitCode);
  241. InStream::textColor(InStream::LightGray);
  242. #endif
  243. std::exit(exitCode);
  244. }
  245. void InStream::quit(TResult result, const char * msg)
  246. {
  247. if (mode != _output && result != _fail)
  248. quits(_fail, std::string(msg) + " (" + name + ")");
  249. std::FILE * resultFile;
  250. std::string errorName;
  251. if (result == _ok)
  252. {
  253. if (!ouf.seekEof())
  254. quit(_dirt, "Extra information in the output file");
  255. }
  256. switch (result)
  257. {
  258. case _fail:
  259. errorName = "FAIL ";
  260. quitscrS(LightRed, errorName);
  261. break;
  262. case _dirt:
  263. errorName = "wrong output format ";
  264. quitscrS(LightCyan, errorName);
  265. result = _pe;
  266. break;
  267. case _pe:
  268. errorName = "wrong output format ";
  269. quitscrS(LightRed, errorName);
  270. break;
  271. case _ok:
  272. errorName = "ok ";
  273. quitscrS(LightGreen, errorName);
  274. break;
  275. case _wa:
  276. errorName = "wrong answer ";
  277. quitscrS(LightRed, errorName);
  278. break;
  279. default:
  280. quit(_fail, "What is the code ??? ");
  281. }
  282. if (resultName != "")
  283. {
  284. resultFile = std::fopen(resultName.c_str(), "w");
  285. if (resultFile == NULL)
  286. quit(_fail, "Can not write to Result file");
  287. if (appesMode)
  288. {
  289. fprintf(resultFile, "<?xml version=\"1.0\" encoding=\"windows-1251\"?>");
  290. fprintf(resultFile, "<result outcome = \"%s\">", outcomes[(int)result].c_str());
  291. xmlSafeWrite(resultFile, msg);
  292. fprintf(resultFile, "</result>\n");
  293. }
  294. else
  295. {
  296. /** old-style format
  297. * fprintf(resultFile, ".Testlib Result Number = %d\n", (int)result);
  298. * fprintf(resultFile, ".Result name (optional) = %s\n", errorName.c_str());
  299. * fprintf(resultFile, ".Check Comments = %s\n", msg);
  300. */
  301. fprintf(resultFile, "%s", msg);
  302. }
  303. if (NULL == resultFile || fclose(resultFile) != 0)
  304. quit(_fail, "Can not write to Result file");
  305. }
  306. quitscr(LightGray, msg);
  307. std::printf("\n");
  308. if (inf.file)
  309. fclose(inf.file);
  310. if (ouf.file)
  311. fclose(ouf.file);
  312. if (ans.file)
  313. fclose(ans.file);
  314. textColor(LightGray);
  315. if (resultName != "")
  316. std::printf("See file to check exit message\n");
  317. halt(resultExitCode(result));
  318. }
  319. void InStream::quits(TResult result, std::string msg)
  320. {
  321. InStream::quit(result, msg.c_str());
  322. }
  323. void InStream::xmlSafeWrite(std::FILE * file, const char * msg)
  324. {
  325. size_t lmsg = strlen(msg);
  326. for (size_t i = 0; i < lmsg; i++)
  327. {
  328. if (msg[i] == '&')
  329. {
  330. fprintf(file, "%s", "&amp;");
  331. continue;
  332. }
  333. if (msg[i] == '<')
  334. {
  335. fprintf(file, "%s", "&lt;");
  336. continue;
  337. }
  338. if (msg[i] == '>')
  339. {
  340. fprintf(file, "%s", "&gt;");
  341. continue;
  342. }
  343. if (msg[i] == '"')
  344. {
  345. fprintf(file, "%s", "&quot;");
  346. continue;
  347. }
  348. if (0 <= msg[i] && msg[i] <= 31)
  349. {
  350. fprintf(file, "%c", '.');
  351. continue;
  352. }
  353. fprintf(file, "%c", msg[i]);
  354. }
  355. }
  356. void InStream::quitscrS(WORD color, std::string msg)
  357. {
  358. quitscr(color, msg.c_str());
  359. }
  360. void InStream::quitscr(WORD color, const char * msg)
  361. {
  362. if (resultName == "")
  363. {
  364. textColor(color);
  365. std::printf("%s", msg);
  366. textColor(LightGray);
  367. }
  368. }
  369. void InStream::reset()
  370. {
  371. if (opened)
  372. close();
  373. if (NULL == (file = std::fopen(name.c_str(), "r")))
  374. {
  375. if (mode == _output)
  376. quits(_pe, std::string("File not found: \"") + name + "\"");
  377. }
  378. opened = true;
  379. }
  380. void InStream::init(std::string fileName, TMode mode)
  381. {
  382. opened = false;
  383. name = fileName;
  384. this->mode = mode;
  385. reset();
  386. }
  387. char InStream::curChar()
  388. {
  389. char c = (char)getc(file);
  390. ungetc(c, file);
  391. return c;
  392. }
  393. char InStream::nextChar()
  394. {
  395. return (char)getc(file);
  396. }
  397. void InStream::skipChar()
  398. {
  399. getc(file);
  400. }
  401. std::string InStream::readWord(TCharSet before, TCharSet after)
  402. {
  403. char cur;
  404. while (before.count(cur = (char)getc(file)) == 1);
  405. if (cur == EOFCHAR && !after.count(cur))
  406. {
  407. quit(_pe, "Unexpected end of file");
  408. }
  409. std::string result = "";
  410. while (!(after.count(cur) || cur == EOFCHAR))
  411. {
  412. result += cur;
  413. cur = (char)getc(file);
  414. }
  415. ungetc(cur, file);
  416. return result;
  417. }
  418. std::string InStream::readWord()
  419. {
  420. return readWord(TCharSet(BLANKS), TCharSet(BLANKS));
  421. }
  422. int InStream::readInteger()
  423. {
  424. char cur;
  425. while (isNumberBefore(cur = (char)getc(file)));
  426. if (cur == EOFCHAR)
  427. quit(_pe, "Unexpected end of file - integer expected");
  428. ungetc(cur, file);
  429. int retval;
  430. if (fscanf(file, "%d", &retval) != 1)
  431. // todo: show insted-of
  432. quit(_pe, "Expected integer");
  433. return retval;
  434. }
  435. long long InStream::readLong()
  436. {
  437. char cur;
  438. while (isNumberBefore(cur = (char)getc(file)));
  439. if (cur == EOFCHAR)
  440. quit(_pe, "Unexpected end of file - long expected");
  441. ungetc(cur, file);
  442. long long retval;
  443. if (fscanf(file, "%I64d", &retval) != 1)
  444. // todo: show insted-of
  445. quit(_pe, "Expected long");
  446. return retval;
  447. }
  448. int InStream::readInt()
  449. {
  450. return readInteger();
  451. }
  452. double InStream::readReal()
  453. {
  454. if (seekEof())
  455. quit(_pe, "Unexpected end of file - double expected");
  456. double retval;
  457. if (fscanf(file, "%lf", &retval) != 1)
  458. // todo: show insted-of
  459. quit(_pe, "Expected double");
  460. return retval;
  461. }
  462. double InStream::readDouble()
  463. {
  464. return readReal();
  465. }
  466. void InStream::skip(TCharSet setof)
  467. {
  468. char cur;
  469. while (setof.count(cur = (char)getc(file)) == 1);
  470. ungetc(cur, file);
  471. }
  472. bool InStream::eof()
  473. {
  474. return (NULL == file || feof(file) != 0);
  475. }
  476. bool InStream::seekEof()
  477. {
  478. if (NULL == file)
  479. return true;
  480. char cur;
  481. while (isBlanks(cur = (char)getc(file)));
  482. ungetc(cur, file);
  483. return (NULL == file || feof(file) != 0 || cur == EOF);
  484. }
  485. bool InStream::eoln()
  486. {
  487. if (NULL == file)
  488. return true;
  489. char c = curChar();
  490. return isEolnChar(c);
  491. }
  492. bool InStream::seekEoln()
  493. {
  494. if (NULL == file)
  495. return true;
  496. char cur;
  497. do
  498. {
  499. cur = (char)getc(file);
  500. }
  501. while (cur == SPACE || cur == TAB);
  502. ungetc(cur, file);
  503. return isEolnChar(cur);
  504. }
  505. void InStream::nextLine()
  506. {
  507. if (NULL == file)
  508. return;
  509. char cur;
  510. while (!isEolnChar(cur = (char)getc(file)));
  511. if (cur == CR)
  512. {
  513. cur = (char)getc(file);
  514. if (cur != LF)
  515. ungetc(cur, file);
  516. }
  517. else
  518. {
  519. if (cur != LF)
  520. ungetc(cur, file);
  521. }
  522. }
  523. std::string InStream::readString()
  524. {
  525. if (NULL == file)
  526. quit(_pe, "Expected line");
  527. std::string retval = "";
  528. char cur;
  529. while (!isEolnChar(cur = (char)getc(file)))
  530. retval += cur;
  531. if (cur == CR)
  532. {
  533. cur = (char)getc(file);
  534. if (cur != LF)
  535. ungetc(cur, file);
  536. }
  537. else
  538. {
  539. if (cur != LF)
  540. ungetc(cur, file);
  541. }
  542. return retval;
  543. }
  544. void InStream::close()
  545. {
  546. if (opened)
  547. fclose(file);
  548. opened = false;
  549. }
  550. void quit(TResult result, const std::string& msg)
  551. {
  552. ouf.quit(result, msg.c_str());
  553. }
  554. void quit(TResult result, const char * msg)
  555. {
  556. ouf.quit(result, msg);
  557. }
  558. void quitf(TResult result, const char * format, ...)
  559. {
  560. char * buffer = new char [OUTPUT_BUFFER_SIZE];
  561. va_list ap;
  562. va_start(ap, format);
  563. std::vsprintf(buffer, format, ap);
  564. va_end(ap);
  565. std::string output(buffer);
  566. delete[] buffer;
  567. quit(result, output);
  568. }
  569. void registerTestlibCmd(int argc, char * argv[])
  570. {
  571. if (argc > 1 && !strcmp("--help", argv[1]))
  572. {
  573. InStream::textColor(InStream::LightCyan);
  574. std::printf("TESTLIB %s ", VERSION);
  575. std::printf("by Mike Mirzayanov, copyright(c) 2005-2006\n");
  576. std::printf("Checker name: \"%s\"\n", checkerName.c_str());
  577. InStream::textColor(InStream::LightGray);
  578. std::printf("\n");
  579. std::printf("Latest features: \n");
  580. for (size_t i = 0; i < sizeof(latestFeatures) / sizeof(char*); i++)
  581. {
  582. std::printf("*) %s\n", latestFeatures[i]);
  583. }
  584. std::printf("\n");
  585. std::printf("Program must be run with the following arguments: \n");
  586. std::printf(" <input-file> <output-file> <answer-file> [<report-file> [<-appes>]]\n\n");
  587. std::exit(0);
  588. }
  589. if (sizeof(int) != 4)
  590. quit(_fail, "'testlib' unit assumes 'sizeof(integer) = 4'");
  591. if (argc < 4 || argc > 6)
  592. {
  593. quit(_fail, std::string("Program must be run with the following arguments: ") +
  594. std::string("<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]") +
  595. "\nUse \"--help\" to get help information");
  596. }
  597. if (argc == 4)
  598. {
  599. resultName = "";
  600. appesMode = false;
  601. }
  602. if (argc == 5)
  603. {
  604. resultName = argv[4];
  605. appesMode = false;
  606. }
  607. if (argc == 6)
  608. {
  609. if (strcmp("-APPES", argv[5]) && strcmp("-appes", argv[5]))
  610. {
  611. quit(_fail, std::string("Program must be run with the following arguments: ") +
  612. "<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]");
  613. }
  614. else
  615. {
  616. resultName = argv[4];
  617. appesMode = true;
  618. }
  619. }
  620. inf.init(argv[1], _input);
  621. ouf.init(argv[2], _output);
  622. ans.init(argv[3], _answer);
  623. }
  624. void registerTestlib(int argc, ...)
  625. {
  626. if (argc < 3 || argc > 5)
  627. quit(_fail, std::string("Program must be run with the following arguments: ") +
  628. "<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]");
  629. char ** argv = new char*[argc + 1];
  630. va_list ap;
  631. va_start(ap, argc);
  632. argv[0] = NULL;
  633. for (int i = 0; i < argc; i++)
  634. {
  635. argv[i + 1] = va_arg(ap, char *);
  636. }
  637. va_end(ap);
  638. registerTestlibCmd(argc + 1, argv);
  639. delete[] argv;
  640. }
  641. inline bool isNaN(double r)
  642. {
  643. return ((r != r) == true) && ((r == r) == false) && ((1.0 > r) == false) && ((1.0 < r) == false);
  644. }
  645. inline bool isInfinite(double r)
  646. {
  647. return (r > 1E100 || r < -1E100);
  648. }
  649. bool doubleCompare(double expected, double result, double MAX_DOUBLE_ERROR)
  650. {
  651. if(isNaN(expected))
  652. {
  653. return isNaN(result);
  654. }
  655. else
  656. if(isInfinite(expected))
  657. {
  658. if(expected > 0)
  659. {
  660. return result > 0 && isInfinite(result);
  661. }
  662. else
  663. {
  664. return result < 0 && isInfinite(result);
  665. }
  666. }
  667. else
  668. if(isNaN(result) || isInfinite(result))
  669. {
  670. return false;
  671. }
  672. else
  673. if(ABS(result - expected) < MAX_DOUBLE_ERROR)
  674. {
  675. return true;
  676. }
  677. else
  678. {
  679. double minv = MIN(expected * (1.0 - MAX_DOUBLE_ERROR),
  680. expected * (1.0 + MAX_DOUBLE_ERROR));
  681. double maxv = MAX(expected * (1.0 - MAX_DOUBLE_ERROR),
  682. expected * (1.0 + MAX_DOUBLE_ERROR));
  683. return result > minv && result < maxv;
  684. }
  685. }
  686. double doubleDelta(double expected, double result)
  687. {
  688. double absolute = ABS(result - expected);
  689. if (ABS(expected) > 1E-9)
  690. {
  691. double relative = ABS(absolute / expected);
  692. return MIN(absolute, relative);
  693. }
  694. else
  695. return absolute;
  696. }
  697. void ensure(bool cond, const std::string msg = "")
  698. {
  699. if (!cond)
  700. {
  701. quitf(_fail, msg.c_str());
  702. }
  703. }
  704. void setName(const char* format, ...)
  705. {
  706. char * buffer = new char [OUTPUT_BUFFER_SIZE];
  707. va_list ap;
  708. va_start(ap, format);
  709. std::vsprintf(buffer, format, ap);
  710. va_end(ap);
  711. std::string name(buffer);
  712. delete[] buffer;
  713. checkerName = name;
  714. }
  715. #endif