You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.5 KiB

2 months ago
  1. #include "yaml-cpp/emitterstyle.h"
  2. #include "yaml-cpp/eventhandler.h"
  3. #include "yaml-cpp/yaml.h" // IWYU pragma: keep
  4. #include <cstdlib>
  5. #include <fstream>
  6. #include <iostream>
  7. class NullEventHandler : public YAML::EventHandler {
  8. public:
  9. using Mark = YAML::Mark;
  10. using anchor_t = YAML::anchor_t;
  11. NullEventHandler() = default;
  12. void OnDocumentStart(const Mark&) override {}
  13. void OnDocumentEnd() override {}
  14. void OnNull(const Mark&, anchor_t) override {}
  15. void OnAlias(const Mark&, anchor_t) override {}
  16. void OnScalar(const Mark&, const std::string&, anchor_t,
  17. const std::string&) override {}
  18. void OnSequenceStart(const Mark&, const std::string&, anchor_t,
  19. YAML::EmitterStyle::value) override {}
  20. void OnSequenceEnd() override {}
  21. void OnMapStart(const Mark&, const std::string&, anchor_t,
  22. YAML::EmitterStyle::value) override {}
  23. void OnMapEnd() override {}
  24. };
  25. void run(std::istream& in) {
  26. YAML::Parser parser(in);
  27. NullEventHandler handler;
  28. parser.HandleNextDocument(handler);
  29. }
  30. void usage() { std::cerr << "Usage: read [-n N] [-c, --cache] [filename]\n"; }
  31. std::string read_stream(std::istream& in) {
  32. return std::string((std::istreambuf_iterator<char>(in)),
  33. std::istreambuf_iterator<char>());
  34. }
  35. int main(int argc, char** argv) {
  36. int N = 1;
  37. bool cache = false;
  38. std::string filename;
  39. for (int i = 1; i < argc; i++) {
  40. std::string arg = argv[i];
  41. if (arg == "-n") {
  42. i++;
  43. if (i >= argc) {
  44. usage();
  45. return -1;
  46. }
  47. N = std::atoi(argv[i]);
  48. if (N <= 0) {
  49. usage();
  50. return -1;
  51. }
  52. } else if (arg == "-c" || arg == "--cache") {
  53. cache = true;
  54. } else {
  55. filename = argv[i];
  56. if (i + 1 != argc) {
  57. usage();
  58. return -1;
  59. }
  60. }
  61. }
  62. if (N > 1 && !cache && filename.empty()) {
  63. usage();
  64. return -1;
  65. }
  66. if (cache) {
  67. std::string input;
  68. if (!filename.empty()) {
  69. std::ifstream in(filename);
  70. input = read_stream(in);
  71. } else {
  72. input = read_stream(std::cin);
  73. }
  74. std::istringstream in(input);
  75. for (int i = 0; i < N; i++) {
  76. in.seekg(std::ios_base::beg);
  77. run(in);
  78. }
  79. } else {
  80. if (!filename.empty()) {
  81. std::ifstream in(filename);
  82. for (int i = 0; i < N; i++) {
  83. in.seekg(std::ios_base::beg);
  84. run(in);
  85. }
  86. } else {
  87. for (int i = 0; i < N; i++) {
  88. run(std::cin);
  89. }
  90. }
  91. }
  92. return 0;
  93. }