1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static int _remspace_internal(FILE* fin, FILE* fout, FILE* ferr, int pc) {
int c = fgetc(fin);
if (c == EOF) {
// Should I still put EOF here? does it work with pipes or not?
//fputc(c, fout);
return 0;
}
if (c == ' ' && pc == ' ') {
// skip it
} else {
fputc(c, fout);
}
__attribute__((musttail))
return _remspace_internal(fin, fout, ferr, c);
}
/* Copy stdin to stdout, replacing consecutive spaces with a single space
Edge case: a leading space is retained if there are leading spaces. */
int remspace(FILE* fin, FILE* fout, FILE* ferr) {
int res = _remspace_internal(fin, fout, ferr, -1);
fflush(fout);
fflush(ferr);
return res;
}
#ifndef test
int main(void) {
return remspace(stdin, stdout, stderr);
}
#else
#include "CuTest.h"
void do_test(CuTest* tc, char* input, const char* expected, const char* err_expected) {
char buf[100] = {0};
char err_buf[100] = {0};
FILE* tin = fmemopen(input, strlen(input), "r");
FILE* tout = fmemopen(buf, 100, "w");
FILE* terr = fmemopen(err_buf, 100, "w");
int res = remspace(tin, tout, terr);
CuAssertIntEquals(tc, 0, res);
CuAssertStrEquals(tc, expected, buf);
CuAssertStrEquals(tc, err_expected, err_buf);
}
void test_remspace_empty(CuTest* tc) {
do_test(tc, "", "", "");
}
void test_remspace_oneword(CuTest* tc) {
do_test(tc, "foobar", "foobar", "");
}
void test_remspace_leadtrailspace(CuTest* tc) {
do_test(tc, " foo bar ", " foo bar ", "");
}
CuSuite* remspace_suite() {
CuSuite* suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_remspace_empty);
SUITE_ADD_TEST(suite, test_remspace_oneword);
SUITE_ADD_TEST(suite, test_remspace_leadtrailspace);
return suite;
}
int main(void) {
CuString* output = CuStringNew();
CuSuite* suite = CuSuiteNew();
CuSuiteAddSuite(suite, remspace_suite());
CuSuiteRun(suite);
CuSuiteSummary(suite, output);
CuSuiteDetails(suite, output);
printf("%s\n", output->buffer);
return 0;
}
#endif
|