/** * main.cpp for jsonstroller * * Author: isundil **/ #include #include #include #include "curseSimpleOutput.hh" #include "curseSplitOutput.hh" #include "streamConsumer.hh" #include "jsonException.hh" #include "simpleOutput.hh" #include "params.hh" void displayException(const std::string &filename, const Params ¶ms, const std::string &type, const JsonException &e) { const std::string buffer = e.getHistory(); std::cerr << params.getProgName() << ": " << filename << " [" << type << "] at line " << e.currentLine() << ", col " << e.currentCol() << " (" << e.what() << ") while reading" << std::endl; std::cerr << buffer << std::endl << std::string(buffer.size() -1, '~') << '^' << std::endl; } StreamConsumer *readFile(std::pair*> input, const Params ¶ms) { StreamConsumer *stream = new StreamConsumer(*(input.second)); stream->withConfig(¶ms); stream->read(); if (!stream->getRoot()) throw EofException(); return stream; } StreamConsumer *readOneFile(std::pair*> input, const Params ¶ms, std::deque &warns) { StreamConsumer *stream; try { stream = readFile(input, params); } catch (EofException &e) { std::cerr << params.getProgName() << ": " << input.first << " " << Warning::getType(e) << " (" << e.what() << ") error while reading" << std::endl; return nullptr; } catch (JsonException &e) { std::cerr << "Error: "; displayException(input.first, params, Warning::getType(e), e); return nullptr; } for (Warning w : stream->getMessages()) { w.filename(input.first); warns.push_back(Warning(w)); } return stream; } void runDiff(const Params ¶ms) { const IndexedDeque inputs = params.getInputs(); const size_t nbInputs = inputs.size(); std::set streams; std::deque roots; std::deque warns; std::deque inputNames; for (std::pair*> input : inputs) { StreamConsumer *stream; inputNames.push_back(input.first); stream = readOneFile(input, params, warns); if (!stream) { for (StreamConsumer *s : streams) delete s; return; } roots.push_back(stream->getRoot()); streams.insert(stream); } if (streams.size() == nbInputs) { CurseSplitOutput out(params); out.run(inputNames, roots); } for (StreamConsumer *stream: streams) delete stream; for (Warning w : warns) { std::cerr << "Warning: "; displayException(w.filename(), params, w.getType(), w()); } } void runStdout(const Params ¶ms) { IndexedDeque inputs = params.getInputs(); std::deque warns; for (std::pair*> input : inputs) { StreamConsumer *stream = readOneFile(input, params, warns); if (!stream) break; SimpleOutput::display(std::cout, stream->getRoot(), params); delete stream; } for (Warning w : warns) { std::cerr << "Warning: "; displayException(w.filename(), params, w.getType(), w()); } } void run(const Params ¶ms) { IndexedDeque inputs = params.getInputs(); CurseSimpleOutput *out = new CurseSimpleOutput(params); std::deque warns; for (std::pair*> input : inputs) { StreamConsumer *stream = readOneFile(input, params, warns); if (!stream) break; out->run(stream->getRoot(), input.first); delete stream; } if (out) delete out; for (Warning w : warns) { std::cerr << "Warning: "; displayException(w.filename(), params, w.getType(), w()); } } int main(int ac, char **av) { (void) ac; Params *params = new Params(av); bool _run = false; try { _run = params->read(); } catch (std::runtime_error &e) { std::cerr << *av << ": " << e.what() << std::endl; params->usage(); delete params; exit (EXIT_FAILURE); } if (_run) { if (!params->isIgnoringUnicode()) setlocale(LC_ALL, ""); if (params->isDiff()) runDiff(*params); else { if (isatty(fileno(stdout))) run(*params); else runStdout(*params); } } delete params; return 0; }