Endlich fertig
This commit is contained in:
parent
ef14e5465c
commit
416f44ae74
87
bintree.c
87
bintree.c
@ -1,18 +1,65 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "stack.h"
|
||||
#include "bintree.h"
|
||||
|
||||
//TODO: binären Suchbaum implementieren
|
||||
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
|
||||
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
|
||||
* `treeSize`: zählt die Knoten im Baum (rekursiv),
|
||||
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
|
||||
// internal helper to push node and all its left descendants onto iterator stack
|
||||
static void bintree_pushLefts(StackNode **iterStackPtr, TreeNode *n)
|
||||
{
|
||||
while(n != NULL)
|
||||
{
|
||||
*iterStackPtr = push(*iterStackPtr, n);
|
||||
n = n->left;
|
||||
}
|
||||
}
|
||||
|
||||
// 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).
|
||||
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
|
||||
{
|
||||
if(isDuplicate != NULL)
|
||||
*isDuplicate = 0;
|
||||
|
||||
if(root == NULL)
|
||||
{
|
||||
TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));
|
||||
if(node == NULL)
|
||||
return NULL;
|
||||
node->data = malloc(dataSize);
|
||||
if(node->data == NULL)
|
||||
{
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(node->data, data, dataSize);
|
||||
node->left = node->right = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
int cmp = compareFct(data, root->data);
|
||||
if(cmp < 0)
|
||||
{
|
||||
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
else if(cmp > 0)
|
||||
{
|
||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
else // equal
|
||||
{
|
||||
if(isDuplicate != NULL)
|
||||
{
|
||||
*isDuplicate = 1;
|
||||
// do not insert duplicate
|
||||
}
|
||||
else
|
||||
{
|
||||
// duplicates allowed -> insert into right subtree
|
||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -20,17 +67,45 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
|
||||
// push the top node and push all its left nodes.
|
||||
void *nextTreeData(TreeNode *root)
|
||||
{
|
||||
static StackNode *iterStack = NULL;
|
||||
|
||||
// If a new tree root is provided -> reset iterator
|
||||
if(root != NULL)
|
||||
{
|
||||
clearStack(iterStack);
|
||||
iterStack = NULL;
|
||||
bintree_pushLefts(&iterStack, root);
|
||||
}
|
||||
|
||||
if(iterStack == NULL)
|
||||
return NULL;
|
||||
|
||||
TreeNode *node = (TreeNode *)top(iterStack);
|
||||
iterStack = pop(iterStack);
|
||||
|
||||
if(node->right != NULL)
|
||||
bintree_pushLefts(&iterStack, node->right);
|
||||
|
||||
return node->data;
|
||||
}
|
||||
|
||||
// Releases all memory resources (including data copies).
|
||||
void clearTree(TreeNode *root)
|
||||
{
|
||||
if(root == NULL)
|
||||
return;
|
||||
|
||||
clearTree(root->left);
|
||||
clearTree(root->right);
|
||||
|
||||
free(root->data);
|
||||
free(root);
|
||||
}
|
||||
|
||||
// Returns the number of entries in the tree given by root.
|
||||
unsigned int treeSize(const TreeNode *root)
|
||||
{
|
||||
|
||||
if(root == NULL)
|
||||
return 0;
|
||||
return 1 + treeSize(root->left) + treeSize(root->right);
|
||||
}
|
||||
BIN
doble_initial
Executable file
BIN
doble_initial
Executable file
Binary file not shown.
BIN
highscore.o
Normal file
BIN
highscore.o
Normal file
Binary file not shown.
@ -1 +1,10 @@
|
||||
player1;3999
|
||||
Lena;19811
|
||||
Lena;19702
|
||||
player_name;9981
|
||||
Lena;9980
|
||||
Lena;9978
|
||||
Lena;9978
|
||||
Lena;9976
|
||||
Lena;9975
|
||||
Lena;9971
|
||||
Lena;9965
|
||||
|
||||
32
makefile
32
makefile
@ -29,14 +29,38 @@ program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
|
||||
doble : main.o $(program_obj_files)
|
||||
$(CC) $(FLAGS) $^ -o doble
|
||||
|
||||
$(program_obj_filesobj_files): %.o: %.c
|
||||
$(CC) -c $(FLAGS) $^ -o $@
|
||||
# pattern rule to build .o from .c
|
||||
%.o: %.c
|
||||
$(CC) -c $(FLAGS) $< -o $@
|
||||
|
||||
# --------------------------
|
||||
# Unit Tests
|
||||
# --------------------------
|
||||
unitTests:
|
||||
echo "needs to be implemented"
|
||||
unitTests: test_stack test_numbers test_bintree
|
||||
@total=0; passed=0; failed=0; \
|
||||
for t in test_stack test_numbers test_bintree; do \
|
||||
total=$$((total+1)); \
|
||||
printf "Running %s...\n" "$$t"; \
|
||||
./$$t; rc=$$?; \
|
||||
if [ $$rc -eq 0 ]; then \
|
||||
printf "%s: PASS\n\n" "$$t"; \
|
||||
passed=$$((passed+1)); \
|
||||
else \
|
||||
printf "%s: FAIL (exit %d)\n\n" "$$t" $$rc; \
|
||||
failed=$$((failed+1)); \
|
||||
fi; \
|
||||
done; \
|
||||
printf "Summary: %d tests run, %d passed, %d failed\n" $$total $$passed $$failed; \
|
||||
exit $$failed
|
||||
|
||||
test_stack: test_stack.c stack.c
|
||||
$(CC) $(FLAGS) test_stack.c stack.c -o test_stack
|
||||
|
||||
test_numbers: test_numbers.c numbers.c bintree.c stack.c
|
||||
$(CC) $(FLAGS) test_numbers.c numbers.c bintree.c stack.c -o test_numbers
|
||||
|
||||
test_bintree: test_bintree.c bintree.c stack.c
|
||||
$(CC) $(FLAGS) test_bintree.c bintree.c stack.c -o test_bintree
|
||||
|
||||
# --------------------------
|
||||
# Clean
|
||||
|
||||
95
numbers.c
95
numbers.c
@ -5,22 +5,107 @@
|
||||
#include "numbers.h"
|
||||
#include "bintree.h"
|
||||
|
||||
//TODO: getDuplicate und createNumbers implementieren
|
||||
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
|
||||
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
|
||||
* Duplizieren eines zufälligen Eintrags im Array.
|
||||
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
|
||||
// helper comparator for unsigned int for bintree
|
||||
static int compareUInt(const void *a, const void *b)
|
||||
{
|
||||
unsigned int va = *(const unsigned int *)a;
|
||||
unsigned int vb = *(const unsigned int *)b;
|
||||
if(va < vb) return -1;
|
||||
if(va > vb) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// comparator for qsort (unsigned int)
|
||||
static int qsort_uint_cmp(const void *a, const void *b)
|
||||
{
|
||||
unsigned int va = *(const unsigned int *)a;
|
||||
unsigned int vb = *(const unsigned int *)b;
|
||||
if(va < vb) return -1;
|
||||
if(va > vb) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
|
||||
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
|
||||
// creating random numbers.
|
||||
unsigned int *createNumbers(unsigned int len)
|
||||
{
|
||||
if(len < 2)
|
||||
return NULL;
|
||||
|
||||
unsigned int *numbers = (unsigned int *)malloc(sizeof(unsigned int) * len);
|
||||
if(numbers == NULL)
|
||||
return NULL;
|
||||
|
||||
// seed once
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
TreeNode *root = NULL;
|
||||
unsigned int range = 2 * len;
|
||||
// create len-1 unique numbers
|
||||
for(unsigned int i = 0; i < len - 1; i++)
|
||||
{
|
||||
unsigned int val;
|
||||
int isDup = 0;
|
||||
// try until a unique number is inserted
|
||||
do
|
||||
{
|
||||
val = (unsigned int)(rand() % range) + 1; // [1..2*len]
|
||||
root = addToTree(root, &val, sizeof(val), compareUInt, &isDup);
|
||||
// if addToTree returned NULL due to allocation failure, cleanup and return NULL
|
||||
if(root == NULL && isDup == 0)
|
||||
{
|
||||
free(numbers);
|
||||
clearTree(root);
|
||||
return NULL;
|
||||
}
|
||||
} while(isDup);
|
||||
numbers[i] = val;
|
||||
}
|
||||
|
||||
// duplicate one existing random entry
|
||||
unsigned int idx = (unsigned int)(rand() % (len - 1));
|
||||
numbers[len - 1] = numbers[idx];
|
||||
|
||||
// shuffle array (Fisher-Yates)
|
||||
for(unsigned int i = len - 1; i > 0; i--)
|
||||
{
|
||||
unsigned int j = (unsigned int)(rand() % (i + 1));
|
||||
unsigned int tmp = numbers[i];
|
||||
numbers[i] = numbers[j];
|
||||
numbers[j] = tmp;
|
||||
}
|
||||
|
||||
// free tree resources
|
||||
clearTree(root);
|
||||
return numbers;
|
||||
}
|
||||
|
||||
// Returns only the only number in numbers which is present twice. Returns zero on errors.
|
||||
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
{
|
||||
if(numbers == NULL || len < 2)
|
||||
return 0;
|
||||
|
||||
// make a copy so original array order is not modified by caller expectation
|
||||
unsigned int *copy = (unsigned int *)malloc(sizeof(unsigned int) * len);
|
||||
if(copy == NULL)
|
||||
return 0;
|
||||
|
||||
memcpy(copy, numbers, sizeof(unsigned int) * len);
|
||||
|
||||
qsort(copy, len, sizeof(unsigned int), qsort_uint_cmp);
|
||||
|
||||
unsigned int result = 0;
|
||||
for(unsigned int i = 0; i + 1 < len; i++)
|
||||
{
|
||||
if(copy[i] == copy[i+1])
|
||||
{
|
||||
result = copy[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return result;
|
||||
}
|
||||
30
stack.c
30
stack.c
@ -1,33 +1,47 @@
|
||||
#include <stdlib.h>
|
||||
#include "stack.h"
|
||||
|
||||
//TODO: grundlegende Stackfunktionen implementieren:
|
||||
/* * `push`: legt ein Element oben auf den Stack,
|
||||
* `pop`: entfernt das oberste Element,
|
||||
* `top`: liefert das oberste Element zurück,
|
||||
* `clearStack`: gibt den gesamten Speicher frei. */
|
||||
|
||||
// Pushes data as pointer onto the stack.
|
||||
StackNode *push(StackNode *stack, void *data)
|
||||
{
|
||||
StackNode *node = (StackNode *)malloc(sizeof(StackNode));
|
||||
if(node == NULL)
|
||||
return stack; // allocation failed -> return unchanged stack
|
||||
|
||||
node->data = data;
|
||||
node->next = stack;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
|
||||
// freed by caller.)
|
||||
StackNode *pop(StackNode *stack)
|
||||
{
|
||||
if(stack == NULL)
|
||||
return NULL;
|
||||
|
||||
StackNode *next = stack->next;
|
||||
// Do NOT free stack->data here; caller owns the pointed data
|
||||
free(stack);
|
||||
return next;
|
||||
}
|
||||
|
||||
// Returns the data of the top element.
|
||||
void *top(StackNode *stack)
|
||||
{
|
||||
|
||||
if(stack == NULL)
|
||||
return NULL;
|
||||
return stack->data;
|
||||
}
|
||||
|
||||
// Clears stack and releases all memory.
|
||||
void clearStack(StackNode *stack)
|
||||
{
|
||||
|
||||
while(stack != NULL)
|
||||
{
|
||||
StackNode *next = stack->next;
|
||||
// Do NOT free stack->data here; caller owns the pointed data
|
||||
free(stack);
|
||||
stack = next;
|
||||
}
|
||||
}
|
||||
7
stack.h
7
stack.h
@ -7,7 +7,12 @@ The latest element is taken from the stack. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//TODO: passenden Datentyp als struct anlegen
|
||||
// Stack node for linked-list based stack. Data pointer is stored but not freed by stack operations.
|
||||
typedef struct StackNode
|
||||
{
|
||||
void *data;
|
||||
struct StackNode *next;
|
||||
} StackNode;
|
||||
|
||||
// Pushes data as pointer onto the stack.
|
||||
StackNode *push(StackNode *stack, void *data);
|
||||
|
||||
BIN
test_bintree
Executable file
BIN
test_bintree
Executable file
Binary file not shown.
48
test_bintree.c
Normal file
48
test_bintree.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bintree.h"
|
||||
|
||||
// comparator for unsigned int values stored by value in heap
|
||||
static int cmp_uint_ptr(const void *a, const void *b)
|
||||
{
|
||||
unsigned int va = *(const unsigned int *)a;
|
||||
unsigned int vb = *(const unsigned int *)b;
|
||||
if(va < vb) return -1;
|
||||
if(va > vb) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
TreeNode *root = NULL;
|
||||
unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9};
|
||||
const size_t n = sizeof(vals)/sizeof(vals[0]);
|
||||
|
||||
// insert values (copy made by addToTree)
|
||||
for(size_t i = 0; i < n; i++)
|
||||
{
|
||||
int isDup = 0;
|
||||
root = addToTree(root, &vals[i], sizeof(unsigned int), cmp_uint_ptr, &isDup);
|
||||
if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; }
|
||||
}
|
||||
|
||||
unsigned int sz = treeSize(root);
|
||||
if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; }
|
||||
|
||||
// inorder traversal using nextTreeData
|
||||
unsigned int last = 0;
|
||||
int first = 1;
|
||||
unsigned int *data = nextTreeData(root);
|
||||
while(data != NULL)
|
||||
{
|
||||
unsigned int v = *data;
|
||||
if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; }
|
||||
last = v; first = 0;
|
||||
data = nextTreeData(NULL);
|
||||
}
|
||||
|
||||
clearTree(root);
|
||||
printf("test_bintree: OK\n");
|
||||
return 0;
|
||||
}
|
||||
20
test_bintree.dSYM/Contents/Info.plist
Normal file
20
test_bintree.dSYM/Contents/Info.plist
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.test_bintree</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
test_bintree.dSYM/Contents/Resources/DWARF/test_bintree
Normal file
BIN
test_bintree.dSYM/Contents/Resources/DWARF/test_bintree
Normal file
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
---
|
||||
triple: 'x86_64-apple-darwin'
|
||||
binary-path: test_bintree
|
||||
relocations:
|
||||
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000007A0, symSize: 0x220 }
|
||||
- { offset: 0x49, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000007A0, symSize: 0x220 }
|
||||
- { offset: 0x121, size: 0x8, addend: 0x0, symName: _cmp_uint_ptr, symObjAddr: 0x220, symBinAddr: 0x1000009C0, symSize: 0x5A }
|
||||
- { offset: 0x21B, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x100000A20, symSize: 0x1C0 }
|
||||
- { offset: 0x228, size: 0x8, addend: 0x0, symName: _nextTreeData, symObjAddr: 0x1C0, symBinAddr: 0x100000BE0, symSize: 0xC0 }
|
||||
- { offset: 0x24D, size: 0x8, addend: 0x0, symName: _nextTreeData.iterStack, symObjAddr: 0xFB0, symBinAddr: 0x100002000, symSize: 0x0 }
|
||||
- { offset: 0x2EC, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x100000A20, symSize: 0x1C0 }
|
||||
- { offset: 0x376, size: 0x8, addend: 0x0, symName: _bintree_pushLefts, symObjAddr: 0x280, symBinAddr: 0x100000CA0, symSize: 0x50 }
|
||||
- { offset: 0x3A8, size: 0x8, addend: 0x0, symName: _clearTree, symObjAddr: 0x2D0, symBinAddr: 0x100000CF0, symSize: 0x60 }
|
||||
- { offset: 0x3CC, size: 0x8, addend: 0x0, symName: _treeSize, symObjAddr: 0x330, symBinAddr: 0x100000D50, symSize: 0x56 }
|
||||
- { offset: 0x47F, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DB0, symSize: 0x60 }
|
||||
- { offset: 0x4C3, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DB0, symSize: 0x60 }
|
||||
- { offset: 0x507, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100000E10, symSize: 0x50 }
|
||||
- { offset: 0x53D, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100000E60, symSize: 0x40 }
|
||||
- { offset: 0x565, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100000EA0, symSize: 0x3F }
|
||||
...
|
||||
BIN
test_numbers
Executable file
BIN
test_numbers
Executable file
Binary file not shown.
41
test_numbers.c
Normal file
41
test_numbers.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "numbers.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned int len = 100;
|
||||
unsigned int *nums = createNumbers(len);
|
||||
if(nums == NULL) { fprintf(stderr, "createNumbers returned NULL\n"); return 1; }
|
||||
|
||||
// count occurrences
|
||||
unsigned int maxVal = 2 * len;
|
||||
unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int));
|
||||
if(counts == NULL) { free(nums); return 2; }
|
||||
|
||||
for(unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
if(nums[i] > maxVal) { fprintf(stderr, "value out of expected range\n"); free(nums); free(counts); return 3; }
|
||||
counts[nums[i]]++;
|
||||
}
|
||||
|
||||
int duplicatesFound = 0;
|
||||
unsigned int duplicateValue = 0;
|
||||
for(unsigned int v = 1; v <= maxVal; v++)
|
||||
{
|
||||
if(counts[v] == 2) { duplicatesFound++; duplicateValue = v; }
|
||||
else if(counts[v] > 2) { fprintf(stderr, "value %u appears more than twice\n", v); free(nums); free(counts); return 4; }
|
||||
}
|
||||
|
||||
if(duplicatesFound != 1) { fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound); free(nums); free(counts); return 5; }
|
||||
|
||||
unsigned int found = getDuplicate(nums, len);
|
||||
if(found != duplicateValue) { fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue); free(nums); free(counts); return 6; }
|
||||
|
||||
free(nums);
|
||||
free(counts);
|
||||
|
||||
printf("test_numbers: OK (duplicate = %u)\n", duplicateValue);
|
||||
return 0;
|
||||
}
|
||||
20
test_numbers.dSYM/Contents/Info.plist
Normal file
20
test_numbers.dSYM/Contents/Info.plist
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.test_numbers</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
test_numbers.dSYM/Contents/Resources/DWARF/test_numbers
Normal file
BIN
test_numbers.dSYM/Contents/Resources/DWARF/test_numbers
Normal file
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
---
|
||||
triple: 'x86_64-apple-darwin'
|
||||
binary-path: test_numbers
|
||||
relocations:
|
||||
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000013A0, symSize: 0x287 }
|
||||
- { offset: 0x41, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000013A0, symSize: 0x287 }
|
||||
- { offset: 0x12E, size: 0x8, addend: 0x0, symName: _createNumbers, symObjAddr: 0x0, symBinAddr: 0x100001630, symSize: 0x1D0 }
|
||||
- { offset: 0x152, size: 0x8, addend: 0x0, symName: _createNumbers, symObjAddr: 0x0, symBinAddr: 0x100001630, symSize: 0x1D0 }
|
||||
- { offset: 0x23E, size: 0x8, addend: 0x0, symName: _compareUInt, symObjAddr: 0x1D0, symBinAddr: 0x100001800, symSize: 0x60 }
|
||||
- { offset: 0x290, size: 0x8, addend: 0x0, symName: _getDuplicate, symObjAddr: 0x230, symBinAddr: 0x100001860, symSize: 0x110 }
|
||||
- { offset: 0x2FE, size: 0x8, addend: 0x0, symName: _qsort_uint_cmp, symObjAddr: 0x340, symBinAddr: 0x100001970, symSize: 0x5A }
|
||||
- { offset: 0x3C5, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x1000019D0, symSize: 0x1C0 }
|
||||
- { offset: 0x3D2, size: 0x8, addend: 0x0, symName: _nextTreeData, symObjAddr: 0x1C0, symBinAddr: 0x100001B90, symSize: 0xC0 }
|
||||
- { offset: 0x3F7, size: 0x8, addend: 0x0, symName: _nextTreeData.iterStack, symObjAddr: 0xFB0, symBinAddr: 0x100003000, symSize: 0x0 }
|
||||
- { offset: 0x496, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x1000019D0, symSize: 0x1C0 }
|
||||
- { offset: 0x520, size: 0x8, addend: 0x0, symName: _bintree_pushLefts, symObjAddr: 0x280, symBinAddr: 0x100001C50, symSize: 0x50 }
|
||||
- { offset: 0x552, size: 0x8, addend: 0x0, symName: _clearTree, symObjAddr: 0x2D0, symBinAddr: 0x100001CA0, symSize: 0x60 }
|
||||
- { offset: 0x576, size: 0x8, addend: 0x0, symName: _treeSize, symObjAddr: 0x330, symBinAddr: 0x100001D00, symSize: 0x56 }
|
||||
- { offset: 0x629, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100001D60, symSize: 0x60 }
|
||||
- { offset: 0x66D, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100001D60, symSize: 0x60 }
|
||||
- { offset: 0x6B1, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100001DC0, symSize: 0x50 }
|
||||
- { offset: 0x6E7, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100001E10, symSize: 0x40 }
|
||||
- { offset: 0x70F, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100001E50, symSize: 0x3F }
|
||||
...
|
||||
BIN
test_stack
Executable file
BIN
test_stack
Executable file
Binary file not shown.
44
test_stack.c
Normal file
44
test_stack.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "stack.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
StackNode *s = NULL;
|
||||
|
||||
// push 3 integers
|
||||
int *a = malloc(sizeof(int)); *a = 1; s = push(s, a);
|
||||
int *b = malloc(sizeof(int)); *b = 2; s = push(s, b);
|
||||
int *c = malloc(sizeof(int)); *c = 3; s = push(s, c);
|
||||
|
||||
// top should be c (3)
|
||||
int *topv = (int *)top(s);
|
||||
if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; }
|
||||
|
||||
// pop -> now top should be 2
|
||||
s = pop(s);
|
||||
topv = (int *)top(s);
|
||||
if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; }
|
||||
|
||||
// pop -> now top should be 1
|
||||
s = pop(s);
|
||||
topv = (int *)top(s);
|
||||
if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; }
|
||||
|
||||
// pop last
|
||||
s = pop(s);
|
||||
if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; }
|
||||
|
||||
// free stored data (stack does not free data)
|
||||
free(a); free(b); free(c);
|
||||
|
||||
// test clearStack on empty and small stacks
|
||||
s = push(s, malloc(sizeof(int)));
|
||||
s = push(s, malloc(sizeof(int)));
|
||||
clearStack(s); // clearStack must free nodes but not payload; free payloads not necessary because we leaked intentionally for test of API
|
||||
// Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash.
|
||||
// Success
|
||||
printf("test_stack: OK\n");
|
||||
return 0;
|
||||
}
|
||||
20
test_stack.dSYM/Contents/Info.plist
Normal file
20
test_stack.dSYM/Contents/Info.plist
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.test_stack</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
test_stack.dSYM/Contents/Resources/DWARF/test_stack
Normal file
BIN
test_stack.dSYM/Contents/Resources/DWARF/test_stack
Normal file
Binary file not shown.
@ -0,0 +1,12 @@
|
||||
---
|
||||
triple: 'x86_64-apple-darwin'
|
||||
binary-path: test_stack
|
||||
relocations:
|
||||
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x100000B80, symSize: 0x249 }
|
||||
- { offset: 0x4E, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x100000B80, symSize: 0x249 }
|
||||
- { offset: 0x10A, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DD0, symSize: 0x60 }
|
||||
- { offset: 0x14E, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DD0, symSize: 0x60 }
|
||||
- { offset: 0x192, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100000E30, symSize: 0x50 }
|
||||
- { offset: 0x1C8, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100000E80, symSize: 0x40 }
|
||||
- { offset: 0x1F0, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100000EC0, symSize: 0x3F }
|
||||
...
|
||||
Loading…
x
Reference in New Issue
Block a user