formatierung
This commit is contained in:
parent
74e2421312
commit
593a86acaa
11
bintree.c
11
bintree.c
@ -14,13 +14,13 @@ static TreeNode *createNode(const void *data, size_t dataSize)
|
|||||||
if (!newNode)
|
if (!newNode)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
newNode->data = malloc(dataSize); //hier kein malloc -> nur data pointer?
|
newNode->data = malloc(dataSize); // hier kein malloc -> nur data pointer?
|
||||||
if (!newNode->data)
|
if (!newNode->data)
|
||||||
{
|
{
|
||||||
free(newNode);
|
free(newNode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//newNode->data = data;
|
// newNode->data = data;
|
||||||
memcpy(newNode->data, data, dataSize);
|
memcpy(newNode->data, data, dataSize);
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
@ -124,12 +124,13 @@ void clearTree(TreeNode *root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of entries in the tree given by root.
|
// Returns the number of entries in the tree given by root.
|
||||||
unsigned int treeSize(const TreeNode* root)
|
unsigned int treeSize(const TreeNode *root)
|
||||||
{
|
{
|
||||||
if (root == NULL) {
|
if (root == NULL)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1 + treeSize(root->left) + treeSize(root->right);
|
return 1 + treeSize(root->left) + treeSize(root->right);
|
||||||
/// ich + alles links + alles rechts
|
/// ich + alles links + alles rechts
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef int (*CompareFctType)(const void *arg1, const void *arg2); //ganz zahlen
|
typedef int (*CompareFctType)(const void *arg1, const void *arg2); // ganz zahlen
|
||||||
|
|
||||||
/*void foo(void* ptr) {
|
/*void foo(void* ptr) {
|
||||||
unsigned int* casted_pointer = ptr;
|
unsigned int* casted_pointer = ptr;
|
||||||
@ -20,11 +20,11 @@ typedef struct nodeT
|
|||||||
struct nodeT *right;
|
struct nodeT *right;
|
||||||
} TreeNode;
|
} TreeNode;
|
||||||
|
|
||||||
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
|
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
|
||||||
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
|
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
|
||||||
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate);
|
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate);
|
||||||
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
|
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
|
||||||
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
|
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
|
||||||
// push the top node and push all its left nodes.
|
// push the top node and push all its left nodes.
|
||||||
void *nextTreeData(TreeNode *root);
|
void *nextTreeData(TreeNode *root);
|
||||||
// Releases all memory resources (including data copies).
|
// Releases all memory resources (including data copies).
|
||||||
|
|||||||
22
highscore.c
22
highscore.c
@ -23,7 +23,7 @@ static int compareHighscoreEntries(const void *arg1, const void *arg2)
|
|||||||
|
|
||||||
int result = entry2->score - entry1->score;
|
int result = entry2->score - entry1->score;
|
||||||
|
|
||||||
if(result == 0)
|
if (result == 0)
|
||||||
result = strcmp(entry1->name, entry2->name);
|
result = strcmp(entry1->name, entry2->name);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -34,10 +34,10 @@ static HighscoreEntry createHighscoreEntry(const char *name, int score)
|
|||||||
{
|
{
|
||||||
HighscoreEntry entry = {"", score};
|
HighscoreEntry entry = {"", score};
|
||||||
|
|
||||||
if(name != NULL)
|
if (name != NULL)
|
||||||
{
|
{
|
||||||
strncpy(entry.name, name, MAX_PLAYER_NAME_LEN);
|
strncpy(entry.name, name, MAX_PLAYER_NAME_LEN);
|
||||||
entry.name[MAX_PLAYER_NAME_LEN-1] = '\0';
|
entry.name[MAX_PLAYER_NAME_LEN - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@ -46,7 +46,7 @@ static HighscoreEntry createHighscoreEntry(const char *name, int score)
|
|||||||
// Calculate score based on time used and number of shown numbers.
|
// Calculate score based on time used and number of shown numbers.
|
||||||
static int calculateScore(double timeInSeconds, unsigned int len)
|
static int calculateScore(double timeInSeconds, unsigned int len)
|
||||||
{
|
{
|
||||||
return (1000.0 - timeInSeconds) * len;
|
return (1000.0 - timeInSeconds) * len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load highscores from file into memory.
|
// Load highscores from file into memory.
|
||||||
@ -54,16 +54,16 @@ void loadHighscores(const char *path)
|
|||||||
{
|
{
|
||||||
FILE *file = fopen(path, "r");
|
FILE *file = fopen(path, "r");
|
||||||
|
|
||||||
if(file != NULL)
|
if (file != NULL)
|
||||||
{
|
{
|
||||||
char buffer[MAX_LINE_LEN+1];
|
char buffer[MAX_LINE_LEN + 1];
|
||||||
|
|
||||||
while(fgets(buffer, MAX_LINE_LEN+1, file) != NULL)
|
while (fgets(buffer, MAX_LINE_LEN + 1, file) != NULL)
|
||||||
{
|
{
|
||||||
char *name = strtok(buffer, ";\n");
|
char *name = strtok(buffer, ";\n");
|
||||||
char *scoreStr = strtok(NULL, ";\n");
|
char *scoreStr = strtok(NULL, ";\n");
|
||||||
|
|
||||||
if(name != NULL && scoreStr != NULL)
|
if (name != NULL && scoreStr != NULL)
|
||||||
{
|
{
|
||||||
HighscoreEntry entry = createHighscoreEntry(name, strtol(scoreStr, NULL, 10));
|
HighscoreEntry entry = createHighscoreEntry(name, strtol(scoreStr, NULL, 10));
|
||||||
highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), compareHighscoreEntries, NULL);
|
highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), compareHighscoreEntries, NULL);
|
||||||
@ -99,7 +99,7 @@ void showHighscores()
|
|||||||
printf("|%*.*s%s%*.*s|\n", blankSpace, blankSpace, blanks, header, blankSpace, blankSpace, blanks);
|
printf("|%*.*s%s%*.*s|\n", blankSpace, blankSpace, blanks, header, blankSpace, blankSpace, blanks);
|
||||||
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
|
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
|
for (int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
|
||||||
{
|
{
|
||||||
printf("| %-*s | %*d |\n", MAX_PLAYER_NAME_LEN, entry->name, MAX_PLAYER_NAME_LEN, entry->score);
|
printf("| %-*s | %*d |\n", MAX_PLAYER_NAME_LEN, entry->name, MAX_PLAYER_NAME_LEN, entry->score);
|
||||||
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
|
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
|
||||||
@ -112,11 +112,11 @@ void saveHighscores(const char *path)
|
|||||||
{
|
{
|
||||||
FILE *file = fopen(path, "w");
|
FILE *file = fopen(path, "w");
|
||||||
|
|
||||||
if(file != NULL)
|
if (file != NULL)
|
||||||
{
|
{
|
||||||
HighscoreEntry *entry = nextTreeData(highscoreTree);
|
HighscoreEntry *entry = nextTreeData(highscoreTree);
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
|
for (int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
|
||||||
{
|
{
|
||||||
fprintf(file, "%s;%d\n", entry->name, entry->score);
|
fprintf(file, "%s;%d\n", entry->name, entry->score);
|
||||||
entry = nextTreeData(NULL);
|
entry = nextTreeData(NULL);
|
||||||
|
|||||||
16
main.c
16
main.c
@ -10,11 +10,13 @@ int inputNumber(const char *promptText)
|
|||||||
unsigned int number;
|
unsigned int number;
|
||||||
int numberOfInputs = 0;
|
int numberOfInputs = 0;
|
||||||
|
|
||||||
while(numberOfInputs != 1)
|
while (numberOfInputs != 1)
|
||||||
{
|
{
|
||||||
printf("%s", promptText);
|
printf("%s", promptText);
|
||||||
numberOfInputs = scanf("%u", &number);
|
numberOfInputs = scanf("%u", &number);
|
||||||
while(getchar() != '\n') {} // clear input buffer
|
while (getchar() != '\n')
|
||||||
|
{
|
||||||
|
} // clear input buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
return number;
|
return number;
|
||||||
@ -23,11 +25,11 @@ int inputNumber(const char *promptText)
|
|||||||
// Print an array of numbers.
|
// Print an array of numbers.
|
||||||
void showNumbers(const unsigned int *numbers, unsigned int len)
|
void showNumbers(const unsigned int *numbers, unsigned int len)
|
||||||
{
|
{
|
||||||
if(numbers != NULL)
|
if (numbers != NULL)
|
||||||
{
|
{
|
||||||
printf("Numbers:");
|
printf("Numbers:");
|
||||||
|
|
||||||
for(int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
printf(" %5d", numbers[i]);
|
printf(" %5d", numbers[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -39,7 +41,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int exitCode = EXIT_FAILURE;
|
int exitCode = EXIT_FAILURE;
|
||||||
|
|
||||||
if(argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s <player name>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <player name>\n", argv[0]);
|
||||||
exitCode = EXIT_FAILURE;
|
exitCode = EXIT_FAILURE;
|
||||||
@ -55,7 +57,7 @@ int main(int argc, char *argv[])
|
|||||||
unsigned int numberOfElements = 0;
|
unsigned int numberOfElements = 0;
|
||||||
|
|
||||||
// ask until valid number of elements (3..1000)
|
// ask until valid number of elements (3..1000)
|
||||||
while(numberOfElements < 3 || numberOfElements > 1000)
|
while (numberOfElements < 3 || numberOfElements > 1000)
|
||||||
numberOfElements = inputNumber("Wie viele Zahlen sollen gezeigt werden: ");
|
numberOfElements = inputNumber("Wie viele Zahlen sollen gezeigt werden: ");
|
||||||
|
|
||||||
// create numbers and show them
|
// create numbers and show them
|
||||||
@ -70,7 +72,7 @@ int main(int argc, char *argv[])
|
|||||||
duplicate = getDuplicate(numbers, numberOfElements);
|
duplicate = getDuplicate(numbers, numberOfElements);
|
||||||
|
|
||||||
// check result and update highscores
|
// check result and update highscores
|
||||||
if(userInput == duplicate)
|
if (userInput == duplicate)
|
||||||
{
|
{
|
||||||
int score = addHighscore(playerName, measuredSeconds, numberOfElements);
|
int score = addHighscore(playerName, measuredSeconds, numberOfElements);
|
||||||
printf("Sie haben die korrekte Zahl in %.6lf Sekunde(n) gefunden und %u Punkte erzielt.\n", measuredSeconds, score);
|
printf("Sie haben die korrekte Zahl in %.6lf Sekunde(n) gefunden und %u Punkte erzielt.\n", measuredSeconds, score);
|
||||||
|
|||||||
12
numbers.c
12
numbers.c
@ -34,7 +34,7 @@ unsigned int *createNumbers(unsigned int len)
|
|||||||
if (array == NULL)
|
if (array == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
TreeNode* numbers = addToTree(NULL, &number, sizeof(unsigned int), compareFct, &isDuplicate);
|
TreeNode *numbers = addToTree(NULL, &number, sizeof(unsigned int), compareFct, &isDuplicate);
|
||||||
array[0] = number;
|
array[0] = number;
|
||||||
|
|
||||||
for (unsigned int i = 1; i < len; i++)
|
for (unsigned int i = 1; i < len; i++)
|
||||||
@ -77,10 +77,10 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned int duplicateValue = 0;
|
unsigned int duplicateValue = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < len; i++)
|
for (unsigned int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
copyNumbers[i] = numbers [i];
|
copyNumbers[i] = numbers[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(copyNumbers, len, sizeof(unsigned int), compareFct);
|
qsort(copyNumbers, len, sizeof(unsigned int), compareFct);
|
||||||
@ -89,9 +89,9 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
|||||||
{
|
{
|
||||||
if (copyNumbers[i] == copyNumbers[i + 1])
|
if (copyNumbers[i] == copyNumbers[i + 1])
|
||||||
{
|
{
|
||||||
duplicateValue = copyNumbers[i];
|
duplicateValue = copyNumbers[i];
|
||||||
free(copyNumbers);
|
free(copyNumbers);
|
||||||
return duplicateValue;
|
return duplicateValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(copyNumbers);
|
free(copyNumbers);
|
||||||
|
|||||||
34
stack.c
34
stack.c
@ -1,22 +1,22 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
|
||||||
//TODO: grundlegende Stackfunktionen implementieren:
|
// TODO: grundlegende Stackfunktionen implementieren:
|
||||||
/* * `push`: legt ein Element oben auf den Stack,
|
/* * `push`: legt ein Element oben auf den Stack,
|
||||||
* `pop`: entfernt das oberste Element,
|
* `pop`: entfernt das oberste Element,
|
||||||
* `top`: liefert das oberste Element zurück,
|
* `top`: liefert das oberste Element zurück,
|
||||||
* `clearStack`: gibt den gesamten Speicher frei. */
|
* `clearStack`: gibt den gesamten Speicher frei. */
|
||||||
|
|
||||||
// Pushes data as pointer onto the stack.
|
// Pushes data as pointer onto the stack.
|
||||||
StackNode* push(StackNode* stack, void* data)
|
StackNode *push(StackNode *stack, void *data)
|
||||||
{
|
{
|
||||||
//if(!data)
|
// if(!data)
|
||||||
//return 0; -> nicht notwendig
|
// return 0; -> nicht notwendig
|
||||||
|
|
||||||
StackNode* newNode = calloc(1, sizeof(StackNode)); //Speicher reserviert für data und prev, jeweils nur zeiger
|
StackNode *newNode = calloc(1, sizeof(StackNode)); // Speicher reserviert für data und prev, jeweils nur zeiger
|
||||||
if (!newNode)
|
if (!newNode)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
newNode->prev = stack;
|
newNode->prev = stack;
|
||||||
newNode->data = data;
|
newNode->data = data;
|
||||||
|
|
||||||
@ -25,28 +25,28 @@ StackNode* push(StackNode* stack, void* data)
|
|||||||
|
|
||||||
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
|
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
|
||||||
// freed by caller.)
|
// freed by caller.)
|
||||||
StackNode* pop(StackNode* stack)
|
StackNode *pop(StackNode *stack)
|
||||||
{
|
{
|
||||||
if(!stack)
|
if (!stack)
|
||||||
return NULL;
|
return NULL;
|
||||||
StackNode* prev = stack->prev;
|
StackNode *prev = stack->prev;
|
||||||
free(stack);
|
free(stack);
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the data of the top element.
|
// Returns the data of the top element.
|
||||||
void* top(StackNode* stack)
|
void *top(StackNode *stack)
|
||||||
{
|
{
|
||||||
if(!stack)
|
if (!stack)
|
||||||
return NULL;
|
return NULL;
|
||||||
return stack->data;
|
return stack->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears stack and releases all memory.
|
// Clears stack and releases all memory.
|
||||||
void clearStack(StackNode *stack) //Annahme: erstes Element: prev = NULL;
|
void clearStack(StackNode *stack) // Annahme: erstes Element: prev = NULL;
|
||||||
{
|
{
|
||||||
if(!stack)
|
if (!stack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clearStack(stack->prev);
|
clearStack(stack->prev);
|
||||||
|
|||||||
13
stack.h
13
stack.h
@ -1,16 +1,17 @@
|
|||||||
#ifndef STACK_H
|
#ifndef STACK_H
|
||||||
#define STACK_H
|
#define STACK_H
|
||||||
|
|
||||||
/* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
|
/* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
|
||||||
This means that with each new element all other elements are pushed deeper into the stack.
|
This means that with each new element all other elements are pushed deeper into the stack.
|
||||||
The latest element is taken from the stack. */
|
The latest element is taken from the stack. */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
//TODO: passenden Datentyp als struct anlegen
|
// TODO: passenden Datentyp als struct anlegen
|
||||||
typedef struct node {
|
typedef struct node
|
||||||
void* data;
|
{
|
||||||
struct node* prev;
|
void *data;
|
||||||
|
struct node *prev;
|
||||||
} StackNode;
|
} StackNode;
|
||||||
|
|
||||||
// Pushes data as pointer onto the stack.
|
// Pushes data as pointer onto the stack.
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include "bintree.h"
|
#include "bintree.h"
|
||||||
#include "unity/unity.h"
|
#include "unity/unity.h"
|
||||||
|
|
||||||
|
|
||||||
void test_getDuplicateLogic()
|
void test_getDuplicateLogic()
|
||||||
{
|
{
|
||||||
unsigned int test1[] = {1, 9, 3, 5, 2, 5, 8};
|
unsigned int test1[] = {1, 9, 3, 5, 2, 5, 8};
|
||||||
@ -22,39 +21,43 @@ void test_getDuplicateLogic()
|
|||||||
unsigned int len3 = 5;
|
unsigned int len3 = 5;
|
||||||
unsigned int res3 = getDuplicate(test3, len3);
|
unsigned int res3 = getDuplicate(test3, len3);
|
||||||
TEST_ASSERT_EQUAL_UINT32(0, res3);
|
TEST_ASSERT_EQUAL_UINT32(0, res3);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_Integration(unsigned int len) {
|
void test_Integration(unsigned int len)
|
||||||
|
{
|
||||||
unsigned int *arr = createNumbers(len);
|
unsigned int *arr = createNumbers(len);
|
||||||
TEST_ASSERT_NOT_NULL(arr);
|
TEST_ASSERT_NOT_NULL(arr);
|
||||||
unsigned int duplicate = getDuplicate(arr, len);
|
unsigned int duplicate = getDuplicate(arr, len);
|
||||||
TEST_ASSERT_NOT_EQUAL_UINT32(0, duplicate);
|
TEST_ASSERT_NOT_EQUAL_UINT32(0, duplicate);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (unsigned int i = 0; i < len; i++) {
|
for (unsigned int i = 0; i < len; i++)
|
||||||
if (arr[i] == duplicate) {
|
{
|
||||||
|
if (arr[i] == duplicate)
|
||||||
|
{
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_UINT32(2, count);
|
TEST_ASSERT_EQUAL_UINT32(2, count);
|
||||||
|
|
||||||
|
|
||||||
free(arr);
|
free(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_IntegrationVar () {
|
void test_IntegrationVar()
|
||||||
|
{
|
||||||
test_Integration(10);
|
test_Integration(10);
|
||||||
test_Integration(100);
|
test_Integration(100);
|
||||||
test_Integration(1000);
|
test_Integration(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUp(void) {
|
void setUp(void)
|
||||||
|
{
|
||||||
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
|
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown(void) {
|
void tearDown(void)
|
||||||
|
{
|
||||||
// Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden
|
// Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
test_numbers.exe
BIN
test_numbers.exe
Binary file not shown.
83
test_stack.c
83
test_stack.c
@ -4,16 +4,20 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "unity/unity.h"
|
#include "unity/unity.h"
|
||||||
|
|
||||||
void test_pushFailsOnNullPointer(StackNode *stack, void *data) {
|
void test_pushFailsOnNullPointer(StackNode *stack, void *data)
|
||||||
|
{
|
||||||
StackNode* test = push(NULL, data);
|
|
||||||
if (test != 0) {
|
StackNode *test = push(NULL, data);
|
||||||
|
if (test != 0)
|
||||||
|
{
|
||||||
printf("Pass test_pushFailsOnNullPointerStack\n");
|
printf("Pass test_pushFailsOnNullPointerStack\n");
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
printf("Did Not Pass test_pushFailsOnNullPointerStack EXPECTED StackNode\n");
|
printf("Did Not Pass test_pushFailsOnNullPointerStack EXPECTED StackNode\n");
|
||||||
|
|
||||||
test = push(stack, NULL);
|
test = push(stack, NULL);
|
||||||
if (test == 0) {
|
if (test == 0)
|
||||||
|
{
|
||||||
printf("Pass test_pushFailsOnNullPointerData\n");
|
printf("Pass test_pushFailsOnNullPointerData\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -21,49 +25,54 @@ void test_pushFailsOnNullPointer(StackNode *stack, void *data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_popFailsOnNullPointer() { //pop on null returns NULL
|
void test_popFailsOnNullPointer()
|
||||||
|
{ // pop on null returns NULL
|
||||||
StackNode* test = pop(NULL);
|
|
||||||
if (test == 0) {
|
StackNode *test = pop(NULL);
|
||||||
|
if (test == 0)
|
||||||
|
{
|
||||||
printf("Pass test_popFailsOnNullPointerStack\n");
|
printf("Pass test_popFailsOnNullPointerStack\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Did Not Pass test_popFailsOnNullPointerStack EXPECTED 0\n");
|
printf("Did Not Pass test_popFailsOnNullPointerStack EXPECTED 0\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_topFailsOnNullPointer() {
|
void test_topFailsOnNullPointer()
|
||||||
|
{
|
||||||
int* test = (int*)top(NULL);
|
|
||||||
if (test == 0) {
|
int *test = (int *)top(NULL);
|
||||||
|
if (test == 0)
|
||||||
|
{
|
||||||
printf("Pass test_topFailsOnNullPointerStack\n");
|
printf("Pass test_topFailsOnNullPointerStack\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Did Not Pass test_topFailsOnNullPointerStack EXPECTED 0\n");
|
printf("Did Not Pass test_topFailsOnNullPointerStack EXPECTED 0\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUp(void)
|
||||||
void setUp(void) {
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown(void) {
|
void tearDown(void)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
int test0 = 3;
|
int test0 = 3;
|
||||||
int* dataTest0 = &test0;
|
int *dataTest0 = &test0;
|
||||||
StackNode *stack0 = push(NULL, dataTest0);
|
StackNode *stack0 = push(NULL, dataTest0);
|
||||||
|
|
||||||
char test1[5] = "test\0";
|
char test1[5] = "test\0";
|
||||||
char* dataTest1 = test1;
|
char *dataTest1 = test1;
|
||||||
|
|
||||||
float test2 = 3.14;
|
float test2 = 3.14;
|
||||||
float* dataTest2 = &test2;
|
float *dataTest2 = &test2;
|
||||||
|
|
||||||
printf("============================\nstack tests\n============================\n");
|
printf("============================\nstack tests\n============================\n");
|
||||||
test_pushFailsOnNullPointer(stack0, dataTest0);
|
test_pushFailsOnNullPointer(stack0, dataTest0);
|
||||||
@ -71,24 +80,30 @@ int main()
|
|||||||
test_topFailsOnNullPointer();
|
test_topFailsOnNullPointer();
|
||||||
|
|
||||||
StackNode *stack1 = push(stack0, dataTest1);
|
StackNode *stack1 = push(stack0, dataTest1);
|
||||||
if(strcmp(stack1->data ,dataTest1) == 0) {
|
if (strcmp(stack1->data, dataTest1) == 0)
|
||||||
|
{
|
||||||
printf("Pass test_pushString\n");
|
printf("Pass test_pushString\n");
|
||||||
} else
|
}
|
||||||
printf("Fails test_pushString\n expected: %s\n was: %s\n", dataTest1, (char*)(stack1->data));
|
else
|
||||||
|
printf("Fails test_pushString\n expected: %s\n was: %s\n", dataTest1, (char *)(stack1->data));
|
||||||
|
|
||||||
StackNode *stack2 = push(stack1, dataTest2);
|
StackNode *stack2 = push(stack1, dataTest2);
|
||||||
if(stack2->data == dataTest2) {
|
if (stack2->data == dataTest2)
|
||||||
|
{
|
||||||
printf("Pass test_pushFloat\n");
|
printf("Pass test_pushFloat\n");
|
||||||
} else
|
}
|
||||||
printf("Fails test_pushFloat\n expected: %f\n was: %f\n", *dataTest2, *(float*)(stack2->data));
|
else
|
||||||
|
printf("Fails test_pushFloat\n expected: %f\n was: %f\n", *dataTest2, *(float *)(stack2->data));
|
||||||
|
|
||||||
int array[10] = {1,2,3,4,5,6,7,8,9,10};
|
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
|
||||||
for(size_t i = 0; i<10; i++) {
|
for (size_t i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
stack2 = push(stack2, &array[i]);
|
stack2 = push(stack2, &array[i]);
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i<10; i++) {
|
for (size_t i = 0; i < 10; i++)
|
||||||
int* data = (int*)top(stack2);
|
{
|
||||||
|
int *data = (int *)top(stack2);
|
||||||
printf("%d\n", *data);
|
printf("%d\n", *data);
|
||||||
stack2 = pop(stack2);
|
stack2 = pop(stack2);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
test_stack.exe
BIN
test_stack.exe
Binary file not shown.
7
timer.c
7
timer.c
@ -14,14 +14,15 @@ void startTimer()
|
|||||||
double stopTimer()
|
double stopTimer()
|
||||||
{
|
{
|
||||||
struct timespec end;
|
struct timespec end;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
|
||||||
unsigned long long delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
unsigned long long delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
||||||
|
|
||||||
double measuredSeconds = (double)delta_us / 1000000.;
|
double measuredSeconds = (double)delta_us / 1000000.;
|
||||||
|
|
||||||
if(start.tv_nsec > 0) {
|
if (start.tv_nsec > 0)
|
||||||
|
{
|
||||||
start.tv_nsec = 0;
|
start.tv_nsec = 0;
|
||||||
start.tv_sec = 0;
|
start.tv_sec = 0;
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ double stopTimer()
|
|||||||
{
|
{
|
||||||
double measuredSeconds = (clock() - (double)startClocks) / CLOCKS_PER_SEC;
|
double measuredSeconds = (clock() - (double)startClocks) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
if(startClocks > 0)
|
if (startClocks > 0)
|
||||||
startClocks = 0;
|
startClocks = 0;
|
||||||
else
|
else
|
||||||
measuredSeconds = -1;
|
measuredSeconds = -1;
|
||||||
|
|||||||
BIN
unittest.o
BIN
unittest.o
Binary file not shown.
BIN
unittestTree.o
BIN
unittestTree.o
Binary file not shown.
@ -4,7 +4,6 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
|
||||||
|
|
||||||
void test_createMatrixFailsOnZeroDimensions(void)
|
void test_createMatrixFailsOnZeroDimensions(void)
|
||||||
{
|
{
|
||||||
Matrix matrixToTest1 = createMatrix(0, 1);
|
Matrix matrixToTest1 = createMatrix(0, 1);
|
||||||
@ -21,7 +20,7 @@ void test_createMatrixReturnsCorrectMatrixDimensions(void)
|
|||||||
{
|
{
|
||||||
const unsigned int expectedRows = 15;
|
const unsigned int expectedRows = 15;
|
||||||
const unsigned int expectedCols = 10;
|
const unsigned int expectedCols = 10;
|
||||||
|
|
||||||
Matrix matrixToTest = createMatrix(expectedRows, expectedCols);
|
Matrix matrixToTest = createMatrix(expectedRows, expectedCols);
|
||||||
TEST_ASSERT_EQUAL_UINT32(expectedRows, matrixToTest.rows);
|
TEST_ASSERT_EQUAL_UINT32(expectedRows, matrixToTest.rows);
|
||||||
TEST_ASSERT_EQUAL_UINT32(expectedCols, matrixToTest.cols);
|
TEST_ASSERT_EQUAL_UINT32(expectedCols, matrixToTest.cols);
|
||||||
@ -41,8 +40,8 @@ void test_addReturnsCorrectResult(void)
|
|||||||
{
|
{
|
||||||
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
||||||
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
||||||
Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1};
|
Matrix matrix1 = {.rows = 2, .cols = 3, .buffer = buffer1};
|
||||||
Matrix matrix2 = {.rows=2, .cols=3, .buffer=buffer2};
|
Matrix matrix2 = {.rows = 2, .cols = 3, .buffer = buffer2};
|
||||||
|
|
||||||
Matrix result = add(matrix1, matrix2);
|
Matrix result = add(matrix1, matrix2);
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ void test_addReturnsCorrectResult(void)
|
|||||||
TEST_ASSERT_EQUAL_UINT32(matrix2.rows, result.rows);
|
TEST_ASSERT_EQUAL_UINT32(matrix2.rows, result.rows);
|
||||||
TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result.cols);
|
TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result.cols);
|
||||||
TEST_ASSERT_EQUAL_UINT32(matrix2.cols, result.cols);
|
TEST_ASSERT_EQUAL_UINT32(matrix2.cols, result.cols);
|
||||||
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result.rows * result.cols);
|
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults) / sizeof(expectedResults[0]), result.rows * result.cols);
|
||||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result.buffer, result.cols * result.rows);
|
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result.buffer, result.cols * result.rows);
|
||||||
free(result.buffer);
|
free(result.buffer);
|
||||||
}
|
}
|
||||||
@ -61,9 +60,9 @@ void test_addFailsOnDifferentInputDimensions(void)
|
|||||||
{
|
{
|
||||||
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
||||||
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
||||||
Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1};
|
Matrix matrix1 = {.rows = 2, .cols = 3, .buffer = buffer1};
|
||||||
Matrix matrix2 = {.rows=3, .cols=2, .buffer=buffer2};
|
Matrix matrix2 = {.rows = 3, .cols = 2, .buffer = buffer2};
|
||||||
|
|
||||||
Matrix result = add(matrix1, matrix2);
|
Matrix result = add(matrix1, matrix2);
|
||||||
|
|
||||||
TEST_ASSERT_NULL(result.buffer);
|
TEST_ASSERT_NULL(result.buffer);
|
||||||
@ -75,8 +74,8 @@ void test_addSupportsBroadcasting(void)
|
|||||||
{
|
{
|
||||||
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
||||||
MatrixType buffer2[] = {7, 8};
|
MatrixType buffer2[] = {7, 8};
|
||||||
Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1};
|
Matrix matrix1 = {.rows = 2, .cols = 3, .buffer = buffer1};
|
||||||
Matrix matrix2 = {.rows=2, .cols=1, .buffer=buffer2};
|
Matrix matrix2 = {.rows = 2, .cols = 1, .buffer = buffer2};
|
||||||
|
|
||||||
Matrix result1 = add(matrix1, matrix2);
|
Matrix result1 = add(matrix1, matrix2);
|
||||||
Matrix result2 = add(matrix2, matrix1);
|
Matrix result2 = add(matrix2, matrix1);
|
||||||
@ -88,9 +87,9 @@ void test_addSupportsBroadcasting(void)
|
|||||||
TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result2.rows);
|
TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result2.rows);
|
||||||
TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result2.cols);
|
TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result2.cols);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result1.rows * result1.cols);
|
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults) / sizeof(expectedResults[0]), result1.rows * result1.cols);
|
||||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result1.buffer, result1.cols * result1.rows);
|
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result1.buffer, result1.cols * result1.rows);
|
||||||
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result2.rows * result2.cols);
|
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults) / sizeof(expectedResults[0]), result2.rows * result2.cols);
|
||||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result2.buffer, result2.cols * result2.rows);
|
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result2.buffer, result2.cols * result2.rows);
|
||||||
|
|
||||||
free(result1.buffer);
|
free(result1.buffer);
|
||||||
@ -101,16 +100,16 @@ void test_multiplyReturnsCorrectResults(void)
|
|||||||
{
|
{
|
||||||
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
||||||
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
|
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
|
||||||
Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1};
|
Matrix matrix1 = {.rows = 2, .cols = 3, .buffer = buffer1};
|
||||||
Matrix matrix2 = {.rows=3, .cols=4, .buffer=buffer2};
|
Matrix matrix2 = {.rows = 3, .cols = 4, .buffer = buffer2};
|
||||||
|
|
||||||
Matrix result = multiply(matrix1, matrix2);
|
Matrix result = multiply(matrix1, matrix2);
|
||||||
|
|
||||||
float expectedResults[] = {74, 80, 86, 92, 173, 188, 203, 218};
|
float expectedResults[] = {74, 80, 86, 92, 173, 188, 203, 218};
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result.rows);
|
TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result.rows);
|
||||||
TEST_ASSERT_EQUAL_UINT32(matrix2.cols, result.cols);
|
TEST_ASSERT_EQUAL_UINT32(matrix2.cols, result.cols);
|
||||||
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result.rows * result.cols);
|
TEST_ASSERT_EQUAL_INT(sizeof(expectedResults) / sizeof(expectedResults[0]), result.rows * result.cols);
|
||||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result.buffer, result.cols * result.rows);
|
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result.buffer, result.cols * result.rows);
|
||||||
|
|
||||||
free(result.buffer);
|
free(result.buffer);
|
||||||
@ -120,8 +119,8 @@ void test_multiplyFailsOnWrongInputDimensions(void)
|
|||||||
{
|
{
|
||||||
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer1[] = {1, 2, 3, 4, 5, 6};
|
||||||
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
MatrixType buffer2[] = {7, 8, 9, 10, 11, 12};
|
||||||
Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1};
|
Matrix matrix1 = {.rows = 2, .cols = 3, .buffer = buffer1};
|
||||||
Matrix matrix2 = {.rows=2, .cols=3, .buffer=buffer2};
|
Matrix matrix2 = {.rows = 2, .cols = 3, .buffer = buffer2};
|
||||||
|
|
||||||
Matrix result = multiply(matrix1, matrix2);
|
Matrix result = multiply(matrix1, matrix2);
|
||||||
|
|
||||||
@ -133,7 +132,7 @@ void test_multiplyFailsOnWrongInputDimensions(void)
|
|||||||
void test_getMatrixAtReturnsCorrectResult(void)
|
void test_getMatrixAtReturnsCorrectResult(void)
|
||||||
{
|
{
|
||||||
MatrixType buffer[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer[] = {1, 2, 3, 4, 5, 6};
|
||||||
Matrix matrixToTest = {.rows=2, .cols=3, .buffer=buffer};
|
Matrix matrixToTest = {.rows = 2, .cols = 3, .buffer = buffer};
|
||||||
int expectedResult = buffer[4];
|
int expectedResult = buffer[4];
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(expectedResult, getMatrixAt(matrixToTest, 1, 1));
|
TEST_ASSERT_EQUAL_INT(expectedResult, getMatrixAt(matrixToTest, 1, 1));
|
||||||
@ -142,7 +141,7 @@ void test_getMatrixAtReturnsCorrectResult(void)
|
|||||||
void test_getMatrixAtFailsOnIndicesOutOfRange(void)
|
void test_getMatrixAtFailsOnIndicesOutOfRange(void)
|
||||||
{
|
{
|
||||||
MatrixType buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
MatrixType buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
Matrix matrixToTest = {.rows=2, .cols=3, .buffer=buffer};
|
Matrix matrixToTest = {.rows = 2, .cols = 3, .buffer = buffer};
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(UNDEFINED_MATRIX_VALUE, getMatrixAt(matrixToTest, 2, 3));
|
TEST_ASSERT_EQUAL_INT(UNDEFINED_MATRIX_VALUE, getMatrixAt(matrixToTest, 2, 3));
|
||||||
}
|
}
|
||||||
@ -151,7 +150,7 @@ void test_setMatrixAtSetsCorrectValue(void)
|
|||||||
{
|
{
|
||||||
const int expectedResult = -1;
|
const int expectedResult = -1;
|
||||||
MatrixType buffer[] = {1, 2, 3, 4, 5, 6};
|
MatrixType buffer[] = {1, 2, 3, 4, 5, 6};
|
||||||
Matrix matrixUnderTest = {.rows=2, .cols=3, .buffer=buffer};
|
Matrix matrixUnderTest = {.rows = 2, .cols = 3, .buffer = buffer};
|
||||||
|
|
||||||
setMatrixAt(expectedResult, matrixUnderTest, 1, 2);
|
setMatrixAt(expectedResult, matrixUnderTest, 1, 2);
|
||||||
TEST_ASSERT_EQUAL_INT(expectedResult, buffer[5]);
|
TEST_ASSERT_EQUAL_INT(expectedResult, buffer[5]);
|
||||||
@ -161,17 +160,19 @@ void test_setMatrixAtFailsOnIndicesOutOfRange(void)
|
|||||||
{
|
{
|
||||||
const float expectedResults[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
const float expectedResults[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
MatrixType buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
MatrixType buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
Matrix matrixToTest = {.rows=2, .cols=3, .buffer=buffer};
|
Matrix matrixToTest = {.rows = 2, .cols = 3, .buffer = buffer};
|
||||||
|
|
||||||
setMatrixAt(-1, matrixToTest, 2, 3);
|
setMatrixAt(-1, matrixToTest, 2, 3);
|
||||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, sizeof(buffer)/sizeof(MatrixType));
|
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, sizeof(buffer) / sizeof(MatrixType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUp(void) {
|
void setUp(void)
|
||||||
|
{
|
||||||
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
|
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown(void) {
|
void tearDown(void)
|
||||||
|
{
|
||||||
// Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden
|
// Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1122
unity/unity.h
1122
unity/unity.h
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user