-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1317321
commit 16ddec5
Showing
16 changed files
with
511 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
CC = clang | ||
CFLAGS = -g | ||
|
||
SRCS = linkedlist.c main.c | ||
HDRS = linkedlist.h value.h | ||
OBJS = $(SRCS:.c=.o) | ||
|
||
.PHONY: linkedlist | ||
linkedlist: $(OBJS) | ||
$(CC) $(CFLAGS) $^ -o $@ | ||
|
||
.PHONY: phony_target | ||
phony_target: | ||
|
||
%.o : %.c $(HDRS) phony_target | ||
$(CC) $(CFLAGS) -c $< -o $@ | ||
|
||
clean: | ||
rm *.o | ||
rm linkedlist | ||
|
||
valgrind: linkedlist | ||
valgrind --leak-check=yes --error-exitcode=1 ./linkedlist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
https://www.tutorialspoint.com/cprogramming/switch_statement_in_c.htm#:~:text=The%20syntax%20for%20a%20switch%20statement%20in%20C,%2A%2F%20default%20%3A%20%2F%2A%20Optional%20%2A%2F%20statement%28s%29%3B%20%7D | ||
|
||
https://www.tutorialspoint.com/c_standard_library/c_function_strlen.htm |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#include <stdbool.h> | ||
#include "value.h" | ||
|
||
#ifndef _LINKEDLIST_H | ||
#define _LINKEDLIST_H | ||
|
||
|
||
// Create a pointer to a new NULL_TYPE Value (hint: where in memory will | ||
// the value have to live?) | ||
Value *makeNull(); | ||
|
||
// Return whether the given pointer points at a NULL_TYPE Value. Use assertions | ||
// to make sure that this is a legitimate operation. See the assignment | ||
// instructions for further explanation on assertions. | ||
bool isNull(Value *value); | ||
|
||
// Create a pointer to a new CONS_TYPE Value | ||
Value *cons(Value *newCar, Value *newCdr); | ||
|
||
// Return a pointer to the car value for the cons cell at the head of the given | ||
// linked list. Use assertions here to make sure that this is a legitimate operation | ||
// (e.g., there is no car value at the head of an empty list). See the assignment | ||
// instructions for further explanation. | ||
Value *car(Value *list); | ||
|
||
// Return a pointer to the cdr value for the cons cell at the head of the given linked | ||
// list. Again use assertions to make sure that this is a legitimate operation. | ||
Value *cdr(Value *list); | ||
|
||
// Display the contents of the linked list to the screen in the | ||
// format of a Scheme list -- e.g., ( 33 "lol" 9.9 ). It's okay | ||
// to just use printf here, though you'll have to add the quotes in | ||
// yourself, for strings. | ||
void display(Value *list); | ||
|
||
// Return a new list that is the reverse of the one that is passed in. All | ||
// content within the list should be duplicated; there should be no shared | ||
// memory whatsoever between the original list and the new one. Use your | ||
// cons(), car(), and cdr() functions from above -- but be sure that you | ||
// don't end up pointing to memory used by the old list! Hint: this means | ||
// that you'll need to make copies of the Value structs that serve as car | ||
// values for the cons cells in the original list; more specifically, you'll | ||
// want to malloc new space for them on the heap. In the case of a string, | ||
// the strlen() function will come in handy, in addition to strcpy(); note | ||
// that strlen() will not include the null terminator in its count. To use | ||
// these functions, you'll need to include <string.h> above. | ||
|
||
// FAQ: What if there are nested lists inside that list? | ||
|
||
// ANS: There won't be for this assignment. There will be later, but that will | ||
// be after we've set up an easier way of managing memory. | ||
Value *reverse(Value *list); | ||
|
||
// Return the length of the given list, i.e., the number of cons cells. | ||
// Use assertions to make sure that this is a legitimate operation. | ||
int length(Value *value); | ||
|
||
// Free up all memory directly or indirectly referred to by list. This includes | ||
// strings, because in the Value defintion these are pointers to character arrays. | ||
|
||
// FAQ: What if a string being pointed to is a string literal? That throws an | ||
// error when freeing. | ||
|
||
// ANS: Don't put a string literal into the list in the first place. All strings | ||
// added to this list should be able to be free'd by the cleanup function. | ||
|
||
// FAQ: What if there are nested lists inside that list? | ||
|
||
// ANS: There won't be for this assignment. There will be later, but that will | ||
// be after we've set up an easier way of managing memory. | ||
void cleanup(Value *list); | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
// Tester for linked list. | ||
|
||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
#include <assert.h> | ||
#include "linkedlist.h" | ||
#include "value.h" | ||
|
||
|
||
// This is a helper function used by main(), which includes | ||
// the actual test cases. Jump down to main() to view those, | ||
// and ignore this function unless it appears to be causing | ||
// tests to fail, in which case you can inspect it further. | ||
void testForward(Value *head, int correctLength) { | ||
|
||
Value *value = head; | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(1 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("2.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("3.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(4 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("5.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(6 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(INT_TYPE == car(value)->type); | ||
assert(7 == car(value)->i); | ||
|
||
value = cdr(value); | ||
assert(NULL_TYPE == value->type); | ||
|
||
assert(correctLength == length(head)); | ||
assert(!isNull(head)); | ||
} | ||
|
||
|
||
// This is a helper function used by main(), which includes | ||
// the actual test cases. Jump down to main() to view those, | ||
// and ignore this function unless it appears to be causing | ||
// tests to fail, in which case you can inspect it further. | ||
void testBackward(Value *head, int correctLength) { | ||
Value *value = head; | ||
|
||
assert(CONS_TYPE == value->type); | ||
assert(INT_TYPE == car(value)->type); | ||
assert(7 == car(value)->i); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(6 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("5.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(4 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("3.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(STR_TYPE == car(value)->type); | ||
assert(!strcmp("2.0s", car(value)->s)); | ||
|
||
value = cdr(value); | ||
assert(CONS_TYPE == value->type); | ||
assert(DOUBLE_TYPE == car(value)->type); | ||
assert(1 == car(value)->d); | ||
|
||
value = cdr(value); | ||
assert(NULL_TYPE == value->type); | ||
|
||
assert(correctLength == length(head)); | ||
assert(!isNull(head)); | ||
} | ||
|
||
|
||
// This contains the actual test cases, which the comments delineate. | ||
int main() { | ||
|
||
// 1. Create a null value (representing an empty list) | ||
printf("Test 1...\n"); | ||
Value *head = makeNull(); | ||
int correctLength = 0; | ||
assert(length(head) == correctLength); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 2. Reverse the empty list: ( ) | ||
printf("Test 2...\n"); | ||
Value *reverseLengthZero = reverse(head); | ||
assert(length(reverseLengthZero) == correctLength); | ||
cleanup(reverseLengthZero); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 3.1 Cons a new cell at the head of the list: ( 7 ) | ||
printf("Test 3.1...\n"); | ||
Value *val1 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val1->type = INT_TYPE; | ||
val1->i = 7; | ||
head = cons(val1, head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 3.2. Display the list of one element: ( 7 ) | ||
printf("Test 3.2....\n"); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 4.1 Reverse this list of one element: ( 7 ) | ||
printf("Test 4.1...\n"); | ||
Value *reverseLengthOne = reverse(head); | ||
assert(length(reverseLengthOne) == correctLength); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 4.2. Display the reversed list of one element: ( 7 ) | ||
printf("Test 4.2...\n"); | ||
printf("\t\t"); | ||
display(reverseLengthOne); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 4.3. Call cleanup() on the reversed list | ||
printf("Test 4.3...\n"); | ||
cleanup(reverseLengthOne); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 5. Cons a new cell at the front of the existing list: ( 6.00 7 ) | ||
printf("Test 5...\n"); | ||
Value *val2 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val2->type = DOUBLE_TYPE; | ||
val2->d = 6.00; | ||
head = cons(val2, head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 6. Cons a new cell at the front of the list: ( "5.0s" 6.00 7 ) | ||
printf("Test 6...\n"); | ||
Value *val3 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val3->type = STR_TYPE; | ||
char *text = "5.0s"; | ||
val3->s = malloc(sizeof(char)*(strlen(text) + 1)); // This will have to be freed eventually! | ||
strcpy(val3->s,text); | ||
head = cons(val3,head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 7. Cons a new cell at the front of the list: ( 4.00000 "5.0s" 6.00 7 ) | ||
printf("Test 7...\n"); | ||
Value *val4 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val4->type = DOUBLE_TYPE; | ||
val4->d = 4.00000; | ||
head = cons(val4,head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 8. Cons a new cell at the front of the list: ( "3.0s" 4.00000 "5.0s" 6.00 7 ) | ||
printf("Test 8...\n"); | ||
Value *val5 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val5->type = STR_TYPE; | ||
text = "3.0s"; | ||
val5->s = malloc(sizeof(char)*(strlen(text) + 1)); // This will have to be freed eventually! | ||
strcpy(val5->s,text); | ||
head = cons(val5,head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 9. Cons a new cell at the front of the list: ( "2.0s" "3.0s" 4.00000 "5.0s" 6.00 7 ) | ||
printf("Test 9...\n"); | ||
Value *val6 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val6->type = STR_TYPE; | ||
text = "2.0s"; | ||
val6->s = malloc(sizeof(char)*(strlen(text) + 1)); // This will have to be freed eventually! | ||
strcpy(val6->s,text); | ||
head = cons(val6,head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 10. Cons a new cell at the front of the list: ( 1.0 "2.0s" "3.0s" 4.00000 "5.0s" 6.00 7 ) | ||
printf("Test 10...\n"); | ||
Value *val7 = malloc(sizeof(Value)); // This will have to be freed eventually! | ||
val7->type = DOUBLE_TYPE; | ||
val7->d = 1.0; | ||
head = cons(val7,head); | ||
correctLength++; | ||
assert(length(head) == correctLength); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 11. Display the contents of the list: ( 1.0 "2.0s" "3.0s" 4.00000 "5.0s" 6.00 7 ) | ||
printf("Test 11...\n"); | ||
printf("\t\t"); | ||
display(head); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 12. Confirm that everything is in the expected order | ||
printf("Test 12...\n"); | ||
testForward(head, correctLength); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 13. Reverse the entire list and display the result: ( 7 6.00 "5.0s" 4.00000 "3.0s" "2.0s" 1.0 ) | ||
printf("Test 13...\n"); | ||
Value *rev = reverse(head); | ||
printf("\t\t"); | ||
display(rev); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 14. Work through the reversed list to ensure it is in the expected order | ||
printf("Test 14...\n"); | ||
testBackward(rev, correctLength); | ||
printf("\tPASSED\n\n"); | ||
|
||
// 15. Free all the memory | ||
printf("Test 15...\n"); | ||
cleanup(head); | ||
cleanup(rev); | ||
printf("\tPASSED\n\n"); | ||
|
||
head = NULL; | ||
rev = NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/python3 | ||
|
||
import unittest | ||
import test_utilities | ||
|
||
class Tests(unittest.TestCase): | ||
def testCode(self): | ||
return_value = test_utilities.runIt() | ||
if return_value != None: | ||
self.fail(return_value) | ||
|
||
unittest.main() |
Oops, something went wrong.