Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/lib/c/statistics.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,11 @@ static inline bool count(
RCN_LOG_DBG(file->path)

bool ok = false;
result->hasLogicalLines = detected.isProgrammingLanguage;
RcnTextFormat sourceFormat = detected.format;
ok = ensureFileContent(stats, options, file, result);
if (ok && options.operations & RCN_OPT_COUNT_LOGICAL_LINES){
if (detected.isProgrammingLanguage) {
if (result->hasLogicalLines) {
ok = countLogicalLines(stats, file, sourceFormat, result);
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/lib/include/reckon/reckon.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,19 @@ typedef struct RcnCountResultGroup {
*/
bool isProcessed;

/**
* Indicates whether logical lines can be computed for the source entity.
*
* If `true`, the `logicalLines` field contains a valid count. If `false`,
* then logical lines are not applicable for the source entity's format,
* e.g. for plain text files, and the `logicalLines` field is zero.
* This field is only set by a counting operation and remains initialized
* as `false` if no such operation was performed.
*
* @since 1.1.0
*/
bool hasLogicalLines;

} RcnCountResultGroup;

/**
Expand Down
26 changes: 26 additions & 0 deletions src/lib/tests/unit/c/test_statistics.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,31 @@ void testCountWithMultipleFilesWhenOneFileHasError(void) {
rcnFreeCountStatistics(stats);
}

void testCountResultGroupLogicalLineCheckField(void) {
char* path = RECKON_TEST_PATH_RES_BASE "/mixed";
RcnCountStatistics* stats = rcnCreateCountStatistics(path);
RcnStatOptions options = {0};
rcnCount(stats, options);
TEST_ASSERT_EQUAL_INT(4, stats->count.size);
RcnSourceFile* fileJava = &stats->count.files[0];
RcnCountResultGroup* resultJava = &stats->count.results[0];
TEST_ASSERT_EQUAL_STRING("Source.java", fileJava->name);
TEST_ASSERT_TRUE(resultJava->hasLogicalLines);
RcnSourceFile* fileC = &stats->count.files[1];
RcnCountResultGroup* resultC = &stats->count.results[1];
TEST_ASSERT_EQUAL_STRING("source.c", fileC->name);
TEST_ASSERT_TRUE(resultC->hasLogicalLines);
RcnSourceFile* fileTxt = &stats->count.files[2];
RcnCountResultGroup* resultTxt = &stats->count.results[2];
TEST_ASSERT_EQUAL_STRING("text.txt", fileTxt->name);
TEST_ASSERT_FALSE(resultTxt->hasLogicalLines);
RcnSourceFile* fileMd = &stats->count.files[3];
RcnCountResultGroup* resultMd = &stats->count.results[3];
TEST_ASSERT_EQUAL_STRING("text2.md", fileMd->name);
TEST_ASSERT_FALSE(resultMd->hasLogicalLines);
rcnFreeCountStatistics(stats);
}

// NOLINTEND(readability-magic-numbers)

int main(void) {
Expand All @@ -229,5 +254,6 @@ int main(void) {
RUN_TEST(testCountWithFileWhenContentIsNullAndStatusIsFileError);
RUN_TEST(testCountWhenFileHasUnsupportedFormat);
RUN_TEST(testCountWithMultipleFilesWhenOneFileHasError);
RUN_TEST(testCountResultGroupLogicalLineCheckField);
return UNITY_END();
}
49 changes: 45 additions & 4 deletions src/scount/c/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static const char TABLE_BORDER_VERTICAL_NORMAL = '|';
static const char TABLE_BORDER_VERTICAL_EMPHASIS = '|';
static const char TABLE_BORDER_CORNER = 'o';
static const char* TABLE_PADDING_LEFT = " ";
static const char* LABEL_NOT_APPLICABLE = "n/a";
static const char errorMessage[] = "Error";

#ifdef _WIN32
Expand Down Expand Up @@ -121,6 +122,15 @@ static bool ensureCapacity(PrintBuffer* buffer, size_t additional) {
return true;
}

static bool hasAnyLogicalLines(const RcnCountStatistics* stats) {
for (size_t i = 0; i < stats->count.size; ++i) {
if (stats->count.results[i].hasLogicalLines) {
return true;
}
}
return false;
}

/**
* Puts a string up to `length` into the buffer.
* The specified length must not exceed the actual length of `string`.
Expand Down Expand Up @@ -233,6 +243,25 @@ static void prCnt(PrintBuffer* buffer, RcnCount value, int width) {
prRpt(buffer, ' ', right);
}

static void prNotApplicable(PrintBuffer* buffer) {
const size_t pad = ((WIDTH_COL1 - strlen(LABEL_NOT_APPLICABLE)) / 2) - 1;
prRpt(buffer, ' ', pad);
prStr(buffer, LABEL_NOT_APPLICABLE);
prRpt(buffer, ' ', pad);
}

static void prLogicalLineCount(
PrintBuffer* buffer,
bool hasLogicalLines,
RcnCount value
) {
if (hasLogicalLines) {
prCnt(buffer, value, WIDTH_COL1);
} else {
prNotApplicable(buffer);
}
}

static void prHeaderCell(PrintBuffer* buffer, const char* label, int width) {
assert(label != NULL);
const int length = (int) strlen(label);
Expand Down Expand Up @@ -384,7 +413,7 @@ static void prFileRowData(
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
prCnt(buffer, res->logicalLines, WIDTH_COL1);
prLogicalLineCount(buffer, res->hasLogicalLines, res->logicalLines);
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
Expand Down Expand Up @@ -443,6 +472,7 @@ static void prSummaryRows(
) {
for (RcnTextFormat frmt = 0; frmt < RECKON_NUM_SUPPORTED_FORMATS; ++frmt) {
const char* label = NULL;
bool hasLogicalLines = false;
switch (frmt) {
case RCN_TEXT_UNFORMATTED:
label = "Plain Text";
Expand All @@ -452,9 +482,11 @@ static void prSummaryRows(
break;
case RCN_LANG_C:
label = "C";
hasLogicalLines = true;
break;
case RCN_LANG_JAVA:
label = "Java";
hasLogicalLines = true;
break;
// LCOV_EXCL_START
default:
Expand All @@ -475,7 +507,7 @@ static void prSummaryRows(
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
prCnt(buffer, stats->logicalLines[frmt], WIDTH_COL1);
prLogicalLineCount(buffer, hasLogicalLines, stats->logicalLines[frmt]);
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
Expand Down Expand Up @@ -506,7 +538,11 @@ static void prTotalsRow(PrintBuffer* buffer, const RcnCountStatistics* stats) {
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
prCnt(buffer, stats->totalLogicalLines, WIDTH_COL1);
prLogicalLineCount(
buffer,
hasAnyLogicalLines(stats),
stats->totalLogicalLines
);
prChr(buffer, ' ');
prChr(buffer, TABLE_BORDER_VERTICAL_NORMAL);
prChr(buffer, ' ');
Expand Down Expand Up @@ -540,7 +576,12 @@ PrintBuffer printResultSingle(const RcnCountStatistics* stats) {
prChr(&buffer, '\n');
prChr(&buffer, '\n');
prStr(&buffer, " Logical Lines of Code (LLC): ");
pr8ld(&buffer, result->logicalLines);
if (result->hasLogicalLines) {
pr8ld(&buffer, result->logicalLines);
} else {
prRpt(&buffer, ' ', 8 - strlen(LABEL_NOT_APPLICABLE));
prStr(&buffer, LABEL_NOT_APPLICABLE);
}
prChr(&buffer, '\n');
prStr(&buffer, " Physical Lines (PHL): ");
pr8ld(&buffer, result->physicalLines);
Expand Down
12 changes: 6 additions & 6 deletions src/scount/tests/functionality/res/expected/mixed.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions src/scount/tests/functionality/sh/test_scount.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ function test_scount_with_relative_directory_input() {
assert_stderr_is_empty;
}

function test_scount_prints_correct_output_for_single_file_no_llc() {
run_app "${TEST_RES_DIR}/mixed/sample1.md";
assert_exit_status $EXIT_SUCCESS;
assert_stdout_equals_file "expected/output_single_file_no_llc.txt";
assert_stderr_is_empty;
}

function test_scount_prints_correct_output_for_multiple_files_no_llc() {
run_app "${TEST_PROJECT_DIR}/src/lib/tests/res/txt";
assert_exit_status $EXIT_SUCCESS;
assert_stdout_equals_file "expected/output_multiple_files_no_llc.txt";
assert_stderr_is_empty;
}

function test_scount_prints_annotated_source_code() {
run_app --annotate-counts "${TEST_PROJECT_DIR}/src/lib/tests/res/java/Sample.java";
assert_exit_status $EXIT_SUCCESS;
Expand Down
2 changes: 2 additions & 0 deletions src/scount/tests/unit/c/test_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>

Expand Down Expand Up @@ -50,6 +51,7 @@ static RcnCountStatistics* mkStats(
stats->count.results[i].words = words;
stats->count.results[i].characters = characters;
stats->count.results[i].sourceSize = sourceSize;
stats->count.results[i].hasLogicalLines = true;
}
stats->logicalLines[RCN_LANG_JAVA] = logical;
stats->physicalLines[RCN_LANG_JAVA] = physical;
Expand Down