| #include "../../unity/unity.h" |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <errno.h> |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| static void set_prefix (char *p); |
| static int copy_rest (FILE *f, int c); |
|
|
| |
| extern bool tabs; |
| extern int in_column; |
| extern int next_prefix_indent; |
|
|
| |
| static FILE* make_input_stream(const char* content) |
| { |
| FILE* f = tmpfile(); |
| if (!f) |
| return NULL; |
| size_t len = content ? strlen(content) : 0; |
| if (len > 0) |
| { |
| if (fwrite(content, 1, len, f) != len) |
| { |
| fclose(f); |
| return NULL; |
| } |
| } |
| rewind(f); |
| return f; |
| } |
|
|
| |
| |
| |
| |
| |
| static char* capture_copy_rest_output(FILE* fin, int c, int* ret_c) |
| { |
| if (!ret_c) |
| return NULL; |
|
|
| fflush(stdout); |
| int saved_fd = dup(fileno(stdout)); |
| if (saved_fd == -1) |
| return NULL; |
|
|
| FILE* cap = tmpfile(); |
| if (!cap) |
| { |
| close(saved_fd); |
| return NULL; |
| } |
| int cap_fd = fileno(cap); |
| if (dup2(cap_fd, fileno(stdout)) == -1) |
| { |
| fclose(cap); |
| close(saved_fd); |
| return NULL; |
| } |
|
|
| int r = copy_rest(fin, c); |
|
|
| fflush(stdout); |
| fflush(cap); |
|
|
| |
| if (dup2(saved_fd, fileno(stdout)) == -1) |
| { |
| fclose(cap); |
| close(saved_fd); |
| return NULL; |
| } |
| close(saved_fd); |
|
|
| |
| if (fseek(cap, 0, SEEK_END) != 0) |
| { |
| fclose(cap); |
| return NULL; |
| } |
| long sz = ftell(cap); |
| if (sz < 0) |
| { |
| fclose(cap); |
| return NULL; |
| } |
| if (fseek(cap, 0, SEEK_SET) != 0) |
| { |
| fclose(cap); |
| return NULL; |
| } |
|
|
| char* buf = (char*)malloc((size_t)sz + 1); |
| if (!buf) |
| { |
| fclose(cap); |
| return NULL; |
| } |
| size_t nread = fread(buf, 1, (size_t)sz, cap); |
| buf[nread] = '\0'; |
| fclose(cap); |
|
|
| *ret_c = r; |
| return buf; |
| } |
|
|
| void setUp(void) |
| { |
| |
| tabs = false; |
| } |
|
|
| void tearDown(void) |
| { |
| |
| } |
|
|
| |
| static void test_copy_rest_blank_line_no_output(void) |
| { |
| char pfx[] = ""; |
| set_prefix(pfx); |
| next_prefix_indent = 0; |
| in_column = 0; |
|
|
| FILE* fin = make_input_stream(""); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, '\n', &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT('\n', retc); |
| TEST_ASSERT_EQUAL_UINT(0, strlen(out)); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_newline_with_partial_prefix(void) |
| { |
| char pfx[] = "ABC"; |
| set_prefix(pfx); |
| next_prefix_indent = 2; |
| in_column = 3; |
|
|
| FILE* fin = make_input_stream(""); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, '\n', &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT('\n', retc); |
| |
| TEST_ASSERT_EQUAL_STRING(" A", out); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_mismatch_no_padding(void) |
| { |
| char pfx[] = "ABC"; |
| set_prefix(pfx); |
| next_prefix_indent = 2; |
| in_column = 3; |
|
|
| |
| FILE* fin = make_input_stream("YZ\n"); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, 'X', &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT('\n', retc); |
| |
| TEST_ASSERT_EQUAL_STRING(" AXYZ", out); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_mismatch_with_padding_beyond_trimmed_prefix(void) |
| { |
| char pfx[] = "AB "; |
| set_prefix(pfx); |
| next_prefix_indent = 1; |
| in_column = next_prefix_indent + 4; |
|
|
| |
| FILE* fin = make_input_stream("T\n"); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, 'X', &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT('\n', retc); |
| |
| TEST_ASSERT_EQUAL_STRING(" AB XT", out); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_eof_emits_newline_after_full_prefix(void) |
| { |
| char pfx[] = "HELLO"; |
| set_prefix(pfx); |
| next_prefix_indent = 3; |
| in_column = next_prefix_indent + (int)strlen("HELLO"); |
|
|
| FILE* fin = make_input_stream(""); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, EOF, &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT(EOF, retc); |
| |
| TEST_ASSERT_EQUAL_STRING(" HELLO\n", out); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_eof_no_output_when_no_progress(void) |
| { |
| char pfx[] = "HELLO"; |
| set_prefix(pfx); |
| next_prefix_indent = 2; |
| in_column = 2; |
|
|
| FILE* fin = make_input_stream(""); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, EOF, &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT(EOF, retc); |
| TEST_ASSERT_EQUAL_UINT(0, strlen(out)); |
| free(out); |
| } |
|
|
| |
| static void test_copy_rest_no_prefix_context_non_newline(void) |
| { |
| char pfx[] = ""; |
| set_prefix(pfx); |
| next_prefix_indent = 0; |
| in_column = 0; |
|
|
| FILE* fin = make_input_stream("RS\n"); |
| TEST_ASSERT_NOT_NULL(fin); |
|
|
| int retc = 0; |
| char* out = capture_copy_rest_output(fin, 'Q', &retc); |
| fclose(fin); |
|
|
| TEST_ASSERT_NOT_NULL(out); |
| TEST_ASSERT_EQUAL_INT('\n', retc); |
| |
| TEST_ASSERT_EQUAL_STRING("QRS", out); |
| free(out); |
| } |
|
|
| int main(void) |
| { |
| UNITY_BEGIN(); |
| RUN_TEST(test_copy_rest_blank_line_no_output); |
| RUN_TEST(test_copy_rest_newline_with_partial_prefix); |
| RUN_TEST(test_copy_rest_mismatch_no_padding); |
| RUN_TEST(test_copy_rest_mismatch_with_padding_beyond_trimmed_prefix); |
| RUN_TEST(test_copy_rest_eof_emits_newline_after_full_prefix); |
| RUN_TEST(test_copy_rest_eof_no_output_when_no_progress); |
| RUN_TEST(test_copy_rest_no_prefix_context_non_newline); |
| return UNITY_END(); |
| } |