From 54042cf2cfa9849641664e06767997abaab9e6a1 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 6 Jun 2024 02:22:54 +0800 Subject: [PATCH] (FEA) Featured for Location_Literalisation, Status_Literalisation etc. --- .gitignore | 3 + Array/include/array.h | 23 ++- Array/src/array.c | 8 +- CMakeLists.txt | 3 +- Classes/integer.h | 50 +++++ Function/include/functiondecls.h | 0 Function/include/functiondefs.h | 0 MemMan/include/memman.h | 39 ++-- MemMan/src/memman.c | 98 ++++++--- Object/include/object.h | 161 ++++++++------- Stack/src/stack.c | 2 +- Status/include/status.h | 328 ++++++++++++++++++++++--------- Status/src/status.c | 173 ++++++++++------ String/include/string.h | 2 +- String/src/string.c | 43 ++-- Utils/include/utils.h | 4 + Utils/src/utils.c | 1 + Var/include/var.h | 4 + Var/src/var.c | 28 +-- attr.h | 9 - catlog.c | 6 +- class.h | 33 ++++ common.h | 47 ++++- install | 4 +- interface.h | 8 + name.h | 5 +- namescope.c | 16 +- namescope.h | 4 + 28 files changed, 744 insertions(+), 358 deletions(-) create mode 100644 Classes/integer.h create mode 100644 Function/include/functiondecls.h create mode 100644 Function/include/functiondefs.h create mode 100644 class.h create mode 100644 interface.h diff --git a/.gitignore b/.gitignore index 32167d4..36fd2c2 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ sample compile ======= >>>>>>> refs/remotes/master/master +.vscode/ +todo +vsc* diff --git a/Array/include/array.h b/Array/include/array.h index 6484650..a1b5e10 100644 --- a/Array/include/array.h +++ b/Array/include/array.h @@ -8,17 +8,20 @@ typedef struct { Var *members; } Array; -static Status ArrayIndexOutOfBound = { - .description = "Given index was accessing illegal address.", - .characteristic = STATUS_ERROR, - .prev = &MemoryViolation -}; +# define ArrayIndexOutOfBound = (Status){\ + .identity = nameof(ArrayIndexOutOfBound),\ + .value = 1,\ + .description = "Given index was accessing illegal address.",\ + .characteristic = STATUS_ERROR,\ + .prev = &MemoryViolation\ +} -static Status InvalidArrayLength = { - .description = "Given length is invalid.", - .characteristic = STATUS_ERROR, - .prev = &ErrorStatus -}; +# define InvalidArrayLength (Status){\ + .value = 1,\ + .description = "Given length is invalid.",\ + .characteristic = STATUS_ERROR,\ + .prev = &ErrorStatus\ +} /* Elementary. */ Status Array_Create(Array *inst, int len, size_t size) diff --git a/Array/src/array.c b/Array/src/array.c index ffe9a15..b5a8197 100644 --- a/Array/src/array.c +++ b/Array/src/array.c @@ -13,7 +13,9 @@ Status Array_Create(Array *inst, int len, size_t size) int erridx = -1; for (register int i = 0; i < len; i++) { // TODO(william): Throw InsufficientMemory at following line. - solve(!StatusUtils_IsOkay(Var_Create(&inst->members[i], size)), { + // DONE(william): ensure(Var_Create(&inst->members[i], size), "Failed to create a new var."); + + notok((Var_Create(&inst->members[i], size)), { #ifdef __DEBUG__ cat("Var_Create failed!\n") #endif @@ -25,7 +27,7 @@ Status Array_Create(Array *inst, int len, size_t size) #endif }) } - + /* Review on erridx. Release data that allocated. */ if (erridx != -1) { for (register int i = erridx; i >= 0; i--) { @@ -99,7 +101,7 @@ Status Array_GetIdx(Array *inst, Var *store, int index) /* Skip unavailable inst and invalid param. */ fails(inst, UnavailableInstance); fails(store, error(InvalidParameter, "Given reference to store was " - "unavailable.")); + "unavailable.")); state((index < 0 || index >= inst->len), ArrayIndexOutOfBound); *store = inst->members[index]; diff --git a/CMakeLists.txt b/CMakeLists.txt index b8fa64c..d769cc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,7 @@ LINK_LIBRARIES(m) add_executable(CompoundTest test.c - Var/src/var.c - Array/src/array.c + MemMan/src/memman.c Status/src/status.c Utils/src/utils.c catlog.c) diff --git a/Classes/integer.h b/Classes/integer.h new file mode 100644 index 0000000..c704309 --- /dev/null +++ b/Classes/integer.h @@ -0,0 +1,50 @@ +#ifndef COMPOUND_CLASSES_INTEGER_H +# define COMPOUND_CLASSES_INTEGER_H + +# include + +typedef Class Integer; + +/* + typedef struct { + String identity; + + Array type(DynStruct) structs; + Array type(DynUnion) unions; + Array type(DynEnum) enums; + Array type(FunctionPointer) functionptrs; + Array type(Field) fields; + + // Interface[] *implementations + Array type(Var type(Interface)) *implementations; + // Class *predecessor + Var type(Class) *predecessor; + } Class; +*/ + +/* STATIC INSTANCE OPERATIONS. */ +Status Integer_Create(Integer *inst, Var *value); +Status Integer_FromInt(Integer *inst, int *value); +Status Integer_FromUnsignedInt(Integer *inst, unsigned int *value); +Status Integer_ToInt(Integer *inst, int *store); +Status Integer_ToUnsignedInt(Integer *inst, unsigned int *store); +Status Integer_CopyOf(Integer *inst, Integer *other); +Status Integer_Delete(Integer *inst); +bool Integer_Equal(Integer *inst, Integer *other); + +/* DYNAMIC INSTANCE OPERATIONS. */ +Status Integer_Generate(Integer *inst, + Array *structs type(dynStruct), + Array *unions type(DynUnion), + Array *enums type(DynEnum), + Array *functionptrs type(FunctionPointer), + Array *fields type(Field), + Array *implementations type(Var type(Interface)), + Var *predecessor type(Class)); +Status Integer_Demolish(Integer *inst); +Status Integer_Literalise(Integer *inst, String *buff); + +/* INSTANCE UTILITIES. */ +Status IntegerUtils_Cast(Integer *inst, Integer *store, size_t sizeInBytes); + +#endif /* COMPOUND_CLASSES_INTEGER_H */ diff --git a/Function/include/functiondecls.h b/Function/include/functiondecls.h new file mode 100644 index 0000000..e69de29 diff --git a/Function/include/functiondefs.h b/Function/include/functiondefs.h new file mode 100644 index 0000000..e69de29 diff --git a/MemMan/include/memman.h b/MemMan/include/memman.h index 8134267..4d55f17 100644 --- a/MemMan/include/memman.h +++ b/MemMan/include/memman.h @@ -4,15 +4,14 @@ # include # include -/* - Higher the priority it is, the less time for lifespan it has. - */ +/* Higher the priority it is, the less lifespan it has. */ typedef struct { void *addr; - size_t length; + size_t size; int priority; // Negative for manual; Higher than 0 it is, // higher the priority is. + bool alive; } Memory; // 20 Bytes typedef struct { @@ -27,27 +26,27 @@ typedef struct { void (*deallocator)(void *addr); } MemoryPoolManager; -Status MemMan_Memory_Allocate(Memory *inst, size_t length); -Status MemMan_Memory_Reallocate(Memory *inst, size_t length); -void MemMan_Memory_Release(Memory *inst); -Status MemMan_Memory_Prioritise(Memory *inst); -Status MemMan_Memory_Deprioritise(Memory *inst); -bool MemMan_Memory_Equals(Memory *inst, Memory *other); +Status Memory_Create(Memory *inst, size_t size); +Status Memory_Delete(Memory *inst); +Status Memory_Allocate(Memory *inst); +Status Memory_Reallocate(Memory *inst, size_t size); +Status Memory_Release(Memory *inst); +bool Memory_Equals(Memory *inst, Memory *other); -Status MemMan_MemoryPool_Create(MemoryPool *inst, size_t volume); -Status MemMan_MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority); -Status MemMan_MemoryPool_AllocateAt(MemoryPool *inst, int idx, size_t sz); -Status MemMan_MemoryPool_ReallocateAt(MemoryPool *inst, int idx, size_t sz); -Status MemMan_MemoryPool_ReleaseAt(MemoryPool *inst, int idx); -void MemMan_MemoryPool_Delete(MemoryPool *inst); +Status MemoryPool_Create(MemoryPool *inst, size_t volume); +Status MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority); +Status MemoryPool_AllocateAt(MemoryPool *inst, int idx, size_t sz); +Status MemoryPool_ReallocateAt(MemoryPool *inst, int idx, size_t sz); +Status MemoryPool_ReleaseAt(MemoryPool *inst, int idx); +void MemoryPool_Delete(MemoryPool *inst); -Status MemMan_MemoryPoolManager_Create(MemoryPoolManager *inst, +Status MemoryPoolManager_Create(MemoryPoolManager *inst, MemoryPool **members); -Status MemMan_MemoryPoolManager_Constr(MemoryPoolManager *inst, +Status MemoryPoolManager_Constr(MemoryPoolManager *inst, MemoryPool **members, void *(*allocator)(size_t sz), void (*deallocator)(void *addr)); -Status MemMan_MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2); -Status MemMan_MemoryPoolManager_Divide(MemoryPool *src, int off, int len); +Status MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2); +Status MemoryPoolManager_Divide(MemoryPool *src, int off, int len); #endif /* COMPOUND_MEMMAN_H */ diff --git a/MemMan/src/memman.c b/MemMan/src/memman.c index 348e1ed..e872983 100644 --- a/MemMan/src/memman.c +++ b/MemMan/src/memman.c @@ -1,35 +1,75 @@ -#include #include -/* - enum { - MEMMAN_RELEASE_LEVEL_INSTANTAL = 0, - MEMMAN_RELEASE_LEVEL_STACK = 1, - MEMMAN_RELEASE_LEVEL_HEAP = 2 - }; - - typedef struct { - void *addr; - int release_level; - } Memory; - - typedef struct { - Memory *members; - int release_level; - } MemoryPool; - - typedef struct { - MemoryPool *members; - void *(*allocator)(size_t sz); - void (*delocator)(void *addr); - } MemoryPoolManager; -*/ - -int memman_memorypoolmanager_create(MemoryPoolManager *inst, - MemoryPool **membersptr) +Status Memory_Create(Memory *inst, size_t size) { - fails(inst, COMMON_ERROR_INVALID_ARGUMENT); - fails(membersptr, COMMON_ERROR_INVALID_ARGUMENT); + fails(inst, UnavailableInstance); + *inst = (Memory) { + .addr = NULL, + .size = size, + .priority = 0, + .alive = false + }; + return NormalStatus; +} + +Status Memory_Allocate(Memory *inst) +{ + fails(inst, UnavailableInstance); + state(inst->alive, InstanceStillAlive); + + /* When failed on allocating. */ + state(!(inst->addr = malloc(inst->size)), InsufficientMemory); + inst->alive = true; + + return NormalStatus; +} + +Status Memory_Reallocate(Memory *inst, size_t size) +{ + fails(inst, UnavailableBuffer); + state(!inst->alive, InstanceNotAlive); + + /* When failed on reallocating. */ + state(!(inst->addr = realloc(inst->addr, size)), + error(InsufficientMemory, "Unsuccessful reallocation was received.")) + + return NormalStatus; +} + +Status Memory_Release(Memory *inst) +{ + fails(inst, UnavailableInstance); + state(!inst->alive, error(InstanceNotAlive, "Cannot release a non-alive " + "instance.")); + + free(inst->addr); + inst->alive = false; + + return NormalStatus; +} + +Status Memory_Delete(Memory *inst) +{ + fails(inst, UnavailableInstance); + state(inst->alive, error(InstanceStillAlive, "Cannot deinitialise a instance " + "still alive.")); + + inst->addr = NULL; + inst->priority = 0; + inst->size = 0; + inst = NULL; + + return NormalStatus; +} + +bool Memory_Equals(Memory *inst, Memory *other) +{ + state(!inst || !other, false); + + return (inst->addr == other->addr + && inst->size == other->size + && inst->priority == other->priority + && inst->alive == other->alive); } diff --git a/Object/include/object.h b/Object/include/object.h index c8f4187..a4eb408 100644 --- a/Object/include/object.h +++ b/Object/include/object.h @@ -4,19 +4,20 @@ # include # include # include +# include -typedef struct { // interface - Var *data; - Array buffer; - Var *(*Literalise)(void); - int (*Correspond)(Var *other); -} Object; +// typedef struct { // interface +// Var *data; +// Array buffer; +// Var *(*Literalise)(void); +// int (*Correspond)(Var *other); +// } Object; -# define OBJECT_IMPLEMENTATION Var *data; Array buffer;\ - int (*Literalise)(void); int (*Correspond)(Var *other); +// # define OBJECT_IMPLEMENTATION Var *data; Array buffer;\ +// int (*Literalise)(void); int (*Correspond)(Var *other); -// private final String IDENTITY = ":D"; -// public static final void main(String[] args) {} +// // private final String IDENTITY = ":D"; +// // public static final void main(String[] args) {} typedef enum { EXPOSURE_PUBLIC = 0, @@ -33,80 +34,100 @@ typedef struct { typedef struct { Type type; Name identity; - Array parameters; -} Function; + Array type(Parameter) parameters; +} FunctionPointer; + +// typedef struct { +// Exposure prefix; +// bool dynamic; +// bool constant; +// Type type; +// Name identity; +// Array type(Parameter) parameters; +// } Member; typedef struct { Exposure prefix; - bool dynamic; - bool constant; + bool is_static; + bool is_constant; Type type; - Name identity; - Array type(Parameter) parameters; -} Member; + Name internal_identity; + String identity; + Var value; +} Field; -typedef struct { - Exposure prefix; - Name identity; - Array type(Parameter) parameters; -} Constructor; -/* As for destructors, they don't have prefixes or parameters, - because at the time you need destructors, you're already talking - in a environment that is private, private to this class alone. - And you also won't need any parameters, because to destruct, everything - you store in this class is bound to be vanished, and whatever you do to - modify them, the results are the same. - However, if you'd like to change something else that is not belong to - this class, why don't you just do them before calling destructors? - Therefor, in real practices, you won't find anything meaningful to let - a destructor having a prefix or a parameter. + +// typedef struct { +// Exposure prefix; +// Name identity; +// Array type(Parameter) parameters; +// } Constructor; + +// /* As for destructors, they don't have prefixes or parameters, +// because at the time you need destructors, you're already talking +// in a environment that is private, private to this class alone. +// And you also won't need any parameters, because to destruct, everything +// you store in this class is bound to be vanished, and whatever you do to +// modify them, the results are the same. +// However, if you'd like to change something else that is not belong to +// this class, why don't you just do them before calling destructors? +// Therefor, in real practices, you won't find anything meaningful to let +// a destructor having a prefix or a parameter. - Summary. - Prefixes are fixed to be "Private"; - Parameters are fixed to be void. - */ -typedef struct { - Name identity; -} Destructor; +// Summary. +// Prefixes are fixed to be "Private"; +// Parameters are fixed to be void. +// */ +// typedef struct { +// Name identity; +// } Destructor; -typedef struct { - // OBJECT_IMPLEMENTATION +// typedef struct { +// // OBJECT_IMPLEMENTATION - Object this; +// Object this; - char *identity; +// char *identity; - Array type(Member type(Constructor)) constructors; // Array> - Member type(Destructor) destructor; // Member +// Array type(Member type(Constructor)) constructors; // Array> +// Member type(Destructor) destructor; // Member - Array type(Member type(?)) fields; // Array> - Array type(Member type(?)) methods; // Array> -} Class; +// Array type(Member type(?)) fields; // Array> +// Array type(Member type(?)) methods; // Array> +// } Class; -typedef enum { - MEMBER_ACCESS_READ = 0b001, - MEMBER_ACCESS_WRITE = 0b010, - MEMBER_ACCESS_EXEC = 0b100, -} MemberAccessMode; +// typedef enum { +// MEMBER_ACCESS_READ = 0b001, +// MEMBER_ACCESS_WRITE = 0b010, +// MEMBER_ACCESS_EXEC = 0b100, +// } MemberAccessMode; -Status Extern(Class *inst, Class *extrn); -Status Implement(Class *inst, Class *impl); +// Status Extern(Class *inst, Class *extrn); +// Status Implement(Class *inst, Class *impl); -Status Class_Create(Class *inst, char *identity); -Status Class_CopyOf(Class *inst, Class *other); -Status Class_Constr(Class *inst, Array buffer, int (*Literalise)(void), - int (*Correspond)(Var*)); -Status Class_Delete(Class *inst); -Status Class_GetIdentity(Class *inst, char *store); -Status Class_GetObject(Class *inst, Object *store); -Status Class_GetFieldByIdentity(Class *inst, Name *identity, Member *store) - throws(MemberNotFound); -Status Class_GetMethodByIdentity(Class *inst, Name *identity, Member *store) - throws(MemberNotFound); -Status Class_GetMembers(Class *inst, Array *store); -Status Class_MemberAccess(Class *inst, MemberAccessMode mode, Member *store); -Status Class_AddMember(Class *inst, int index, Member *target); -Status Class_RemoveMember(Class *inst, int index); +// Status Class_Create(Class *inst, char *identity); +// Status Class_CopyOf(Class *inst, Class *other); +// Status Class_Constr(Class *inst, Array buffer, int (*Literalise)(void), +// int (*Correspond)(Var*)); +// Status Class_Delete(Class *inst); +// Status Class_GetIdentity(Class *inst, char *store); +// Status Class_GetObject(Class *inst, Object *store); +// Status Class_GetFieldByIdentity(Class *inst, Name *identity, Member *store) +// throws(MemberNotFound); +// Status Class_GetMethodByIdentity(Class *inst, Name *identity, Member *store) +// throws(MemberNotFound); +// Status Class_GetMembers(Class *inst, Array *store); +// Status Class_MemberAccess(Class *inst, MemberAccessMode mode, Member *store); +// Status Class_AddMember(Class *inst, int index, Member *target); +// Status Class_RemoveMember(Class *inst, int index); + +typedef struct { + +} Pointer; + +typedef struct { + +} FunctionPointer; #endif /* COMPOUND_OBJECT_H */ diff --git a/Stack/src/stack.c b/Stack/src/stack.c index 0931d82..3843a09 100644 --- a/Stack/src/stack.c +++ b/Stack/src/stack.c @@ -6,7 +6,7 @@ Status Stack_Create(Stack *inst, int len) // state((len < 0), InvalidParameter); // /* Initialise before access. */ - // if (inst == NULL) { + // if (!inst) { // *inst = (Stack) { // .members = NULL, // .len = len diff --git a/Status/include/status.h b/Status/include/status.h index 19b914a..da14a2d 100644 --- a/Status/include/status.h +++ b/Status/include/status.h @@ -3,16 +3,15 @@ # include # include +# include # include # include # include # include -# include -# include # include -# include # include +# include /* Status characteristics */ typedef enum { @@ -39,14 +38,21 @@ typedef struct { } Location; # define __HERE__ (Location){ \ - .file = (char *)__FILE__, \ - .line = __LINE__, \ - .func = (char *)__func__ \ + .file = (char *)__FILE__, \ + .line = __LINE__, \ + .func = (char *)__func__ \ +} + +# define __GLOBAL__ (Location){ \ + .file = (char *)__FILE__, \ + .line = __LINE__, \ + .func = (char *)"(GLOBAL)" \ } /* Common return type for reporting functions that require to give more information about the procedure. */ typedef struct _Status { + char *identity; int value; /* Traditional returning data "int". Only used when the function called and received legacy functions that uses "int" as the returning type that wish to have place to hold the value. @@ -65,17 +71,30 @@ typedef struct _Status { */ -# ifdef __COMPOUND_32__ -# define STATUS_LITERALISE_LENGTH(stat) \ - (utils_calc_digits(stat.value) + strlen(stat.description) + 2 + \ - utils_calc_digits(INT32_DIGITS_DEC)) -# elif defined __COMPOUND_64__ -# define STATUS_LITERALISE_LENGTH(stat) \ - (utils_calc_digits(stat.value) + strlen(stat.description) + 2 + \ - utils_calc_digits(INT64_DIGITS_DEC)) -# endif +/* line, func, file */ +// # define LOCATION_LITERALISE_FORMAT "at line %d, in %s, %s" -# define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p" +/* file, line, func */ +# define LOCATION_LITERALISE_FORMAT "at %s:%d, in function `%s\'" +# define LOCATION_LITERALISE_FORMAT_LENGTH 20 + +/* value, description, characteristic, prev */ +// # define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p" +/* identity, prev->identity, value, characteristic, description, */ +// # define STATUS_LITERALISE_FORMAT "%s (prev: %s): $=%d @=%d\n\t\"%s\"\n\t%s" + +// MaximumLiteralisationLengthExceeded (prev: MaximumLengthExceeded): $=1 @=1 + +/* +MaximumLengthExceeded: "Buffer was too long." + predecessor= value=(1) characteristic=[1] + at line 40, in Main, /home/william/Documents/Projects/Compound/test.c + +*/ + +// identity, description, prev->identity, value, characteristic, +# define STATUS_LITERALISE_FORMAT \ + "%s: \"%s\"\n\tpredecessor=<%s> value=(%d) characteristic=[%d]\n\t%s\n" typedef enum { REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value. @@ -130,20 +149,6 @@ Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buf # define REPORT_LITERALISE_CHAINS_FORMAT " at %s:%d, %s" # define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT "!!!!at %s:%d, %s" -// # define REPORT_LITERALISE_HEADER_FORMAT_LENGTH(buff, PRIORITY, STATUSNAME, \ -// ORIGINATOR, DESCRIPTION) \ -// { \ -// const time_t now = time(NULL); \ -// (void)strflen(buff, 28, DATETIME_FORMAT, localtime(&now)); \ -// *length = strlen(buff); \ -// } - -// # define REPORT_LITERALISE_CHAINS_FORMAT_LENGTH(FILEPATH, LINE, FUNCNAME) \ -// (strlen(FILEPATH) + utils_calc_digits(LINE) + \ -// strlen(FUNCNAME) + 10) // Does not count '\0' -// # define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT_LENGTH \ -// REPORT_LITERALISE_CHAINS_FORMAT_LENGTH - typedef enum { REPORT_SENDER_RESULT_FINISHED, REPORT_SENDER_RESULT_PROGRESSING, @@ -200,29 +205,26 @@ typedef struct { # define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX +Status Location_Literalise(Location *inst, char *buff); bool Location_Equals(Location lc1, Location lc2); Status Status_Literalise(Status *inst, char *buff); -bool Status_Equals(Status stat1, Status stat2); +bool Status_Equal(Status *stat1, Status *stat2); void StatusUtils_Dump(Status *inst, Status *store, int idx); -bool StatusUtils_HasPrev(Status *inst); +bool StatusUtils_HasPrev(Status inst); bool StatusUtils_IsOkay(Status inst); bool StatusUtils_IsValid(Status inst); bool StatusUtils_IsRecursive(Status inst); int StatusUtils_Depth(Status *inst); -Status -Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator, - int priority); -bool -Report_Equals(Report repo1, Report repo2); -Status -Report_Literalise(Report *inst, char *buff); +Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator, + int priority); +Status Report_CopyOf(Report *inst, Report *other); +Status Report_Literalise(Report *inst, char *buff); +void Report_Delete(Report *inst); +bool Report_Equals(Report repo1, Report repo2); - -Status -ReportSender_Create(ReportSender *inst, Report *report); -Status -ReportSender_Send(ReportSender *inst, ReportSendingTask task); +Status ReportSender_Create(ReportSender *inst, Report *report); +Status ReportSender_Send(ReportSender *inst, ReportSendingTask task); // ReportSendingTaskStatus // ReportSender_GetStatus(ReportSender *inst); @@ -254,177 +256,309 @@ Status ReportSenderManager_RemoveTask(ReportSendingManager *inst, // ---------------------ELEMENTARY------------------------- -static Status UnknownStatus = { +/* + typedef struct _Status { + char *identity; + int value; + char *description; + int characteristic; + Location loc; + struct _Status *prev; + } Status; +*/ + +static const Status UnknownStatus = { + .identity = nameof(UnknownStatus), + .value = -1, .description = "An unknown status.", .characteristic = STATUS_UNKNOWN, + .loc = __GLOBAL__, .prev = NULL }; -static Status NormalStatus = { +static const Status NormalStatus = { + .identity = nameof(NormalStatus), + .value = 0, .description = "A normal status.", .characteristic = STATUS_NORMAL, + .loc = __GLOBAL__, .prev = NULL }; -static Status ErrorStatus = { +static const Status ErrorStatus = { + .identity = nameof(ErrorStatus), + .value = 1, .description = "An error status.", .characteristic = STATUS_ERROR, + .loc = __GLOBAL__, .prev = NULL }; // ----------------------EXTENDED-------------------------- -static Status MemoryViolation = { +static const Status MemoryViolation = (Status){ + .identity = nameof(MemoryViolation), + .value = 1, .description = "Illegal access on certain memory address.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status NullPointerAccounted = { +static const Status NullPointerAccounted = (Status){ + .identity = nameof(NullPointerAccounted), + .value = 1, .description = "An involving null pointer was not accepted.", .characteristic = STATUS_ERROR, - .prev = &MemoryViolation + .loc = __GLOBAL__, + .prev = (Status *)&MemoryViolation }; -static Status InvalidObject = { +static const Status InvalidObject = (Status){ + .identity = nameof(InvalidObject), + .value = 1, .description = "An invalid object was presented.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status UnavailableObject = { +static const Status UnavailableObject = (Status){ + .identity = nameof(UnavailableObject), + .value = 1, .description = "An unavailable object was presented.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status InvalidParameter = { +static const Status InstanceStillAlive = (Status){ + .identity = nameof(InstanceStillAlive), + .value = 1, + .description = "Given instance was yet alive.", + .characteristic = STATUS_ERROR, + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus +}; + +static const Status InstanceNotAlive = (Status){ + .identity = nameof(InstanceNotAlive), + .value = 1, + .description = "Given instance for reallocation was not alive.", + .characteristic = STATUS_ERROR, + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus +}; + +static const Status InvalidParameter = (Status){ + .identity = nameof(InvalidParameter), + .value = 1, .description = "An invalid parameter was presented.", .characteristic = STATUS_ERROR, - .prev = &InvalidObject + .loc = __GLOBAL__, + .prev = (Status *)&InvalidObject }; -static Status InsufficientMemory = { +static const Status InsufficientMemory = (Status){ + .identity = nameof(InsufficientMemory), + .value = 1, .description = "Not enough room for further memory allocations.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status ArithmeticError = { +static const Status ArithmeticError = (Status){ + .identity = nameof(ArithmeticError), + .value = 1, .description = "An arithmetic error occurred.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status RuntimeError = { +static const Status IntegerOverFlow = (Status){ + .identity = nameof(IntegerOverFlow), + .value = 1, + .description = "An integer had overflowed.", + .characteristic = STATUS_ERROR, + .loc = __GLOBAL__, + .prev = (Status *)&ArithmeticError +}; + +static const Status RuntimeError = (Status){ + .identity = nameof(RuntimeError), + .value = 1, .description = "A runtime error occurred.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status ArrayLengthError = { +static const Status ArrayLengthError = (Status){ + .identity = nameof(ArrayLengthError), + .value = 1, .description = "Given array length does not meet the requirement.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status VariableFormatMismatch = { +static const Status VariableFormatMismatch = (Status){ + .identity = nameof(VariableFormatMismatch), + .value = 1, .description = "Given format does not match with given subjects.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .loc = __GLOBAL__, + .prev = (Status *)&ErrorStatus }; -static Status ImprecisionError = { +static const Status ImprecisionError = (Status){ + .identity = nameof(ImprecisionError), + .value = 1, .description = "Precision was not enough for handling the calculation.", .characteristic = STATUS_ERROR, - .prev = &RuntimeError + .loc = __GLOBAL__, + .prev = (Status *)&RuntimeError }; // ---------------------USER DEFINED----------------------- -static Status UnavailableInstance = { +static const Status UnavailableInstance = (Status){ + .identity = nameof(UnavailableInstance), + .value = 1, .description = "An unavailable instance was given for initialisation.", .characteristic = STATUS_ERROR, - .prev = &NullPointerAccounted + .loc = __GLOBAL__, + .prev = (Status *)&NullPointerAccounted }; -static Status UnavailableParameter = { +static const Status RecreationOnInstanceStillAlive = (Status){ + .identity = nameof(RecreationOnInstanceStillAlive), + .value = 1, + .description = "Given instance was still alive, yet, was sent for another " + "session of recreation.", + .characteristic = STATUS_ERROR, + .loc = __GLOBAL__, + .prev = (Status *)&InstanceStillAlive\ +}; + +static const Status UnavailableParameter = (Status){ + .identity = nameof(UnavailableParameter), + .value = 1, .description = "An unavailable instance was given as a parameter.", .characteristic = STATUS_ERROR, - .prev = &UnavailableInstance + .loc = __GLOBAL__, + .prev = (Status *)&UnavailableInstance }; -static Status InvalidReportTask = { +static const Status InvalidReportTask = (Status){ + .identity = nameof(InvalidReportTask), + .value = 1, .description = "An unavailable or illegal report task was given.", .characteristic = STATUS_ERROR, - .prev = &InvalidParameter + .loc = __GLOBAL__, + .prev = (Status *)&InvalidParameter }; -static Status UnableToThrowError = { +static const Status UnableToThrowError = (Status){ + .identity = nameof(UnableToThrowError), + .value = 1, .description = "Unable to report an exceptional situation.", .characteristic = STATUS_ERROR, - .prev = &RuntimeError + .loc = __GLOBAL__, + .prev = (Status *)&RuntimeError }; -static Status ReadWriteError = { +static const Status ReadWriteError = (Status){ + .identity = nameof(ReadWriteError), + .value = 1, .description = "Error occurred during IO session.", .characteristic = STATUS_ERROR, - .prev = &RuntimeError + .loc = __GLOBAL__, + .prev = (Status *)&RuntimeError }; -static Status FileNotFound = { +static const Status FileNotFound = (Status){ + .identity = nameof(FileNotFound), + .value = 1, .description = "Target file was unavailable and unable to find.", .characteristic = STATUS_ERROR, - .prev = &ReadWriteError + .loc = __GLOBAL__, + .prev = (Status *)&ReadWriteError }; -static Status InvalidFileName = { +static const Status InvalidFileName = (Status){ + .identity = nameof(InvalidFileName), + .value = 1, .description = "Given file name was invalid.", .characteristic = STATUS_ERROR, - .prev = &ReadWriteError + .loc = __GLOBAL__, + .prev = (Status *)&ReadWriteError }; -static Status UnavailableFileName = { +static const Status UnavailableFileName = (Status){ + .identity = nameof(UnavailableFileName), + .value = 1, .description = "Given file name was unavailable", .characteristic = STATUS_ERROR, - .prev = &UnavailableObject + .loc = __GLOBAL__, + .prev = (Status *)&UnavailableObject }; -static Status ReportThrown = { +static const Status ReportThrown = (Status){ + .identity = nameof(ReportThrown), + .value = 1, .description = "This function has thrown a report, " "following instructions aborted.", .characteristic = STATUS_ERROR, - .prev = &RuntimeError + .loc = __GLOBAL__, + .prev = (Status *)&RuntimeError\ }; -static Status ReportMessageTooLong = { +static const Status ReportMessageTooLong = (Status){ + .identity = nameof(ReportMessageTooLong), + .value = 1, .description = "Given message is too long.", .characteristic = STATUS_ERROR, - .prev = &ArrayLengthError + .loc = __GLOBAL__, + .prev = (Status *)&ArrayLengthError }; -static Status MaximumLengthExceeded = { +static const Status MaximumLengthExceeded = (Status){ + .identity = nameof(MaximumLengthExceeded), + .value = 1, .description = "Buffer was too long.", .characteristic = STATUS_ERROR, - .prev = &ArrayLengthError + .loc = __GLOBAL__, + .prev = (Status *)&ArrayLengthError }; -static Status MaximumLiteralisationLengthExceeded = { +static const Status MaximumLiteralisationLengthExceeded = (Status){ + .identity = nameof(MaximumLiteralisationLengthExceeded), + .value = 1, .description = "Literalisation was too long.", .characteristic = STATUS_ERROR, - .prev = &MaximumLengthExceeded + .loc = __GLOBAL__, + .prev = (Status *)&MaximumLengthExceeded }; -static Status UnavailableBuffer = { +static const Status UnavailableBuffer = (Status){ + .identity = nameof(UnavailableBuffer), + .value = 1, .description = "Given buffer was unavailable.", .characteristic = STATUS_ERROR, - .prev = &UnavailableInstance + .loc = __GLOBAL__, + .prev = (Status *)&UnavailableInstance }; -static Status InvalidLiteralisingBuffer = { +static const Status InvalidLiteralisingBuffer = (Status){ + .identity = nameof(InvalidLiteralisingBuffer), + .value = 1, .description = "Given buffer does not have a good integrity on its length.", .characteristic = STATUS_ERROR, - .prev = &InvalidObject + .loc = __GLOBAL__, + .prev = (Status *)&InvalidObject }; // ======================================================== diff --git a/Status/src/status.c b/Status/src/status.c index 4cc5cd5..438cf34 100644 --- a/Status/src/status.c +++ b/Status/src/status.c @@ -2,69 +2,89 @@ #include #include -bool Location_Equal(Location lc1, Location lc2) +/* +typedef struct { + char *file; + int line; + char *func; +} Location; +*/ +Status Location_Literalise(Location *inst, char *buff) { - return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) && - (!strcmp(lc1.func, lc2.func))); + fails(inst, UnavailableInstance); + fails(buff, UnavailableBuffer); + + /* Literalise line. */ + char line_buff[LITERALISATION_LENGTH_MAXIMUM]; + Utils_LiteraliseInteger(inst->line, line_buff); + + /* Concatenate every buff. */ + const long total_len = strlen(inst->file) + strlen(line_buff) + + strlen(inst->func) + + LOCATION_LITERALISE_FORMAT_LENGTH; + state(total_len > LITERALISATION_LENGTH_MAXIMUM, + MaximumLiteralisationLengthExceeded); + + /* Copy and assign. */ + return (Status) { + .value = !sprintf(buff, LOCATION_LITERALISE_FORMAT, + inst->file, inst->line, inst->func), + .description = NormalStatus.description, + .characteristic = NormalStatus.characteristic, + .loc = __HERE__, + .prev = NormalStatus.prev + }; } -bool Status_Equals(Status stat1, Status stat2) +bool Location_Equal(Location *lc1, Location *lc2) { + state(lc1 == NULL || lc2 == NULL, false); - /* Skip when both stat1 and stat2 are empty. */ - state((stat1.value == 0 && stat2.value == 0 && stat1.description == 0x0 && - stat2.description == 0x0 && stat1.characteristic == 0 && - stat2.characteristic == 0 && stat1.prev == 0x0 && stat2.prev == 0x0), - true); + return ((!strcmp(lc1->file, lc2->file)) && (lc1->line == lc2->line) && + (!strcmp(lc1->func, lc2->func))); +} - /* True for equality; False for inequality. */ - return ((stat1.value == stat2.value) && - (!strcmp(stat1.description, stat2.description)) && - (stat1.characteristic == stat2.characteristic) && - (Status_Equals(*stat1.prev, *stat2.prev))); +bool Status_Equal(Status *stat1, Status *stat2) +{ + state(stat1 == NULL || stat2 == NULL, false); + + return ( + stat1->value == stat2->value && + !strcmp(stat1->description, stat2->description) && + stat1->characteristic == stat2->characteristic && + Location_Equal(&stat1->loc, &stat2->loc) && + ((StatusUtils_HasPrev(*stat1) && StatusUtils_HasPrev(*stat2)) + ? Status_Equal(stat1->prev, stat2->prev) + : true) + ); } Status Status_Literalise(Status *inst, char *buff) { - /* Skip unavailable or invalid parameters. */ + /* Skip unavailable instance and invalid parameter. */ fails(inst, UnavailableInstance); fails(buff, UnavailableBuffer); - // state(strlen(buff) != LITERALISATION_LENGTH_MAXIMUM, - // InvalidLiteralisingBuffer); - - /* Set up idx for counting final literalisation length to ensure the - string copying is index access safe. */ - int idx = 0; - const int status_dump_buffer_len = StatusUtils_Depth(inst); - - Status status_dump_buffer[status_dump_buffer_len]; - /* Literalise every status that flattened on status_dump_buffer. */ - for (register int i = 0; i < status_dump_buffer_len; i++) { - char status_literalising_buffer[LITERALISATION_LENGTH_MAXIMUM]; - (void)Status_Literalise(&status_dump_buffer[i], status_literalising_buffer); - - /* Append to buff. */ - /* Prevent buffer-out-of-bound access. */ - const int status_literalising_buffer_len = strlen(status_literalising_buffer); - if (idx + status_literalising_buffer_len >= LITERALISATION_LENGTH_MAXIMUM) { - buff = NULL; - return MaximumLiteralisationLengthExceeded; - } - - idx += status_literalising_buffer_len; - (void)strcat(buff, status_literalising_buffer); - } + /* Literalise loc. */ + char loc_buff[LITERALISATION_LENGTH_MAXIMUM]; + notok(Location_Literalise(&inst->loc, loc_buff), { + return error(_, "Failed on literalising the \"loc\" of a status."); + }); + + /* Concatenate every buffer. */ + state(!sprintf(buff, STATUS_LITERALISE_FORMAT, + inst->identity, inst->description, + (!inst->prev ? "(null)" : (inst->prev->identity)), + inst->value, inst->characteristic, loc_buff), + error(RuntimeError, "Returned 0 byte written on concatenating buffers " + "during literalisation of a status using \"sprintf\".")); return NormalStatus; } -bool StatusUtils_HasPrev(Status *stat) +bool StatusUtils_HasPrev(Status stat) { - /* Skip when stat is unavailable for accessing. */ - state(Status_Equals(*stat, (Status){}), false); - - return (stat->prev != NULL); + return (stat.prev != NULL); } bool StatusUtils_IsOkay(Status stat) @@ -74,20 +94,20 @@ bool StatusUtils_IsOkay(Status stat) bool StatusUtils_IsValid(Status stat) { - return (!strcmp(stat.description, "") && stat.characteristic >= 0 && - stat.prev != NULL); + return (!strcmp(stat.description, "") && stat.characteristic >= 0 + && !stat.prev); } bool StatusUtils_IsRecursive(Status stat) { - return (stat.prev != NULL && stat.prev == &stat); + return (stat.prev && stat.prev == &stat); } void StatusUtils_Dump(Status *inst, Status *store, int idx) { /* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */ - solve((store == NULL || !StatusUtils_HasPrev(inst) || idx < 0), return;); + solve((!store || !StatusUtils_HasPrev(*inst) || idx < 0), return;); store[idx] = *inst; @@ -97,17 +117,13 @@ void StatusUtils_Dump(Status *inst, Status *store, int idx) int StatusUtils_Depth(Status *stat) { /* Skip unavailable stat. */ - state((stat == NULL), -1); + state((!stat || !stat->prev), -1); Status *p = stat; // Include this layer of Status. - int cnt = 1; - while (p != NULL) { - if (StatusUtils_IsRecursive(*p) || !StatusUtils_HasPrev(stat)) break; - - p = p->prev; - cnt += 1; - } - + register int cnt; + for (cnt = 0; (!StatusUtils_IsRecursive(*p) + && StatusUtils_HasPrev(*p)); cnt++) p = p->prev; + return cnt; } @@ -116,21 +132,51 @@ Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator, { /* Skip unavailable parameters. */ fails(inst, UnavailableInstance); - fails(stat, error(InvalidParameter, "Given initiator was null.")); + fails(stat, error(InvalidParameter, "Given stat was null.")); fails(initiator, error(InvalidParameter, "Given initiator was null.")); state(priority < 0, error(InvalidParameter, "Given priority was negative.")); /* Copy and assign. */ inst->status = *stat; - inst->initiator = initiator; + inst->initiator = calloc(strlen(initiator), sizeof(char)); + (void)strcpy(inst->initiator, initiator); inst->time = time(NULL); inst->priority = priority; inst->task_status = REPORT_SENDING_TASK_STATUS_PENDING; - inst->dest = (dest == NULL ? stderr : dest); + inst->dest = (dest == NULL ? stdout : dest); return NormalStatus; } +Status Report_CopyOf(Report *inst, Report *other) +{ + fails(inst, UnavailableInstance); + fails(other, error(InvalidParameter, "Given report is unavailable.")); + + // Status status; + // char *initiator; + // time_t time; + // ReportSendingPriority priority; + // ReportSendingTaskStatus task_status; + // FILE *dest; + inst->status = other->status; + +} + +void Report_Delete(Report *inst) +{ + svoid(inst); + + free(inst->initiator); + inst->initiator = NULL; + inst->dest = NULL; + inst->priority = 0; + inst->status = (Status){}; + inst->task_status = REPORT_SENDING_TASK_STATUS_NOTFOUND; + inst->time = 0; + inst = NULL; +} + Status Report_Literalise(Report *inst, char *buff) { fails(inst, UnavailableInstance); @@ -195,7 +241,9 @@ Status ReportSender_Create(ReportSender *inst, Report *report) fails(report, error(UnavailableParameter, "Given report was unavailable.")); thrd_create(&inst->thread, &HANDLER, report); - *inst->report = *report; + notok(Report_CopyOf(inst->report, report), + return error(ErrorStatus, "Cannot copy to create new instance of report."); + ) // *inst->report = *report; inst->elapsed = 0; inst->result = REPORT_SENDER_RESULT_PENDING; inst->successful = false; @@ -294,4 +342,3 @@ int HANDLER(void *report) return 0; } - diff --git a/String/include/string.h b/String/include/string.h index 167a8a4..9b64abc 100644 --- a/String/include/string.h +++ b/String/include/string.h @@ -22,7 +22,6 @@ Status String_Delete(String *inst); Status String_GetIdx(String *inst, Char *item, int index); Status String_SetIdx(String *inst, Char *item, int index); Status String_Literalise(String *inst, String *store); -bool String_Equals(String *arr1, String *arr2); /* Extensional. */ Status StringUtils_FromInteger(String *inst, int value); @@ -83,6 +82,7 @@ Status String_Decode(String *inst, StringEncoding encoding); int StringUtils_Compare(String *a, String *b); static Status StringConversionPrecisionError = { + .value = 1, .description = "Unpreventable precision loss was found during conversion " "between string and raw data.", .characteristic = STATUS_ERROR, diff --git a/String/src/string.c b/String/src/string.c index 4b4ccc0..2751cd8 100644 --- a/String/src/string.c +++ b/String/src/string.c @@ -2,14 +2,9 @@ Status String_Create(String *inst, int len) { - Status create = Array_Create(inst, len); - solve(!(StatusUtils_IsOkay(create)), { - Report e = stamp(error(create, "Failed to create a string."), - nameof(Array_Create)); - (void)_throw(e); - return ReportThrown; - }) - + /* Create an array has length len + 1, for termination character in string. */ + ensure(Array_Create(inst, len + 1, sizeof(int)), "Failed to create a string."); + return NormalStatus; } @@ -23,12 +18,12 @@ Status String_Delete(String *inst) fails(inst, UnavailableInstance); } -Status String_GetIdx(String *inst, Char *store, int index) +Status String_GetAt(String *inst, Char *store, int index) { fails(inst, UnavailableInstance); } -Status String_SetIdx(String *inst, Char *source, int index) +Status String_SetAt(String *inst, Char *source, int index) { fails(inst, UnavailableInstance); } @@ -38,8 +33,30 @@ Status String_Literalise(String *inst, String *store) fails(inst, UnavailableInstance); } -bool String_Equals(String *arr1, String *arr2) +int StringUtils_Compare(String *a, String *b) { - fails(inst, UnavailableInstance); -} + /* Both being null is counted as equal. */ + state(a == NULL && b == NULL, 0); + /* Compare by iterating through each element to calculate differing + values between a[i] and b[i]. */ + const int len = max(a->len, b->len); + for (register int i = 0; i < len; i++) { + const int comp = + (*(char *)(a->members[i].addr) - *(char *)(b->members[i].addr)); + + /* + If values from both side does not equal, return the differential value. + */ + if (!comp) { + return comp; + } + } + + /* Even the previous elements are same, but the length must be compared + because we haven't really done this. + The reason that we don't compare it earlier is though we can know whether + the lengths are the same or not, we, however, cannot give a precise value + telling which content from string is "greater" or "less". */ + return (a->len != b->len); +} diff --git a/Utils/include/utils.h b/Utils/include/utils.h index 9d9eb13..4065f08 100644 --- a/Utils/include/utils.h +++ b/Utils/include/utils.h @@ -5,10 +5,14 @@ # include # include # include +# include # include # include +# define max(a, b) (a >= b ? a : b) +# define min(a, b) (a <= b ? a : b) + # define DATETIME_FORMAT "%a %d %b %X %Z %Y" int Utils_CalcDigits(long long int n); diff --git a/Utils/src/utils.c b/Utils/src/utils.c index 7883db2..f9a509f 100644 --- a/Utils/src/utils.c +++ b/Utils/src/utils.c @@ -46,3 +46,4 @@ int Utils_DateTimeLiteralise(time_t t, char *buff) { return 0; } + diff --git a/Var/include/var.h b/Var/include/var.h index 01b42fb..8a210af 100644 --- a/Var/include/var.h +++ b/Var/include/var.h @@ -15,6 +15,7 @@ // # define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ " // static Status IllegalVarIdentity = { +// .value = 1, // .description = "Given identity does not fit the standard of Var Naming " // "convention.", // .characteristic = STATUS_ERROR, @@ -22,6 +23,7 @@ // }; // static Status VarIdentityTooLong = { +// .value = 1, // .description = "Given identity has longer length that the maximum length " // "limitation.", // .characteristic = STATUS_ERROR, @@ -34,6 +36,8 @@ typedef struct { void *addr; size_t size; + bool alive; + // /* Identification */ // char *identity; // Maximum up to VAR_IDENTITY_LENGTH diff --git a/Var/src/var.c b/Var/src/var.c index 5f27543..bceddb2 100644 --- a/Var/src/var.c +++ b/Var/src/var.c @@ -2,14 +2,14 @@ Status Var_Create(Var *inst, size_t size) { - *inst = (Var) { - .addr = malloc(size), - .size = size - }; + fails(inst, UnavailableInstance); + state(inst->alive, InstanceStillAlive); + state(!size, normal(NormalStatus, "Exited with given parameter" + "size as ZERO.")); - if (inst->addr == NULL) { - return InsufficientMemory; - } + state(((inst->addr = malloc(size)) == NULL), InsufficientMemory); + inst->size = size; + inst->alive = true; return NormalStatus; } @@ -34,18 +34,20 @@ Status Var_CopyOf(Var *inst, Var *other) { /* Skip when inst or other is unavailable. */ fails(inst, UnavailableInstance); + state(inst->alive, InstanceStillAlive); fails(other, InvalidParameter); /* Copy members from other. Only has to apply size, no addr is needed. */ - inst->addr = malloc(other->size); + state(!((inst->addr = malloc(other->size))), InsufficientMemory); inst->size = other->size; + inst->alive = true; return NormalStatus; } void Var_Delete(Var *inst) { - if (inst == NULL) return; + svoid(!inst); free(inst->addr); inst->addr = NULL; @@ -55,7 +57,7 @@ void Var_Delete(Var *inst) // void Var_Delete(Var *inst) // { // /* Skip when inst or inst->addr is unavailable. */ -// svoid(inst == NULL || inst->addr == NULL); +// svoid(!inst || inst->addr == NULL); // inst->addr = NULL; // inst->size = 0; @@ -65,7 +67,7 @@ void Var_Delete(Var *inst) void VarUtils_Swap(Var *v1, Var *v2) { /* Skip when v1 or v2 is unavailable. */ - svoid(v1 == NULL || v2 == NULL); + svoid(!v1 || !v2); Var v3 = *v1; *v1 = *v2; @@ -75,7 +77,7 @@ void VarUtils_Swap(Var *v1, Var *v2) Status Var_Literalise(Var *inst, char *buff) { /* Skip when inst is unavailable. */ - state(inst == NULL, UnavailableInstance); + state(!inst, UnavailableInstance); /* Write into buffer. */ state(!sprintf(buff, VAR_LITERALISE_FORMAT"\n", inst->addr, inst->size), @@ -87,7 +89,7 @@ Status Var_Literalise(Var *inst, char *buff) bool Var_Equals(Var *a, Var *b) { /* Skip unavailable inst and invalid param. */ - state((a == NULL || b == NULL), false); + state((!a || !b), false); return (a->addr == b->addr && a->size == b->size); } diff --git a/attr.h b/attr.h index 2dd68df..26d1f34 100644 --- a/attr.h +++ b/attr.h @@ -3,15 +3,6 @@ # include -/* Only effect (probably) when formal Attribute is defined. - * __ATTRIBUTABLE indicates this field is used for further process by Attribute. - * Or, to put this way, this field has attributions not used so far, but - * eventually will. - */ -# define __ATTRIBUTABLE -# define __ATTRIBUTABLE__ -# define attr(a) - typedef struct _Attribute{ int serialNo; int (*exec)(void *); diff --git a/catlog.c b/catlog.c index 9a132b2..9e57acf 100755 --- a/catlog.c +++ b/catlog.c @@ -30,7 +30,7 @@ Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other) bool CatlogMsg_Equals(CatlogMsg *inst, CatlogMsg *other) { /* Skip unavailable instances and parameters. */ - state((inst == NULL || other == NULL), false); + state((!inst || other == NULL), false); return ( inst->time == other->time && @@ -73,7 +73,7 @@ Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other) bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other) { /* Skip unavailable instances and parameters. */ - state((inst == NULL || other == NULL), false); + state((!inst || other == NULL), false); return ( CatlogMsg_Equals(&inst->msg, &other->msg) && @@ -97,7 +97,7 @@ Status CatlogSender_Send(CatlogSender *inst, char *filepath, bool append) (void)CatlogUtils_OpenFile(inst->dst, filepath, (append ? "a" : "w")); /* Write msg. */ - return normal(NormalStatus, "", fprintf(inst->dst, "%s", inst->msg.content)); + return unknown(NormalStatus, "", !fprintf(inst->dst, "%s", inst->msg.content)); } Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); diff --git a/class.h b/class.h new file mode 100644 index 0000000..fc587f5 --- /dev/null +++ b/class.h @@ -0,0 +1,33 @@ +#ifndef COMPOUND_CLASS_H +# define COMPOUND_CLASS_H + +# include + +typedef struct {} _Interface; + +typedef struct { + String identity; + + Array type(DynStruct) structs; + Array type(DynUnion) unions; + Array type(DynEnum) enums; + Array type(FunctionPointer) functionptrs; + Array type(Field) fields; + + // Interface[] *implementations + Array type(Var type(Interface)) *implementations; + // Class *predecessor + Var type(Class) *predecessor; +} Class; + +Status Class_Create(Class *inst, Array type(DynStruct) structs, + Array type(DynUnion) unions, + Array type(DynEnum) enums, + Array type(FunctionPointer) functionptrs, + Array type(Field) fields); +Status Class_CreateEmpty(Class *inst); +Status Class_CopyOf(Class *inst, Class *other); +Status Class_Implement(Class *inst, _Interface *interface); +Status Class_Extern(Class *inst, Class *) + +#endif /* COMPOUND_CLASS_H */ diff --git a/common.h b/common.h index e07ba92..3500018 100644 --- a/common.h +++ b/common.h @@ -43,33 +43,43 @@ /* Create a new UnknownStatus on the fly. */ # define unknown(e, c, v) ((Status) {\ + .identity = nameof(UnknownStatus),\ .value = v,\ .description = c,\ .characteristic = STATUS_UNKNOWN,\ + .loc = __HERE__,\ .prev = e.prev\ }) /* Create a new NormalStatus on the fly. */ -# define normal(e, c, v) ((Status) {\ - .value = v,\ +# define normal(e, c) ((Status) {\ + .identity = nameof(NormalStatus),\ + .value = 0,\ .description = c,\ .characteristic = STATUS_NORMAL,\ + .loc = __HERE__,\ .prev = e.prev\ }) /* Create a new ErrorStatus on the fly. */ # define error(e, c) ((Status) {\ + .identity = nameof(ErrorStatus),\ + .value = e.value,\ .description = c,\ .characteristic = STATUS_ERROR,\ + .loc = __HERE__,\ .prev = e.prev\ }) /* Extend the Status chain by giving 'p' for "predecessor" - and 'c' for "comment/description". */ -# define extend(p, c) ((Status) {\ - .description = c,\ + and 'e' for "Eval-Status". */ +# define extend(p, e) ((Status) {\ + .identity = e.identity,\ + .value = p.value,\ + .description = e.description,\ .characteristic = p.characteristic,\ - .prev = p\ + .loc = e.loc,\ + .prev = &p\ }) /** @brief Create a report in place. @@ -83,7 +93,7 @@ .initiator = c,\ .time = time(NULL),\ .priority = REPORT_SENDING_PRIORITY_NORMAL,\ - .status = REPORT_SENDING_TASK_STATUS_PENDING\ + .task_status = REPORT_SENDING_TASK_STATUS_PENDING\ }) /** @@ -104,7 +114,7 @@ // */ // # define force(s, k, v) solve((s) != (k), v) -// # define sforce(s, k, v) solve((!Status_Equals(s, k)), v) +// # define sforce(s, k, v) solve((!Status_Equal(s, k)), v) /* Get the literal. */ # define nameof(obj) #obj @@ -124,6 +134,13 @@ CatlogSender_Send(&sender, "stdout", false);\ } +# define _status(s) {\ + const Status _ = s;\ + char buff[LITERALISATION_LENGTH_MAXIMUM];\ + (void)Status_Literalise((Status *)&_, buff);\ + (void)printf("%s\n", buff);\ +} + # define ok(s, b) {\ const Status _ = s;\ if (StatusUtils_IsOkay(_)) b\ @@ -162,11 +179,21 @@ typedef bool _Bit; # define WHICH_MIN(a, b) # define INRANGE(lf, inclf, rt, incrt, v) \ - (! ((lf > rt) || ((v <= lf && !inclf) || (v >= rt && !incrt)))) + (!((lf > rt) || ((v <= lf && !inclf) || (v >= rt && !incrt)))) # define ATRANGE(lf, rt, v) \ (INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt)) -# define LITERALISATION_LENGTH_MAXIMUM 0xFFFF +# define LITERALISATION_LENGTH_MAXIMUM 0xFFFFL + + +/* Only effect (probably) when formal Attribute is defined. + * __ATTRIBUTABLE indicates this field is used for further process by Attribute. + * Or, to put this way, this field has attributions not used so far, but + * eventually will. + */ +# define __ATTRIBUTABLE +# define __ATTRIBUTABLE__ +# define attr(a) #endif /* NO COMPOUND_COMMON_h */ diff --git a/install b/install index d3537e9..e1352c0 100755 --- a/install +++ b/install @@ -12,7 +12,7 @@ fi SRC="$PWD" DST=/usr/include/Compound PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan" "Stack" "Utils"\ - "String") + "String" "Object") PROJLEN=${#PROJ[*]} echo "======== $PROJLEN projects in total ========" @@ -35,5 +35,5 @@ done cp -v "common.h" "const.h" "platform.h"\ "name.h" "namescope.h" "type.h" "catlog.h"\ - "attr.h" "registry.h" "$DST" + "attr.h" "registry.h" "class.h" "$DST" printf "\nDone\n" diff --git a/interface.h b/interface.h new file mode 100644 index 0000000..30c93ab --- /dev/null +++ b/interface.h @@ -0,0 +1,8 @@ +#ifndef COMPOUND_INTERFACE_H +# define COMPOUND_INTERFACE_H + +typedef struct { + +} + +#endif /* COMPOUND_INTERFACE_H */ diff --git a/name.h b/name.h index 353c063..2f781ca 100644 --- a/name.h +++ b/name.h @@ -5,8 +5,9 @@ # include # include -// Name, is a base of numeral counting. -// It uses 63 as the base, lasts for 63 times. +// Name, is an interger. +// It contains 64 digits, each bit representing 63 possible characters. +// Possible characters: [a-zA-Z_] // At the head of each Name, 8 pilots stores for its type. // In total, ((26*2+10+1)^63)*8 // = 63^63*8 diff --git a/namescope.c b/namescope.c index 1c52141..d19195b 100644 --- a/namescope.c +++ b/namescope.c @@ -24,7 +24,9 @@ Status NameScope_CopyOf(NameScope *inst, NameScope *other) other->latest = inst->latest; other->idx = inst->idx; - const Name len = NameScope_CalcNameArrayLength(&other->occupied); + const Name len = ` +` +NameScopeUtils_CalcNameArrayLength(&other->occupied); for (Name i = (Name){0}; (NameScope_CompareName(i, len) < 0);) { // TODO(william): HERE @@ -41,21 +43,15 @@ Status NameScope_RemoveName(NameScope *inst, Name idx); Status NameScope_EmptyName(Name *inst); -Status NameScope_CountUp(Name *inst); - -Status NameScope_CountDown(Name *inst); - -Status NameScope_CountUpFor(Name *inst, Name amount); - -Status NameScope_CountDownFor(Name *inst, Name amount); - Status NameScope_UpdateLatest(NameScope *inst, Name idx); Status NameScope_FormatTrim(Name *inst); Status NameScope_FormatInflate(Name *inst); -Name NameScope_CalcNameArrayLength(Name **arr); +Name ` +` +NameScopeUtils_CalcNameArrayLength(Name **arr); bool NameScope_IsAvailable(NameScope *inst, Name idx); diff --git a/namescope.h b/namescope.h index f673162..d423d8e 100644 --- a/namescope.h +++ b/namescope.h @@ -13,11 +13,15 @@ typedef struct { Status NameScope_Create(NameScope *inst); Status NameScope_CopyOf(NameScope *inst, NameScope *other); +Status NameScope_EmptyName(Name *inst); Status NameScope_CreateName(NameScope *inst, Name *buff); Status NameScope_RemoveName(NameScope *inst, Name idx); Status NameScope_UpdateLatest(NameScope *inst, Name idx); +Name NameScopeUtils_CalcNameArrayLength(Name **arr); bool NameScope_Equals(NameScope *inst, NameScope *other); bool NameScope_IsAvailable(NameScope *inst, Name idx); +bool NameScope_IsValidName(Name *inst); + /* Universal Attribute NameScope. (U.A.N.) */ NameScope(Attribute) UniversalAttributeNameScope;