all: reverse
clean:
- -rm *.o reverse
+ -rm *.o reverse reverse_test
distclean: clean
-rm deps.makefile deps.makefile.bak
depend: *.c
makedepend -f- $^ > deps.makefile
-.PHONY: clean distclean depend
+test: reverse_test
+ ./reverse_test
+
+.PHONY: clean distclean depend test
reverse: reverse.o reverse_lib.o
+reverse_test: reverse_test.o reverse_lib.o
$(CC) -o $@ $^ $(CFLAGS)
%.o: %.c
--- /dev/null
+#include "reverse_lib.h"
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static const char test_file[] = "reverse.c";
+
+char* reverse_to_temp_file(const char* input_file) {
+ char* temp_filename = strdup("/tmp/reverse_test.XXXXXX");
+ int fd = mkstemp(temp_filename);
+ if (fd == -1) err(EX_IOERR, "Couldn't make a temporary file");
+ reverse_file(input_file, fd);
+ if (close(fd) == -1) err(EX_IOERR, "Couldn't close temporary file");
+ return temp_filename;
+}
+
+void test_reverse_twice_is_the_same() {
+ char* intermediate = reverse_to_temp_file(test_file);
+ char* back_to_normal = reverse_to_temp_file(intermediate);
+
+ FILE* f1 = fopen(test_file, "r");
+ if (f1 == NULL) err(EX_IOERR, "Couldn't open test file");
+ FILE* f2 = fopen(back_to_normal, "r");
+ if (f2 == NULL) err(EX_IOERR, "Couldn't open twice-reversed temp file");
+
+ for (int pos = 0; ; pos++) {
+ int c1 = fgetc(f1);
+ int c2 = fgetc(f2);
+ if (c1 == EOF && ferror(f1)) err(EX_IOERR, "Error reading test file");
+ if (c2 == EOF && ferror(f2)) err(EX_IOERR, "Error reading twice-reversed temp file");
+ if (c1 != c2) {
+ errx(EX_SOFTWARE, "Unexpected difference found at offset %d after reversing twice. "
+ "Expected %d but found %d", pos, c1, c2);
+ }
+ if (c1 == EOF) break;
+ }
+
+ if (fclose(f1) != 0) err(EX_IOERR, "Couldn't close test file");
+ if (fclose(f2) != 0) err(EX_IOERR, "Couldn't close twice-reversed temp file");
+ if (unlink(intermediate) == -1) err(EX_IOERR, "Couldn't remove intermediate temp file");
+ if (unlink(back_to_normal) == -1) err(EX_IOERR, "Couldn't remove twice-reversed temp file");
+ free(intermediate);
+ free(back_to_normal);
+}
+
+int main() {
+ test_reverse_twice_is_the_same();
+ puts("PASS");
+ return 0;
+}