main.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /**
  2. * main.cpp for jsonstroller
  3. *
  4. * Author: isundil <isundill@gmail.com>
  5. **/
  6. #include <iostream>
  7. #include <unistd.h>
  8. #include <locale.h>
  9. #include "curseSimpleOutput.hh"
  10. #include "curseSplitOutput.hh"
  11. #include "streamConsumer.hh"
  12. #include "jsonException.hh"
  13. #include "simpleOutput.hh"
  14. #include "params.hh"
  15. void displayException(const std::string &filename, const Params &params, const std::string &type, const JsonException &e)
  16. {
  17. const std::string buffer = e.getHistory();
  18. std::cerr << params.getProgName() << ": " << filename << " [" << type << "] at line " << e.currentLine() << ", col " << e.currentCol() << " (" << e.what() << ") while reading" << std::endl;
  19. std::cerr << buffer << std::endl << std::string(buffer.size() -1, '~') << '^' << std::endl;
  20. }
  21. StreamConsumer *readFile(std::pair<std::string, std::basic_istream<char>*> input, const Params &params)
  22. {
  23. StreamConsumer *stream = new StreamConsumer(*(input.second));
  24. stream->withConfig(&params);
  25. stream->read();
  26. if (!stream->getRoot())
  27. throw EofException();
  28. return stream;
  29. }
  30. StreamConsumer *readOneFile(std::pair<std::string, std::basic_istream<char>*> input, const Params &params, std::deque<Warning> &warns)
  31. {
  32. StreamConsumer *stream;
  33. try
  34. {
  35. stream = readFile(input, params);
  36. }
  37. catch (EofException &e)
  38. {
  39. std::cerr << params.getProgName() << ": " << input.first << " " << Warning::getType(e) << " (" << e.what() << ") error while reading" << std::endl;
  40. return nullptr;
  41. }
  42. catch (JsonException &e)
  43. {
  44. std::cerr << "Error: ";
  45. displayException(input.first, params, Warning::getType(e), e);
  46. return nullptr;
  47. }
  48. for (Warning w : stream->getMessages())
  49. {
  50. w.filename(input.first);
  51. warns.push_back(Warning(w));
  52. }
  53. return stream;
  54. }
  55. void runDiff(const Params &params)
  56. {
  57. const IndexedDeque inputs = params.getInputs();
  58. const size_t nbInputs = inputs.size();
  59. std::set<StreamConsumer *> streams;
  60. std::deque<JSonElement *> roots;
  61. std::deque<Warning> warns;
  62. std::deque<std::string> inputNames;
  63. for (std::pair<std::string, std::basic_istream<char>*> input : inputs)
  64. {
  65. StreamConsumer *stream;
  66. inputNames.push_back(input.first);
  67. stream = readOneFile(input, params, warns);
  68. if (!stream)
  69. {
  70. for (StreamConsumer *s : streams)
  71. delete s;
  72. return;
  73. }
  74. roots.push_back(stream->getRoot());
  75. streams.insert(stream);
  76. }
  77. if (streams.size() == nbInputs)
  78. {
  79. CurseSplitOutput out(params);
  80. out.run(inputNames, roots);
  81. }
  82. for (StreamConsumer *stream: streams)
  83. delete stream;
  84. for (Warning w : warns)
  85. {
  86. std::cerr << "Warning: ";
  87. displayException(w.filename(), params, w.getType(), w());
  88. }
  89. }
  90. void runStdout(const Params &params)
  91. {
  92. IndexedDeque inputs = params.getInputs();
  93. std::deque<Warning> warns;
  94. for (std::pair<std::string, std::basic_istream<char>*> input : inputs)
  95. {
  96. StreamConsumer *stream = readOneFile(input, params, warns);
  97. if (!stream)
  98. break;
  99. SimpleOutput::display(std::cout, stream->getRoot(), params);
  100. delete stream;
  101. }
  102. for (Warning w : warns)
  103. {
  104. std::cerr << "Warning: ";
  105. displayException(w.filename(), params, w.getType(), w());
  106. }
  107. }
  108. void run(const Params &params)
  109. {
  110. IndexedDeque inputs = params.getInputs();
  111. CurseSimpleOutput *out = new CurseSimpleOutput(params);
  112. std::deque<Warning> warns;
  113. for (std::pair<std::string, std::basic_istream<char>*> input : inputs)
  114. {
  115. StreamConsumer *stream = readOneFile(input, params, warns);
  116. if (!stream)
  117. break;
  118. out->run(stream->getRoot(), input.first);
  119. delete stream;
  120. }
  121. if (out)
  122. delete out;
  123. for (Warning w : warns)
  124. {
  125. std::cerr << "Warning: ";
  126. displayException(w.filename(), params, w.getType(), w());
  127. }
  128. }
  129. int main(int ac, char **av)
  130. {
  131. (void) ac;
  132. Params *params = new Params(av);
  133. bool _run = false;
  134. try {
  135. _run = params->read();
  136. }
  137. catch (std::runtime_error &e)
  138. {
  139. std::cerr << *av << ": " << e.what() << std::endl;
  140. params->usage();
  141. delete params;
  142. exit (EXIT_FAILURE);
  143. }
  144. if (_run)
  145. {
  146. if (!params->isIgnoringUnicode())
  147. setlocale(LC_ALL, "");
  148. if (params->isDiff())
  149. runDiff(*params);
  150. else
  151. {
  152. if (isatty(fileno(stdout)))
  153. run(*params);
  154. else
  155. runStdout(*params);
  156. }
  157. }
  158. delete params;
  159. return 0;
  160. }