diff --git a/lib/lrama/option_parser.rb b/lib/lrama/option_parser.rb index 5a15d59c..ac200d34 100644 --- a/lib/lrama/option_parser.rb +++ b/lib/lrama/option_parser.rb @@ -30,7 +30,7 @@ def parse(argv) parse_by_option_parser(argv) @options.trace_opts = validate_trace(@trace) - @options.report_opts = validate_report(@report) + report_opts = @options.report_opts = validate_report(@report) @options.profile_opts = validate_profile(@profile) @options.grammar_file = argv.shift @@ -44,7 +44,7 @@ def parse(argv) @options.y = File.open(@options.grammar_file, 'r') end - if !@report.empty? && @options.report_file.nil? && @options.grammar_file + if !@report.empty? && !report_opts.empty? && @options.report_file.nil? && @options.grammar_file @options.report_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".output" end @@ -89,7 +89,7 @@ def parse_by_option_parser(argv) o.separator 'Output:' o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v } o.on('-d', 'also produce a header file') { @options.header = true } - o.on('-r', '--report=REPORTS', Array, 'also produce details on the automaton') {|v| @report = v } + o.on('-r', '--report=REPORTS', Array, 'also produce details on the automaton') {|v| @report.concat(v) } o.on_tail '' o.on_tail 'REPORTS is a list of comma-separated words that can include:' o.on_tail ' states describe the states' @@ -124,7 +124,7 @@ def parse_by_option_parser(argv) o.on_tail 'PROFILES is a list of comma-separated words that can include:' o.on_tail ' call-stack use sampling call-stack profiler (stackprof gem)' o.on_tail ' memory use memory profiler (memory_profiler gem)' - o.on('-v', '--verbose', "same as '--report=state'") {|_v| @report << 'states' } + o.on('-v', '--verbose', "same as '--report=states'") {|_v| @report << 'states' } o.separator '' o.separator 'Diagnostics:' o.on('-W', '--warnings', 'report the warnings') {|v| @options.warnings = true } @@ -147,18 +147,21 @@ def parse_by_option_parser(argv) def validate_report(report) h = { grammar: true } return h if report.empty? - return {} if report == ['none'] - if report == ['all'] - VALID_REPORTS.each { |r| h[r] = true } - return h - end report.each do |r| - aliased = aliased_report_option(r) - if VALID_REPORTS.include?(aliased) - h[aliased] = true + case r + when 'none' + h.clear + when 'all' + h[:grammar] = true + VALID_REPORTS.each { |report_name| h[report_name] = true } else - raise "Invalid report option \"#{r}\"." + aliased = aliased_report_option(r) + if VALID_REPORTS.include?(aliased) + h[aliased] = true + else + raise "Invalid report option \"#{r}\"." + end end end diff --git a/spec/lrama/option_parser_spec.rb b/spec/lrama/option_parser_spec.rb index 7675c4da..52ffb508 100644 --- a/spec/lrama/option_parser_spec.rb +++ b/spec/lrama/option_parser_spec.rb @@ -62,7 +62,7 @@ --trace=TRACES also output trace logs at runtime --diagram=[FILE] generate a diagram of the rules --profile=PROFILES profiles parser generation parts - -v, --verbose same as '--report=state' + -v, --verbose same as '--report=states' Diagnostics: -W, --warnings report the warnings @@ -137,6 +137,15 @@ rules: true, terms: true, verbose: true }) end + + it "can be combined with another report" do + opts = option_parser.send(:validate_report, ["all", "cex"]) + expect(opts).to eq({ + grammar: true, states: true, itemsets: true, + lookaheads: true, solved: true, counterexamples: true, + rules: true, terms: true, verbose: true + }) + end end context "when none is passed" do @@ -144,6 +153,11 @@ opts = option_parser.send(:validate_report, ["none"]) expect(opts).to eq({}) end + + it "can be followed by another report" do + opts = option_parser.send(:validate_report, ["none", "states"]) + expect(opts).to eq({states: true}) + end end end @@ -158,6 +172,13 @@ opts = option_parser.send(:validate_report, ["states"]) expect(opts).to eq({grammar: true, states: true}) end + + it "combines with --report regardless of argument order" do + [["--report=rules", "-v"], ["-v", "--report=rules"], ["-v", "-r", "rules"]].each do |args| + opts = Lrama::OptionParser.parse(args + ["-", "test.y"]) + expect(opts.report_opts).to eq({grammar: true, rules: true, states: true}) + end + end end context "when --verbose option is passed" do @@ -298,6 +319,13 @@ options = option_parser.instance_variable_get(:@options) expect(options.report_file).to eq "./test.output" end + + it "does not set @report_file when reports are disabled" do + [["--report=none"], ["--report=states,none"], ["-v", "--report=none"]].each do |args| + options = Lrama::OptionParser.parse(args + ["-", "test.y"]) + expect(options.report_file).to be_nil + end + end end context "report file name is passed" do