arraylists + relocation of strbuilder

This commit is contained in:
overflowerror 2017-03-12 01:18:08 +01:00
parent fe1db529a2
commit 057b059343
15 changed files with 290 additions and 12 deletions

View file

@ -12,22 +12,28 @@ LIBFLAGS = -shared $(DEFS)
.PHONY: all clean
all: libcrap.so
all: example libcrap.so
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
example: example.o memory.o try.o oop.o exceptions/stdex.o
example: example.o memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o
$(CC) $(LDFLAGS) -o $@ $^
libcrap.so: memory.o try.o oop.o exceptions/stdex.o
libcrap.so: memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o
$(CC) $(LIBFLAGS) -o $@ $^
example.o: example.c try.h
memory.o: memory.c memory.h oop.h exceptions/stdex.h
try.o: try.c try.h oop.h exceptions/stdex.h
oop.o: oop.h misc.h
exceptions/stdex.o: exceptions/stdex.c exceptions/stdex.h
tools/strbuilder.o: tools/strbuilder.c tools/strbuilder.h exceptions/stdex.h
lists/lists.o: lists/lists.c lists/lists.h oop.h
lists/arraylist.o: lists/arraylist.c lists/arraylist.h oop.h
clean:
rm -f *.o exceptions/*.o example
rm -f *.o exceptions/*.o tools/*.o lists/*.o example

5
crap.h
View file

@ -3,3 +3,8 @@
#include "memory.h"
#include "exceptions/stdex.h"
#include "misc.h"
#include "tools/strbuilder.h"
#include "lists/lists.h"
#include "lists/arraylist.h"

View file

@ -1,6 +1,29 @@
#include "crap.h"
#include <stdio.h>
int main(void) {
ArrayList_t* list = new ArrayList();
printf("adding some strings\n");
list->add(list, "Hallo");
list->add(list, "Welt");
list->add(list, "Hello");
list->add(list, "World");
for (size_t i = 0; i < list->length(list); i++) {
printf("%lu: %s\n", i, (const char*) list->get(list, i));
}
printf("\nremoving index 0\n");
list->remove(list, 0);
for (size_t i = 0; i < list->length(list); i++) {
printf("%lu: %s\n", i, (const char*) list->get(list, i));
}
printf("\nremoving index %lu\n", list->length(list));
list->remove(list, list->length(list));
return 0;
}

View file

@ -33,8 +33,6 @@ void method(NullPointerException, destruct)(NullPointerException_t* this) {
}
void method(NullPointerException, populate)(NullPointerException_t* obj, class_t c) {
populate(Exception)((Exception_t*) obj, c);
obj->super.msg = "Unexpected Null-pointer.";
add_method(obj, NullPointerException, destruct);
}
@ -43,6 +41,8 @@ NullPointerException_t* method(NullPointerException, construct)() {
sr_(NullPointerException_t* obj = allocate_object(NullPointerException_t), NULL);
populate(NullPointerException)(obj, NullPointerException_class);
obj->super.msg = "Unexpected Null-pointer.";
return obj;
}
@ -54,8 +54,6 @@ void method(OutOfMemoryException, destruct)(OutOfMemoryException_t* this) {
}
void method(OutOfMemoryException, populate)(OutOfMemoryException_t* obj, class_t c) {
populate(Exception)((Exception_t*) obj, c);
obj->super.msg = "Could not allocate memory.";
add_method(obj, OutOfMemoryException, destruct);
}
@ -68,5 +66,39 @@ OutOfMemoryException_t* method(OutOfMemoryException, construct)() {
populate(OutOfMemoryException)(obj, OutOfMemoryException_class);
obj->super.msg = "Could not allocate memory.";
return obj;
}
class_t IndexOutOfBoundsException_class;
void method(IndexOutOfBoundsException, destruct)(IndexOutOfBoundsException_t* this) {
free((void*) this->super.msg); // I don't like C.
this->super.destruct((Exception_t*) this);
}
void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t* obj, class_t c) {
populate(Exception)((Exception_t*) obj, c);
add_method(obj, IndexOutOfBoundsException, destruct);
}
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t index, size_t length) {
throws(OutOfMemoryException_t);
sr_(IndexOutOfBoundsException_t* obj = allocate_object(IndexOutOfBoundsException_t), NULL);
populate(IndexOutOfBoundsException)(obj, IndexOutOfBoundsException_class);
const char* format = "Requested index %i is out of bounds (%i).";
size_t len = strlen(format) - 4; // 2x "%i"
for(int i = index; i > 0; i /= 10)
len++;
for(int i = length; i > 0; i /= 10)
len++;
sr_(char* msg = allocate(len + 1), NULL);
snprintf(msg, len + 1, format, index, length);
obj->super.msg = msg;
return obj;
}

View file

@ -35,4 +35,14 @@ extern class(OutOfMemoryException, Exception_class, NO_INTERFACES, true) {
void method(OutOfMemoryException, populate)(OutOfMemoryException_t*, class_t);
OutOfMemoryException_t* method(OutOfMemoryException, construct)(void);
#define IndexOutOfBoundsException construct(IndexOutOfBoundsException)
extern class(IndexOutOfBoundsException, Exception_class, NO_INTERFACES, true) {
extends(Exception_t);
void (*destruct)(defclass IndexOutOfBoundsException*);
} IndexOutOfBoundsException_t;
void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t);
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t);
#endif

BIN
exceptions/stdex.o Normal file

Binary file not shown.

126
lists/arraylist.c Normal file
View file

@ -0,0 +1,126 @@
#include "arraylist.h"
#include "lists.h"
#include "../oop.h"
#include "../try.h"
#include "../exceptions/stdex.h"
#include "../memory.h"
#include <stdlib.h>
#define DEFAULT_SIZE_STEP 64
#define to_list(name, obj) ArrayList_t* name = (ArrayList_t*) obj
class_t ArrayList_class;
ArrayList_t* method(ArrayList, construct)(void) {
throws(OutOfMemoryException_t);
sr_(ArrayList_t* list = allocate_object(ArrayList_t), NULL);
populate(ArrayList)(list, ArrayList_class);
return list;
}
size_t method(ArrayList, length)(void* this) {
to_list(list, this);
return list->currentSize;
}
void method(ArrayList, add)(void* this, void* obj) {
throws(NullPointerException_t, OutOfMemoryException_t);
if (this == NULL)
throw(new NullPointerException());
to_list(list, this);
if (list->data == NULL) {
s_(list->data = allocate(++list->steps * list->sizeStep * sizeof(void*)));
}
if (list->currentSize + 1 >= list->steps * list->sizeStep) {
s_(list->data = reallocate(list->data, ++list->steps * list->sizeStep * sizeof(void*)));
}
list->data[list->currentSize++] = obj;
}
void* method(ArrayList, get)(void* this, size_t index) {
throws(NullPointerException_t, IndexOutOfBoundsException_t);
if (this == NULL)
throwr(new NullPointerException(), NULL);
to_list(list, this);
if (index >= list->currentSize)
throwr(new IndexOutOfBoundsException(index, list->currentSize), NULL);
return list->data[index];
}
void method(ArrayList, remove)(void* this, size_t index) {
throws(NullPointerException_t, OutOfMemoryException_t);
if (this == NULL)
throw(new NullPointerException());
to_list(list, this);
if (index >= list->currentSize)
throw(new IndexOutOfBoundsException(index, list->currentSize));
for(size_t i = index; i < list->currentSize - 1; i++) {
list->data[i] = list->data[i + 1];
}
if (--list->currentSize < (list->steps - 1) * list->sizeStep) {
s_(list->data = reallocate(list->data, --list->steps * list->sizeStep * sizeof(void*)));
}
}
void method(ArrayList, push)(void* this, void* obj) {
throws(NullPointerException_t);
if (this == NULL)
throw(new NullPointerException());
to_list(list, this);
list->add(list, obj);
}
void* method(ArrayList, pop)(void* this) {
throws(NullPointerException_t, OutOfMemoryException_t);
if (this == NULL)
throwr(new NullPointerException(), NULL);
to_list(list, this);
int size = list->currentSize;
sr_(void* element = list->get(this, size - 1), NULL);
sr_(list->remove(this, size - 1), NULL);
return element;
}
void method(ArrayList, destruct)(ArrayList_t* this) {
throws(NullPointerException_t);
if (this == NULL)
throw(new NullPointerException());
}
void method(ArrayList, populate)(ArrayList_t* obj, class_t c) {
populate(Object)((Object_t*) obj, c);
obj->data = NULL;
obj->currentSize = 0;
obj->steps = 0;
obj->sizeStep = DEFAULT_SIZE_STEP;
add_method(obj, ArrayList, destruct);
add_method(obj, ArrayList, length);
add_method(obj, ArrayList, add);
add_method(obj, ArrayList, get);
add_method(obj, ArrayList, remove);
add_method(obj, ArrayList, push);
add_method(obj, ArrayList, pop);
}

25
lists/arraylist.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef ARRAYLIST_H
#define ARRAYLIST_H
#include "../oop.h"
#include "lists.h"
#define ArrayList construct(ArrayList)
extern class(ArrayList, Object_class, (interfaces){4 namely {Cloneable_class and List_class and Countable_class and Stack_class}}, true) {
extends(Object_t);
implements(Cloneable);
implements(List);
implements(Countable);
implements(Stack);
void (*destruct)(defclass ArrayList*);
size_t currentSize;
size_t sizeStep;
int steps;
void** data;
} ArrayList_t;
ArrayList_t* method(ArrayList, construct)(void);
void method(ArrayList, populate)(ArrayList_t*, class_t);
#endif

BIN
lists/arraylist.o Normal file

Binary file not shown.

5
lists/lists.c Normal file
View file

@ -0,0 +1,5 @@
#include "lists.h"
class_t Countable_class;
class_t List_class;
class_t Stack_class;

13
lists/lists.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef LISTS_H
#define LISTS_H
#include "../oop.h"
extern interface(Countable)
#define Countable_interface size_t (*length)(void*);
extern interface(List)
#define List_interface void (*add)(void*, void*); void* (*get)(void*, size_t); void (*remove)(void*, size_t);
extern interface(Stack)
#define Stack_interface void (*push)(void*, void*); void* (*pop)(void*);
#endif

BIN
lists/lists.o Normal file

Binary file not shown.

View file

@ -1,5 +1,7 @@
#include "strbuilder.h"
#include "../memory.h"
#include "../try.h"
#include "../exceptions/stdex.h"
#include <string.h>
#include <stdbool.h>
@ -7,6 +9,11 @@
class_t Strbuilder_class;
void method(Strbuilder, clear)(Strbuilder_t* this) {
throws(NullPointerException_t);
if (this == NULL)
throw(new NullPointerException());
for (int i = 0; i < this->nrstrings; i++) {
free(this->strings[i]);
}
@ -16,12 +23,20 @@ void method(Strbuilder, clear)(Strbuilder_t* this) {
}
void method(Strbuilder, destruct)(Strbuilder_t* this) {
throws(NullPointerException_t);
if (this == NULL)
throw(new NullPointerException());
this->clear(this);
this->super.destruct((Object_t*) this);
}
void method(Strbuilder, add)(Strbuilder_t* this, const char* string) {
throws(OutOfMemoryException_t);
throws(OutOfMemoryException_t, NullPointerException_t);
if (this == NULL || string == NULL)
throw(new NullPointerException());
s_(this->strings = reallocate(this->strings, ++this->nrstrings * sizeof(char*)));
s_(this->strings[this->nrstrings - 1] = allocate(strlen(string) + 1));
@ -29,6 +44,11 @@ void method(Strbuilder, add)(Strbuilder_t* this, const char* string) {
}
size_t method(Strbuilder, length)(Strbuilder_t* this) {
throws(NullPointerException_t);
if (this == NULL)
throwr(new NullPointerException(), 0);
size_t length = 0;
if (this->string != NULL)
length = strlen(this->string);
@ -39,7 +59,10 @@ size_t method(Strbuilder, length)(Strbuilder_t* this) {
}
void method(Strbuilder, build)(Strbuilder_t* this) {
throws(OutOfMemoryException_t);
throws(OutOfMemoryException_t, NullPointerException_t);
if (this == NULL)
throw(new NullPointerException());
size_t length = this->length(this);
bool empty = this->string == NULL;
@ -54,6 +77,14 @@ void method(Strbuilder, build)(Strbuilder_t* this) {
}
const char* method(Strbuilder, get)(Strbuilder_t* this) {
throws(NullPointerException_t);
if (this == NULL)
throwr(new NullPointerException(), NULL);
if (this->string == NULL)
return "";
return this->string;
}
@ -64,8 +95,10 @@ Strbuilder_t* method(Strbuilder, construct)(const char* string) {
populate(Strbuilder)(obj, Strbuilder_class);
sr_(obj->string = allocate(strlen(string) + 1), NULL);
strcpy(obj->string, string);
if (string != NULL) {
sr_(obj->string = allocate(strlen(string) + 1), NULL);
strcpy(obj->string, string);
}
return obj;
}

BIN
tools/strbuilder.o Normal file

Binary file not shown.