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