| #include "../../unity/unity.h" |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
|
|
| |
| |
| |
|
|
| |
| |
|
|
| |
| extern char parabuf[]; |
| extern char *wptr; |
| extern int max_width; |
| extern int goal_width; |
| extern int first_indent; |
| extern int other_indent; |
| extern int last_line_length; |
| extern int prefix_indent; |
| extern char const *prefix; |
| extern int prefix_length; |
| extern int prefix_full_length; |
| extern int prefix_lead_space; |
| extern int out_column; |
| extern int tabs; |
|
|
| |
| |
| extern struct Word; |
| extern __typeof__(((struct Word*)0)->length) dummy_len_for_type; |
| extern __typeof__(((struct Word*)0)) dummy_word_type; |
| extern struct Word *word_limit; |
| extern struct Word word[]; |
|
|
| |
| static int redirect_stdout_start(char *path_buf, size_t path_buf_sz, FILE **cap_fp, int *saved_fd) |
| { |
| if (!path_buf || path_buf_sz < 32 || !cap_fp || !saved_fd) return -1; |
| snprintf(path_buf, path_buf_sz, "/tmp/fmt_flush_paragraph_XXXXXX"); |
| int fd = mkstemp(path_buf); |
| if (fd < 0) return -1; |
| FILE *fp = fdopen(fd, "w+"); |
| if (!fp) { |
| close(fd); |
| return -1; |
| } |
| fflush(stdout); |
| *saved_fd = dup(fileno(stdout)); |
| if (*saved_fd < 0) { |
| fclose(fp); |
| unlink(path_buf); |
| return -1; |
| } |
| if (dup2(fd, fileno(stdout)) < 0) { |
| close(*saved_fd); |
| fclose(fp); |
| unlink(path_buf); |
| return -1; |
| } |
| *cap_fp = fp; |
| return 0; |
| } |
|
|
| |
| static void redirect_stdout_end(FILE *cap_fp, int saved_fd) |
| { |
| fflush(stdout); |
| if (saved_fd >= 0) { |
| dup2(saved_fd, fileno(stdout)); |
| close(saved_fd); |
| } |
| fflush(stdout); |
| (void)cap_fp; |
| } |
|
|
| |
| static void reset_globals_defaults(void) |
| { |
| |
| prefix = ""; |
| prefix_length = 0; |
| prefix_full_length = 0; |
| prefix_lead_space = 0; |
| prefix_indent = 0; |
| first_indent = 0; |
| other_indent = 0; |
| out_column = 0; |
| last_line_length = 0; |
| tabs = 0; |
|
|
| |
| max_width = 12; |
| goal_width = 12; |
|
|
| |
| wptr = parabuf; |
| } |
|
|
| |
| void setUp(void) { |
| reset_globals_defaults(); |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| |
| void test_flush_paragraph_single_chunk_no_words(void) |
| { |
| |
| const char *payload = "XYZ"; |
| memcpy(parabuf, payload, 3); |
| wptr = parabuf + 3; |
|
|
| |
| word_limit = word; |
|
|
| char path[64]; |
| FILE *cap = NULL; int saved = -1; |
|
|
| TEST_ASSERT_EQUAL_INT(0, redirect_stdout_start(path, sizeof(path), &cap, &saved)); |
|
|
| |
| flush_paragraph(); |
|
|
| redirect_stdout_end(cap, saved); |
|
|
| |
| fseek(cap, 0, SEEK_SET); |
| char buf[32] = {0}; |
| size_t n = fread(buf, 1, sizeof(buf), cap); |
| fclose(cap); |
|
|
| |
| unlink(path); |
|
|
| TEST_ASSERT_EQUAL_size_t(3, n); |
| TEST_ASSERT_EQUAL_UINT8_ARRAY(payload, buf, 3); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(parabuf, wptr); |
| } |
|
|
| |
| |
| static void init_three_word_paragraph(void) |
| { |
| |
| const char *w1 = "aaaaa"; |
| const char *w2 = "bbbbb"; |
| const char *w3 = "ccccc"; |
|
|
| |
| char *p = parabuf; |
| memcpy(p, w1, 5); word[0].text = p; word[0].length = 5; p += 5; |
| memcpy(p, w2, 5); word[1].text = p; word[1].length = 5; p += 5; |
| memcpy(p, w3, 5); word[2].text = p; word[2].length = 5; p += 5; |
| wptr = p; |
|
|
| |
| word[0].space = 1; word[0].paren = 0; word[0].period = 0; word[0].punct = 0; word[0].final = 0; |
| word[1].space = 1; word[1].paren = 0; word[1].period = 0; word[1].punct = 0; word[1].final = 0; |
| word[2].space = 1; word[2].paren = 0; word[2].period = 0; word[2].punct = 0; word[2].final = 0; |
|
|
| |
| word_limit = word + 3; |
|
|
| |
| max_width = 12; |
| goal_width = 12; |
| first_indent = 0; |
| other_indent = 0; |
| last_line_length = 0; |
| prefix = ""; |
| prefix_length = 0; |
| prefix_full_length = 0; |
| prefix_indent = 0; |
| tabs = 0; |
| } |
|
|
| |
| |
| |
| void test_flush_paragraph_split_and_compact(void) |
| { |
| init_three_word_paragraph(); |
|
|
| char path[64]; |
| FILE *cap = NULL; int saved = -1; |
|
|
| TEST_ASSERT_EQUAL_INT(0, redirect_stdout_start(path, sizeof(path), &cap, &saved)); |
|
|
| |
| flush_paragraph(); |
|
|
| redirect_stdout_end(cap, saved); |
|
|
| |
| fseek(cap, 0, SEEK_SET); |
| char outbuf[128] = {0}; |
| size_t n = fread(outbuf, 1, sizeof(outbuf), cap); |
| fclose(cap); |
| unlink(path); |
|
|
| |
| const char *expected_line = "aaaaa bbbbb\n"; |
| size_t expected_len = strlen(expected_line); |
| TEST_ASSERT_TRUE(n >= expected_len); |
| TEST_ASSERT_EQUAL_MEMORY(expected_line, outbuf, expected_len); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(5, (int)(wptr - parabuf)); |
| TEST_ASSERT_EQUAL_MEMORY("ccccc", parabuf, 5); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(word + 1, word_limit); |
| TEST_ASSERT_EQUAL_INT(5, word[0].length); |
| TEST_ASSERT_EQUAL_MEMORY("ccccc", word[0].text, 5); |
| TEST_ASSERT_EQUAL_INT(1, word[0].space); |
| } |
|
|
| int main(void) |
| { |
| UNITY_BEGIN(); |
| RUN_TEST(test_flush_paragraph_single_chunk_no_words); |
| RUN_TEST(test_flush_paragraph_split_and_compact); |
| return UNITY_END(); |
| } |