PageRenderTime 384ms CodeModel.GetById 180ms app.highlight 13ms RepoModel.GetById 188ms app.codeStats 1ms

/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
  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//////////////////////////////////////////////////////////////////////