/src/ESCParser/ESCParser.cpp

http://ukncbtl.googlecode.com/ · C++ · 172 lines · 115 code · 31 blank · 26 comment · 24 complexity · e074cdf0bb488894bd45b6e154366bc1 MD5 · raw file

  1. /* This file is part of UKNCBTL.
  2. UKNCBTL is free software: you can redistribute it and/or modify it under the terms
  3. of the GNU Lesser General Public License as published by the Free Software Foundation,
  4. either version 3 of the License, or (at your option) any later version.
  5. UKNCBTL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  6. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  7. See the GNU Lesser General Public License for more details.
  8. You should have received a copy of the GNU Lesser General Public License along with
  9. UKNCBTL. If not, see <http://www.gnu.org/licenses/>. */
  10. #define _CRT_SECURE_NO_WARNINGS
  11. #include "ESCParser.h"
  12. #include <iostream>
  13. #include <fstream>
  14. //////////////////////////////////////////////////////////////////////
  15. // Globals
  16. const char* g_InputFileName = 0;
  17. int g_OutputDriverType = OUTPUT_DRIVER_POSTSCRIPT;
  18. OutputDriver* g_pOutputDriver = 0;
  19. //////////////////////////////////////////////////////////////////////
  20. bool ParseCommandLine(int argc, char* argv[])
  21. {
  22. for (int argn = 1; argn < argc; argn++)
  23. {
  24. const char* arg = argv[argn];
  25. if (arg[0] == '-' || arg[0] == '/')
  26. {
  27. if (_stricmp(arg + 1, "svg") == 0)
  28. g_OutputDriverType = OUTPUT_DRIVER_SVG;
  29. else if (_stricmp(arg + 1, "ps") == 0)
  30. g_OutputDriverType = OUTPUT_DRIVER_POSTSCRIPT;
  31. else
  32. {
  33. std::cerr << "Unknown option: " << arg << std::endl;
  34. return false;
  35. }
  36. }
  37. else
  38. {
  39. if (g_InputFileName == 0)
  40. g_InputFileName = arg;
  41. }
  42. }
  43. // Parsed options validation
  44. if (g_InputFileName == 0)
  45. {
  46. std::cerr << "Input file is not specified." << std::endl;
  47. return false;
  48. }
  49. return true;
  50. }
  51. // Print usage info
  52. void PrintUsage()
  53. {
  54. std::cerr << "Usage:" << std::endl
  55. << "\tESCParser [options] InputFile > OutputFile" << std::endl
  56. << "Options:" << std::endl
  57. << "\t-ps\tPostScript output with multipage support" << std::endl
  58. << "\t-svg\tSVG output, no multipage support" << std::endl;
  59. }
  60. void main(int argc, char* argv[])
  61. {
  62. std::cerr << "ESCParser utility by Nikita Zimin " << __DATE__ << " " << __TIME__ << std::endl;
  63. if (!ParseCommandLine(argc, argv))
  64. {
  65. PrintUsage();
  66. return;
  67. }
  68. // Choose a proper output driver
  69. switch (g_OutputDriverType)
  70. {
  71. case OUTPUT_DRIVER_SVG:
  72. g_pOutputDriver = new OutputDriverSvg(std::cout);
  73. break;
  74. case OUTPUT_DRIVER_POSTSCRIPT:
  75. g_pOutputDriver = new OutputDriverPostScript(std::cout);
  76. break;
  77. default:
  78. std::cerr << "Output driver type is not defined." << std::endl;
  79. return;
  80. }
  81. // First run: calculate total page count
  82. int pagestotal = 1;
  83. {
  84. // Prepare the input stream
  85. std::ifstream input(g_InputFileName, std::ifstream::in | std::ifstream::binary);
  86. if (input.fail())
  87. {
  88. std::cerr << "Failed to open the input file." << std::endl;
  89. return;
  90. }
  91. // Prepare stub driver
  92. OutputDriverStub driverstub(std::cout);
  93. // Run the interpreter to count the pages
  94. EscInterpreter intrpr1(input, driverstub);
  95. while (true)
  96. {
  97. if (!intrpr1.InterpretNext())
  98. {
  99. if (intrpr1.IsEndOfFile())
  100. break;
  101. pagestotal++;
  102. }
  103. }
  104. }
  105. std::cerr << "Pages total: " << pagestotal << std::endl;
  106. // Second run: output the pages
  107. {
  108. // Prepare the input stream
  109. std::ifstream input(g_InputFileName, std::ifstream::in | std::ifstream::binary);
  110. if (input.fail())
  111. {
  112. std::cerr << "Failed to open the input file." << std::endl;
  113. return;
  114. }
  115. // Prepare the output driver
  116. g_pOutputDriver->WriteBeginning(pagestotal);
  117. int pageno = 1;
  118. std::cerr << "Page " << pageno << std::endl;
  119. g_pOutputDriver->WritePageBeginning(pageno);
  120. // Initialize the interpreter
  121. EscInterpreter intrpr(input, *g_pOutputDriver);
  122. // Run the interpreter to produce the pages
  123. while (true)
  124. {
  125. if (!intrpr.InterpretNext())
  126. {
  127. g_pOutputDriver->WritePageEnding();
  128. if (intrpr.IsEndOfFile())
  129. break;
  130. pageno++;
  131. std::cerr << "Page " << pageno << std::endl;
  132. g_pOutputDriver->WritePageBeginning(pageno);
  133. }
  134. }
  135. g_pOutputDriver->WriteEnding();
  136. }
  137. // Cleanup
  138. delete g_pOutputDriver;
  139. g_pOutputDriver = 0;
  140. }
  141. //////////////////////////////////////////////////////////////////////