From 9b2539294536f017b06383f773e792a9826defea Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Fri, 8 Nov 2019 08:48:30 +0100 Subject: [PATCH] 2019-11-08 in class --- headlines/headlines.c | 82 ++++++ headlines/test.expected | 106 ++++++++ headlines/test.in | 88 +++++++ headlines/test.out | 0 headlines/test_headlines.sh | 289 +++++++++++++++++++++ midterm/lists/Makefile | 144 ++++++++++ midterm/lists/lists.c | 42 +++ midterm/lists/lists.h | 14 + midterm/lists/tests/basic_testing.h | 13 + midterm/lists/tests/test0.c | 12 + midterm/lists/tests/test1.c | 77 ++++++ midterm/lists/tests/test2.c | 151 +++++++++++ midterm/tank_control/Makefile | 144 ++++++++++ midterm/tank_control/tank_control.c | 46 ++++ midterm/tank_control/tank_control.h | 15 ++ midterm/tank_control/tests/basic_testing.h | 13 + midterm/tank_control/tests/test0.c | 9 + midterm/tank_control/tests/test1.c | 32 +++ midterm/tank_control/tests/test2.c | 55 ++++ midterm/tank_control/tests/test3.c | 37 +++ 20 files changed, 1369 insertions(+) create mode 100644 headlines/headlines.c create mode 100644 headlines/test.expected create mode 100644 headlines/test.in create mode 100644 headlines/test.out create mode 100755 headlines/test_headlines.sh create mode 100644 midterm/lists/Makefile create mode 100644 midterm/lists/lists.c create mode 100644 midterm/lists/lists.h create mode 100644 midterm/lists/tests/basic_testing.h create mode 100644 midterm/lists/tests/test0.c create mode 100644 midterm/lists/tests/test1.c create mode 100644 midterm/lists/tests/test2.c create mode 100644 midterm/tank_control/Makefile create mode 100644 midterm/tank_control/tank_control.c create mode 100644 midterm/tank_control/tank_control.h create mode 100644 midterm/tank_control/tests/basic_testing.h create mode 100644 midterm/tank_control/tests/test0.c create mode 100644 midterm/tank_control/tests/test1.c create mode 100644 midterm/tank_control/tests/test2.c create mode 100644 midterm/tank_control/tests/test3.c diff --git a/headlines/headlines.c b/headlines/headlines.c new file mode 100644 index 0000000..d147930 --- /dev/null +++ b/headlines/headlines.c @@ -0,0 +1,82 @@ +#include +#include + +int heading_length(const char heading_char) { + int c; + unsigned int i = 0; + while ((c = getchar()) == heading_char) { + i++; + } + if (c != EOF) { + ungetc(c, stdin); + return i; + } else { + return -1; + } +} + +void print_section(unsigned int* section_arr, int level) { + for (int i = 0; i <= level; i++) { + printf("%u.", section_arr[i]); + } + printf("%u)", section_arr[level + 1]); +} + +int main(int argc, const char** argv) { + char sect; + + if (argc == 1) { + sect = '*'; + } else if (argc == 3 && !strcmp(argv[1], "-c")) { + sect = argv[2][0]; + } else { + printf("Usage: %s [-c {symbol}]\n", argv[0]); + return 1; + } + + + int level = 0; + unsigned int sections[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + int begin_of_line = 1; + int c; + + while ((c = getchar()) != EOF) { + if (!begin_of_line) { + putchar(c); + while ((c = getchar()) != '\n' && c != EOF) + putchar(c); + if (c == EOF) break; + putchar('\n'); + begin_of_line = 1; + } else { + int n = heading_length(sect); + if (n > 8) { + n = 8; + } + + begin_of_line = 0; + if (n == -1) break; + if (n == 0) continue; + + n--; + + if (level == n) { + sections[level]++; + } else if (n > level) { + for (int i = level + 1; i < n; i++) + sections[i] = 0; + sections[n] = 1; + level = n; + } else { + sections[n]++; + level = n; + } + + print_section(sections, level); + + } + } + + return 0; +} diff --git a/headlines/test.expected b/headlines/test.expected new file mode 100644 index 0000000..3801655 --- /dev/null +++ b/headlines/test.expected @@ -0,0 +1,106 @@ + +1) Introduction +This is just a test, you really don't need to worry about this text. + +2) Related Work +Here we compare with others + +2.1) The Good Ones +There are many others who are really good. + +2.2) The Bad Ones +There are also some bad ones. However there are no ugly ones + +2.3) The Ugly Ones + +3) Preliminaries +Here's a list of things we need to know: + * Pizza + * Pasta + * Gelato + +4) A New Way of Doing Things + +4.1) Mathematical Model +Model of what? +Model of what? +Model of what? +Model of what? +Model of what? + +4.1.1) Dynamic model + +4.1.2) Static model + +4.1.3) Semi-dynamic model + +4.2) New pipeline +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +5) Evaluation +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +5.1) Subjects +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +5.2) Workload +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +5.3) Testbed +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +5.4) Results +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +6) Conclusion +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. diff --git a/headlines/test.in b/headlines/test.in new file mode 100644 index 0000000..ff971b8 --- /dev/null +++ b/headlines/test.in @@ -0,0 +1,88 @@ +* Introduction +This is just a test, you really don't need to worry about this text. +* Related Work +Here we compare with others +** The Good Ones +There are many others who are really good. +** The Bad Ones +There are also some bad ones. However there are no ugly ones +** The Ugly Ones +* Preliminaries +Here's a list of things we need to know: + * Pizza + * Pasta + * Gelato +* A New Way of Doing Things +** Mathematical Model +Model of what? +Model of what? +Model of what? +Model of what? +Model of what? +*** Dynamic model +*** Static model +*** Semi-dynamic model +** New pipeline +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +* Evaluation +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +** Subjects +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +** Workload +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +** Testbed +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +** Results +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. +* Conclusion +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad +minim veniam, quis nostrud exercitation ullamco laboris nisi ut +aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. diff --git a/headlines/test.out b/headlines/test.out new file mode 100644 index 0000000..e69de29 diff --git a/headlines/test_headlines.sh b/headlines/test_headlines.sh new file mode 100755 index 0000000..2581893 --- /dev/null +++ b/headlines/test_headlines.sh @@ -0,0 +1,289 @@ +#!/bin/sh +# +if test -z "$1" +then + PROGRAM=./headlines +else + PROGRAM="$1" +fi + +test -x "$PROGRAM" || { echo "Could not find executable $PROGRAM" && exit 1; } + +run_test() { + echo Running test "$@" + "$@" < test.in | tee test.out || { echo "headlines returns FAILURE. Check test.in and test.out." && exit 1; } + diff -q test.out test.expected || { echo "Bad output from headlines FAILURE. Check test.in, test.out, and test.expected." && exit 1; } + echo PASSED. +} + +cat > test.in < test.expected < test.expected < test.in < test.expected < /dev/null; \ + for p in $(foreach prog,$(PROGRAMS),$(dir $(prog))$(prog)); do \ + echo "Testing $${p}:" ; \ + for t in $(TESTS_IO_NAMES); do \ + echo -n "Running test $$t..." ; \ + "$$p" < "$(TESTS_DIR)/$$t.in" > "$$t.out" 2>&1 & \ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "see $(TESTS_DIR)/$$t.in" ;\ + echo "you may run $$p < $(TESTS_DIR)/$$t.in" ;\ + echo "to see what went wrong";\ + rm -f "$$t.out" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \ + then \ + echo "PASS" ;\ + rm -f "$$t.out" ;\ + else \ + echo "FAIL" ;\ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\ + echo "to see the difference between the actual and expected output";\ + fi; \ + fi; \ + done; \ + for t in $(TESTS_SH_NAMES); do \ + echo -n "Running test $$t..." ; \ + $(SHELL) "$(TESTS_DIR)/$$t.sh" "$$p" > "$$t.out" 2>&1 & \ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "you may run $(TESTS_DIR)/$$t.sh $$p" ;\ + echo "to see what went wrong";\ + rm -f "$$t.out" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \ + then \ + echo "PASS" ;\ + rm -f "$$t.out" ;\ + else \ + echo "FAIL" ;\ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\ + echo "to see the difference between the actual and expected output";\ + fi; \ + fi; \ + done; \ + done + +$(TESTS_DIR)/%: $(TESTS_DIR)/%.c $(OBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.c $(OBJECTS) -o $@ + +$(TESTS_DIR)/%: $(TESTS_DIR)/%.cc $(OBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.cc $(OBJECTS) -o $@ + +.PHONY: check-bin +check-bin: $(TESTS_BIN) + @exec 2> /dev/null; \ + for t in $(TESTS_BIN_NAMES); do \ + echo -n "Running test $$t..." ; \ + "$(TESTS_DIR)/$$t" &\ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "you may run $(TESTS_DIR)/$$t to see what went wrong" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + echo "PASS" ;\ + fi; \ + done + + +.PHONY: clean +clean: + rm -f $(PROGRAMS) $(OBJECTS) tests/*.o $(TESTS_BIN) diff --git a/midterm/lists/lists.c b/midterm/lists/lists.c new file mode 100644 index 0000000..ee309b3 --- /dev/null +++ b/midterm/lists/lists.c @@ -0,0 +1,42 @@ +#include "lists.h" + +struct list* concatenate_all(int count, struct list* lists[]) { + struct list* first = 0; + + for (int i = 0; i < count; i++) { + struct list* l = lists[i]; + if (l == 0) continue; + if (first == 0) { + first = l; + } + while (l->next != 0) { + l = l->next; + } + i++; + for (; lists[i] == 0 && i < count; i++); + if (i == count) { + break; + } + l->next = lists[i]; + i--; + } + + return first; +} + +struct list* merge_sorted(struct list* a, struct list* b) { + if (a == 0) { + return b; + } else if (b == 0) { + return a; + } else { + if (a->value < b->value) { + a->next = merge_sorted(a->next, b); + return a; + } else { + b->next = merge_sorted(a, b->next); + return b; + } + } +} + diff --git a/midterm/lists/lists.h b/midterm/lists/lists.h new file mode 100644 index 0000000..e43b80e --- /dev/null +++ b/midterm/lists/lists.h @@ -0,0 +1,14 @@ +#ifndef LISTS_H_INCLUDED +#define LISTS_H_INCLUDED + +struct list { + int value; + struct list * next; +}; + +extern struct list * concatenate_all(int count, struct list * lists[]); + +extern struct list * merge_sorted(struct list * a, struct list * b); + +#endif + diff --git a/midterm/lists/tests/basic_testing.h b/midterm/lists/tests/basic_testing.h new file mode 100644 index 0000000..96217dd --- /dev/null +++ b/midterm/lists/tests/basic_testing.h @@ -0,0 +1,13 @@ +#ifndef BASIC_TESTING_H_INCLUDED +#define BASIC_TESTING_H_INCLUDED + +#include +#include + +#define assert_int_equal(expr,value) \ + do { int e = (expr); int v = (value); \ + if (e != v) { \ + fprintf(stderr, "%s:%d: Assertion `%s == %s' failed (%d != %d).\n", __FILE__, __LINE__, #expr, #value, e, v); \ + abort(); } } while(0) + +#endif diff --git a/midterm/lists/tests/test0.c b/midterm/lists/tests/test0.c new file mode 100644 index 0000000..26b123a --- /dev/null +++ b/midterm/lists/tests/test0.c @@ -0,0 +1,12 @@ +#include + +#include "basic_testing.h" +#include "../lists.h" + +int main() { + struct list * L[] = { 0, 0, 0 }; + + assert(concatenate_all(3, L) == 0); + assert(merge_sorted(0, 0) == 0); + return 0; +} diff --git a/midterm/lists/tests/test1.c b/midterm/lists/tests/test1.c new file mode 100644 index 0000000..3da6610 --- /dev/null +++ b/midterm/lists/tests/test1.c @@ -0,0 +1,77 @@ +#include + +#include "basic_testing.h" +#include "../lists.h" + +int main() { + struct list * LV[10]; + struct list L[100]; + struct list * l; + + for(int i = 0; i < 100; ++i) + L[i].value = i; + + for(int i = 0; i < 10; ++i) { + struct list * l = L + i*10; + LV[i] = l; + for (int j = 0; j < 5; ++j) { + l->next = l + 1; + l = l->next; + } + l->next = 0; + } + + l = concatenate_all(10, LV); + + for(int i = 0; i < 10; ++i) + for (int j = 0; j <= 5; ++j) { + assert(l); + assert_int_equal(l->value, i*10 + j); + l = l->next; + } + + for(int i = 0; i < 10; ++i) { + if (i % 2 == 0) { + LV[i] = 0; + } else { + struct list * l = L + i*10; + LV[i] = l; + for (int j = 0; j < 5; ++j) { + l->next = l + 1; + l = l->next; + } + l->next = 0; + } + } + + l = concatenate_all(10, LV); + for(int i = 1; i < 10; i += 2) + for (int j = 0; j <= 5; ++j) { + assert(l); + assert_int_equal(l->value, i*10 + j); + l = l->next; + } + + for(int i = 0; i < 10; ++i) { + if (i == 7) { + struct list * l = L + i*10; + LV[i] = l; + for (int j = 0; j < 5; ++j) { + l->next = l + 1; + l = l->next; + } + l->next = 0; + } else { + LV[i] = 0; + } + } + + l = concatenate_all(10, LV); + for (int j = 0; j <= 5; ++j) { + assert(l); + assert_int_equal(l->value, 70 + j); + l = l->next; + } + + return 0; +} diff --git a/midterm/lists/tests/test2.c b/midterm/lists/tests/test2.c new file mode 100644 index 0000000..46cf9e2 --- /dev/null +++ b/midterm/lists/tests/test2.c @@ -0,0 +1,151 @@ +#include + +#include "basic_testing.h" + +#include "../lists.h" + +int main() { + struct list L1[100]; + struct list L2[100]; + struct list * l; + int i; + + /* L1 = [0, 1, 2, 3, 4, 5] */ + l = L1; + for(i = 0; i < 5; ++i) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + l = merge_sorted(L1, 0); + + /* l should be: 0, 1, 2, 3, 4, 5 */ + for (int j = 0; j <= 5; ++j) { + assert(l); + assert_int_equal(l->value, j); + l = l->next; + } + assert(!l); + + /* L2 = [0, 1, 2, 3, 4, 5, 6] */ + l = L2; + for(i = 0; i < 6; ++i) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + l = merge_sorted(0, L2); + + /* l should be: 0, 1, 2, 3, 4, 5, 6 */ + for (int j = 0; j <= 6; ++j) { + assert(l); + assert_int_equal(l->value, j); + l = l->next; + } + assert(!l); + + /* L1 = [0, 1, 2, 3, 4] */ + l = L1; + for(i = 0; i < 4; ++i) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + /* L2 = [1, 3, 5] */ + l = L2; + for(i = 1; i < 5; i += 2) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + l = merge_sorted(L1, L2); + /* l should be: 0, 1, 1, 2, 3, 3, 4, 5 */ + assert(l); + assert_int_equal(l->value, 0); + l = l->next; + assert(l); + assert_int_equal(l->value, 1); + l = l->next; + assert(l); + assert_int_equal(l->value, 1); + l = l->next; + assert(l); + assert_int_equal(l->value, 2); + l = l->next; + assert(l); + assert_int_equal(l->value, 3); + l = l->next; + assert(l); + assert_int_equal(l->value, 3); + l = l->next; + assert(l); + assert_int_equal(l->value, 4); + l = l->next; + assert(l); + assert_int_equal(l->value, 5); + l = l->next; + assert(!l); + + /* L1 = [0, 1, 2, 3, 4] */ + l = L1; + for(i = 0; i < 4; ++i) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + /* L2 = [1, 3, 5] */ + l = L2; + for(i = 1; i < 5; i += 2) { + l->value = i; + l->next = l + 1; + l = l->next; + } + l->value = i; + l->next = 0; + + l = merge_sorted(L2, L1); + /* l should be: 0, 1, 1, 2, 3, 3, 4, 5 */ + assert(l); + assert_int_equal(l->value, 0); + l = l->next; + assert(l); + assert_int_equal(l->value, 1); + l = l->next; + assert(l); + assert_int_equal(l->value, 1); + l = l->next; + assert(l); + assert_int_equal(l->value, 2); + l = l->next; + assert(l); + assert_int_equal(l->value, 3); + l = l->next; + assert(l); + assert_int_equal(l->value, 3); + l = l->next; + assert(l); + assert_int_equal(l->value, 4); + l = l->next; + assert(l); + assert_int_equal(l->value, 5); + l = l->next; + assert(!l); + + + return 0; +} diff --git a/midterm/tank_control/Makefile b/midterm/tank_control/Makefile new file mode 100644 index 0000000..7e2b4d9 --- /dev/null +++ b/midterm/tank_control/Makefile @@ -0,0 +1,144 @@ +OBJECTS=tank_control.o + +CFLAGS=-Wall -g +CXXFLAGS=-Wall -g + +SHELL=/bin/bash + +TIMEOUT=8 + +TESTS_DIR=tests + +TESTS_SH:=$(wildcard $(TESTS_DIR)/*.sh) +TESTS_SH_NAMES:=$(patsubst $(TESTS_DIR)/%.sh, %, $(TESTS_SH)) + +TESTS_IO:=$(wildcard $(TESTS_DIR)/*.in) +TESTS_IO_NAMES:=$(patsubst $(TESTS_DIR)/%.in, %, $(TESTS_IO)) + +TESTS_C:=$(wildcard $(TESTS_DIR)/*.c) +TESTS_CXX:=$(wildcard $(TESTS_DIR)/*.cc) +TESTS_BIN:=$(patsubst $(TESTS_DIR)/%.c, $(TESTS_DIR)/%, $(TESTS_C)) \ + $(patsubst $(TESTS_DIR)/%.cc, $(TESTS_DIR)/%, $(TESTS_CXX)) +TESTS_BIN_NAMES:=$(patsubst $(TESTS_DIR)/%.c, %, $(TESTS_C)) $(patsubst $(TESTS_DIR)/%.cc, %, $(TESTS_CXX)) + +.PHONY: all +all: compile check + +.PHONY: compile-program + +compile: $(PROGRAMS) $(OBJECTS) + +.PHONY: check +check: check-bin check-io-sh + +.PHONY: check-io-sh +check-io-sh: compile $(TESTS_IO) $(TESTS_SH) + @exec 2> /dev/null; \ + for p in $(foreach prog,$(PROGRAMS),$(dir $(prog))$(prog)); do \ + echo "Testing $${p}:" ; \ + for t in $(TESTS_IO_NAMES); do \ + echo -n "Running test $$t..." ; \ + "$$p" < "$(TESTS_DIR)/$$t.in" > "$$t.out" 2>&1 & \ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "see $(TESTS_DIR)/$$t.in" ;\ + echo "you may run $$p < $(TESTS_DIR)/$$t.in" ;\ + echo "to see what went wrong";\ + rm -f "$$t.out" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \ + then \ + echo "PASS" ;\ + rm -f "$$t.out" ;\ + else \ + echo "FAIL" ;\ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\ + echo "to see the difference between the actual and expected output";\ + fi; \ + fi; \ + done; \ + for t in $(TESTS_SH_NAMES); do \ + echo -n "Running test $$t..." ; \ + $(SHELL) "$(TESTS_DIR)/$$t.sh" "$$p" > "$$t.out" 2>&1 & \ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "you may run $(TESTS_DIR)/$$t.sh $$p" ;\ + echo "to see what went wrong";\ + rm -f "$$t.out" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \ + then \ + echo "PASS" ;\ + rm -f "$$t.out" ;\ + else \ + echo "FAIL" ;\ + echo "see $(TESTS_DIR)/$$t.sh" ;\ + echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\ + echo "to see the difference between the actual and expected output";\ + fi; \ + fi; \ + done; \ + done + +$(TESTS_DIR)/%: $(TESTS_DIR)/%.c $(OBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.c $(OBJECTS) -o $@ + +$(TESTS_DIR)/%: $(TESTS_DIR)/%.cc $(OBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.cc $(OBJECTS) -o $@ + +.PHONY: check-bin +check-bin: $(TESTS_BIN) + @exec 2> /dev/null; \ + for t in $(TESTS_BIN_NAMES); do \ + echo -n "Running test $$t..." ; \ + "$(TESTS_DIR)/$$t" &\ + prog_pid=$$!; \ + ( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \ + killer_pid=$$!; \ + wait $$prog_pid; \ + res=$$?; \ + if test $$res -gt 128; \ + then \ + case `kill -l $$(($$res - 128))` in \ + ABRT ) echo "FAIL"; ;; \ + TERM ) echo "TIME OUT"; ;; \ + * ) echo "UNKNOWN ERROR"; ;; \ + esac ; \ + echo "you may run $(TESTS_DIR)/$$t to see what went wrong" ;\ + else \ + kill $$killer_pid > /dev/null 2>&1 ;\ + wait $$killer_pid; \ + echo "PASS" ;\ + fi; \ + done + + +.PHONY: clean +clean: + rm -f $(PROGRAMS) $(OBJECTS) tests/*.o $(TESTS_BIN) diff --git a/midterm/tank_control/tank_control.c b/midterm/tank_control/tank_control.c new file mode 100644 index 0000000..c1deed6 --- /dev/null +++ b/midterm/tank_control/tank_control.c @@ -0,0 +1,46 @@ +#include "tank_control.h" + +unsigned int level = 0; +unsigned int cap = 1000000; +unsigned int bottle_size = 750; + +unsigned int waste = 0; + +void clear() { + waste = 0; + level = 0; +} + +void change_bottle_capacity(unsigned int c) { + bottle_size = c; +} + +void change_tank(unsigned int c) { + cap = c; + if (level > cap) { + waste += level - cap; + level = cap; + } +} + +void add(unsigned int c) { + level += c; + if (level > cap) { + waste += level - cap; + level = cap; + } +} + +unsigned int ship_out_bottles() { + unsigned int bottles = level / bottle_size; + level = level % bottle_size; + return bottles; +} + +unsigned int get_tank_level() { + return level; +} + +unsigned int get_wastes() { + return waste; +} diff --git a/midterm/tank_control/tank_control.h b/midterm/tank_control/tank_control.h new file mode 100644 index 0000000..b208c2d --- /dev/null +++ b/midterm/tank_control/tank_control.h @@ -0,0 +1,15 @@ +#ifndef TANK_CONTROL_H_INCLUDED +#define TANK_CONTROL_H_INCLUDED + +extern void clear(); + +extern void change_bottle_capacity(unsigned int c); +extern void change_tank(unsigned int c); + +extern void add(unsigned int c); +extern unsigned int ship_out_bottles(); + +extern unsigned int get_wastes(); +extern unsigned int get_tank_level(); + +#endif diff --git a/midterm/tank_control/tests/basic_testing.h b/midterm/tank_control/tests/basic_testing.h new file mode 100644 index 0000000..96217dd --- /dev/null +++ b/midterm/tank_control/tests/basic_testing.h @@ -0,0 +1,13 @@ +#ifndef BASIC_TESTING_H_INCLUDED +#define BASIC_TESTING_H_INCLUDED + +#include +#include + +#define assert_int_equal(expr,value) \ + do { int e = (expr); int v = (value); \ + if (e != v) { \ + fprintf(stderr, "%s:%d: Assertion `%s == %s' failed (%d != %d).\n", __FILE__, __LINE__, #expr, #value, e, v); \ + abort(); } } while(0) + +#endif diff --git a/midterm/tank_control/tests/test0.c b/midterm/tank_control/tests/test0.c new file mode 100644 index 0000000..a22f413 --- /dev/null +++ b/midterm/tank_control/tests/test0.c @@ -0,0 +1,9 @@ +#include + +#include "../tank_control.h" + +int main() { + assert(get_tank_level() == 0); + assert(get_wastes() == 0); + return 0; +} diff --git a/midterm/tank_control/tests/test1.c b/midterm/tank_control/tests/test1.c new file mode 100644 index 0000000..37b9004 --- /dev/null +++ b/midterm/tank_control/tests/test1.c @@ -0,0 +1,32 @@ +#include "basic_testing.h" + +#include "../tank_control.h" + +int main() { + assert_int_equal(ship_out_bottles(), 0); + + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + add(90300); + + assert_int_equal(get_tank_level(), 90300); + assert_int_equal(get_wastes(), 0); + + assert_int_equal(ship_out_bottles(), 120); + assert_int_equal(get_tank_level(), 300); + assert_int_equal(get_wastes(), 0); + + add(90300); + + assert_int_equal(ship_out_bottles(), 120); + assert_int_equal(get_tank_level(), 600); + assert_int_equal(get_wastes(), 0); + + add(5400); + assert_int_equal(ship_out_bottles(), 8); + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + return 0; +} diff --git a/midterm/tank_control/tests/test2.c b/midterm/tank_control/tests/test2.c new file mode 100644 index 0000000..1ff03fd --- /dev/null +++ b/midterm/tank_control/tests/test2.c @@ -0,0 +1,55 @@ +#include "basic_testing.h" +#include "../tank_control.h" + +int main() { + assert_int_equal(ship_out_bottles(), 0); + + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + add(90300); + + assert_int_equal(get_tank_level(), 90300); + assert_int_equal(get_wastes(), 0); + + clear(); + + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + add(200000); + assert_int_equal(get_tank_level(), 200000); + assert_int_equal(get_wastes(), 0); + + add(1200000); + assert_int_equal(get_tank_level(), 1000000); + assert_int_equal(get_wastes(), 400000); + + assert_int_equal(ship_out_bottles(), 1333); + assert_int_equal(get_tank_level(), 250); + assert_int_equal(get_wastes(), 400000); + + clear(); + + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + add(200000); + assert_int_equal(get_tank_level(), 200000); + assert_int_equal(get_wastes(), 0); + + add(900000); + assert_int_equal(get_tank_level(), 1000000); + assert_int_equal(get_wastes(), 100000); + + assert_int_equal(ship_out_bottles(), 1333); + assert_int_equal(get_tank_level(), 250); + assert_int_equal(get_wastes(), 100000); + + clear(); + + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 0); + + return 0; +} diff --git a/midterm/tank_control/tests/test3.c b/midterm/tank_control/tests/test3.c new file mode 100644 index 0000000..265eac7 --- /dev/null +++ b/midterm/tank_control/tests/test3.c @@ -0,0 +1,37 @@ +#include "basic_testing.h" +#include "../tank_control.h" + +int main() { + add(100000); + + assert_int_equal(get_tank_level(), 100000); + assert_int_equal(get_wastes(), 0); + + change_tank(80000); + + assert_int_equal(get_tank_level(), 80000); + assert_int_equal(get_wastes(), 20000); + + change_bottle_capacity(800); + + assert_int_equal(get_tank_level(), 80000); + assert_int_equal(get_wastes(), 20000); + + add(10000); + assert_int_equal(get_tank_level(), 80000); + assert_int_equal(get_wastes(), 30000); + + assert_int_equal(ship_out_bottles(), 100); + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 30000); + + change_tank(50000); + + add(10000); + change_bottle_capacity(500); + assert_int_equal(ship_out_bottles(), 20); + assert_int_equal(get_tank_level(), 0); + assert_int_equal(get_wastes(), 30000); + + return 0; +}