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