diff --git a/man/scount.1 b/man/scount.1 index 9583dde..c65f4aa 100644 --- a/man/scount.1 +++ b/man/scount.1 @@ -5,6 +5,7 @@ scount \- A tool to count logical lines of code and other metrics .B scount [\fB\-\-verbose\fR] [\fB\-\-annotate\-counts\fR] +[\fB\-\-stop\-on\-error\fR] .I .SH DESCRIPTION scount counts source code lines in a single file @@ -43,6 +44,12 @@ Mark counted logical lines and output the result. .br This option can only be used on a single file input. .TP +.B \-\-stop\-on\-error +Stop the processing on the first encountered error, +even for non\-critical errors. Without this option (the default), +some errors are considered non-critical, in which case the corresponding +file is skipped and the processing continues. +.TP .B \-\-verbose Enable verbose output. .TP diff --git a/src/lib/c/statistics.c b/src/lib/c/statistics.c index ba5e8df..48aeb58 100644 --- a/src/lib/c/statistics.c +++ b/src/lib/c/statistics.c @@ -272,6 +272,10 @@ static inline bool count( if (!options.keepFileContent) { freeSourceFileContent(file); } + if (!ok && options.stopOnError) { + stats->state = result->state; + stats->state.ok = false; + } RCN_LOG_DBG("Done processing file:") RCN_LOG_DBG(file->path) diff --git a/src/scount/c/arguments.c b/src/scount/c/arguments.c index a8ef01f..a3aec35 100644 --- a/src/scount/c/arguments.c +++ b/src/scount/c/arguments.c @@ -28,6 +28,8 @@ AppArgs parseArgs(int argc, char** argv) { for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--annotate-counts") == 0) { args.annotateCounts = true; + } else if (strcmp(argv[i], "--stop-on-error") == 0) { + args.stopOnError = true; } else if (strcmp(argv[i], "--verbose") == 0) { args.verbose = true; } else if (strcmp(argv[i], "--help") == 0 @@ -58,7 +60,7 @@ AppArgs parseArgs(int argc, char** argv) { } void showUsage(void) { - logI("Usage: scount [--verbose] [--annotate-counts] "); + logI("Usage: scount [--verbose] [--annotate-counts] [--stop-on-error] "); } void showVersion(AppArgs args) { @@ -95,6 +97,8 @@ void showHelpText(void) { logI(" [--annotate-counts] Mark counted logical lines and output the result."); logI(" This option can only be used on a single file input."); logI(" "); + logI(" [--stop-on-error] Stop processing immediately when an error is encountered."); + logI(" "); logI(" [--verbose] Enable verbose output."); logI(" "); logI(" [-#|--version] Show program version information."); diff --git a/src/scount/c/scount.h b/src/scount/c/scount.h index 44c0248..c6defb7 100644 --- a/src/scount/c/scount.h +++ b/src/scount/c/scount.h @@ -50,6 +50,7 @@ typedef struct AppArgs { char* errorMessage; // Error message in case of invalid input int indexUnknown; // Index into `argv` when unknown arg found, or zero bool annotateCounts; // Option: `--annotate-counts` + bool stopOnError; // Option: `--stop-on-error` bool verbose; // Option: `--verbose` bool version; // Option: `-#|--version` bool versionShort; // Option: `-#` diff --git a/src/scount/c/statistics.c b/src/scount/c/statistics.c index 36a7d9e..6515f6c 100644 --- a/src/scount/c/statistics.c +++ b/src/scount/c/statistics.c @@ -97,7 +97,10 @@ ExitStatus outputStatistics(AppArgs args) { reportInputVerbose(path, stats); } - RcnStatOptions options = {0}; + RcnStatOptions options = { + .stopOnError = args.stopOnError + }; + rcnCount(stats, options); const RcnErrorCode errorCode = stats->state.errorCode; diff --git a/src/scount/tests/functionality/res/expected/mixedWithSyntaxError.txt b/src/scount/tests/functionality/res/expected/mixedWithSyntaxError.txt index 34dcb42..9b8610c 100644 --- a/src/scount/tests/functionality/res/expected/mixedWithSyntaxError.txt +++ b/src/scount/tests/functionality/res/expected/mixedWithSyntaxError.txt @@ -2,8 +2,8 @@ Directory: mixedWithSyntaxError Scanned files: 3 o---------- File ----------o--- LLC ---o--- PHL ---o--- WRD ---o--- CHR ---o--- SZE ---o - | CorrectFile.java | 5 | 12 | 33 | 273 | 273 | - | correct_file.txt | 0 | 1 | 20 | 109 | 109 | + | 01_CorrectFile.java | 5 | 12 | 33 | 273 | 273 | + | 03_correct_file.txt | 0 | 1 | 20 | 109 | 109 | o--------------------------o-----------o-----------o-----------o-----------o-----------o Summary: diff --git a/src/scount/tests/functionality/res/mixedWithSyntaxError/CorrectFile.java b/src/scount/tests/functionality/res/mixedWithSyntaxError/01_CorrectFile.java similarity index 100% rename from src/scount/tests/functionality/res/mixedWithSyntaxError/CorrectFile.java rename to src/scount/tests/functionality/res/mixedWithSyntaxError/01_CorrectFile.java diff --git a/src/scount/tests/functionality/res/mixedWithSyntaxError/has_syntax_error.c b/src/scount/tests/functionality/res/mixedWithSyntaxError/02_has_syntax_error.c similarity index 100% rename from src/scount/tests/functionality/res/mixedWithSyntaxError/has_syntax_error.c rename to src/scount/tests/functionality/res/mixedWithSyntaxError/02_has_syntax_error.c diff --git a/src/scount/tests/functionality/res/mixedWithSyntaxError/correct_file.txt b/src/scount/tests/functionality/res/mixedWithSyntaxError/03_correct_file.txt similarity index 100% rename from src/scount/tests/functionality/res/mixedWithSyntaxError/correct_file.txt rename to src/scount/tests/functionality/res/mixedWithSyntaxError/03_correct_file.txt diff --git a/src/scount/tests/functionality/sh/test_scount.sh b/src/scount/tests/functionality/sh/test_scount.sh index a85a0a3..37acfb8 100644 --- a/src/scount/tests/functionality/sh/test_scount.sh +++ b/src/scount/tests/functionality/sh/test_scount.sh @@ -125,7 +125,7 @@ function test_scount_with_directory_that_contains_file_with_syntax_error() { } function test_scount_with_file_that_has_syntax_error() { - local file="${TEST_RES_DIR}/mixedWithSyntaxError/has_syntax_error.c"; + local file="${TEST_RES_DIR}/mixedWithSyntaxError/02_has_syntax_error.c"; run_app "$file"; assert_exit_status $EXIT_INVALID_INPUT; assert_stdout_is_empty; @@ -133,3 +133,18 @@ function test_scount_with_file_that_has_syntax_error() { assert_stderr_contains "${file}"; assert_stderr_contains "Syntax error detected in source code (0x04)"; } + +function test_scount_with_stop_on_error_option() { + run_app --stop-on-error "${TEST_RES_DIR}/mixedWithSyntaxError"; + assert_exit_status $EXIT_INVALID_INPUT; + assert_stdout_is_empty; + assert_stderr_contains "An error has occurred"; + assert_stderr_contains "Syntax error detected in source code"; +} + +function test_scount_with_valid_directory_input_and_stop_on_error_option() { + run_app --stop-on-error "${TEST_PROJECT_DIR}/src/lib/tests/res/java"; + assert_exit_status $EXIT_SUCCESS; + assert_stdout_equals_file "expected/output_multiple_files.txt"; + assert_stderr_is_empty; +}