diff --git a/applications/Parser/src/main.cpp b/applications/Parser/src/main.cpp index 6a05319..84c670a 100644 --- a/applications/Parser/src/main.cpp +++ b/applications/Parser/src/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2019 - University of Strathclyde, King's College London and Schlumberger Ltd +// Copyright 2019-2025 - University of Strathclyde, King's College London, Schlumberger Ltd and SIFT, LLC // This source code is licensed under the BSD license found in the LICENSE file in the root directory of this source tree. #include "FlexLexer.h" @@ -10,6 +10,10 @@ extern int yyparse(); extern int yydebug; +void usage(); + +static bool failOnBadInput = 0; + using std::ifstream; using std::ofstream; @@ -39,8 +43,24 @@ int main(int argc, char *argv[]) { yfl = new yyFlexLexer; + int argcount = 1; + + // Parse command line options (extensible) + while (argcount < argc && argv[argcount][0] == '-') { + switch (argv[argcount][1]) { + case 'x': + failOnBadInput = true; + ++argcount; + break; + default: + cout << "Unknown option: " << argv[argcount] << "\n"; + usage(); + exit(1); + } + } + // Loop over given args - for (int a = 1; a < argc; ++a) { + for (int a = argcount; a < argc; ++a) { current_filename = argv[a]; cout << "File: " << current_filename << '\n'; current_in_stream = new ifstream(current_filename); @@ -66,4 +86,20 @@ int main(int argc, char *argv[]) { // Output the errors from all input files current_analysis->error_list.report(); delete yfl; + if (failOnBadInput && current_analysis->error_list.errors > 0) { + return 1; + } + return 0; } + + +void usage() { + cout << "Parser: The PDDL+ plan parsing tool\n" + << "Version 4: Validates continuous effects, events and processes.\n" + << "\nAuthors: Derek Long, Richard Howey, Stephen Cresswell and Maria " + "Fox\n" + << "https:://github.com/KCL-Planning/VAL\n\n" + << "Usage: Parser [options] domainFile problemFile planFile1 ...\n" + << "Options:\n" + << " -x -- Fail with non-zero exit code if the input fails to parse.\n"; +}; diff --git a/applications/Validate/src/main.cpp b/applications/Validate/src/main.cpp index 428acaf..70e1f05 100644 --- a/applications/Validate/src/main.cpp +++ b/applications/Validate/src/main.cpp @@ -33,6 +33,8 @@ extern int yydebug; extern char *current_filename; +static bool failOnBadPlan = 0; + namespace VAL { extern parse_category *top_thing; @@ -80,6 +82,7 @@ void usage() { << " -j -- When varying the values of PNEs also vary for " "event preconditions. (default = false)\n" << " -v -- Verbose reporting of plan check progress.\n" + << " -x -- Fail with non-zero exit code on validation failures.\n" << " -l -- Verbose LaTeX reporting of plan check progress.\n" << " -a -- Do not output plan repair advice when Verbose is " "on.\n" @@ -125,7 +128,11 @@ plan *getPlan(int &argc, char *argv[], int &argcount, TypeChecker &tc, failed.push_back(name); *report << "Bad plan file!\n"; the_plan = 0; - return the_plan; + if ( failOnBadPlan ) { + exit(1); + } else { + return the_plan; + } }; yfl = new yyFlexLexer(&planFile, &cout); @@ -141,7 +148,11 @@ plan *getPlan(int &argc, char *argv[], int &argcount, TypeChecker &tc, if (Silent > 1) *report << "failed\n"; delete the_plan; the_plan = 0; - return the_plan; + if ( failOnBadPlan ) { + exit(1); + } else { + return the_plan; + } }; if (the_plan->getTime() >= 0) { @@ -502,7 +513,7 @@ int main(int argc, char *argv[]) { try { if (argc < 2) { usage(); - return 0; + return 1; }; current_analysis = &an_analysis; @@ -708,6 +719,10 @@ int main(int argc, char *argv[]) { giveAdvice = false; ++argcount; break; + case 'x': + failOnBadPlan = true; + ++argcount; + break; case 'f': { LaTeX = true; Verbose = true; @@ -777,6 +792,8 @@ int main(int argc, char *argv[]) { exit(-1); }; + // I believe this means that there is only one argument, and it's + // been processed successfully. if (argcount >= argc) { return 0; };