From 32ac505a9c5992bc30a76eb8cd4d12c6e0550b5b Mon Sep 17 00:00:00 2001 From: stsh Date: Thu, 17 Feb 2022 14:55:47 +0100 Subject: [PATCH] rm sol --- P01_Erste_Schritte_mit_C/solution/converter.c | 39 -- P01_Erste_Schritte_mit_C/solution/hello.c | 25 - P01_Erste_Schritte_mit_C/solution/wordcount.c | 47 -- .../README_solution.md | 125 ----- .../work/modularize-solution/java/read.java | 88 ---- .../modularize-solution/java/rectang.java | 32 -- .../modularize-solution/java/triangle.java | 73 --- .../work/modularize-solution/src/read.c | 94 ---- .../work/modularize-solution/src/read.h | 27 -- .../work/modularize-solution/src/rectang.c | 38 -- .../work/modularize-solution/src/rectang.h | 26 - .../work/modularize-solution/src/trace.h | 26 - .../work/modularize-solution/src/triangle.c | 78 --- .../tests/stim-error.input | 12 - .../tests/stim-not-right-angled.input | 12 - .../tests/stim-right-angled.input | 12 - .../work/modularize-solution/tests/tests.c | 205 -------- .../work/show-dependencies-solution/Makefile | 57 --- .../show-dependencies-solution/mainpage.dox | 8 - .../show-dependencies-solution/src/data.c | 149 ------ .../show-dependencies-solution/src/data.h | 72 --- .../show-dependencies-solution/src/error.h | 17 - .../show-dependencies-solution/src/main.c | 36 -- .../show-dependencies-solution/src/output.c | 95 ---- .../show-dependencies-solution/src/output.h | 20 - .../tests/dep.input | 7 - .../tests/no_dep.input | 2 - .../show-dependencies-solution/tests/tests.c | 140 ------ .../work/tic-tac-toe-solution/Makefile | 9 - .../work/tic-tac-toe-solution/mainpage.dox | 8 - .../work/tic-tac-toe-solution/src/control.c | 154 ------ .../work/tic-tac-toe-solution/src/control.h | 80 ---- .../work/tic-tac-toe-solution/src/main.c | 39 -- .../work/tic-tac-toe-solution/src/model.c | 154 ------ .../work/tic-tac-toe-solution/src/model.h | 108 ----- .../work/tic-tac-toe-solution/src/view.c | 255 ---------- .../work/tic-tac-toe-solution/src/view.h | 31 -- .../work/tic-tac-toe-solution/tests/tests.c | 445 ------------------ .../personen-verwaltung-solution/Makefile | 13 - .../personen-verwaltung-solution/mainpage.dox | 8 - .../personen-verwaltung-solution/src/list.c | 103 ---- .../personen-verwaltung-solution/src/list.h | 17 - .../personen-verwaltung-solution/src/main.c | 68 --- .../personen-verwaltung-solution/src/person.c | 22 - .../personen-verwaltung-solution/src/person.h | 26 - .../tests/tests.c | 299 ------------ P07_Prozesse_und_Threads/Solution/A03.dot | 76 --- P07_Prozesse_und_Threads/Solution/A03.png | Bin 79253 -> 0 bytes ...09_1_Prozesse_und_Threads-Kommentiert.docx | Bin 715221 -> 0 bytes ...P09_1_Prozesse_und_Threads-Kommentiert.pdf | Bin 622838 -> 0 bytes .../P09_2_Dämon_Prozesse-Kommentiert.docx | Bin 271958 -> 0 bytes .../P09_2_Dämon_Prozesse-Kommentiert.pdf | Bin 384639 -> 0 bytes .../ProcThreadsLsg.pdf | Bin 45771 -> 0 bytes .../SyncLsg.tar.gz | Bin 7726 -> 0 bytes 54 files changed, 3477 deletions(-) delete mode 100644 P01_Erste_Schritte_mit_C/solution/converter.c delete mode 100644 P01_Erste_Schritte_mit_C/solution/hello.c delete mode 100644 P01_Erste_Schritte_mit_C/solution/wordcount.c delete mode 100644 P02_Funktionen_Datentyp_enum/README_solution.md delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/java/read.java delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/java/rectang.java delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/java/triangle.java delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.c delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.h delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.c delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.h delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/trace.h delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/src/triangle.c delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-error.input delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-not-right-angled.input delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-right-angled.input delete mode 100644 P04_Modularisieren_von_C_Code/work/modularize-solution/tests/tests.c delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/Makefile delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/mainpage.dox delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.c delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.h delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/error.h delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/main.c delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.c delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.h delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/dep.input delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/no_dep.input delete mode 100644 P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/tests.c delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/Makefile delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/mainpage.dox delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/control.c delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/control.h delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/main.c delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/model.c delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/model.h delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/view.c delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/src/view.h delete mode 100644 P05_TicTacToe/work/tic-tac-toe-solution/tests/tests.c delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/Makefile delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/mainpage.dox delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.c delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.h delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/main.c delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.c delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.h delete mode 100644 P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/tests/tests.c delete mode 100644 P07_Prozesse_und_Threads/Solution/A03.dot delete mode 100644 P07_Prozesse_und_Threads/Solution/A03.png delete mode 100644 P07_Prozesse_und_Threads/Solution/P09_1_Prozesse_und_Threads-Kommentiert.docx delete mode 100644 P07_Prozesse_und_Threads/Solution/P09_1_Prozesse_und_Threads-Kommentiert.pdf delete mode 100644 P07_Prozesse_und_Threads/Solution/P09_2_Dämon_Prozesse-Kommentiert.docx delete mode 100644 P07_Prozesse_und_Threads/Solution/P09_2_Dämon_Prozesse-Kommentiert.pdf delete mode 100644 P07_Prozesse_und_Threads/SolutionFromBSYDonn20210513/ProcThreadsLsg.pdf delete mode 100644 P08_Sync/SolutionFromBSYDonn20210513/SyncLsg.tar.gz diff --git a/P01_Erste_Schritte_mit_C/solution/converter.c b/P01_Erste_Schritte_mit_C/solution/converter.c deleted file mode 100644 index 2538f6c..0000000 --- a/P01_Erste_Schritte_mit_C/solution/converter.c +++ /dev/null @@ -1,39 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include - -#define ROW_COUNT 8 - -/** - * @brief Main entry point. - * @param[in] argc The size of the argv array. - * @param[in] argv The command line arguments... - * @returns Returns EXIT_SUCCESS (=0) on success, EXIT_FAILURE (=1) if there is an input error. - */ -int main(char argc, char* argv){ - uint16_t i; - double rate; - - printf("Umwandlungskurs eingeben (1.00 BTC -> CHF): "); - if (1!= scanf("%lf", &rate)){ - printf("Ungültige Eingabe! Geben Sie eine Fliesskommazahl ein.\n"); - return 1; - } - - for(i = 1; i <= ROW_COUNT; i++) { - printf("%5d CHF\t<-->\t %5.5lf BTC\n", i*200, (double)i*200/rate); - } - return 0; -} \ No newline at end of file diff --git a/P01_Erste_Schritte_mit_C/solution/hello.c b/P01_Erste_Schritte_mit_C/solution/hello.c deleted file mode 100644 index 64d2c41..0000000 --- a/P01_Erste_Schritte_mit_C/solution/hello.c +++ /dev/null @@ -1,25 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include - -/** - * @brief Main entry point. - * @param[in] argc The size of the argv array. - * @param[in] argv The command line arguments... - * @returns Returns EXIT_SUCCESS (=0) on success. - */ -int main(char argc, char* argv[]) { - printf("hello world.\n"); - return 0; -} \ No newline at end of file diff --git a/P01_Erste_Schritte_mit_C/solution/wordcount.c b/P01_Erste_Schritte_mit_C/solution/wordcount.c deleted file mode 100644 index 0a9f182..0000000 --- a/P01_Erste_Schritte_mit_C/solution/wordcount.c +++ /dev/null @@ -1,47 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include - -/** - * @brief Main entry point. - * @param[in] argc The size of the argv array. - * @param[in] argv The command line arguments... - * @returns Returns EXIT_SUCCESS (=0) on success, EXIT_FAILURE (=1) there is an expression syntax error. - */ -int main(char argc, char* argv[]) { - uint16_t char_count = 0, word_count = 0; - char c; - uint8_t is_word = 0; - - printf("Eingabe: "); - c=getchar(); - while('\n' != c){ - char_count++; - if(c != ' ' && c !='\t'){ - if(! is_word){ - is_word = 1; - word_count++; - } - } else { - is_word = 0; - } - c = getchar(); - } - - printf("%d Zeichen, %d W\u00F6rter\n", char_count, word_count); - return 0; - - -} \ No newline at end of file diff --git a/P02_Funktionen_Datentyp_enum/README_solution.md b/P02_Funktionen_Datentyp_enum/README_solution.md deleted file mode 100644 index 5d5cf18..0000000 --- a/P02_Funktionen_Datentyp_enum/README_solution.md +++ /dev/null @@ -1,125 +0,0 @@ - -# Lösungsskizzen -## Aufgabe 1 -``` -/** - * Tage Pro Monat - * - * Das Programm liest einen Monat (1-12) und ein Jahr (1600-2400) ein und - * gibt die Anzahl der Tage dieses Monats aus. - * - * @author Gerrit Burkert, Adaptation bazz - * @version 15-FEB-2013, 16-OCT-2017, 17-OCT-2019, 16-FEB-2022 - */ - -#include -#include - -#define ERROR_IN_MONTH 1 -#define ERROR_IN_YEAR 2 - -///// Student Code - - - -// Konstante Werte fuer die Monate -// =============================== - -enum { JAN=1, FEB, MAR, APR, MAI, JUN, JUL, AUG, SEP, OKT, NOV, DEZ }; - - -// Eingabe pruefen (0 ist vom atoi als Fehelcode verwendet und darf nicht verwendet werden) -// =============== - -int gibIntWert(char *name, int von, int bis) { - - int wert; - char wertS[20]; // - - do { - printf("%s: ", name); - fgets(wertS, 20, stdin); - wert = atoi(wertS); - if (wert < von || wert > bis) { - printf("Der Wert muss zwischen %d und %d sein.\n", von, bis); - } else { - break; - } - } while(1); - return wert; -} - - -// Schaltjahr bestimmen -// ==================== - -int istSchaltjahr(int jahr){ - - if ( (jahr % 400 == 0) || ( (jahr %100 != 0) && (jahr % 4 ==0) ) ) - return 1; - else - return 0; -} - - -// Berechnung Anzahl Tage pro Monat -// ================================ - -int tageProMonat(int jahr, int monat) { - - int anzTage; - - // Tage pro Monat bestimmen - switch (monat) { - - // Monate mit 31 Tagen - case JAN: case MAR: case MAI: case JUL: case AUG: case OKT: case DEZ: - anzTage = 31; - break; - - // Monate mit 30 Tagen - case APR: case JUN: case SEP: case NOV: - anzTage = 30; - break; - - // Februar: 28 oder 29 Tage - case FEB: - - if (istSchaltjahr(jahr)) { - anzTage = 29; - } else { - anzTage = 28; - } - break; - } - - return anzTage; -} - -///// END Student Code - - -int main (int argc, char *argv[]) { - - int monat, jahr; - - // Monat einlesen und Bereich ueberpruefen - monat = gibIntWert("Monat", 1, 12); - jahr = gibIntWert("Jahr", 1600, 9999); - - // Ausgabe zum Test - printf("Monat: %d, Jahr: %d \n", monat, jahr); - - // Ausgabe zum Test (hier mit dem ternaeren Operator "?:") - printf("%d ist %s Schaltjahr\n", jahr, istSchaltjahr(jahr) ? "ein" : "kein"); - - // Ausgabe - printf("Der Monat %02d-%d hat %d Tage.\n", monat, jahr, tageProMonat(jahr, monat)); - - return 0; -} - -``` -## Aufgabe 2 -Alter bestehender Boilerplate Code - diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/read.java b/P04_Modularisieren_von_C_Code/work/modularize-solution/java/read.java deleted file mode 100644 index 35570de..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/read.java +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************** - M. Thaler, Jan. 2000 - Datei read.java - Funktion: Unsigned int Zahl via Bytestream von stdin einlesen. - Es wird zuerst eine Zeile eingelesen und dann konvertiert. - Die eingelesene Zeile darf nur eine Zahl enthalten - (mit optionalen Leerzeichen vor/nach der Zahl). - Returns: Die konvertierte Zahl - oder -1 (PARSE_ERROR) wenn keine Zahl oder zu gross - oder -2 (READ_ERROR) wenn Fehler beim einlesen. - Korrekturen: - Maerz 2002: M. Thaler, H. Fierz, Mar. 2002 - liest bis EOL oder EOF, korrekter Rueckgabewert - - Sept 2016: A. Gieriet - Refactored (sprechende Variablen-Namen, - MS Windows Support, 0 Wert erlaubt, - Leerzeichen Support, - "magic" Numbers durch Symbole ersetzt, - maxResult Parameter, etc.) -******************************************************************************/ - -public class read { - public int getInt(int maxResult) - throws java.io.IOException - { - // end of input - int EOF = -1; // end of file - int EOL = 10; // end of line - // abnormal return values - int PARSE_ERROR = -1; - int READ_ERROR = -2; - // ASCII Codes - int ASCII_SPACE = 32; // ' ' - int ASCII_DIGIT_0 = 48; // '0' - int ASCII_DIGIT_9 = 57; // '9' - - // conversion buffer - int NO_POS = -1; - int BUFFERSIZE = 10; - byte[] buffer = new byte[BUFFERSIZE]; - - int result = 0; - - // read line: up to EOL or EOF (i.e. error while reading) - int bytes = 0; - int input = System.in.read(); - while ((input != EOL) && (input != EOF)) { // read whole line - if (bytes < BUFFERSIZE) { // only buffer first n characters - buffer[bytes] = (byte)input; - bytes++; - } else { - result = PARSE_ERROR; // exceed buffer size, continue read line - } - input = System.in.read(); - } - if (input == EOF) { - result = READ_ERROR; - } - // check for numbers: skip leading and trailing spaces - // (i.e. this includes all control chars below the space ASCII code) - int pos = 0; - while((pos < bytes) && (buffer[pos] <= ASCII_SPACE)) pos++; // skip SP - int posOfFirstDigit = pos; - int posOfLastDigit = NO_POS; - while ((pos < bytes) - && (buffer[pos] >= ASCII_DIGIT_0) - && (buffer[pos] <= ASCII_DIGIT_9)) - { - posOfLastDigit = pos; - pos++; - } - while((pos < bytes) && (buffer[pos] <= ASCII_SPACE)) pos++; // skip SP - // produce return value - if (result != 0) { - // previously detected read or parse error given - } else if ((pos != bytes) || (posOfLastDigit == NO_POS)) { - result = PARSE_ERROR; - } else { // convert number - for(int i = posOfFirstDigit; i <= posOfLastDigit; i++) { - result = result * 10 + (buffer[i] - ASCII_DIGIT_0); - if (result > maxResult) { - result = PARSE_ERROR; - break; - } - } - } - return result; - } -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/rectang.java b/P04_Modularisieren_von_C_Code/work/modularize-solution/java/rectang.java deleted file mode 100644 index 34b1302..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/rectang.java +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** - M. Thaler, Jan. 2000 - Datei: rectang.java - Funktion: Bestimmt, ob Dreieck rechtwinklig ist. - Returns: true wenn rechtwinklig, sonst false. - Korrekturen: - Sept 2016, A. Gieriet - Refactored (sprechende Variablen Namen, etc.) -******************************************************************************/ - -public class rectang { - - public boolean Rectangular(int a, int b, int c) { - - int aS = a*a; - int bS = b*b; - int cS = c*c; - - boolean isRightAngled; - if ((a == 0) && (b == 0) && (c == 0)) - isRightAngled = false; - else if ((aS + bS) == cS) - isRightAngled = true; - else if ((aS + cS) == bS) - isRightAngled = true; - else if ((bS + cS) == aS) - isRightAngled = true; - else - isRightAngled = false; - - return isRightAngled; - } -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/triangle.java b/P04_Modularisieren_von_C_Code/work/modularize-solution/java/triangle.java deleted file mode 100644 index 8c24aca..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/java/triangle.java +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** - M. Thaler, Jan. 2000 - Datei: triangle.java - Funktion: Die drei Seiten eines Dreiecks einlesen und bestimmen ob - das Dreieck rechtwinklig ist. - Returns: Nichts. - Korrekturen: - Maerz 2002, M. Thaler, H. Fierz - Abfrage bei unkorrekter Eingabe wiederholen - - Sept 2016, A. Gieriet - Refactored (sprechende Variablen-Namen, - "magic" Numbers durch Symbole ersetzt, etc.) -******************************************************************************/ - -class triangle { - - public static void main(String[] args) - throws java.io.IOException - { - int READ_ERROR = -2; - int MAX_NUMBER = 1000; - - read ReadInt = new read(); - rectang Rect = new rectang(); - - while (true) { - System.out.println("\nDreiecksbestimmung (CTRL-C: Abbruch)\n"); - - int word = 0; - int a = 0; - int b = 0; - int c = 0; - - do { - System.out.print("Seite a: "); - word = ReadInt.getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - a = word; - else - break; - - do { - System.out.print("Seite b: "); - word = ReadInt.getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - b = word; - else - break; - - do { - System.out.print("Seite c: "); - word = ReadInt.getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - c = word; - else - break; - - if (Rect.Rectangular(a, b, c) == true) - System.out.println("-> Dreieck " + a + "-" + b + "-" + c - + " ist rechtwinklig"); - else - System.out.println("-> Dreieck " + a + "-" + b + "-" + c - + " ist nicht rechtwinklig"); - System.out.println("\n"); - } - System.out.println("\n\nbye bye\n"); - } -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.c b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.c deleted file mode 100644 index 74c502a..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.c +++ /dev/null @@ -1,94 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include -#include "read.h" -#include "trace.h" - -//#define EOF (-1) // end of file - -/// end-of-line -#define EOL 10 // end of line - -// abnormal return values -/// parse-error -#define PARSE_ERROR (-1) - -// ASCII Codes -/// ascii code for space -#define ASCII_SPACE ' ' -/// ascii code for 0 -#define ASCII_DIGIT_0 '0' -/// ascii code for 9 -#define ASCII_DIGIT_9 '9' - -// conversion buffer -/// no buffer position sentry -#define NO_POS (-1) -/// buffer size -#define BUFFERSIZE (10) - -int getInt(int maxResult) -{ - TRACE("getInt(%d)", maxResult); - - char buffer[BUFFERSIZE] = { 0 }; - - int result = 0; - - // read line: up to EOL or EOF (i.e. error while reading) - int bytes = 0; - int input = getchar(); - while ((input != EOL) && (input != EOF)) { // read whole line - if (bytes < BUFFERSIZE) { // only buffer first n characters - buffer[bytes] = (char)input; - bytes++; - } else { - result = PARSE_ERROR; // exceed buffer size, continue read line - } - input = getchar(); - } - if (input == EOF) { - result = READ_ERROR; - } - // check for numbers: skip leading and trailing spaces - // (i.e. this includes all control chars below the space ASCII code) - int pos = 0; - while((pos < bytes) && (buffer[pos] <= ASCII_SPACE)) pos++; // skip SP - int posOfFirstDigit = pos; - int posOfLastDigit = NO_POS; - while ((pos < bytes) - && (buffer[pos] >= ASCII_DIGIT_0) - && (buffer[pos] <= ASCII_DIGIT_9)) - { - posOfLastDigit = pos; - pos++; - } - while((pos < bytes) && (buffer[pos] <= ASCII_SPACE)) pos++; // skip SP - // produce return value - if (result != 0) { - // previously detected read or parse error given - } else if ((pos != bytes) || (posOfLastDigit == NO_POS)) { - result = PARSE_ERROR; - } else { // convert number - for(int i = posOfFirstDigit; i <= posOfLastDigit; i++) { - result = result * 10 + (buffer[i] - ASCII_DIGIT_0); - if (result > maxResult) { - result = PARSE_ERROR; - break; - } - } - } - return result; -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.h b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.h deleted file mode 100644 index e3f6192..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/read.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#ifndef READ_H -#define READ_H - -/// I/O error which leads to aborting. -#define READ_ERROR (-2) - -/** - * @brief Reads a line from stdin and tries to parse it as number (with optional leading and trailing spaces). - * @param[in] maxResult gives the limit for the number to be read. - * @returns the succesfully read and parsed number or a negative value if in error (READ_ERROR in case of I/O error). - */ -int getInt(int maxResult); - -#endif diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.c b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.c deleted file mode 100644 index 4cc8f4c..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.c +++ /dev/null @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include "rectang.h" -#include "trace.h" - -int rectangular(int a, int b, int c) -{ - TRACE("rectangular(%d, %d, %d)", a, b, c); - - int aS = a*a; - int bS = b*b; - int cS = c*c; - - int isRightAngled; - if ((a == 0) && (b == 0) && (c == 0)) - isRightAngled = 0; - else if ((aS + bS) == cS) - isRightAngled = 1; - else if ((aS + cS) == bS) - isRightAngled = 1; - else if ((bS + cS) == aS) - isRightAngled = 1; - else - isRightAngled = 0; - - return isRightAngled; -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.h b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.h deleted file mode 100644 index 38e3577..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/rectang.h +++ /dev/null @@ -1,26 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#ifndef RECTANG_H -#define RECTANG_H - -/** - * @brief checks if the three lengths give a right-angled triangle. - * @param[in] a 1st side - * @param[in] b 2nd side - * @param[in] c 3rd side - * @returns 1 if right-angled, 0 otherwise - */ -int rectangular(int a, int b, int c); - -#endif diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/trace.h b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/trace.h deleted file mode 100644 index 56f5209..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/trace.h +++ /dev/null @@ -1,26 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#ifndef TRACE_H -#define TRACE_H - -#include - -/** - * @brief TRACE macro. - * @param[in] MSG "..." format string literal. - * @param[in] ... optional arguments to the format string. - */ -#define TRACE(MSG, ...) do { (void)fprintf(stderr, "TRACE: " MSG "\n", ##__VA_ARGS__); } while(0) - -#endif diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/triangle.c b/P04_Modularisieren_von_C_Code/work/modularize-solution/src/triangle.c deleted file mode 100644 index b1cd649..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/src/triangle.c +++ /dev/null @@ -1,78 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include -#include "read.h" -#include "rectang.h" -#include "trace.h" - -/// max side length -#define MAX_NUMBER 1000 - - -/** - * @brief Main entry point. - * @returns Returns EXIT_SUCCESS (=0) on success, EXIT_FAILURE (=1) on failure. - */ -int main(void) -{ - TRACE("main()"); - - while (1) { - (void)printf("\nDreiecksbestimmung (CTRL-C: Abbruch)\n\n"); - - int word = 0; - int a = 0; - int b = 0; - int c = 0; - - do { - (void)printf("Seite a: "); - word = getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - a = word; - else - break; - - do { - (void)printf("Seite b: "); - word = getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - b = word; - else - break; - - do { - (void)printf("Seite c: "); - word = getInt(MAX_NUMBER); - } - while ((word < 0) && (word != READ_ERROR)); - if (word >= 0) - c = word; - else - break; - - if (rectangular(a, b, c)) - (void)printf("-> Dreieck %d-%d-%d ist rechtwinklig\n", a, b, c); - else - (void)printf("-> Dreieck %d-%d-%d ist nicht rechtwinklig\n", a, b, c); - (void)printf("\n\n"); - } - (void)printf("\n\nbye bye\n\n"); - return EXIT_SUCCESS; -} diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-error.input b/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-error.input deleted file mode 100644 index ab2d76b..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-error.input +++ /dev/null @@ -1,12 +0,0 @@ - -a - a - a - 3 -4444 - 4444 - 44444444444444 - 4 - 4 - 5 - 5 diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-not-right-angled.input b/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-not-right-angled.input deleted file mode 100644 index 07b2e27..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-not-right-angled.input +++ /dev/null @@ -1,12 +0,0 @@ -3 -4 -6 -5 -4 -4 -3 -5 -5 -33 -43 -55 diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-right-angled.input b/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-right-angled.input deleted file mode 100644 index fa866ac..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/stim-right-angled.input +++ /dev/null @@ -1,12 +0,0 @@ -3 -4 -5 -5 -4 -3 -3 -5 -4 -33 -44 -55 diff --git a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/tests.c b/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/tests.c deleted file mode 100644 index 699b64a..0000000 --- a/P04_Modularisieren_von_C_Code/work/modularize-solution/tests/tests.c +++ /dev/null @@ -1,205 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include -#include "CUnit/Basic.h" -#include "test_utils.h" - -#ifndef TARGET // must be given by the make file --> see test target -#error missing TARGET define -#endif - -/// @brief The name of the STDOUT text file. -#define OUTFILE "stdout.txt" -/// @brief The name of the STDERR text file. -#define ERRFILE "stderr.txt" - -/// @brief The stimulus for the right-angled triangles -#define INFILE_RIGHT_ANGLED "stim-right-angled.input" -/// @brief The stimulus for the not right-angled triangles -#define INFILE_NOT_RIGHT_ANGLED "stim-not-right-angled.input" -/// @brief The stimulus for input errors -#define INFILE_ERROR "stim-error.input" - -// setup & cleanup -static int setup(void) -{ - remove_file_if_exists(OUTFILE); - remove_file_if_exists(ERRFILE); - return 0; // success -} - -static int teardown(void) -{ - // Do nothing. - // Especially: do not remove result files - they are removed in int setup(void) *before* running a test. - return 0; // success -} - - -// tests -static void test_right_angled(void) -{ - // arrange - const char *out_txt[] = { - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 3-4-5 ist rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 5-4-3 ist rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 3-5-4 ist rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 33-44-55 ist rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: \n", - "\n", - "bye bye\n", - "\n", - }; - // act - int exit_code = system(XSTR(TARGET) " 1>" OUTFILE " 2>" ERRFILE " <" INFILE_RIGHT_ANGLED); - // assert - CU_ASSERT_EQUAL(exit_code, 0); - assert_lines(OUTFILE, out_txt, sizeof(out_txt)/sizeof(*out_txt)); -} - -static void test_not_right_angled(void) -{ - // arrange - const char *out_txt[] = { - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 3-4-6 ist nicht rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 5-4-4 ist nicht rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 3-5-5 ist nicht rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite b: Seite c: -> Dreieck 33-43-55 ist nicht rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: \n", - "\n", - "bye bye\n", - "\n", - }; - // act - int exit_code = system(XSTR(TARGET) " 1>" OUTFILE " 2>" ERRFILE " <" INFILE_NOT_RIGHT_ANGLED); - // assert - CU_ASSERT_EQUAL(exit_code, 0); - assert_lines(OUTFILE, out_txt, sizeof(out_txt)/sizeof(*out_txt)); -} - -static void test_trace(void) -{ - // arrange - const char *err_txt[] = { - "TRACE: main()\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: rectangular(3, 4, 6)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: rectangular(5, 4, 4)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: rectangular(3, 5, 5)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: getInt(1000)\n", - "TRACE: rectangular(33, 43, 55)\n", - "TRACE: getInt(1000)\n", - }; - // act - int exit_code = system(XSTR(TARGET) " 1>" OUTFILE " 2>" ERRFILE " <" INFILE_NOT_RIGHT_ANGLED); - // assert - CU_ASSERT_EQUAL(exit_code, 0); - assert_lines(ERRFILE, err_txt, sizeof(err_txt)/sizeof(*err_txt)); -} - -static void test_error(void) -{ - // arrange - const char *out_txt[] = { - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: Seite a: Seite a: Seite a: Seite a: Seite b: Seite b: Seite b: Seite b: Seite b: Seite c: Seite c: -> Dreieck 3-4-5 ist rechtwinklig\n", - "\n", - "\n", - "\n", - "Dreiecksbestimmung (CTRL-C: Abbruch)\n", - "\n", - "Seite a: \n", - "\n", - "bye bye\n", - "\n", - }; - // act - int exit_code = system(XSTR(TARGET) " 1>" OUTFILE " 2>" ERRFILE " <" INFILE_ERROR); - // assert - CU_ASSERT_EQUAL(exit_code, 0); - assert_lines(OUTFILE, out_txt, sizeof(out_txt)/sizeof(*out_txt)); -} - -/** - * @brief Registers and runs the tests. - */ -int main(void) -{ - // setup, run, teardown - TestMainBasic("Triangle", setup, teardown - , test_right_angled - , test_not_right_angled - , test_trace - , test_error - ); -} diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/Makefile b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/Makefile deleted file mode 100644 index d05b3d8..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -SNP_SHARED_MAKEFILE := $(if $(SNP_SHARED_MAKEFILE),$(SNP_SHARED_MAKEFILE),"~/snp/shared.mk") - -TARGET := bin/dep2dot -SOURCES := src/main.c src/data.c src/output.c -TSTSOURCES := tests/tests.c - -include $(SNP_SHARED_MAKEFILE) - - -# DEPFILES := ... define a list of png file names: %.c -> %.c.png -# BEGIN-STUDENTS-TO-ADD-CODE -DEPFILES := $(SOURCES:%.c=%.c.png) -# END-STUDENTS-TO-ADD-CODE - - -# define dep target as .PHONEY -# BEGIN-STUDENTS-TO-ADD-CODE -.PHONY: dep -# BEGIN-STUDENTS-TO-ADD-CODE - - -# define dep target depending on FULLTARGET and DEPFILES above -# action: echo some text telling that the target is done using $@ - the echo command shall not be echoed before execution -# BEGIN-STUDENTS-TO-ADD-CODE -dep: $(FULLTARGET) $(DEPFILES) - @echo "### $@ done ###" - -# BEGIN-STUDENTS-TO-ADD-CODE - - -# define new suffix rule for %.png depending on %.dot -# action: dot -Tpng $< >$@ || $(RM) $@ -# BEGIN-STUDENTS-TO-ADD-CODE -%.png: %.dot - dot -Tpng $< >$@ || $(RM) $@ - -# BEGIN-STUDENTS-TO-ADD-CODE - - -# define new suffix rule for %.dot depending on %.dep -# action: call $(TARGET) $(@:.dot=) <$< >$@ || $(RM) $@ -# BEGIN-STUDENTS-TO-ADD-CODE -%.dot: %.dep - $(TARGET) $(@:.dot=) <$< >$@ || $(RM) $@ - -# BEGIN-STUDENTS-TO-ADD-CODE - -# converts any .c file into a .c.dep file by means of GCC -H switch -# note: it removes intermediate files which were created as side effect -%.c.dep: %.c - $(COMPILE.c) -H -o $@.x $< 2>$@ && $(RM) $@.x $@.d - - -# cleanup all results, including the ones od creating the dependencies -dep-clean: clean - $(RM) $(DEPFILES) $(wildcard src/*.dep src/*.dot) - diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/mainpage.dox b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/mainpage.dox deleted file mode 100644 index cd6b69a..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/mainpage.dox +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @mainpage SNP - P04 Modularisation - * - * @section Purpose - * - * This is a lab for splitting functionality into multiple modules. - * - */ diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.c b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.c deleted file mode 100644 index a9f28f8..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file - * @brief Implementation of the dependency file access. - */ -#include "data.h" -#include "error.h" -#include -#include -#include -#include -#include - -#define MAX_PATH_LEN 512 ///< @brief Arbitrarily chosen maximum accepted path lenght. -#define MAX_LINE_LEN 512 ///< @brief Arbitrarily chosen maximum accepted line length -#define MAX_DIRS 64 ///< @brief Arbitrarily chosen maximum number of supported individual directories per dependency file. -#define MAX_FILES 256 ///< @brief Arbitrarily chosen maximum number of supported individual denendency entries. - -/** - * @brief Declaration of POSIX (but not C99) function. - * @param s [IN] The string to duplicate on the heap memory. - * @return The duplicated string. - * @remark Since the Makefile calls gcc with -std=c99, non-C99 POSIX and GNU extensions are excluded - the glibc, though, provides the function to the linker. - */ -char *strdup(const char *s); // not stdc99, but available in the glibc - -/** - * @brief Initialized the data structure before the data is to be read from th edependency file. - * @param data [INOUT] The address of the instance to initialize. - */ -static void init(data_t *data) -{ - assert(data); - memset(data, 0, sizeof(data_t)); - data->dirs = malloc(MAX_DIRS * sizeof(dir_t)); - if (!data->dirs) FATAL("no memory left"); - data->files = malloc(MAX_FILES * sizeof(file_t)); - if (!data->files) FATAL("no memory left"); -} - -/** - * @brief Updates the directory list with the given data. - * @param data [INOUT] The instance to update. - * @param path [IN] The file path of a dependency entry as given by the dependency file. - * @return The index of the directory entry (either an existing matching one or a newly added one). - * @remark Extracts the directory part by means of dirname() from the given path and looks up an existing entry or adds a new one. - */ -static size_t get_or_add_dir(data_t *data, const char *path) -{ - assert(data); - assert(path); - // The function dirname() gives no guarantee to not modify the parameter, therefore, need to produce a copy before calling dirname(). - // Likewise, the returned value may refer to the passed paremater, therefore, a copy is made from the return value. - char *dup = strdup(path); - if (!dup) FATAL("no memory left"); - char *name = strdup(dirname(dup)); - if (!name) FATAL("no memory left"); - free(dup); - - // search for a matching entry... - size_t i = 0; - while(i < data->n_dirs && strcmp(data->dirs[i].name, name) != 0) { - i++; - } - if (i >= MAX_DIRS) FATAL("too many directories"); - - if (i == data->n_dirs) { // no match found: add - // handover the allocated name to the owning new directory entry - dir_t dir = { .name = name }; - // append the new directory entry - data->dirs[data->n_dirs] = dir; - data->n_dirs++; - } else { - // release the name since match found, and therefore, no need to keep the allocated name anymore - free(name); - } - return i; -} - -/** - * @brief Add a file entry from the dependency file to the data structure. - * @param data [INOUT] The data container instance. - * @param path [IN] The path of one file entry from the dependency file. - * @param level [IN] The dependency level of the file entry from the dependency file. - * @remark The sequence of entries in the dependency file is relevant - it implies direct dependencies. - */ -static void add_file(data_t *data, const char *path, size_t level) -{ - assert(data); - assert(path); - // The function basename() gives no guarantee to not modify the parameter, therefore, need to produce a copy before calling basename(). - // Likewise, the returned value may refer to the passed paremater, therefore, a copy is made from the return value. - char *dup = strdup(path); - if (!dup) FATAL("no memory left"); - char *name = strdup(basename(dup)); - if (!name) FATAL("no memory left"); - free(dup); - - if (data->n_files >= MAX_FILES) FATAL("too many files"); - // produce a file entry - file_t file = { .name = name, .dir = get_or_add_dir(data, path), .level = level }; - data->files[data->n_files] = file; - data->n_files++; -} - -/** - * @brief Processes one dependency line of the dependency file. - * @param data [INOUT] The data container instance. - * @param line [IN] The line to parse and store in data. - */ -static void process_line(data_t *data, const char line[]) -{ - assert(data); - - size_t len = strlen(line); - assert(len > 0); - assert(line[0] == '.'); - - // read level - size_t i = strspn(line, "."); - size_t level = i; - // skip spaces - i += strspn(line+i, " \t"); - // take rest as path and add the file to the records - add_file(data, line+i, level); -} - -/* - * The public interface. - */ -const data_t data_read_all(const char *root) -{ - data_t data; - init(&data); - // add as first file the root for the given dependencies - add_file(&data, root, 0); - - char line[MAX_LINE_LEN] = { 0 }; - - // read all stdin line and only process dependency lines (those starting on a '.') - clearerr(stdin); - while(fgets(line, MAX_LINE_LEN, stdin)) { - size_t len = strlen(line); - if (len > 0 && line[len-1] == '\n' && line[0] == '.') { // only dependency lines - line[len-1] = '\0'; - process_line(&data, line); - } - } - return data; -} diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.h b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.h deleted file mode 100644 index ab1880b..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/data.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file - * @brief Access to the GCC produced dependency data (via -H command line option). - */ - -// begin of include guard -// BEGIN-STUDENTS-TO-ADD-CODE -#ifndef _DATA_H_ -#define _DATA_H_ -// END-STUDENTS-TO-ADD-CODE - - -// includes which are needed in this header file -// BEGIN-STUDENTS-TO-ADD-CODE -#include -// END-STUDENTS-TO-ADD-CODE - - - -/** - * @brief Directory container for file entries of the dependency file. - */ -// BEGIN-STUDENTS-TO-ADD-CODE -typedef struct { - const char *name; ///< @brief the path name of the directory as given by the GCC produced dependency file. -} dir_t; -// END-STUDENTS-TO-ADD-CODE - - - -/** - * @brief File container for the file entries of the dependency file. - */ -// BEGIN-STUDENTS-TO-ADD-CODE -typedef struct { - const char *name; ///< @brief The base name of the file from the GGC produced dependency file (i.e. the plain name, without any directory path). - size_t dir; ///< @brief The index of the directory entry which represents the path as given by the dependency file. - size_t level; ///< @brief The level as read out from the dependecy file. -} file_t; -// END-STUDENTS-TO-ADD-CODE - - - -/** - * @brief Overall container for all directories and all files from the dependency file. - */ -// BEGIN-STUDENTS-TO-ADD-CODE -typedef struct { - size_t n_dirs; ///< @brief The number of valid entries in the dirs list. - dir_t *dirs; ///< @brief The list of directories. - size_t n_files; ///< @brief The number of valid entries in the files list. - file_t *files; ///< @brief The list of files from the dependency file (the sequence is relevant to determine the dependencies). -} data_t; -// END-STUDENTS-TO-ADD-CODE - - - -/** - * @brief Entry function to read the deendency data from stdin. - * @param root [IN] The name of the root file (the deoendency file does not mention the root file, so, it has to be passed from outside). - * @return The container of the read data from stdin. See the documentation on gcc -H for details on the dependencies, etc. - */ -// BEGIN-STUDENTS-TO-ADD-CODE -const data_t data_read_all(const char *root); -// END-STUDENTS-TO-ADD-CODE - - - -// end of include guard -// BEGIN-STUDENTS-TO-ADD-CODE -#endif // _DATA_H_ -// END-STUDENTS-TO-ADD-CODE diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/error.h b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/error.h deleted file mode 100644 index 3a38ab6..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/error.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file - * @brief Error handling convenience functions. - */ -#ifndef _ERROR_H_ -#define _ERROR_H_ - -#include -#include - -/** - * @brief Prints the message to stderr and terminates with EXIT_FAILURE. - * @param MSG [IN] The "..." *string literal* to emit as error - no format parameters nor variables supported. - */ -#define FATAL(MSG) do { fprintf(stderr, "ERROR: %s\n", MSG); exit(EXIT_FAILURE); } while(0) - -#endif // _ERROR_H_ diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/main.c b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/main.c deleted file mode 100644 index 8cf35f9..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/main.c +++ /dev/null @@ -1,36 +0,0 @@ - /* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab P04 dep2dot - */ -#include -#include - -#include "error.h" -#include "data.h" -#include "output.h" - -/** - * @brief main function - * @param argc [in] number of entries in argv - * @param argv [in] program name plus command line arguments - * @returns returns success if valid date is given, failure otherwise - * @remark Prerequisit to convert the resulting DOT file on the shell: sodo apt install graphviz - * @remark Convert: gcc -H ... file.c ... 2>file.dep ; dep2dot file.c file.dot && dot -Tpng file.dot >file.png - */ -int main(int argc, const char *argv[]) -{ - if (argc < 2) FATAL("missing arguments\nusage: dep2dot file.c file.dot # from gcc -H ... file.c ... 2>file.dep\n"); - - output_dot(data_read_all(argv[1])); - - return EXIT_SUCCESS; -} diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.c b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.c deleted file mode 100644 index 3a3d33e..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file - * @brief Provides output functions for various file formats. - */ -#include "output.h" -#include -#include -#include - -/** - * @brief Writes the node name of the given file. - * @param file [IN] The file for which to write the node name. - * @remark The dependency data contain duplicates of file entries - the node name must be unique for the path and the *basename* of the files. - */ -static void print_node(file_t file) -{ - printf("\"%s (cluster_c%zd)\"", file.name, file.dir); -} - -/** - * @brief Recursively writes the individual direct dependencies for the file given by curr. - * @param files [IN] The array of all files - the sequence is relevant. - * @param len [IN] The lenght of the files array, i.e. the upper limit for curr values and the subsequent index values. - * @param curr [IN] The index into files for the current root for dependencies: curr -> x, curr -> y, ... - * @return Returns the index into files for the next file to process (i.e. curr value for the next call to this function). - * @remark For a given *curr* file, all following files are with depth level + 1 are direct include files. - * @remark All files with a higher level are *indirect* include files, thus *direct* includes from files processed by recursive calls. - * @remark The list of direct includes to the *curr* file terminates with a level equal of less the the *curr* one (or when the list is exchausted). - */ -static size_t dependencies(file_t files[], size_t len, size_t curr) -{ - assert(curr < len); - size_t level = files[curr].level; - size_t file = curr + 1; - while(file < len && files[file].level > level) { - if (files[file].level == level + 1) { - // Write to stdout " file -> include;\n" where file and include are the DOT node names of the respective files - // BEGIN-STUDENTS-TO-ADD-CODE - printf(" "); - print_node(files[curr]); - printf(" -> "); - print_node(files[file]); - printf(";\n"); - // END-STUDENTS-TO-ADD-CODE - file = dependencies(files, len, file); - } else { - file++; - } - } - return file; -} - -/* - * Public interface - */ -void output_dot(const data_t data) -{ - printf("digraph dep {\n"); - // nodes - printf(" node [shape=box]\n"); - for (size_t file = 0; file < data.n_files; file++) { - // Write to stdout " file [label=\"name\"];\n" where file is the DOT node name and name is the file name - // BEGIN-STUDENTS-TO-ADD-CODE - printf(" "); - print_node(data.files[file]); - printf(" [label=\"%s\"];\n", data.files[file].name); - // END-STUDENTS-TO-ADD-CODE - } - // directory clusters - for (size_t dir = 0; dir < data.n_dirs; dir++) { - printf(" subgraph cluster_c%zd {\n", dir); - printf(" label=\"%s\"; %s\n", data.dirs[dir].name, strncmp(data.dirs[dir].name, "/usr/", 5) == 0 ? "style=filled; color=lightgrey;" : "color=black;"); - for (size_t file = 0; file < data.n_files; file++) { - if (data.files[file].dir == dir) { - // Write to stdout " file;\n" where file is the DOT node name - // BEGIN-STUDENTS-TO-ADD-CODE - printf(" "); - print_node(data.files[file]); - printf(";\n"); - // END-STUDENTS-TO-ADD-CODE - } - } - printf(" }\n"); - } - - // dependencies - size_t curr = 0; - do { - curr = dependencies(data.files, data.n_files, curr); - } while(curr < data.n_files); - - printf("}\n"); -} - - diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.h b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.h deleted file mode 100644 index e0a1b1e..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/src/output.h +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file - * @brief Provides output functions for various file formats. - */ -// define proper header file here, with include gaurd, etc. -// BEGIN-STUDENTS-TO-ADD-CODE -#ifndef _OUTPUT_H_ -#define _OUTPUT_H_ - -#include "data.h" - -/** - * @brief Produces DOT output of the dependencies given in data. - * @param data [IN] Container of the dependenciy data. - */ -void output_dot(const data_t data); - - -#endif // _OUTPUT_H_ -// END-STUDENTS-TO-ADD-CODE diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/dep.input b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/dep.input deleted file mode 100644 index d21a54c..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/dep.input +++ /dev/null @@ -1,7 +0,0 @@ -Test File -. dir1/h1_1 -.. dir1/h1_1_2 -. dir1/h1_2 -. dir2/h2_1 -.. dir1/h1_1 -Done diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/no_dep.input b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/no_dep.input deleted file mode 100644 index 6565e2d..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/no_dep.input +++ /dev/null @@ -1,2 +0,0 @@ -Test File -Done diff --git a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/tests.c b/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/tests.c deleted file mode 100644 index 119800f..0000000 --- a/P04_Modularisieren_von_C_Code/work/show-dependencies-solution/tests/tests.c +++ /dev/null @@ -1,140 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Test suite for the given package. - */ -#include -#include -#include -#include -#include -#include -#include "test_utils.h" - -#ifndef TARGET // must be given by the make file --> see test target -#error missing TARGET define -#endif - -/// @brief alias for EXIT_SUCCESS -#define OK EXIT_SUCCESS -/// @brief alias for EXIT_FAILURE -#define FAIL EXIT_FAILURE - -/// @brief The name of the STDOUT text file. -#define OUTFILE "stdout.txt" -/// @brief The name of the STDERR text file. -#define ERRFILE "stderr.txt" - -/// @brief test data file -#define IN_NO_DEP "no_dep.input" -/// @brief test data file -#define IN_DEP "dep.input" - -// setup & cleanup -static int setup(void) -{ - remove_file_if_exists(OUTFILE); - remove_file_if_exists(ERRFILE); - return 0; // success -} - -static int teardown(void) -{ - // Do nothing. - // Especially: do not remove result files - they are removed in int setup(void) *before* running a test. - return 0; // success -} - -// tests -static void test_fail_no_arg(void) -{ - // arrange & act & assert - CU_ASSERT_EQUAL(WEXITSTATUS(system(XSTR(TARGET) " >" OUTFILE " 2>" ERRFILE)), FAIL); -} - -static void test_no_dep(void) -{ - // arrange - const char *out_txt[] = { - "digraph dep {\n", - " node [shape=box]\n", - " \"root (cluster_c0)\" [label=\"root\"];\n", - " subgraph cluster_c0 {\n", - " label=\".\"; color=black;\n", - " \"root (cluster_c0)\";\n", - " }\n", - "}\n", - }; - - // act & assert - CU_ASSERT_EQUAL(WEXITSTATUS(system(XSTR(TARGET) " root <" IN_NO_DEP " >" OUTFILE " 2>" ERRFILE)), OK); - - // assert - - assert_lines(OUTFILE, out_txt, sizeof(out_txt)/sizeof(*out_txt)); -} - -static void test_dep(void) -{ - // arrange - const char *out_txt[] = { - "digraph dep {\n", - " node [shape=box]\n", - " \"root (cluster_c0)\" [label=\"root\"];\n", - " \"h1_1 (cluster_c1)\" [label=\"h1_1\"];\n", - " \"h1_1_2 (cluster_c1)\" [label=\"h1_1_2\"];\n", - " \"h1_2 (cluster_c1)\" [label=\"h1_2\"];\n", - " \"h2_1 (cluster_c2)\" [label=\"h2_1\"];\n", - " \"h1_1 (cluster_c1)\" [label=\"h1_1\"];\n", - " subgraph cluster_c0 {\n", - " label=\".\"; color=black;\n", - " \"root (cluster_c0)\";\n", - " }\n", - " subgraph cluster_c1 {\n", - " label=\"dir1\"; color=black;\n", - " \"h1_1 (cluster_c1)\";\n", - " \"h1_1_2 (cluster_c1)\";\n", - " \"h1_2 (cluster_c1)\";\n", - " \"h1_1 (cluster_c1)\";\n", - " }\n", - " subgraph cluster_c2 {\n", - " label=\"dir2\"; color=black;\n", - " \"h2_1 (cluster_c2)\";\n", - " }\n", - " \"root (cluster_c0)\" -> \"h1_1 (cluster_c1)\";\n", - " \"h1_1 (cluster_c1)\" -> \"h1_1_2 (cluster_c1)\";\n", - " \"root (cluster_c0)\" -> \"h1_2 (cluster_c1)\";\n", - " \"root (cluster_c0)\" -> \"h2_1 (cluster_c2)\";\n", - " \"h2_1 (cluster_c2)\" -> \"h1_1 (cluster_c1)\";\n", - "}\n", - }; - - // act & assert - CU_ASSERT_EQUAL(WEXITSTATUS(system(XSTR(TARGET) " root <" IN_DEP " >" OUTFILE " 2>" ERRFILE)), OK); - - // assert - - assert_lines(OUTFILE, out_txt, sizeof(out_txt)/sizeof(*out_txt)); -} - -/** - * @brief Registers and runs the tests. - * @returns success (0) or one of the CU_ErrorCode (>0) - */ -int main(void) -{ - // setup, run, teardown - TestMainBasic("lab test", setup, teardown - , test_fail_no_arg - , test_no_dep - , test_dep - ); -} diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/Makefile b/P05_TicTacToe/work/tic-tac-toe-solution/Makefile deleted file mode 100644 index a29984f..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -SNP_SHARED_MAKEFILE := $(if $(SNP_SHARED_MAKEFILE),$(SNP_SHARED_MAKEFILE),"~/snp/shared.mk") - -TARGET := bin/tic-tac-toe -MODULES := src/model.c src/view.c src/control.c -SOURCES := src/main.c $(MODULES) -TSTSOURCES := tests/tests.c $(MODULES) - -include $(SNP_SHARED_MAKEFILE) - diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/mainpage.dox b/P05_TicTacToe/work/tic-tac-toe-solution/mainpage.dox deleted file mode 100644 index b07e65d..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/mainpage.dox +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @mainpage SNP - P05 Tic Tac Toe Game - * - * @section Purpose - * - * This is a lab on usage of arrays. - * - */ diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/control.c b/P05_TicTacToe/work/tic-tac-toe-solution/src/control.c deleted file mode 100644 index ccae643..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/control.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file - * @brief Implementation - */ -#include "control.h" -#include "model.h" -#include - -/** - * @brief Conversion from control field number (1...9) to 0-based model position (row, col). - * @param cell [IN] Field number (1...9). - * @return Returns the position of the field. - * @remark Asserts proper field range. - */ -static model_pos_t get_pos(size_t cell) -{ - assert(1 <= cell && cell <= 9); - model_pos_t pos = { (cell - 1) / 3, (cell - 1) % 3 }; - return pos; -} - -/** - * @brief Conversion from control player to model state. - * @param player [IN] Control player value to convert. - * @return Returns the matching model state. - * @remark No assertion is done - defaults to model_state_none. - */ -static model_state_t get_state(control_player_t player) -{ - switch(player) { - case control_player_a: return model_state_a; - case control_player_b: return model_state_b; - default: return model_state_none; - } -} - -/** - * @brief Conversion from 0-based model position (row, col) to control field number (1...9). - * @param pos [IN] 0-based model position (row,col). - * @return The control filed number (1...9) - * @remark Asserts proper position range. - */ -static size_t get_cell(model_pos_t pos) -{ - assert(pos.row < 3); - assert(pos.col < 3); - return 1 + pos.row * 3 + pos.col; -} - -/** - * @brief Conversion from model state to control player. - * @param state [IN] Model state to convert - * @return Returns the matching control player value. - * @remark No assertion is done - defaults to control_no_player. - */ -static control_player_t get_player(model_state_t state) -{ - switch(state) { - case model_state_a: return control_player_a; - case model_state_b: return control_player_b; - default: return control_no_player; - } -} - -/** - * @brief Queries if a move is possible. - * @param instance [INOUT] The instance which holds the state. - * @return Returns 0 if no move is possible any more, otherwise 1. - */ -static int control_can_move(control_t *instance) -{ - assert(instance); - return model_can_move(instance->model); -} - -// public API function which is documented in the header file. -void control_init(control_t *instance, model_t *model) -{ - assert(instance); - assert(model); - instance->player = control_player_a; - instance->model = model; -} - -// public API function which is documented in the header file. -void control_move(control_t *instance, size_t cell) -{ - assert(instance); - if (model_move(instance->model, get_pos(cell), get_state(instance->player))) { - if (control_can_move(instance)) { - switch(instance->player) { - case control_player_a: - instance->player = control_player_b; - break; - case control_player_b: - instance->player = control_player_a; - break; - default: - break; - } - } else { - instance->player = control_no_player; - } - } -} - -// public API function which is documented in the header file. -control_player_t control_get_winner(control_t *instance) -{ - assert(instance); - return get_player(model_get_winner(instance->model)); -} - -// public API function which is documented in the header file. -control_player_t control_get_player(control_t *instance) -{ - assert(instance); - return instance->player; -} - -// public API function which is documented in the header file. -control_player_t control_get_state(control_t *instance, size_t cell) -{ - assert(instance); - return get_player(model_get_state(instance->model, get_pos(cell))); -} - -// public API function which is documented in the header file. -control_line_t control_get_win(control_t *instance) -{ - assert(instance); - if (control_get_winner(instance) == control_no_player) { - control_line_t no_win = { 0 }; - return no_win; - } - - model_line_t line = model_get_win_line(instance->model); - assert(line.dir != model_dir_none); - size_t start_cell = get_cell(line.start); - switch(line.dir) { - case model_dir_h: - return (control_line_t) { { start_cell, start_cell + 1, start_cell + 2 } }; - case model_dir_v: - return (control_line_t) { { start_cell, start_cell + 3, start_cell + 6 } }; - case model_dir_d: - if (start_cell == 1) { - return (control_line_t) { { start_cell, start_cell + 4, start_cell + 8 } }; - } else { - return (control_line_t) { { start_cell, start_cell + 2, start_cell + 6 } }; - } - default: - return (control_line_t) { { 1, 1, 1 } }; - } -} diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/control.h b/P05_TicTacToe/work/tic-tac-toe-solution/src/control.h deleted file mode 100644 index 613bd8f..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/control.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file - * @brief MVC - agent between model and view - */ -#ifndef _CONTROL_H_ -#define _CONTROL_H_ - -#include "model.h" - -/** - * @brief The selection of possible players. - */ -typedef enum { - control_no_player, ///< none of the players - control_player_a, ///< first player - control_player_b, ///< second player -} control_player_t; - -/** - * @brief Sequence of winning cell numbers in increasing cell numbers. - */ -typedef struct { - size_t line[3]; ///< the sequence of cells (1...9) or 0 in the first element if no win -} control_line_t; - -/** - * @brief The instance type. - */ -typedef struct { - control_player_t player; ///< the current player - model_t *model; ///< the reference to the model -} control_t; - -/** - * @brief Constructor: initialize the instance memory. - * @param instance [INOUT] The instance which holds the state. - * @param model [IN] Dependency Injection of the model instance. - */ -void control_init(control_t *instance, model_t *model); - -/** - * @brief Performs a move on the board. - * @param instance [INOUT] The instance which holds the state. - * @param cell [IN] The affected field (1...9) - * @remark Silently ignores a move if it is not allowed (e.g. if already completed or the field is already played, etc.). - */ -void control_move(control_t *instance, size_t cell); - -/** - * @brief Queries the winning player. - * @param instance [INOUT] The instance which holds the state. - * @returns Returns the winning player (if any). - */ -control_player_t control_get_winner(control_t *instance); - -/** - * @brief Queries the next player. - * @param instance [INOUT] The instance which holds the state. - * @returns Returns the next player (if any). - * @remark This is updated by the control_move() function. - */ -control_player_t control_get_player(control_t *instance); - -/** - * @brief Queries the state of a field. - * @param instance [INOUT] The instance which holds the state. - * @param cell [IN] The affected field of the board (1...9). - * @returns Returns the player which played this field (if any). - */ -control_player_t control_get_state(control_t *instance, size_t cell); - -/** - * @brief Gets the winning fields (if any). - * @param instance [INOUT] The instance which holds the state. - * @returns Returns the field numbers in increasing order (1...9) which win the game (if any). - * @remark If there is no winner (yet), the first entry in the result is 0. - */ -control_line_t control_get_win(control_t *instance); - -#endif // _CONTROL_H_ diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/main.c b/P05_TicTacToe/work/tic-tac-toe-solution/src/main.c deleted file mode 100644 index 7e66b7e..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/main.c +++ /dev/null @@ -1,39 +0,0 @@ - /* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab P04 dep2dot - */ -#include -#include - -#include "view.h" -#include "model.h" -#include "control.h" - -/** - * @brief main function - * @param argc [in] number of entries in argv - * @param argv [in] program name plus command line arguments - * @returns returns success if valid date is given, failure otherwise - */ -int main(int argc, const char *argv[]) -{ - view_t view; - control_t control; - model_t model; - - model_init(&model); - control_init(&control, &model); - view_init(&view, &control); - view_run(&view); - - return EXIT_SUCCESS; -} diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/model.c b/P05_TicTacToe/work/tic-tac-toe-solution/src/model.c deleted file mode 100644 index b544f17..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/model.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file - * @brief Implementation - */ -#include "model.h" -#include - -/** - * @brief Asserts that the position is in range. - * @param [IN] The position to check. - */ -static void assert_pos(model_pos_t pos) -{ - assert(pos.row < MODEL_SIZE); - assert(pos.col < MODEL_SIZE); -} - -/** - * @brief Sets the field on the board to the given state. - * @param instance [INOUT] The instance which holds the state. - * @param pos [IN] The affected field. - * @param state [IN] The new state of the field. - */ -static void set_state(model_t *instance, model_pos_t pos, model_state_t state) -{ - assert_pos(pos); - - // Instructions to the students: - // set the field of the board to the new state - // BEGIN-STUDENTS-TO-ADD-CODE - instance->board[pos.row][pos.col] = state; - // END-STUDENTS-TO-ADD-CODE -} - -// public API function which is documented in the header file. -model_pos_t model_pos(size_t row, size_t col) -{ - return (model_pos_t){row, col}; -} - -// public API function which is documented in the header file. -void model_init(model_t *instance) -{ - assert(instance); - - // Instructions to the students: - // set all fields of the board to model_state_none - // BEGIN-STUDENTS-TO-ADD-CODE - for(size_t row = 0; row < MODEL_SIZE; row++) { - for(size_t col = 0; col < MODEL_SIZE; col++) { - instance->board[row][col] = model_state_none; - } - } - // END-STUDENTS-TO-ADD-CODE -} - -// public API function which is documented in the header file. -model_state_t model_get_state(model_t *instance, model_pos_t pos) -{ - assert(instance); - assert_pos(pos); - - // Instructions to the students: - // replace the stub implementation my access to the field at the given position. - // BEGIN-STUDENTS-TO-ADD-CODE - return instance->board[pos.row][pos.col]; // stub return model_state_none; - // END-STUDENTS-TO-ADD-CODE -} - -// public API function which is documented in the header file. -model_line_t model_get_win_line(model_t *instance) -{ - assert(instance); - model_state_t anchor; - - // horizontal - for(size_t row = 0; row < MODEL_SIZE; row++) { - anchor = model_get_state(instance, model_pos(row, 0)); - if (anchor != model_state_none - && anchor == model_get_state(instance, model_pos(row, 1)) - && anchor == model_get_state(instance, model_pos(row, 2))) { - return (model_line_t) { model_dir_h, { row, 0 } }; - } - } - - // vertical - for(size_t col = 0; col < MODEL_SIZE; col++) { - anchor = model_get_state(instance, model_pos(0, col)); - if (anchor != model_state_none - && anchor == model_get_state(instance, model_pos(1, col)) - && anchor == model_get_state(instance, model_pos(2, col))) { - return (model_line_t) { model_dir_v, { 0, col } }; - } - - - } - - // diagonal - anchor = model_get_state(instance, model_pos(1, 1)); - if (anchor != model_state_none) { - if (anchor == model_get_state(instance, model_pos(0, 0)) && anchor == model_get_state(instance, model_pos(2, 2))) { - return (model_line_t) { model_dir_d, { 0, 0 } }; - } - if (anchor == model_get_state(instance, model_pos(2, 0)) && anchor == model_get_state(instance, model_pos(0, 2))) { - return (model_line_t) { model_dir_d, { 0, 2 } }; - } - } - - // fallback - return (model_line_t) { model_dir_none, { 0, 0 } }; -} - -// public API function which is documented in the header file. -model_state_t model_get_winner(model_t *instance) -{ - assert(instance); - model_line_t line = model_get_win_line(instance); - return line.dir == model_dir_none - ? model_state_none - : model_get_state(instance, model_pos(line.start.row, line.start.col)) - ; -} - -// public API function which is documented in the header file. -int model_can_move(model_t *instance) -{ - assert(instance); - if (model_get_winner(instance) == model_state_none) { - // Instructions to the students: - // scan all fields: return 1 with first field which equals model_state_none - // BEGIN-STUDENTS-TO-ADD-CODE - for(size_t row = 0; row < MODEL_SIZE; row++) { - for (size_t col = 0; col < MODEL_SIZE; col++) { - if (instance->board[row][col] == model_state_none) { - return 1; - } - } - } - // END-STUDENTS-TO-ADD-CODE - } - return 0; -} - -// public API function which is documented in the header file. -int model_move(model_t *instance, model_pos_t pos, model_state_t state) -{ - assert(instance); - assert_pos(pos); - if (model_get_state(instance, pos) == model_state_none && model_can_move(instance)) { - set_state(instance, pos, state); - return 1; - } - return 0; -} diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/model.h b/P05_TicTacToe/work/tic-tac-toe-solution/src/model.h deleted file mode 100644 index 51e2678..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/model.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file - * @brief MVC - Model instance - */ -#ifndef _MODEL_H_ -#define _MODEL_H_ - -#include - -#define MODEL_SIZE 3 ///< size of the game to avoid magic numbers in the code (not meant to modify) - -/** - * @brief The position on the board. - */ -typedef struct { - size_t row; ///< The row (0-based). - size_t col; ///< The column (0-based). -} model_pos_t; - -/** - * @brief Winner line direction - the winner line is given together with the start position. - */ -typedef enum { - model_dir_none, ///< no winner line - model_dir_h, ///< horizontal - model_dir_v, ///< vertical - model_dir_d, ///< diagonal -} model_dir_t; - -/** - * @brief The Winner line (if any). - */ -typedef struct { - model_dir_t dir; ///< the winner line direction (if any) - model_pos_t start; ///< the start position of the winner line -} model_line_t; - -/** - * @brief The state of a field. - */ -typedef enum { - model_state_none, ///< field available to play - model_state_a, ///< field already played - model_state_b, ///< field already played -} model_state_t; - -/** - * @brief The instance type. - */ -typedef struct { - model_state_t board[MODEL_SIZE][MODEL_SIZE]; ///< the play board -} model_t; - -/** - * @brief Convert to row and col to position. - * @param row [IN] position parameter - * @param col [IN] position parameter - * @return Returns the position given be row and col parameters. - */ -model_pos_t model_pos(size_t row, size_t col); - -/** - * @brief Constructor: initialize the instance memory. - * @param instance [INOUT] The instance which holds the state. - */ -void model_init(model_t *instance); - -/** - * @brief Queries the state of the given field. - * @param instance [INOUT] The instance which holds the state. - * @param pos [IN] The affected field. - * @return Returns the state of the field. - */ -model_state_t model_get_state(model_t *instance, model_pos_t pos); - -/** - * @brief Queries the winner (if any). - * @param instance [INOUT] The instance which holds the state. - * @return Returns the wining player or model_state_none if no winner (yet). - */ -model_state_t model_get_winner(model_t *instance); - -/** - * @brief Queries if a move is possible (i.e. not won yet and any field available?). - * @param instance [INOUT] The instance which holds the state. - * @return Returns 0 if no move possible, 1 otherwise. - */ -int model_can_move(model_t *instance); - -/** - * @brief Do a move if possible. - * @param instance [INOUT] The instance which holds the state. - * @param pos [IN] The field to play. - * @param state [IN] The new state (only model_state_a and model_state_b allowed). - * @return Returns if the attempt to move was successful. - * @remark Does only succeed if not yet won and if the field is available. - */ -int model_move(model_t *instance, model_pos_t pos, model_state_t state); - -/** - * @brief Gets the winner line (if any). - * @param instance [INOUT] The instance which holds the state. - * @returns The line which wins (if any). - * @remark The start position is 0/0, 1/0, 2/0 for horizontal, 0/0, 0/1, 0/2 for vertical, 0/0, 0/2 for diagonal. - */ -model_line_t model_get_win_line(model_t *instance); - -#endif // _MODEL_H_ diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/view.c b/P05_TicTacToe/work/tic-tac-toe-solution/src/view.c deleted file mode 100644 index a248c49..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/view.c +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @file - * @brief Implementation - */ -#include "view.h" -#include "control.h" - -#include // assert() -#include // various i/o -#include // isdigit() -#include // STDIN_FILENO, isatty() -#include // tcgetattr(), tcsetattr() - -#define EXIT '0' ///< the UI exit request - -#define CLS "\033[2J" ///< ANSI termial CSI sequence for clear screen -#define AVAILABLE "\033[40m" ///< ANSI termial CSI sequence for available fields (black) -#define PLAYER_A "\033[42m" ///< ANSI termial CSI sequence for one player (green) -#define PLAYER_B "\033[41m" ///< ANSI termial CSI sequence for the other player (red) -#define GAP "\033[47m" ///< ANSI termial CSI sequence for boarder (white) -#define RESET "\033[0m" ///< ANSI termial CSI sequence to reset all settings - -#define CELL_WIDTH 10 ///< rendering parameter: columns per cell -#define CELL_HEIGHT 5 ///< rendering parameter: rows per cell -#define GAP_WIDTH 4 ///< rendering parameter: columns per border -#define GAP_HEIGHT 2 ///< rendering parameter: rows per boarder - -#define SIZE 3 ///< size of the game to avoid magic numbers in the code (not meant to modify) -#define CELLS (SIZE * SIZE) ///< size of the game to avoid magic numbers in the code (not meant to modify) - -/** - * @brief Position the cursor for further output. - * @param row [IN] position parameter - * @param col [IN] position parameter - */ -static void goto_pos(size_t row, size_t col) -{ - printf("\033[%zd;%zdH", row, col); -} - -/** - * @brief Displays a sequence of spaces at the given position in the given background color. - * @param row [IN] position parameter - * @param col [IN] position parameter - * @param width [IN] how many spaces to write - * @param color [IN] the format string before writing the spaces (intent: background color) - * @remark After writing the spaces, the format is reset. - */ -static size_t show_bar(size_t row, size_t col, size_t width, const char* color) -{ - goto_pos(row, col); - printf("%s", color); - for(size_t col = 0; col < width; col++) { - putchar(' '); - } - printf(RESET); - return col + width; -} - -/** - * @brief Displays a horizontal border over the whole board width. - * @param row [IN] position parameter - * @param col [IN] position parameter - */ -static size_t show_h_gap(size_t row, size_t col) { - for(size_t i = 0; i < GAP_HEIGHT; i++) { - show_bar(row+i, col, GAP_WIDTH + CELL_WIDTH + GAP_WIDTH, GAP); - } - return row + GAP_HEIGHT; -} - -/** - * @brief Writes for the call at position y/x the given number with the given background color. - * @param y [IN] position parameter: the upper left row of the cell - * @param x [IN] position parameter: the upper left column of the cell - * @param n [IN] the number to write as text - * @param color [IN] the format string before writing the text (intent: background color) - * @remark After writing the number, the format is reset. - */ -static void show_cell_nr(size_t y, size_t x, size_t n, const char *color) -{ - size_t cy = (y + y + CELL_HEIGHT)/2; - size_t cx = (x + x + CELL_WIDTH - 2)/2; - - goto_pos(cy, cx); - printf("%s", color); - printf("%2zd", n); - printf(RESET); -} - -/** - * @brief Renders the given cell with the given background color, including the surrounding border. - * @param n [IN] the cell number (0...CELLS-1) - * @param color [IN] the format string for the cell content (intent: background color) - * @remark After writing the number, the format is reset. - */ -static void show_cell(size_t n, const char *color) -{ - // goto upper-left corner of a cell (the cell starts with an upper and left gap) - size_t y = 1 + n / SIZE * (GAP_HEIGHT + CELL_HEIGHT); - size_t x = 1 + n % SIZE * (GAP_WIDTH + CELL_WIDTH); - - size_t row = show_h_gap(y, x); - for(size_t i = 0; i < CELL_HEIGHT; i++) { - size_t col = x; - col = show_bar(row, col, GAP_WIDTH, GAP); - col = show_bar(row, col, CELL_WIDTH, color); - col = show_bar(row, col, GAP_WIDTH, GAP); - row++; - } - row = show_h_gap(row, x); - show_cell_nr(y + GAP_HEIGHT, x + GAP_WIDTH, n + 1, color); - goto_pos(row, 0); -} - -/** - * @brief Renders the given player's name in the given background color. - * @param player [IN] the player to render (select the background color and the name of the player - * @remark After writing the content, the format is reset. - */ -static void print_player(control_player_t player) -{ - switch(player) { - case control_player_a: - printf(PLAYER_A); - printf("Player A"); - printf(RESET); - break; - case control_player_b: - printf(PLAYER_B); - printf("Player B"); - printf(RESET); - break; - default: - printf(RESET); - printf("none"); - break; - } -} - -/** - * @brief Displays a label followed by the given player. - * @param row [IN] position parameter - * @param col [IN] position parameter - * @param label [IN] the profixing label - * @param player [IN] the player to display - */ -static void show_player(size_t row, size_t col, const char *label, control_player_t player) -{ - goto_pos(row, col); - printf(RESET); - col += printf("%s", label); - goto_pos(row, col); - print_player(player); -} - -/** - * @brief Renders the winner and the next player. - * @param winner [IN] the winning player (if any) - * @param next [IN] the next player (if any) - */ -static void show_status(control_player_t winner, control_player_t next) -{ - size_t y = GAP_HEIGHT; - size_t x = SIZE * (GAP_WIDTH + CELL_WIDTH) + GAP_WIDTH + GAP_WIDTH; - size_t row = y; - size_t col = x; - - show_player(row, col, "Winner is: ", winner); - row += 2; - show_player(row, col, "Next player is: ", next); - row += 2; - row += 2; - goto_pos(row, col); - printf("0: exit"); - row += 2; - goto_pos(row, col); - printf("1..9: play field"); -} - -/** - * @brief Renders the board from the status given by the control instance. - * @param instance [IN] the instance which holds the control instance - */ -static void show(view_t *instance) -{ - assert(instance); - assert(instance->control); - puts(CLS); - show_status(control_get_winner(instance->control), control_get_player(instance->control)); - - for(size_t i = 0; i < CELLS; i++) { - const char *color = AVAILABLE; - switch(control_get_state(instance->control, i+1)) { - case control_player_a: - color = PLAYER_A; - break; - case control_player_b: - color = PLAYER_B; - break; - default: - break; - } - show_cell(i, color); - } -} - -/** - * @brief Processes the input and dsiplays the result. - * @param the instance which holds the control instance - */ -static void notifier_loop(view_t *instance) -{ - show(instance); - int c = getchar(); - while(c != EOF && c != EXIT) { - if (isdigit(c)) { - control_move(instance->control, c-'0'); - } - show(instance); - c = getchar(); - } -} - - -// public API function which is documented in the header file. -void view_init(view_t *instance, control_t *control) -{ - assert(instance); - assert(control); - instance->control = control; -} - -// public API function which is documented in the header file. -void view_run(view_t *instance) -{ - if (isatty(STDIN_FILENO)) { // in case of an interactive terminal, the exhoing and buffering is disabled - // declare non POSIX function, which is available in glibc, but not in strinct C99 mode - void cfmakeraw(struct termios *termios_p); - - // replace original tty IO state... - struct termios orig; - struct termios raw; - cfmakeraw(&raw); - tcgetattr(STDIN_FILENO, &orig); - tcsetattr(STDIN_FILENO, TCSANOW, &raw); - // ...do the work... - notifier_loop(instance); - // ...and finalle restore original tty IO state - tcsetattr(STDIN_FILENO, TCSANOW, &orig); - } else { // if not an interactive terminal, no tweaking with IO is done - notifier_loop(instance); - } -} - diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/src/view.h b/P05_TicTacToe/work/tic-tac-toe-solution/src/view.h deleted file mode 100644 index 84cee90..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/src/view.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file - * @brief MVC - View instance - */ -#ifndef _VIEW_H_ -#define _VIEW_H_ - -#include "control.h" - -/** - * @brief The instance type. - */ -typedef struct { - control_t *control; ///< the instance knows of the control instance -} view_t; - -/** - * @brief Constructor: initialize the instance memory. - * @param instance [INOUT] The instance which holds the state. - * @param control [IN] Dependency Injection of the control instance. - */ -void view_init(view_t *instance, control_t *control); - -/** - * @brief Starts the notifyer loop: accepts input and displays the results. - * @param instance [INOUT] The instance which holds the state. - * @remark Does only return when termination is requested through the UI. - */ -void view_run(view_t *instance); - -#endif // _VIEW_H_ diff --git a/P05_TicTacToe/work/tic-tac-toe-solution/tests/tests.c b/P05_TicTacToe/work/tic-tac-toe-solution/tests/tests.c deleted file mode 100644 index f2d15df..0000000 --- a/P05_TicTacToe/work/tic-tac-toe-solution/tests/tests.c +++ /dev/null @@ -1,445 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Test suite for the given package. - */ -#include -#include -#include -#include -#include -#include -#include "test_utils.h" -#include "model.h" - -#ifndef TARGET // must be given by the make file --> see test target -#error missing TARGET define -#endif - -/// @brief alias for EXIT_SUCCESS -#define OK EXIT_SUCCESS -/// @brief alias for EXIT_FAILURE -#define FAIL EXIT_FAILURE - -/// @brief The name of the STDOUT text file. -#define OUTFILE "stdout.txt" -/// @brief The name of the STDERR text file. -#define ERRFILE "stderr.txt" - -#define TRACE_INDENT "\n " ///< allow for better stdout formatting in case of error - -// setup & cleanup -static int setup(void) -{ - remove_file_if_exists(OUTFILE); - remove_file_if_exists(ERRFILE); - return 0; // success -} - -static int teardown(void) -{ - // Do nothing. - // Especially: do not remove result files - they are removed in int setup(void) *before* running a test. - return 0; // success -} - -// test utils -static void init_model(model_t *instance, int act) -{ - if (act) printf(TRACE_INDENT "init_model:... "); - model_init(instance); - for(size_t row = 0; row < MODEL_SIZE; row++) { - for(size_t col = 0; col < MODEL_SIZE; col++) { - if (act) printf("%zd/%zd ", row, col); - CU_ASSERT_EQUAL_FATAL(instance->board[row][col], model_state_none); - } - } - if (act) printf(TRACE_INDENT); -} - -static void print_board(model_state_t board[MODEL_SIZE][MODEL_SIZE]) -{ - for(size_t row = 0; row < MODEL_SIZE; row++) { - printf("{ "); - for(size_t col = 0; col < MODEL_SIZE; col++) { - printf("%d ", board[row][col]); - } - printf("} "); - } -} - - -// tests -static void test_model_init(void) -{ - // check void model_init(model_t *instance); - - // arrange - model_t model; - // act & assert - init_model(&model, 1); -} - -static void test_model_get_state(void) -{ - // check: model_state_t model_get_state(model_t *instance, model_pos_t pos); - - { - // arrange - model_t model; - init_model(&model, 0); - // act & assert - printf(TRACE_INDENT "initial state:... "); - print_board(model.board); - for(size_t row = 0; row < MODEL_SIZE; row++) { - for(size_t col = 0; col < MODEL_SIZE; col++) { - printf("%zd/%zd ", row, col); - CU_ASSERT_EQUAL_FATAL(model_get_state(&model, model_pos(row, col)), model_state_none); - } - } - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_b }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "modified state:... "); - print_board(model.board); - for(size_t row = 0; row < MODEL_SIZE; row++) { - for(size_t col = 0; col < MODEL_SIZE; col++) { - printf("%zd/%zd ", row, col); - CU_ASSERT_EQUAL_FATAL(model_get_state(&model, model_pos(row, col)), board[row][col]); - } - } - } - printf(TRACE_INDENT); -} - -static void test_model_get_winner(void) -{ - // check: model_state_t model_get_winner(model_t *instance); - - { - // arrange - model_t model; - init_model(&model, 0); - // act & assert - printf(TRACE_INDENT "initial no winner:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_get_winner(&model), model_state_none); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_b }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "winner:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_get_winner(&model), model_state_b); - } - printf(TRACE_INDENT); -} - -static void test_model_can_move(void) -{ - // check: int model_can_move(model_t *instance); - - { - // arrange - model_t model; - init_model(&model, 0); - // act & assert - printf(TRACE_INDENT "initial can move:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 1); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_b }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "can move while not yet done nor win:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 1); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_b }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "cannot move after win:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_b, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_b }, - { model_state_b, model_state_a, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "cannot move when all done:... "); - print_board(model.board); - CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0); - } - printf(TRACE_INDENT); -} - -static void test_model_move(void) -{ - // check: int model_move(model_t *instance, model_pos_t pos, model_state_t state); - - { - // arrange - model_t model; - init_model(&model, 0); - // act & assert - printf(TRACE_INDENT "initial move:... "); - print_board(model.board); - model_pos_t pos_a = model_pos(0, 0); - printf("%zd/%zd ", pos_a.row, pos_a.col); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_a), 1); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_a), 0); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_b), 0); - model_pos_t pos_b = model_pos(2, 2); - printf("%zd/%zd ", pos_b.row, pos_b.col); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_b), 1); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_b), 0); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_a), 0); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_b }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "can move while not yet done nor win:... "); - print_board(model.board); - model_pos_t pos = model_pos(2, 1); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 1); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_b }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "cannot move after win:... "); - print_board(model.board); - model_pos_t pos = model_pos(2, 1); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_b, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_b }, - { model_state_b, model_state_a, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "cannot move when all done:... "); - print_board(model.board); - for(size_t row = 0; row < MODEL_SIZE; row++) { - for(size_t col = 0; col < MODEL_SIZE; col++) { - model_pos_t pos = model_pos(row, col); - printf("%zd/%zd ", row, col); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0); - CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0); - } - } - CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0); - } - printf(TRACE_INDENT); -} - -static void test_model_get_win_line(void) -{ - // check: model_line_t model_get_win_line(model_t *instance); - - { - // arrange - model_t model; - init_model(&model, 0); - // act & assert - printf(TRACE_INDENT "initial no winner:... "); - print_board(model.board); - model_line_t no_win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_none, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_none }, - { model_state_b, model_state_none, model_state_b }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "no winner while not yet done nor win:... "); - print_board(model.board); - model_line_t no_win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none); - } - { - // arrange - static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = { - { model_state_b, model_state_a, model_state_a }, - { model_state_a, model_state_b, model_state_b }, - { model_state_b, model_state_a, model_state_a }, - }; - model_t model; - init_model(&model, 0); - memcpy(model.board, board, sizeof(board)); - - // act & assert - printf(TRACE_INDENT "no winner when all done:... "); - print_board(model.board); - model_line_t no_win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none); - } - { - for(size_t row = 0; row < MODEL_SIZE; row++) { - // arrange - model_t model; - init_model(&model, 0); - for(size_t col = 0; col < MODEL_SIZE; col++) { - CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(row, col), model_state_a), 1); - } - // act & assert - printf(TRACE_INDENT "row winner:... "); - print_board(model.board); - model_line_t win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_h); - CU_ASSERT_EQUAL_FATAL(win.start.row, row); - CU_ASSERT_EQUAL_FATAL(win.start.col, 0); - } - } - { - for(size_t col = 0; col < MODEL_SIZE; col++) { - // arrange - model_t model; - init_model(&model, 0); - for(size_t row = 0; row < MODEL_SIZE; row++) { - CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(row, col), model_state_a), 1); - } - // act & assert - printf(TRACE_INDENT "column winner:... "); - print_board(model.board); - model_line_t win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_v); - CU_ASSERT_EQUAL_FATAL(win.start.row, 0); - CU_ASSERT_EQUAL_FATAL(win.start.col, col); - } - } - { - printf(TRACE_INDENT "diagonal left-right winner:... "); - // arrange - model_t model; - init_model(&model, 0); - for(size_t i = 0; i < MODEL_SIZE; i++) { - CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(i, i), model_state_a), 1); - } - // act & assert - print_board(model.board); - model_line_t win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_d); - CU_ASSERT_EQUAL_FATAL(win.start.row, 0); - CU_ASSERT_EQUAL_FATAL(win.start.col, 0); - } - { - printf(TRACE_INDENT "diagonal right-left winner:... "); - // arrange - model_t model; - init_model(&model, 0); - for(size_t i = 0; i < MODEL_SIZE; i++) { - CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(MODEL_SIZE - 1 - i, i), model_state_a), 1); - } - // act & assert - print_board(model.board); - model_line_t win = model_get_win_line(&model); - CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_d); - CU_ASSERT_EQUAL_FATAL(win.start.row, 0); - CU_ASSERT_EQUAL_FATAL(win.start.col, MODEL_SIZE - 1); - } - printf(TRACE_INDENT); -} - -/** - * @brief Registers and runs the tests. - * @returns success (0) or one of the CU_ErrorCode (>0) - */ -int main(void) -{ - // setup, run, teardown - TestMainBasic("lab test", setup, teardown - , test_model_init - , test_model_get_state - , test_model_get_winner - , test_model_can_move - , test_model_move - , test_model_get_win_line - ); -} diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/Makefile b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/Makefile deleted file mode 100644 index 95121b9..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -SNP_SHARED_MAKEFILE := $(if $(SNP_SHARED_MAKEFILE),$(SNP_SHARED_MAKEFILE),"~/snp/shared.mk") - -TARGET := bin/personen-verwaltung -# BEGIN-STUDENTS-TO-ADD-CODE -MODULES := src/person.c src/list.c -# END-STUDENTS-TO-ADD-CODE -SOURCES := src/main.c $(MODULES) -TSTSOURCES := tests/tests.c $(MODULES) - - -include $(SNP_SHARED_MAKEFILE) - -# CFLAGS += -Werror diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/mainpage.dox b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/mainpage.dox deleted file mode 100644 index 05d1c72..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/mainpage.dox +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @mainpage SNP - P07 Linked List - * - * @section Purpose - * - * This is a lab on usage of arrays. - * - */ diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.c b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.c deleted file mode 100644 index 49d2d51..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.c +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include -#include -#include "list.h" - -static node_t anchor; - -static int is_anchor(const node_t *node) -{ - return node == &anchor; -} - -static void remove_next(node_t *at) -{ - assert(at); - assert(at->next); - if (!is_anchor(at->next)) { - node_t *next = at->next->next; - free(at->next); - at->next = next; - } -} - -static node_t *find_insert(const person_t *p) -{ - assert(p); - node_t *last = &anchor; - for(node_t *n = anchor.next; !is_anchor(n); last = n, n = n->next) { - int res = person_compare(&(n->content), p); - if (res == 0) { - return NULL; // *** EARLY RETURN ***// // already part of the list - } else if (res > 0) { - break; // the predecessor is the insert point - } - } - return last; -} - -static node_t *find_remove(const person_t *p) -{ - assert(p); - node_t *last = &anchor; - for(node_t *n = anchor.next; !is_anchor(n); last = n, n = n->next) { - int res = person_compare(&(n->content), p); - if (res == 0) { - break; // the predecessor is the remove point - } - } - return is_anchor(last->next) ? NULL : last; -} - -const node_t *list_anchor(void) -{ - return &anchor; -} - -const node_t *list_init() -{ - anchor.next = &anchor; - return &anchor; -} - -int list_insert(const person_t *p) -{ - node_t *at = find_insert(p); - node_t *insert = NULL; - if (at) { - insert = malloc(sizeof(node_t)); - if (insert) { - insert->content = *p; - insert->next = at->next; - at->next = insert; - } - } - return at && insert; -} - -int list_remove(const person_t *p) -{ - node_t *at = find_remove(p); - if (at) { - remove_next(at); - } - return at != NULL; -} - -void list_clear(void) -{ - node_t *n = &anchor; - do { - remove_next(n); - } while (!is_anchor(n->next)); -} - -void list_show(void) -{ - node_t *n = &anchor; - do { - if (!is_anchor(n)) printf("%20s %20s %u\n", n->content.name, n->content.first_name, n->content.age); - n = n->next; - } while(!is_anchor(n)); -} - diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.h b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.h deleted file mode 100644 index 3703d97..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/list.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _LIST_H_ -#define _LIST_H_ - -#include "person.h" - -typedef struct node { - person_t content; // in diesem Knoten gespeicherte Person - struct node *next; // Pointer auf den nächsten Knoten in der Liste -} node_t; - -const node_t *list_init(); -int list_insert(const person_t *p); -int list_remove(const person_t *p); -void list_clear(void); -void list_show(void); - -#endif // _LIST_H_ diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/main.c b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/main.c deleted file mode 100644 index 77aefb4..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/main.c +++ /dev/null @@ -1,68 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Lab implementation - */ -#include -#include - -#include "person.h" -#include "list.h" - -/** - * @brief Main entry point. - * @param[in] argc The size of the argv array. - * @param[in] argv The command line arguments... - * @returns Returns EXIT_SUCCESS (=0) on success, EXIT_FAILURE (=1) there is an expression syntax error. - */ -int main(int argc, char* argv[]) -{ - // BEGIN-STUDENTS-TO-ADD-CODE - list_init(); - person_t p; - int show_menu = 1; - while(1) { - if (show_menu) printf("I(nsert), R(emove), S(how), C(lear), E(nd)\n"); - show_menu = 1; - int op = getchar(); - switch(op) { - case 'I': case 'i': - if (!person_read(&p) || !list_insert(&p)) { - printf("failed to insert person\n"); - } - break; - case 'R': case 'r': - if (!person_read(&p) || !list_remove(&p)) { - printf("failed to remove person\n"); - } - break; - case 'S': case 's': - list_show(); - break; - case 'C': case 'c': - list_clear(); - break; - case EOF: - case 'E': case 'e': - return EXIT_SUCCESS; // *** EARLY RETURN *** // - break; - case ' ': case '\n': - show_menu = 0; - break; - default: - printf("Unknown command: %c\n", op); - break; - } - } - - // END-STUDENTS-TO-ADD-CODE - return EXIT_SUCCESS; -} diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.c b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.c deleted file mode 100644 index 21c39bd..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -#include "person.h" - -int person_compare(const person_t *a, const person_t *b) -{ - assert(a); - assert(b); - int res = strncmp(a->name, b->name, NAME_LEN); - if (res == 0) res = strncmp(a->first_name, b->first_name, NAME_LEN); - if (res == 0) res = a->age - b->age; - return res; -} - -int person_read(person_t *p) -{ - assert(p); - assert(NAME_LEN == 20); - return scanf("%19s %19s %u", p->name, p->first_name, &(p->age)) == 3; -} diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.h b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.h deleted file mode 100644 index 79bd22e..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/src/person.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _PERSON_H_ -#define _PERSON_H_ - -#define NAME_LEN 20 - -typedef struct { - char name[NAME_LEN]; - char first_name[NAME_LEN]; - unsigned int age; -} person_t; - -/** - * @brief Compares two persons in this sequence: 1st=name, 2nd=first_name, 3rd=age - * @param a [IN] const reference to 1st person in the comparison - * @param b [IN] const reference to 2nd person in the comparison - * @return =0 if all record fields are the same - * >0 if all previous fields are the same, but for this field, a is greater - * <0 if all previous fields are the same, but for this field, b is greater - * @remark strncmp() is used for producing the result of string field comparisons - * @remark a->age – b->age is used for producing the result of age comparison - */ -int person_compare(const person_t *a, const person_t *b); - -int person_read(person_t *p); - -#endif // _PERSON_H_ diff --git a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/tests/tests.c b/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/tests/tests.c deleted file mode 100644 index addb7e4..0000000 --- a/P06_Personen_Verwaltung_Linked_List/work/personen-verwaltung-solution/tests/tests.c +++ /dev/null @@ -1,299 +0,0 @@ -/* ---------------------------------------------------------------------------- - * -- _____ ______ _____ - - * -- |_ _| | ____|/ ____| - - * -- | | _ __ | |__ | (___ Institute of Embedded Systems - - * -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur - - * -- _| |_| | | | |____ ____) | (University of Applied Sciences) - - * -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland - - * ---------------------------------------------------------------------------- - */ -/** - * @file - * @brief Test suite for the given package. - */ -#include -#include -#include -#include -#include -#include -#include "test_utils.h" -#include "person.h" -#include "list.h" - -#ifndef TARGET // must be given by the make file --> see test target -#error missing TARGET define -#endif - -/// @brief alias for EXIT_SUCCESS -#define OK EXIT_SUCCESS -/// @brief alias for EXIT_FAILURE -#define FAIL EXIT_FAILURE - -/// @brief The name of the STDOUT text file. -#define OUTFILE "stdout.txt" -/// @brief The name of the STDERR text file. -#define ERRFILE "stderr.txt" - -#define TRACE_INDENT "\n " ///< allow for better stdout formatting in case of error - -// setup & cleanup -static int setup(void) -{ - remove_file_if_exists(OUTFILE); - remove_file_if_exists(ERRFILE); - return 0; // success -} - -static int teardown(void) -{ - // Do nothing. - // Especially: do not remove result files - they are removed in int setup(void) *before* running a test. - return 0; // success -} - -// tests -static void test_person_compare(void) -{ - // BEGIN-STUDENTS-TO-ADD-CODE - // arrange - person_t a = { "a", "a", 1 }; - person_t b = { "a", "a", 2 }; - person_t c = { "a", "b", 1 }; - person_t d = { "a", "b", 2 }; - person_t e = { "b", "a", 1 }; - person_t f = { "b", "a", 2 }; - person_t g = { "b", "b", 1 }; - person_t h = { "b", "b", 2 }; - - // act & assert - CU_ASSERT_TRUE(person_compare(&a, &a) == 0); - CU_ASSERT_TRUE(person_compare(&a, &b) < 0); - CU_ASSERT_TRUE(person_compare(&a, &c) < 0); - CU_ASSERT_TRUE(person_compare(&a, &d) < 0); - CU_ASSERT_TRUE(person_compare(&a, &e) < 0); - CU_ASSERT_TRUE(person_compare(&a, &f) < 0); - CU_ASSERT_TRUE(person_compare(&a, &g) < 0); - CU_ASSERT_TRUE(person_compare(&a, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&b, &a) > 0); - CU_ASSERT_TRUE(person_compare(&b, &b) == 0); - CU_ASSERT_TRUE(person_compare(&b, &c) < 0); - CU_ASSERT_TRUE(person_compare(&b, &d) < 0); - CU_ASSERT_TRUE(person_compare(&b, &e) < 0); - CU_ASSERT_TRUE(person_compare(&b, &f) < 0); - CU_ASSERT_TRUE(person_compare(&b, &g) < 0); - CU_ASSERT_TRUE(person_compare(&b, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&c, &a) > 0); - CU_ASSERT_TRUE(person_compare(&c, &b) > 0); - CU_ASSERT_TRUE(person_compare(&c, &c) == 0); - CU_ASSERT_TRUE(person_compare(&c, &d) < 0); - CU_ASSERT_TRUE(person_compare(&c, &e) < 0); - CU_ASSERT_TRUE(person_compare(&c, &f) < 0); - CU_ASSERT_TRUE(person_compare(&c, &g) < 0); - CU_ASSERT_TRUE(person_compare(&c, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&d, &a) > 0); - CU_ASSERT_TRUE(person_compare(&d, &b) > 0); - CU_ASSERT_TRUE(person_compare(&d, &c) > 0); - CU_ASSERT_TRUE(person_compare(&d, &d) == 0); - CU_ASSERT_TRUE(person_compare(&d, &e) < 0); - CU_ASSERT_TRUE(person_compare(&d, &f) < 0); - CU_ASSERT_TRUE(person_compare(&d, &g) < 0); - CU_ASSERT_TRUE(person_compare(&d, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&e, &a) > 0); - CU_ASSERT_TRUE(person_compare(&e, &b) > 0); - CU_ASSERT_TRUE(person_compare(&e, &c) > 0); - CU_ASSERT_TRUE(person_compare(&e, &d) > 0); - CU_ASSERT_TRUE(person_compare(&e, &e) == 0); - CU_ASSERT_TRUE(person_compare(&e, &f) < 0); - CU_ASSERT_TRUE(person_compare(&e, &g) < 0); - CU_ASSERT_TRUE(person_compare(&e, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&f, &a) > 0); - CU_ASSERT_TRUE(person_compare(&f, &b) > 0); - CU_ASSERT_TRUE(person_compare(&f, &c) > 0); - CU_ASSERT_TRUE(person_compare(&f, &d) > 0); - CU_ASSERT_TRUE(person_compare(&f, &e) > 0); - CU_ASSERT_TRUE(person_compare(&f, &f) == 0); - CU_ASSERT_TRUE(person_compare(&f, &g) < 0); - CU_ASSERT_TRUE(person_compare(&f, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&g, &a) > 0); - CU_ASSERT_TRUE(person_compare(&g, &b) > 0); - CU_ASSERT_TRUE(person_compare(&g, &c) > 0); - CU_ASSERT_TRUE(person_compare(&g, &d) > 0); - CU_ASSERT_TRUE(person_compare(&g, &e) > 0); - CU_ASSERT_TRUE(person_compare(&g, &f) > 0); - CU_ASSERT_TRUE(person_compare(&g, &g) == 0); - CU_ASSERT_TRUE(person_compare(&g, &h) < 0); - - CU_ASSERT_TRUE(person_compare(&h, &a) > 0); - CU_ASSERT_TRUE(person_compare(&h, &b) > 0); - CU_ASSERT_TRUE(person_compare(&h, &c) > 0); - CU_ASSERT_TRUE(person_compare(&h, &d) > 0); - CU_ASSERT_TRUE(person_compare(&h, &e) > 0); - CU_ASSERT_TRUE(person_compare(&h, &f) > 0); - CU_ASSERT_TRUE(person_compare(&h, &g) > 0); - CU_ASSERT_TRUE(person_compare(&h, &h) == 0); - - // END-STUDENTS-TO-ADD-CODE -} - -static void test_list_insert(void) -{ - // BEGIN-STUDENTS-TO-ADD-CODE - // arrange - const node_t *anchor = list_init(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: insert one - person_t p1 = { "a", "b", 123 }; - CU_ASSERT_TRUE(list_insert(&p1)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - - // act & assert: insert a second after first - person_t p2 = { "a", "b", 124 }; - CU_ASSERT_TRUE(list_insert(&p2)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p2) == 0); - - // act & assert: insert a second before first - person_t p3 = { "a", "b", 122 }; - CU_ASSERT_TRUE(list_insert(&p3)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p3) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->next->content), &p2) == 0); - - // act & assert: reject inserting same - CU_ASSERT_FALSE(list_insert(&p1)); - // unchanged - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next->next); - // unchanged - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p3) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->next->content), &p2) == 0); - - // END-STUDENTS-TO-ADD-CODE -} - -static void test_list_remove(void) -{ - // BEGIN-STUDENTS-TO-ADD-CODE - // arrange - const node_t *anchor = list_init(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: remove one - person_t p1 = { "a", "b", 123 }; - CU_ASSERT_TRUE(list_insert(&p1)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - // remove same - CU_ASSERT_TRUE_FATAL(list_remove(&p1)); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: failed to remove - CU_ASSERT_TRUE(list_insert(&p1)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - // remove not found - person_t p2 = { "a", "b", 124 }; - CU_ASSERT_FALSE_FATAL(list_remove(&p2)); - // unchanged - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - - // act & assert: remove last - CU_ASSERT_TRUE(list_insert(&p2)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p2) == 0); - CU_ASSERT_TRUE_FATAL(list_remove(&p2)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - - // act & assert: remove first - CU_ASSERT_TRUE(list_insert(&p2)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p2) == 0); - CU_ASSERT_TRUE_FATAL(list_remove(&p1)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p2) == 0); - - // END-STUDENTS-TO-ADD-CODE -} - -static void test_list_clear(void) -{ - // BEGIN-STUDENTS-TO-ADD-CODE - // arrange - const node_t *anchor = list_init(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: empty list - list_clear(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: clear list of one - person_t p1 = { "a", "b", 123 }; - CU_ASSERT_TRUE(list_insert(&p1)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - list_clear(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // act & assert: clear list of two - person_t p2 = { "a", "b", 124 }; - CU_ASSERT_TRUE(list_insert(&p1)); - CU_ASSERT_TRUE(list_insert(&p2)); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next); - CU_ASSERT_PTR_NOT_EQUAL(anchor, anchor->next->next); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next->next->next); - CU_ASSERT_TRUE(person_compare(&(anchor->next->content), &p1) == 0); - CU_ASSERT_TRUE(person_compare(&(anchor->next->next->content), &p2) == 0); - list_clear(); - CU_ASSERT_PTR_EQUAL(anchor, anchor->next); - - // END-STUDENTS-TO-ADD-CODE -} - -/** - * @brief Registers and runs the tests. - * @returns success (0) or one of the CU_ErrorCode (>0) - */ -int main(void) -{ - // setup, run, teardown - TestMainBasic("lab test", setup, teardown - , test_person_compare - , test_list_insert - , test_list_remove - , test_list_clear - ); -} diff --git a/P07_Prozesse_und_Threads/Solution/A03.dot b/P07_Prozesse_und_Threads/Solution/A03.dot deleted file mode 100644 index d56eab7..0000000 --- a/P07_Prozesse_und_Threads/Solution/A03.dot +++ /dev/null @@ -1,76 +0,0 @@ -digraph ProcessHierarchie { - - P1[label="P01\nfork()"]; - - P11[label="P01\nfork()"]; - P12[label="P02\nfork()"]; - - P111[label="P01\nfork()"]; - P112[label="P03\nfork()"]; - P121[label="P02\nfork()"]; - P122[label="P04\nfork()"]; - - P1111[label="P01\nfork()"]; - P1112[label="P05\nfork()"]; - P1121[label="P03\nfork()"]; - P1122[label="P06\nfork()"]; - P1211[label="P02\nfork()"]; - P1212[label="P07\nfork()"]; - P1221[label="P04\nfork()"]; - P1222[label="P08\nfork()"]; - - P11111[label="P01"]; - P11112[label="P09"]; - P11121[label="P05"]; - P11122[label="P10"]; - P11211[label="P03"]; - P11212[label="P11"]; - P11221[label="P06"]; - P11222[label="P12"]; - P12111[label="P02"]; - P12112[label="P13"]; - P12121[label="P07"]; - P12122[label="P14"]; - P12211[label="P04"]; - P12212[label="P15"]; - P12221[label="P08"]; - P12222[label="P16"]; - - P1 -> P11 - P1 -> P12 - - P11 -> P111 - P11 -> P112 - P12 -> P121 - P12 -> P122 - - P111 -> P1111 - P111 -> P1112 - P112 -> P1121 - P112 -> P1122 - P121 -> P1211 - P121 -> P1212 - P122 -> P1221 - P122 -> P1222 - - P1111 -> P11111 - P1111 -> P11112 - P1112 -> P11121 - P1112 -> P11122 - P1121 -> P11211 - P1121 -> P11212 - P1122 -> P11221 - P1122 -> P11222 - P1211 -> P12111 - P1211 -> P12112 - P1212 -> P12121 - P1212 -> P12122 - P1221 -> P12211 - P1221 -> P12212 - P1222 -> P12221 - P1222 -> P12222 - - { rank="same"; P11; P12; } -# { rank="same"; P1; P11; P111; P1111; P11111; } - -} diff --git a/P07_Prozesse_und_Threads/Solution/A03.png b/P07_Prozesse_und_Threads/Solution/A03.png deleted file mode 100644 index 0d954161f99b2a56f0c97ee89180ee76923fdd5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79253 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