test-line-readers (windows-port iterate)

This commit is contained in:
John Kerl 2017-03-06 23:19:46 -05:00
parent cf6b1400d0
commit 508dd42739
3 changed files with 39 additions and 30 deletions

View file

@ -90,7 +90,7 @@ char* mlr_get_sline(FILE* fp, char* irs, int irslen) {
}
// ----------------------------------------------------------------
int local_getdelim(char** restrict pline, size_t* restrict plinecap, int delimiter, FILE* restrict stream) {
ssize_t local_getdelim(char** restrict pline, size_t* restrict plinecap, int delimiter, FILE* restrict stream) {
size_t linecap = INITIAL_SIZE;
char* restrict line = mlr_malloc_or_die(INITIAL_SIZE);
char* restrict p = line;
@ -106,26 +106,32 @@ int local_getdelim(char** restrict pline, size_t* restrict plinecap, int delimit
}
c = mlr_arch_getc(stream);
if (c == delimiter) {
*(p++) = 0;
*(p++) = delimiter;
break;
} else if (c == EOF) {
if (p == line)
eof = TRUE;
*p = 0;
break;
} else {
*(p++) = c;
}
}
// xxx check length
size_t offset = p - line;
if (offset >= linecap) {
linecap = linecap + 1;
line = mlr_realloc_or_die(line, linecap);
p = line + offset;
}
p[1] = 0;
*pline = line;
*plinecap = linecap;
if (eof) {
free(line);
*pline = NULL;
*plinecap = 0;
**pline = 0;
return -1;
} else {
*pline = line;
*plinecap = linecap;
return p - line;
}
}

View file

@ -22,6 +22,6 @@ char* mlr_get_sline(FILE* input_stream, char* irs, int irslen);
// getdelim is built-in on OSX and modern unix-like OSs. For MSYS2, we need to
// roll our own. The function is exposed publicly here, rather than privately
// inside mlr_arch.c, for unit-testing visibility.
int local_getdelim(char** restrict pline, size_t* restrict plinecap, int delimiter, FILE* restrict stream);
ssize_t local_getdelim(char** restrict pline, size_t* restrict plinecap, int delimiter, FILE* restrict stream);
#endif // LINE_READERS_H

View file

@ -13,6 +13,8 @@ int tests_failed = 0;
int assertions_run = 0;
int assertions_failed = 0;
typedef ssize_t getdelim_t(char** restrict pline, size_t* restrict plinecap, int delimiter, FILE* restrict stream);
// ----------------------------------------------------------------
static FILE* fopen_or_die(char* filename) {
FILE* fp = fopen(filename, "r");
@ -24,20 +26,7 @@ static FILE* fopen_or_die(char* filename) {
return fp;
}
// ----------------------------------------------------------------
// This tests our homemade getdelim replacement, for running on Windows which lacks getdelim.
static char* test_local_getdelim() {
return NULL;
}
// ----------------------------------------------------------------
// On unixish platforms this is testing the system getdelim() which is correct by definition.
// (At least, we verify it's behaving as we expect.) On Windows, this tests our local_getdelim
// which is a radundant test -- but again, it confirms behavior is as expected.
static char* test_getdelim() {
static char* test_getdelim_impl(getdelim_t* pgetdelim) {
char delimiter = '\n';
char* contents = NULL;
char* path = NULL;
@ -54,7 +43,7 @@ static char* test_getdelim() {
// Read line
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == -1);
mu_assert_lf(streq(line, ""));
mu_assert_lf(linecap >= 1+strlen(contents));
@ -62,7 +51,7 @@ static char* test_getdelim() {
// Read past EOF
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == -1);
mu_assert_lf(streq(line, ""));
@ -78,7 +67,7 @@ static char* test_getdelim() {
// Read line
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == 1);
mu_assert_lf(streq(line, "\n"));
mu_assert_lf(linecap >= 1+strlen(contents));
@ -86,7 +75,7 @@ static char* test_getdelim() {
// Read past EOF
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == -1);
mu_assert_lf(streq(line, ""));
@ -102,7 +91,7 @@ static char* test_getdelim() {
// Read line
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == 2);
mu_assert_lf(streq(line, "\r\n"));
mu_assert_lf(linecap >= 1+strlen(contents));
@ -110,7 +99,7 @@ static char* test_getdelim() {
// Read past EOF
line = NULL;
linecap = 0;
rc = getdelim(&line, &linecap, delimiter, fp);
rc = (*pgetdelim)(&line, &linecap, delimiter, fp);
mu_assert_lf(rc == -1);
mu_assert_lf(streq(line, ""));
@ -121,10 +110,24 @@ static char* test_getdelim() {
return NULL;
}
// ----------------------------------------------------------------
// On unixish platforms this is testing the system getdelim() which is correct by definition.
// (At least, we verify it's behaving as we expect.) On Windows, this tests our local_getdelim
// which is a radundant test -- but again, it confirms behavior is as expected.
static char* test_getdelim() {
return test_getdelim_impl(&mlr_arch_getdelim);
}
// ----------------------------------------------------------------
// This tests our homemade getdelim replacement, for running on Windows which lacks getdelim.
static char* test_local_getdelim() {
return test_getdelim_impl(&local_getdelim);
}
// ================================================================
static char * run_all_tests() {
mu_run_test(test_local_getdelim);
mu_run_test(test_getdelim);
mu_run_test(test_local_getdelim);
return 0;
}