Skip to content

Commit 6e8920a

Browse files
committed
Fix argument handling in ryml-parse-emit
1 parent c401610 commit 6e8920a

2 files changed

Lines changed: 61 additions & 18 deletions

File tree

changelog/current.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### Fixes
22

33
- Fix [#524](https://github.com/biojppm/rapidyaml/issues/524) ([PR#525](https://github.com/biojppm/rapidyaml/pull/525)): problem parsing nested map value in complex map. Kudos to @MatthewSteel!
4+
- Fix argument handling in ryml-parse-emit
45

56

67
### Thanks

tools/parse_emit.cpp

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ using namespace c4;
3434
struct Args
3535
{
3636
c4::csubstr filename = "-";
37+
c4::csubstr output = {};
3738
c4::yml::id_type reserve_size = false;
3839
bool resolve_refs = false;
3940
bool keep_refs = false;
@@ -54,6 +55,7 @@ Parse yaml from file (or stdin when file is `-`) and emit to stdout.
5455
5556
Options:
5657
58+
-h,--help print this message
5759
-e [N],--reserve [N] reserve tree size before parsing (default: N=%d):
5860
0=do not reserve
5961
1=reserve by estimating size
@@ -63,9 +65,10 @@ Parse yaml from file (or stdin when file is `-`) and emit to stdout.
6365
-p,--print-tree print parsed rapidyaml tree before emitting (default: %s)
6466
-q,--quiet do not emit (default: %s)
6567
-j,--json emit json instead of yaml (default: %s)
66-
-s,--string emit to string before dumping to stdout.
68+
-s,--string emit to string before dumping to stdout/file.
6769
otherwise, emit directly to stdout (default: %s)
6870
-t,--timed time sections (print timings to stderr) (default: %s)
71+
-o,--output <filename> emit to the given filename (default: %s)
6972
7073
)",
7174
exename,
@@ -76,20 +79,15 @@ Parse yaml from file (or stdin when file is `-`) and emit to stdout.
7679
defs.quiet ? "do not emit" : "emit",
7780
defs.emit_as_json ? "emit as json" : "emit as yaml",
7881
defs.emit_to_string ? "emit to string" : "no",
79-
defs.timed_sections ? "show timings" : "no"
82+
defs.timed_sections ? "show timings" : "no",
83+
defs.output.empty() ? "no" : defs.output.str
8084
);
8185
}
8286
bool timing_enabled = false;
83-
Args parse_args(int argc, const char *argv[])
87+
bool parse_args(int argc, const char *argv[], Args &args)
8488
{
85-
if(argc < 2)
86-
{
87-
print_usage(argv[0]);
88-
c4::yml::error("missing filename (use - to read from stdin)");
89-
}
90-
Args args = {};
91-
args.filename = c4::to_csubstr(argv[argc - 1]);
92-
for(int i = 1; i+1 < argc; ++i)
89+
args = {};
90+
for(int i = 1; i < argc; ++i)
9391
{
9492
c4::csubstr arg = c4::to_csubstr(argv[i]);
9593
auto arg0_is = [&](c4::csubstr argshort, c4::csubstr arglong){
@@ -106,20 +104,32 @@ Args parse_args(int argc, const char *argv[])
106104
};
107105
if /**/(arg1_is("-e", "--reserve")) C4_CHECK(c4::from_chars(c4::to_csubstr(argv[++i]), &args.reserve_size));
108106
else if(arg1_is("-r", "--resolve")) args.resolve_refs = true;
107+
else if(arg1_is("-o", "--output")) args.output = c4::to_csubstr(argv[++i]);
109108
else if(arg0_is("-k", "--keep-refs")) args.keep_refs = true;
110109
else if(arg0_is("-p", "--print-tree")) args.print_tree = true;
111110
else if(arg0_is("-q", "--quiet")) args.quiet = true;
112111
else if(arg0_is("-j", "--json")) args.emit_as_json = true;
113112
else if(arg0_is("-s", "--string")) args.emit_to_string = true;
114113
else if(arg0_is("-t", "--timed")) args.timed_sections = true;
115-
else
114+
else if(arg0_is("-h", "--help"))
115+
{
116+
print_usage(argv[0]);
117+
return false;
118+
}
119+
else if(i+1 < argc)
116120
{
117121
print_usage(argv[0]);
118122
c4::yml::error("unknown argument");
119123
}
120124
}
121125
timing_enabled = args.timed_sections;
122-
return args;
126+
if(argc < 2)
127+
{
128+
print_usage(argv[0]);
129+
c4::yml::error("missing filename (use - to read from stdin)");
130+
}
131+
args.filename = c4::to_csubstr(argv[argc - 1]);
132+
return true;
123133
}
124134

125135
void read_file(csubstr filename, std::string *buf)
@@ -167,6 +177,20 @@ void emit_json_docs(yml::Tree const& tree, std::string *dst=nullptr)
167177
emitnode(doc);
168178
}
169179

180+
void emit_json_docs(yml::Tree const& tree, FILE *output)
181+
{
182+
auto emitnode = [&](yml::ConstNodeRef node){
183+
emit_json(node, output);
184+
(void)fputc('\n', output);
185+
};
186+
yml::ConstNodeRef root = tree.rootref();
187+
if(!root.is_stream())
188+
emitnode(root);
189+
else
190+
for(yml::ConstNodeRef doc : root.children())
191+
emitnode(doc);
192+
}
193+
170194
void report_error(const char* msg, size_t length, yml::Location loc, FILE *f)
171195
{
172196
if(!loc.name.empty())
@@ -287,18 +311,36 @@ void process_file(Args const& args)
287311
}
288312
else if(!args.quiet)
289313
{
290-
TS(emit_to_stdout);
291-
if(!args.emit_as_json)
292-
yml::emit_yaml(tree);
314+
if(args.output.empty())
315+
{
316+
TS(emit_to_stdout);
317+
if(!args.emit_as_json)
318+
yml::emit_yaml(tree);
319+
else
320+
emit_json_docs(tree);
321+
}
293322
else
294-
emit_json_docs(tree);
323+
{
324+
FILE *output = fopen(args.output.str, "wb");
325+
if (!output) c4::yml::error("could not open file");
326+
{
327+
TS(emit_to_file);
328+
if(!args.emit_as_json)
329+
yml::emit_yaml(tree, output);
330+
else
331+
emit_json_docs(tree, output);
332+
}
333+
(void)fclose(output);
334+
}
295335
}
296336
}
297337
// LCOV_EXCL_STOP
298338

299339
int main(int argc, const char *argv[])
300340
{
301-
const Args args = parse_args(argc, argv);
341+
Args args;
342+
if(!parse_args(argc, argv, args))
343+
return 0;
302344
TS(TOTAL);
303345
set_callbacks(create_custom_callbacks());
304346
C4_IF_EXCEPTIONS_(try, if(setjmp(jmp_env) == 0))

0 commit comments

Comments
 (0)