mirror of
https://github.com/sigmasternchen/crap-libs
synced 2025-03-15 07:38:56 +00:00
more interfaces, interface constructors + error message, instanceable filter + exception, and a few more things
This commit is contained in:
parent
f5d8997c2a
commit
155dbb607f
12 changed files with 145 additions and 17 deletions
|
@ -23,7 +23,10 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nremoving index %lu\n", list->length(list));
|
printf("\nremoving index %lu\n", list->length(list));
|
||||||
list->remove(list, list->length(list));
|
//list->remove(list, list->length(list));
|
||||||
|
//List_t* list2 = new List();
|
||||||
|
|
||||||
|
Object_t* obj = new Object();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "stdex.h"
|
#include "stdex.h"
|
||||||
#include "../memory.h"
|
#include "../memory.h"
|
||||||
#include "../try.h"
|
#include "../try.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -18,7 +17,7 @@ void method(Exception, populate)(Exception_t* obj, class_t c) {
|
||||||
Exception_t* method(Exception, construct)(const char* msg) {
|
Exception_t* method(Exception, construct)(const char* msg) {
|
||||||
throws(OutOfMemoryException_t);
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
sr_(Exception_t* obj = allocate_object(Exception_t), NULL);
|
sr_(Exception_t* obj = allocate_object(Exception), NULL);
|
||||||
populate(Exception)(obj, Exception_class);
|
populate(Exception)(obj, Exception_class);
|
||||||
|
|
||||||
obj->msg = msg;
|
obj->msg = msg;
|
||||||
|
@ -39,7 +38,7 @@ void method(NullPointerException, populate)(NullPointerException_t* obj, class_t
|
||||||
NullPointerException_t* method(NullPointerException, construct)() {
|
NullPointerException_t* method(NullPointerException, construct)() {
|
||||||
throws(OutOfMemoryException_t);
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
sr_(NullPointerException_t* obj = allocate_object(NullPointerException_t), NULL);
|
sr_(NullPointerException_t* obj = allocate_object(NullPointerException), NULL);
|
||||||
populate(NullPointerException)(obj, NullPointerException_class);
|
populate(NullPointerException)(obj, NullPointerException_class);
|
||||||
|
|
||||||
obj->super.msg = "Unexpected Null-pointer.";
|
obj->super.msg = "Unexpected Null-pointer.";
|
||||||
|
@ -84,7 +83,7 @@ void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t* ob
|
||||||
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t index, size_t length) {
|
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t index, size_t length) {
|
||||||
throws(OutOfMemoryException_t);
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
sr_(IndexOutOfBoundsException_t* obj = allocate_object(IndexOutOfBoundsException_t), NULL);
|
sr_(IndexOutOfBoundsException_t* obj = allocate_object(IndexOutOfBoundsException), NULL);
|
||||||
populate(IndexOutOfBoundsException)(obj, IndexOutOfBoundsException_class);
|
populate(IndexOutOfBoundsException)(obj, IndexOutOfBoundsException_class);
|
||||||
|
|
||||||
const char* format = "Requested index %i is out of bounds (%i).";
|
const char* format = "Requested index %i is out of bounds (%i).";
|
||||||
|
@ -102,3 +101,52 @@ IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class_t IllegalArgumentException_class;
|
||||||
|
void method(IllegalArgumentException, destruct)(IllegalArgumentException_t* this) {
|
||||||
|
this->super.destruct((Exception_t*) this);
|
||||||
|
}
|
||||||
|
void method(IllegalArgumentException, populate)(IllegalArgumentException_t* obj, class_t c) {
|
||||||
|
populate(Exception)((Exception_t*) obj, c);
|
||||||
|
|
||||||
|
add_method(obj, IllegalArgumentException, destruct);
|
||||||
|
}
|
||||||
|
IllegalArgumentException_t* method(IllegalArgumentException, construct)(const char* msg) {
|
||||||
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
|
sr_(IllegalArgumentException_t* obj = allocate_object(IllegalArgumentException), NULL);
|
||||||
|
populate(IllegalArgumentException)(obj, IllegalArgumentException_class);
|
||||||
|
|
||||||
|
obj->super.msg = msg;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_t ClassNotInstanceableException_class;
|
||||||
|
void method(ClassNotInstanceableException, destruct)(ClassNotInstanceableException_t* this) {
|
||||||
|
free((void*) this->super.msg);
|
||||||
|
|
||||||
|
this->super.destruct((Exception_t*) this);
|
||||||
|
}
|
||||||
|
void method(ClassNotInstanceableException, populate)(ClassNotInstanceableException_t* obj, class_t c) {
|
||||||
|
populate(Exception)((Exception_t*) obj, c);
|
||||||
|
|
||||||
|
add_method(obj, ClassNotInstanceableException, destruct);
|
||||||
|
}
|
||||||
|
ClassNotInstanceableException_t* method(ClassNotInstanceableException, construct)(const char* c) {
|
||||||
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
|
sr_(ClassNotInstanceableException_t* obj = allocate_object(ClassNotInstanceableException), NULL);
|
||||||
|
populate(ClassNotInstanceableException)(obj, ClassNotInstanceableException_class);
|
||||||
|
|
||||||
|
const char* format = "Class %s is not instanceable.";
|
||||||
|
size_t size = strlen(format) - 2 + strlen(c);
|
||||||
|
|
||||||
|
sr_(char* msg = allocate(size + 1), NULL);
|
||||||
|
|
||||||
|
snprintf(msg, size + 1, format, c);
|
||||||
|
|
||||||
|
obj->super.msg = msg;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
|
@ -45,4 +45,24 @@ extern class(IndexOutOfBoundsException, Exception_class, NO_INTERFACES, true) {
|
||||||
void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t);
|
void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t);
|
||||||
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t);
|
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t);
|
||||||
|
|
||||||
|
#define IllegalArgumentException construct(IllegalArgumentException)
|
||||||
|
extern class(IllegalArgumentException, Exception_class, NO_INTERFACES, true) {
|
||||||
|
extends(Exception_t);
|
||||||
|
|
||||||
|
void (*destruct)(defclass IllegalArgumentException*);
|
||||||
|
} IllegalArgumentException_t;
|
||||||
|
|
||||||
|
void method(IllegalArgumentException, populate)(IllegalArgumentException_t*, class_t);
|
||||||
|
IllegalArgumentException_t* method(IllegalArgumentException, construct)(const char*);
|
||||||
|
|
||||||
|
#define ClassNotInstanceableException construct(ClassNotInstanceableException)
|
||||||
|
extern class(ClassNotInstanceableException, Exception_class, NO_INTERFACES, true) {
|
||||||
|
extends(Exception_t);
|
||||||
|
|
||||||
|
void (*destruct)(defclass ClassNotInstanceableException*);
|
||||||
|
} ClassNotInstanceableException_t;
|
||||||
|
|
||||||
|
void method(ClassNotInstanceableException, populate)(ClassNotInstanceableException_t*, class_t);
|
||||||
|
ClassNotInstanceableException_t* method(ClassNotInstanceableException, construct)(const char*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,7 @@ class_t ArrayList_class;
|
||||||
ArrayList_t* method(ArrayList, construct)(void) {
|
ArrayList_t* method(ArrayList, construct)(void) {
|
||||||
throws(OutOfMemoryException_t);
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
sr_(ArrayList_t* list = allocate_object(ArrayList_t), NULL);
|
sr_(ArrayList_t* list = allocate_object(ArrayList), NULL);
|
||||||
populate(ArrayList)(list, ArrayList_class);
|
populate(ArrayList)(list, ArrayList_class);
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
class_t Countable_class;
|
class_t Countable_class;
|
||||||
class_t List_class;
|
class_t List_class;
|
||||||
class_t Stack_class;
|
class_t Stack_class;
|
||||||
|
class_t Iterateable_class;
|
||||||
|
|
|
@ -3,11 +3,33 @@
|
||||||
|
|
||||||
#include "../oop.h"
|
#include "../oop.h"
|
||||||
|
|
||||||
|
typedef Object_t Countable_t;
|
||||||
extern interface(Countable)
|
extern interface(Countable)
|
||||||
#define Countable_interface size_t (*length)(void*);
|
#define Countable_interface size_t (*length)(void*);
|
||||||
|
#define Countable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Countable.\"");
|
||||||
|
|
||||||
|
typedef Object_t List_t;
|
||||||
extern interface(List)
|
extern interface(List)
|
||||||
#define List_interface void (*add)(void*, void*); void* (*get)(void*, size_t); void (*remove)(void*, size_t);
|
#define List_interface void (*add)(void*, void*); void* (*get)(void*, size_t); void (*remove)(void*, size_t);
|
||||||
|
#define List(...) NULL; _Pragma("GCC error \"Cannot make instance of interface List.\"");
|
||||||
|
|
||||||
|
typedef Object_t Stack_t;
|
||||||
extern interface(Stack)
|
extern interface(Stack)
|
||||||
#define Stack_interface void (*push)(void*, void*); void* (*pop)(void*);
|
#define Stack_interface void (*push)(void*, void*); void* (*pop)(void*);
|
||||||
|
#define Stack(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Stack.\"");
|
||||||
|
|
||||||
|
typedef struct iterator_args {
|
||||||
|
void* list;
|
||||||
|
void* parameter;
|
||||||
|
void* obj;
|
||||||
|
int num; // -1 if no id
|
||||||
|
} iterator_args;
|
||||||
|
|
||||||
|
typedef bool (*iterator)(iterator_args);
|
||||||
|
|
||||||
|
typedef Object_t Iterateable_t;
|
||||||
|
extern interface(Iterateable)
|
||||||
|
#define Iterateable_interface bool (*iterate)(void*, iterator, void*)
|
||||||
|
#define Iterateable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Iterateable.\"");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
22
memory.c
22
memory.c
|
@ -5,33 +5,41 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void allocate_sub(size_t size, void** ptr) { throws(Exception_t);
|
void allocate_sub(size_t size, void** ptr) { throws(OutOfMemoryException_t);
|
||||||
*ptr = malloc(size);
|
*ptr = malloc(size);
|
||||||
if (*ptr == NULL) {
|
if (*ptr == NULL) {
|
||||||
throw(new Exception(strerror(errno)));
|
throw(new OutOfMemoryException());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* allocate(size_t size) { throws(Exception_t);
|
void* allocate_o(class_t c, size_t size) { throws(OutOfMemoryException_t, ClassNotInstanceableException_t);
|
||||||
|
if (!oop_is_instanceable(c))
|
||||||
|
throwr(new ClassNotInstanceableException(oop_get_class_name(c)), NULL);
|
||||||
void* ptr;
|
void* ptr;
|
||||||
sr_(allocate_sub(size, &ptr), NULL);
|
sr_(allocate_sub(size, &ptr), NULL);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reallocate_sub(size_t size, void** ptr, void* old) { throws(Exception_t);
|
void* allocate(size_t size) { throws(OutOfMemoryException_t);
|
||||||
|
void* ptr;
|
||||||
|
sr_(allocate_sub(size, &ptr), NULL);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reallocate_sub(size_t size, void** ptr, void* old) { throws(OutOfMemoryException_t);
|
||||||
*ptr = realloc(old, size);
|
*ptr = realloc(old, size);
|
||||||
if (*ptr == NULL) {
|
if (*ptr == NULL) {
|
||||||
throw(new Exception(strerror(errno)));
|
throw(new OutOfMemoryException());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* reallocate(void* old, size_t size) { throws(Exception_t);
|
void* reallocate(void* old, size_t size) { throws(OutOfMemoryException_t);
|
||||||
void* ptr;
|
void* ptr;
|
||||||
sr_(reallocate_sub(size, &ptr, old), NULL);
|
sr_(reallocate_sub(size, &ptr, old), NULL);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* clone(const void* org, size_t size) { throws(Exception_t);
|
void* clone(const void* org, size_t size) { throws(OutOfMemoryException_t);
|
||||||
void* ptr;
|
void* ptr;
|
||||||
sr_(allocate_sub(size, &ptr), NULL);
|
sr_(allocate_sub(size, &ptr), NULL);
|
||||||
memcpy(ptr, org, size);
|
memcpy(ptr, org, size);
|
||||||
|
|
7
memory.h
7
memory.h
|
@ -4,11 +4,16 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define allocate_object(type) allocate(sizeof(type));
|
#include "oop.h"
|
||||||
|
#include "try.h"
|
||||||
|
#include "exceptions/stdex.h"
|
||||||
|
|
||||||
|
#define allocate_object(type) allocate_o(type##_class, sizeof(type##_t));
|
||||||
|
|
||||||
#define clone_string(s) clone((void*) s, strlen(s) + 1)
|
#define clone_string(s) clone((void*) s, strlen(s) + 1)
|
||||||
#define clone_obj(obj, class) clone((void*) obj, sizeof(class))
|
#define clone_obj(obj, class) clone((void*) obj, sizeof(class))
|
||||||
|
|
||||||
|
void* allocate_o(class_t, size_t);
|
||||||
void* allocate(size_t);
|
void* allocate(size_t);
|
||||||
void* reallocate(void*, size_t);
|
void* reallocate(void*, size_t);
|
||||||
void* clone(const void*, size_t);
|
void* clone(const void*, size_t);
|
||||||
|
|
14
oop.c
14
oop.c
|
@ -78,6 +78,10 @@ bool oop_class_exists(const char* class_name) {
|
||||||
return oop_id_from_name(class_name) != NO_CLASS_ID;
|
return oop_id_from_name(class_name) != NO_CLASS_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool oop_is_instanceable(class_t c) {
|
||||||
|
return classes[c.id].instanceable;
|
||||||
|
}
|
||||||
|
|
||||||
class_t oop_class_from_id(class_id_t id) {
|
class_t oop_class_from_id(class_id_t id) {
|
||||||
return (class_t) {.id = id};
|
return (class_t) {.id = id};
|
||||||
}
|
}
|
||||||
|
@ -90,12 +94,20 @@ class_t oop_get_class_from_obj(Object_t* obj) {
|
||||||
return oop_class_from_id(((Object_t*) obj)->meta_obj.type.id);
|
return oop_class_from_id(((Object_t*) obj)->meta_obj.type.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void oop_check_interface(class_t c, Object_t* obj) {
|
||||||
|
throws(IllegalArgumentException_t);
|
||||||
|
|
||||||
|
if (!instanceof(obj, c))
|
||||||
|
throw(new IllegalArgumentException("Object is not instance of interface."));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// defined by class macro in h-file
|
// defined by class macro in h-file
|
||||||
class_t Object_class;
|
class_t Object_class;
|
||||||
|
|
||||||
// defined by interface macro in h-file
|
// defined by interface macro in h-file
|
||||||
class_t Cloneable_class;
|
class_t Cloneable_class;
|
||||||
|
class_t Compareable_class;
|
||||||
|
|
||||||
|
|
||||||
void method(Object, destruct)(Object_t* obj) {
|
void method(Object, destruct)(Object_t* obj) {
|
||||||
|
@ -103,7 +115,7 @@ void method(Object, destruct)(Object_t* obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Object_t* method(Object, construct)() { throws(OutOfMemoryException_t);
|
Object_t* method(Object, construct)() { throws(OutOfMemoryException_t);
|
||||||
sr_(Object_t* obj = allocate_object(Object_t), NULL);
|
sr_(Object_t* obj = allocate_object(Object), NULL);
|
||||||
populate(Object)(obj, Object_class);
|
populate(Object)(obj, Object_class);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
9
oop.h
9
oop.h
|
@ -59,13 +59,18 @@ typedef struct meta_object {
|
||||||
class_id_t oop_add_class(const char*, bool, class_t, iflist_t, bool);
|
class_id_t oop_add_class(const char*, bool, class_t, iflist_t, bool);
|
||||||
|
|
||||||
#define Object construct(Object)
|
#define Object construct(Object)
|
||||||
extern class(Object, NO_SUPER_CLASS, NO_INTERFACES, true) {
|
extern class(Object, NO_SUPER_CLASS, NO_INTERFACES, false) {
|
||||||
meta_object_t meta_obj;
|
meta_object_t meta_obj;
|
||||||
void (*destruct)(defclass Object*);
|
void (*destruct)(defclass Object*);
|
||||||
} Object_t;
|
} Object_t;
|
||||||
|
|
||||||
extern interface(Cloneable)
|
extern interface(Cloneable)
|
||||||
#define Cloneable_interface void*(*clone)(void*)
|
#define Cloneable_interface void*(*clone)(void*)
|
||||||
|
#define Cloneable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Cloneable.\"");
|
||||||
|
|
||||||
|
extern interface(Compareable)
|
||||||
|
#define Compareable_interface int(*compare)(void*)
|
||||||
|
#define Compareable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Compareable.\"");
|
||||||
|
|
||||||
bool oop_instance_of_id(void*, class_id_t);
|
bool oop_instance_of_id(void*, class_id_t);
|
||||||
bool oop_instance_of(void*, class_t);
|
bool oop_instance_of(void*, class_t);
|
||||||
|
@ -74,7 +79,9 @@ class_id_t oop_id_from_name(const char*);
|
||||||
bool oop_class_exists(const char*);
|
bool oop_class_exists(const char*);
|
||||||
class_t oop_class_from_id(class_id_t);
|
class_t oop_class_from_id(class_id_t);
|
||||||
class_t oop_get_super_class(class_t);
|
class_t oop_get_super_class(class_t);
|
||||||
|
bool oop_is_instanceable(class_t);
|
||||||
class_t oop_get_class_from_obj(Object_t*);
|
class_t oop_get_class_from_obj(Object_t*);
|
||||||
|
void oop_check_interface(class_t, Object_t*);
|
||||||
|
|
||||||
Object_t* method(Object, construct)(void);
|
Object_t* method(Object, construct)(void);
|
||||||
void method(Object, populate)(Object_t* obj, class_t);
|
void method(Object, populate)(Object_t* obj, class_t);
|
||||||
|
|
|
@ -91,7 +91,7 @@ const char* method(Strbuilder, get)(Strbuilder_t* this) {
|
||||||
Strbuilder_t* method(Strbuilder, construct)(const char* string) {
|
Strbuilder_t* method(Strbuilder, construct)(const char* string) {
|
||||||
throws(OutOfMemoryException_t);
|
throws(OutOfMemoryException_t);
|
||||||
|
|
||||||
sr_(Strbuilder_t* obj = allocate_object(Strbuilder_t), NULL);
|
sr_(Strbuilder_t* obj = allocate_object(Strbuilder), NULL);
|
||||||
|
|
||||||
populate(Strbuilder)(obj, Strbuilder_class);
|
populate(Strbuilder)(obj, Strbuilder_class);
|
||||||
|
|
||||||
|
|
2
try.c
2
try.c
|
@ -109,6 +109,8 @@ void try_throw(try_t id, void* exception) {
|
||||||
e->msg);
|
e->msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
e->destruct(); // destruct of exception (not sub classes), because we don't know what this is
|
||||||
|
|
||||||
_print_backtrace(stderr, 2);
|
_print_backtrace(stderr, 2);
|
||||||
} else {
|
} else {
|
||||||
trys[id].exception = exception;
|
trys[id].exception = exception;
|
||||||
|
|
Loading…
Reference in a new issue