|
|
#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(); |
|
|
} |