From 5f7a6c6f93de1dca1d1af6e8d8f3ac291b276e01 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 16 May 2024 00:04:42 +0800 Subject: [PATCH] (SOC) Storage Only Commit (ADD) Name, NameScope, Catlog, Object, String, Attribute, Char, Registry, Utils, Type, , , README (MOD) Array, Var, Status, MemMan, --- Array/include/array.h | 46 +++++ Array/src/array.c | 83 ++++++++ CMakeLists.txt | 13 +- MemMan/include/memman.h | 64 +++---- Object/include/object.h | 110 +++++++++++ Object/src/object.c | 0 README.md | 46 +++++ Stack/include/stack.h | 18 ++ Stack/src/stack.c | 28 +++ Status/include/status.h | 416 +++++++++++++++++++++++++++++----------- Status/src/status.c | 168 ++++++++++++++-- String/include/char.h | 9 + String/include/string.h | 97 ++++++++++ String/src/char.c | 0 String/src/string.c | 45 +++++ Utils/include/utils.h | 9 + Utils/src/utils.c | 16 ++ Var/include/var.h | 46 ++++- Var/src/var.c | 91 ++++++++- attr.h | 27 +++ catlog.c | 105 ++++++++++ catlog.h | 45 +++++ common.h | 119 +++++++++--- const.h | 17 ++ install | 7 +- name.c | 71 +++++++ name.h | 88 +++++++++ namescope.c | 0 namescope.h | 26 +++ platform.h | 14 ++ registry.h | 54 ++++++ type.h | 11 ++ 32 files changed, 1694 insertions(+), 195 deletions(-) create mode 100644 Array/include/array.h create mode 100644 Array/src/array.c create mode 100644 Object/include/object.h create mode 100644 Object/src/object.c create mode 100644 README.md create mode 100644 Stack/include/stack.h create mode 100644 Stack/src/stack.c create mode 100644 String/include/char.h create mode 100644 String/include/string.h create mode 100644 String/src/char.c create mode 100644 String/src/string.c create mode 100644 Utils/include/utils.h create mode 100644 Utils/src/utils.c create mode 100644 attr.h create mode 100755 catlog.c create mode 100755 catlog.h create mode 100644 const.h create mode 100644 name.c create mode 100644 name.h create mode 100644 namescope.c create mode 100644 namescope.h create mode 100644 platform.h create mode 100644 registry.h create mode 100644 type.h diff --git a/Array/include/array.h b/Array/include/array.h new file mode 100644 index 0000000..065a85a --- /dev/null +++ b/Array/include/array.h @@ -0,0 +1,46 @@ +#ifndef ARRAY_H +# define ARRAY_H + +# include + +typedef struct { + int len; + Var *members; +} Array; + +static Status ArrayIndexOutOfBound = { + .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 +}; + +/* Elementary. */ +Status Array_Create(Array *inst, int len); +Status Array_CopyOf(Array *inst, Array *other); +Status Array_Delete(Array *inst); +Status Array_GetIdx(Array *inst, Var *store, int index); +Status Array_SetIdx(Array *inst, Var *source, int index); +Status Array_Literalise(Array *inst, char const *store); +bool Array_Equal(Array *arr1, Array *arr2); + +/* Extensional. */ +Status ArrayUtils_Insert(Array *inst, Var *item, int index); +Status ArrayUtils_InsertArray(Array *inst, Array *items, int index); +Status ArrayUtils_Remove(Array *inst, int index); +Status ArrayUtils_RemoveArray(Array *inst, int off, int len); +Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len); +Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len); +Status ArrayUtils_Search(Array *inst, Var *item, int *store); +Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store); +Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index); +Status ArrayUtils_Revert(Array *inst); +bool ArrayUtils_IsEmpty(Array *inst); +bool ArrayUtils_IsBlank(Array *inst); + +#endif /* ARRAY_H */ diff --git a/Array/src/array.c b/Array/src/array.c new file mode 100644 index 0000000..e30c91f --- /dev/null +++ b/Array/src/array.c @@ -0,0 +1,83 @@ +#include + +Status Array_Create(Array *inst, int len) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + state((len < 0), InvalidArrayLength); + solve((!len), { inst->len = 0; inst->members = NULL; return NormalStatus; }) + + +} + +Status Array_CopyOf(Array *inst, Array *other) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + +} + +Status Array_Delete(Array *inst) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + +} + +Status Array_GetIdx(Array *inst, Var *store, int index) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + +} + +Status Array_SetIdx(Array *inst, Var *source, int index) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + +} + +Status Array_Literalise(Array *inst, char const *store) +{ + /* Skip unavailable inst and invalid param. */ + fails(inst, UnavailableInstance); + +} + +bool Array_Equal(Array *arr1, Array *arr2) +{ + /* Skip unavailable inst and invalid param. */ + state((arr1 == NULL || arr2 == NULL), false); + +} + + + + +// Status Array_Create(Array *inst, int len) +// { +// fails(inst, UnavailableInstance); +// state(len < 0, InvalidArrayLength); + +// Var arr[len] = {}; +// *inst = (Array) { +// .len = len, +// .members = arr +// }; + +// /* Initialise members. */ +// for (register int i = 0; i < inst->len; i++) { +// state(!(StatusUtils_IsOkay(Var_Create(&inst->members[i], NULL, 0, NULL))), +// error(RuntimeError, +// "Failed initialisations on var_create for array_create.")); +// } + +// return NormalStatus; +// } + +// Status Array_Delete(Array *inst); + +// bool ArrayUtils_IsEmpty(Array *inst); + +// bool Array_Equal(Array *arr1, Array *arr2); diff --git a/CMakeLists.txt b/CMakeLists.txt index 232f641..d15ae8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,14 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.5) project (Compound) -add_executable(CompoundTest test.c) +add_compile_options(-g -std=c99 -Wall -Wextra -Wformat) + +add_executable(CompoundTest test.c + Var/src/var.c + Status/src/status.c + Stack/src/stack.c + Array/src/array.c + Utils/src/utils.c + catlog.c + name.c) diff --git a/MemMan/include/memman.h b/MemMan/include/memman.h index bebc8da..5bad53d 100644 --- a/MemMan/include/memman.h +++ b/MemMan/include/memman.h @@ -1,8 +1,8 @@ -#ifndef MEMMAN_H -#define MEMMAN_H +#ifndef COMPOUND_MEMMAN_H +# define COMPOUND_MEMMAN_H -#include -#include +# include +# include /* Higher the priority it is, the less time for lifespan it has. @@ -10,48 +10,44 @@ typedef struct { void *addr; - int priority; // -1 for manual -} Memory; + size_t length; + int priority; // Negative for manual; Higher than 0 it is, + // higher the priority is. +} Memory; // 20 Bytes typedef struct { Memory *members; - size_t poolsize; + size_t volume; int priority; } MemoryPool; typedef struct { MemoryPool *members; void *(*allocator)(size_t sz); - void (*delocator)(void *addr); + void (*deallocator)(void *addr); } MemoryPoolManager; -Status memman_memory_allocate(Memory *inst, size_t sz); -Status memman_memory_reallocate(Memory *inst, size_t sz); -void memman_memory_release(Memory *inst); +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_Equal(Memory *inst, Memory *other); -Status memman_memorypool_create(MemoryPool *inst, Memory **members, - size_t poolsize); -Status memman_memorypool_constr(MemoryPool *inst, Memory **members, - size_t poolsize, int priority); -Status memman_memorypool_allocate(MemoryPool *inst, int idx, size_t sz); -Status memman_memorypool_reallocate(MemoryPool *inst, int idx, size_t sz); -Status memman_memorypool_release(MemoryPool *inst, int idx); -Status memman_memorypool_prioritise(MemoryPool *inst, int idx); -Status memman_memorypool_deprioritise(MemoryPool *inst, int idx); -void memman_memorypool_delete(MemoryPool *inst); +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 memman_memorypoolmanager_create(MemoryPoolManager *inst, - MemoryPool **membersptr); -Status memman_memorypoolmanager_constr(MemoryPoolManager *inst, - MemoryPool **membersptr, +Status MemMan_MemoryPoolManager_Create(MemoryPoolManager *inst, + MemoryPool **members); +Status MemMan_MemoryPoolManager_Constr(MemoryPoolManager *inst, + MemoryPool **members, void *(*allocator)(size_t sz), - void (*delocator)(void *addr)); -Status memman_memorypoolmanager_addmember(MemoryPoolManager *inst, - MemoryPool *newmember); -Status memman_memorypoolmanager_removemember(MemoryPoolManager *inst, int idx); -Status memman_memorypoolmanager_allocate(MemoryPoolManager *inst, - ArrayIndexerRange selected, size_t sz); -Status memman_memorypoolmanager_release(MemoryPoolManager *inst, - ArrayIndexerRange selected); + void (*deallocator)(void *addr)); +Status MemMan_MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2); +Status MemMan_MemoryPoolManager_Divide(MemoryPool *src, int off, int len); -#endif /* MEMMAN_H */ +#endif /* COMPOUND_MEMMAN_H */ diff --git a/Object/include/object.h b/Object/include/object.h new file mode 100644 index 0000000..1a589bc --- /dev/null +++ b/Object/include/object.h @@ -0,0 +1,110 @@ +#ifndef COMPOUND_OBJECT_H +# define COMPOUND_OBJECT_H + +# include +# include +# include + +typedef struct { // interface + Var *data; + Array buffer; + int (*Literalise)(void); + int (*Correspond)(Var *other); +} Object; + +# 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) {} + +typedef enum { + EXPOSURE_PUBLIC = 0, + EXPOSURE_PROTECTED, + EXPOSURE_PACKAGE, + EXPOSURE_PRIVATE +} Exposure; + +typedef struct { + Type type; + Name identity; +} Parameter; + +typedef struct { + Type type; + Name identity; + Array parameters; +} Function; + +typedef struct { + Exposure prefix; + bool dynamic; + bool constant; + Type type; + Name identity; + Array type(Parameter) parameters; +} Member; + +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; + +typedef struct { + OBJECT_IMPLEMENTATION + + char *identity; + + 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; + +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 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); + +#endif /* COMPOUND_OBJECT_H */ diff --git a/Object/src/object.c b/Object/src/object.c new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e0814fb --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# YOU NEED COMPOUND + +Generally, Compound is a library for general-purposes programming which you will find essential for higher level of abstraction based on c. + +It is worth noticing that, this library is completely aimed for creating another language. That means, every feature update is supposedly to serve the language. + +--- +## BUILDING + +To build Compound, all you need is to type as follow in a terminal: +```shell +cmake . # Generate "Makefile" +make # Build +``` + +> *PLEASE NOTICE* +> *Compound is originally designed for GNU/Linux and other Unix-like operating systems.* +> *Support for MS Windows will be possible in the future.* + +### Platform specifications +```C +/* Copied on Fri 10 May 16:24:09 CST 2024 */ + +# if defined __x86_64__ || defined __x86_64 // For 64-bits operating systems. +# define __COMPOUND_64__ +# define __COMPOUND_PRODUCT__ compound64 +# elif defined __i386__ || __i486__ || __i586__ || __i686__ || _X86_ || __X86__ // For 32-bits operating systems. +# define __COMPOUND_32__ +# define __COMPOUND_PRODUCT__ compound32 +# else +# error Platform not supported. Please issue this on github.com/Wilhelm-Lee/Compound --William +# endif +``` +Compound, now, roughly divides platform compatibilities into 2 major parts, the 64-bits and the 32-bits. +This idea is ready for refinements, you can put up such suggestions and they're welcomed. + +## Installation +To install Compound, all you need to do is to run `install`, something like below. +```shell +./install # (Require root privilege) +``` + +If you cannot execute ./install script, try to add permission for execution: +```shell +chmod +x ./install # (Require root privilege) +``` diff --git a/Stack/include/stack.h b/Stack/include/stack.h new file mode 100644 index 0000000..a92ceaf --- /dev/null +++ b/Stack/include/stack.h @@ -0,0 +1,18 @@ +#ifndef STACK_H +# define STACK_H + +# include +# include + +typedef struct { + Var *members; + int len; +} Stack; + +Status Stack_Create(Stack *inst, int len); +Status Stack_CopyOf(Stack *inst, Stack *other); +Status Stack_Push(Stack *inst, Var *item); +Status Stack_Pop(Stack *inst); +bool Stack_IsEmpty(Stack *inst); + +#endif /* STACK_H */ diff --git a/Stack/src/stack.c b/Stack/src/stack.c new file mode 100644 index 0000000..0931d82 --- /dev/null +++ b/Stack/src/stack.c @@ -0,0 +1,28 @@ +#include + +Status Stack_Create(Stack *inst, int len) +{ + // /* Skip once len is negative. */ + // state((len < 0), InvalidParameter); + + // /* Initialise before access. */ + // if (inst == NULL) { + // *inst = (Stack) { + // .members = NULL, + // .len = len + // }; + + // /* Assign for each member. */ + // inst->members = malloc(len * sizeof(Var)); + // for (register int i = 0; i < len; i++) { + // inst->members[i] = (Var) { + // .addr = NULL, + // .sz = 0 + // }; + // } + // } +} +Status Stack_CopyOf(Stack *inst, Stack *other); +Status Stack_Push(Stack *inst, Var *item); +Status Stack_Pop(Stack *inst); +bool Stack_IsEmpty(Stack *inst); diff --git a/Status/include/status.h b/Status/include/status.h index fecc837..475f43a 100644 --- a/Status/include/status.h +++ b/Status/include/status.h @@ -9,7 +9,9 @@ # include # include -# define __HERE__ { .file = __FILE__, .line = __LINE__, .func = __func__ } +# include +# include +# include /* Status characteristics */ typedef enum { @@ -18,22 +20,30 @@ typedef enum { STATUS_ERROR = 1 } StatusCharacteristics; -//!!! UNKNOWN ENTITY !!! -// enum { -// ARGUE_FINALISED = 0b01, -// ARGUE_UNSETTLED =-0b01, -// ARGUE_POSITIVE = 0b10, -// ARGUE_NEGATIVE = -0b10, -// }; +typedef enum { + /* Settlement. */ + ARGUE_RESULT_FINALISED = 0b01, + ARGUE_RESULT_UNSETTLED = -0b01, + + /* Nature. */ + ARGUE_RESULT_POSITIVE = 0b10, + ARGUE_RESULT_NEGATIVE = -0b10, +} ArgueResult; /* Indicated the exact location where the "issue" was occurred at. */ typedef struct { - const char *file; + char *file; int line; - const char *func; + char *func; } Location; +# define __HERE__ (Location){ \ + .file = (char *)__FILE__, \ + .line = __LINE__, \ + .func = (char *)__func__ \ +} + /* Common return type for reporting functions that require to give more information about the procedure. */ typedef struct _Status { @@ -43,36 +53,41 @@ typedef struct _Status { Otherwise, the function would just return the structure Status. */ char *description; int characteristic; + Location loc; struct _Status *prev; } Status; -/* "Report" recollects essential informations, included but not limited to - Status and others for making an report for debugging and such. */ -typedef struct { - Status stat; - Location pos; - char *originator; - struct tm time; - int priority; -} Report; +/* -typedef struct { - FILE **dests_ref; - Report **reports_ref; - int totalreports; - int reportsent; - struct timespec elapsed; -} ReportSender; +{value "description" characteristic prev} -typedef Status (*ReportSendingTask) (FILE **, Report *); -typedef int ReportSendingTaskID; +"%d \"%s\" %d %p" -typedef struct { - ReportSendingTask *tasks_ref; - int sendercount; - int finishedcount; - Status *senderreturn; -} ReportSendingManager; +*/ + +# 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 + +# define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p" + +typedef enum { + REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value. + REPORT_SENDING_PRIORITY_FATAL, + REPORT_SENDING_PRIORITY_EXCEPTIONAL, + REPORT_SENDING_PRIORITY_CRITICAL, + REPORT_SENDING_PRIORITY_MAJOR, + REPORT_SENDING_PRIORITY_NORMAL, + REPORT_SENDING_PRIORITY_MINOR, + REPORT_SENDING_PRIORITY_DEBUG, + REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value. +} ReportSendingPriority; typedef enum { REPORT_SENDING_TASK_STATUS_FINISHED = 0, @@ -82,30 +97,97 @@ typedef enum { REPORT_SENDING_TASK_STATUS_NOTFOUND } ReportSendingTaskStatus; -typedef Status (*Argue) (Report); - +/* "Report" recollects essential informations, included but not limited to + Status and others for making an report for debugging and such. */ typedef struct { - Argue argue_start; // Implicitly converting thrd_start_t to Argue - void *external_param; -} ArgueStarter; + Status stat; + char *originator; + time_t time; + ReportSendingPriority priority; + ReportSendingTaskStatus status; + FILE *dest; // The destination where the report is sending to. +} Report; + +/* + +TIME [PRIORITY] STATUSNAME (ORIGINATOR): STATUS.DESCRIPTION + at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC + at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC + at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC + at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC + + +Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buffer was unavailable. + at /external/Documents/Projects/Compound/Status/src/status.c:104, report_literalise + at /external/Documents/Projects/Compound/Status/src/status.c:114, reportsender_send + at /external/Documents/Projects/Compound/Status/src/status.c:69, _throw +!!!!at /external/Documents/Projects/Compound/Array/src/array.c:16, array_create + at /external/Documents/Projects/Compound/test.c:24, main + +*/ + +# define REPORT_LITERALISE_HEADER_FORMAT "%ld [%s] %s (%s): %s" +# 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(PRIORITY, STATUSNAME, \ + ORIGINATOR, DESCRIPTION) \ + (INT64_DIGITS_DEC + strlen(PRIORITY) + strlen(STATUSNAME) + \ + strlen(ORIGINATOR) + strlen(DESCRIPTION) + 9) // Does not count '\0' +# 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 -/* Argument levels (qualities) */ typedef enum { - ARGUMENT_NONE = 0, - ARGUMENT_MINOR, - ARGUMENT_NORMAL, - ARGUMENT_MAJOR, - ARGUMENT_CRITICAL, - ARGUMENT_SEVERE, - ARGUMENT_ALL, -} ArgumentLevel; + REPORT_SENDER_RESULT_FINISHED, + REPORT_SENDER_RESULT_PROGRESSING, + REPORT_SENDER_RESULT_PENDING +} ReportSenderResult; typedef struct { - ReportSender *streams; - ArgueStarter handler; - ArgumentLevel level; - bool muted; -} Argument; + thrd_t thread; + Report *report; // The report for sending. + time_t elapsed; // The individual elapsed time for each report. (Array) + ReportSenderResult result; + bool successful; +} ReportSender; + +typedef int (*ReportSendingTask)(Report *rep); +typedef int ReportSendingTaskID; + +typedef struct { + ReportSendingTask *tasks; // Array Ref + int sendercount; + int finishedcount; + int *results; // Array +} ReportSendingManager; + +// typedef thrd_start_t ArgueStart; + +// typedef struct { +// ArgueStart handler; +// void *external_param; +// } ArgueStartParam; + +// /* Argument levels (qualities) */ +// typedef enum { +// ARGUMENT_NONE = 0, +// ARGUMENT_MINOR, +// ARGUMENT_NORMAL, +// ARGUMENT_MAJOR, +// ARGUMENT_CRITICAL, +// ARGUMENT_SEVERE, +// ARGUMENT_ALL, +// } ArgumentLevel; + +// typedef struct { +// ReportSender stream; +// ArgueStartParam handler; // Obsolete? +// ArgumentLevel level; +// bool muted; +// } Argument; // typedef struct { // Argument *members; @@ -114,73 +196,58 @@ typedef struct { # define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX +bool Location_Equal(Location lc1, Location lc2); +void Status_Dump(Status stat, Status *statbuff, int idx); +bool Status_Equal(Status stat1, Status stat2); +bool StatusUtils_HasPrev(Status stat); +bool StatusUtils_IsOkay(Status stat); +bool StatusUtils_IsValid(Status stat); +bool StatusUtils_IsRecursive(Status stat); +int StatusUtils_Depth(Status *stat); +Status +Report_Create(Report *inst, Status *stat, FILE *dest, char *originator, + int priority); bool -status_issueposition_compare(Location lc1, Location lc2); -bool -status_hasprev(Status stat); -bool -status_isnormal(Status stat); -bool -status_isvalid(Status stat); -bool -status_recursive(Status stat); -void -status_dump(Status stat, Status *statbuff, int idx); -bool -status_compare(Status stat1, Status stat2); - - -bool -report_compare(Report repo1, Report repo2); +Report_Equal(Report repo1, Report repo2); +Status +Report_Literalise(Report *inst, char *buff); Status -reportsender_create(ReportSender *inst, FILE **dests_ref, - ReportSendingTask *tasks_ref); +ReportSender_Create(ReportSender *inst, Report *report); Status -reportsender_send(ReportSender sender, ReportSendingTask *tasks_ref); - +ReportSender_Send(ReportSender *inst, ReportSendingTask task); +ReportSendingTaskStatus +ReportSender_GetStatus(ReportSender *inst); ReportSendingTaskID -reportsendingmanager_appendtask(ReportSendingManager *inst, +ReportSenderManager_AppendTask(ReportSendingManager *inst, ReportSendingTask task); -Status -reportsendingmanager_removetask(ReportSendingManager *inst, - ReportSendingTaskID taskid); -ReportSendingTaskStatus -reportsendingmanager_taskstatus(ReportSendingManager *inst, - ReportSendingTaskID taskid); +Status ReportSenderManager_RemoveTask(ReportSendingManager *inst, + ReportSendingTaskID taskid); + +// Status +// arguestarter_create(ArgueStartParam *inst, void *external_param); +// Status +// arguestarter_constr(ArgueStartParam *inst, ArgueStart argue_start, +// void *external_param); +// Status +// arguestarter_start(ArgueStartParam *inst); +// bool +// arguestarter_equal(ArgueStartParam *inst1, ArgueStartParam *inst2); +// Status arguestarter_current(void); +// Status arguestarter_sleep(const struct timespec *time_point, +// struct timespec *remaining); +// void arguestarter_exit(int code) __attribute__ ((__noreturn__)); +// Status arguestarter_join(ArgueStart thrd); -Status -arguestarter_create(ArgueStarter *inst, void *external_param); -Status -arguestarter_constr(ArgueStarter *inst, Argue argue_start, - void *external_param); -Status -arguestarter_start(ArgueStarter *inst); -static inline int -arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2) -{ - return (inst1->argue_start == inst2->argue_start) - || (inst1->external_param == inst2->external_param); -} -Status arguestarter_current(void); -Status arguestarter_sleep(const struct timespec *time_point, - struct timespec *remaining); -void arguestarter_exit(int code) __attribute__ ((__noreturn__)); -Status arguestarter_join(Argue thrd); +// Status +// argument_create(Argument *inst, ReportSender *streams, ArgueStartParam handler, +// int level, bool muted); - -Status -argument_create(Argument *inst, ReportSender *streams, ArgueStarter handler); -Status -argument_constr(Argument *inst, ReportSender *streams, ArgueStarter handler, - int level, bool muted); - - -// -------------------------------------------------------- +// ---------------------ELEMENTARY------------------------- static Status UnknownStatus = { .description = "An unknown status.", @@ -200,12 +267,18 @@ static Status ErrorStatus = { .prev = NULL }; -// -------------------------------------------------------- +// ----------------------EXTENDED-------------------------- + +static Status MemoryViolation = { + .description = "Illegal access on certain memory address.", + .characteristic = STATUS_ERROR, + .prev = &ErrorStatus +}; static Status NullPointerAccounted = { .description = "An involving null pointer was not accepted.", .characteristic = STATUS_ERROR, - .prev = &ErrorStatus + .prev = &MemoryViolation }; static Status InvalidParameter = { @@ -226,4 +299,127 @@ static Status ArithmeticError = { .prev = &ErrorStatus }; +static Status RuntimeError = { + .description = "A runtime error occurred.", + .characteristic = STATUS_ERROR, + .prev = &ErrorStatus +}; + +static Status ArrayLengthError = { + .description = "Given array length does not meet the requirement.", + .characteristic = STATUS_ERROR, + .prev = &ErrorStatus +}; + +static Status VariableFormatMismatch = { + .description = "Given format does not match with given subjects.", + .characteristic = STATUS_ERROR, + .prev = &ErrorStatus +}; + +static Status ImprecisionError = { + .description = "Precision was not enough for handling the calculation.", + .characteristic = STATUS_ERROR, + .prev = &RuntimeError +}; + +// ---------------USER DEFINED | RUNTIME------------------- + +static Status UnavailableInstance = { + .description = "An unavailable instance was given for initialisation.", + .characteristic = STATUS_ERROR, + .prev = &NullPointerAccounted +}; + +static Status UnavailableParameter = { + .description = "An unavailable instance was given as a parameter.", + .characteristic = STATUS_ERROR, + .prev = &UnavailableInstance +}; + +static Status InvalidReportTask = { + .description = "An unavailable or illegal report task was given.", + .characteristic = STATUS_ERROR, + .prev = &InvalidParameter +}; + +static Status UnableToThrowError = { + .description = "Unable to report an exceptional situation.", + .characteristic = STATUS_ERROR, + .prev = &RuntimeError +}; + +static Status ReadWriteError = { + .description = "Error occurred during IO session.", + .characteristic = STATUS_ERROR, + .prev = &RuntimeError +}; + +static Status FileNotFound = { + .description = "Target file was unavailable and unable to find.", + .characteristic = STATUS_ERROR, + .prev = &ReadWriteError +}; + +static Status InvalidFileName = { + .description = "Given file name was invalid.", + .characteristic = STATUS_ERROR, + .prev = &ReadWriteError +}; + +static Status ReportThrown = { + .description = "This function has thrown a report, " + "following instructions aborted.", + .characteristic = STATUS_ERROR, + .prev = &RuntimeError +}; + +static Status ReportMessageLengthTooLong = { + .description = "Given message is too long.", + .characteristic = STATUS_ERROR, + .prev = &ArrayLengthError +}; + +// ======================================================== + +# define ensure(e, c) { \ + Status stat = e; \ + solve(!(StatusUtils_IsOkay(stat)), { \ + Report rep = stamp(error(stat, c), (char *)__func__); \ + (void)throw(rep); \ + return ReportThrown; \ + }) \ +} + +/* Add location parameter requirement in order to give proper information + * before throwing the report out. */ +# define throw(report) __throw(report, __HERE__) + +/* Useless in C, only for human to see. + Probably rewrite this in Classify. */ +# define throws(e) + +ReportSendingTaskID __throw(Report report, Location loc); +Report catch(ReportSendingTaskID taskid); +static int HANDLER(void *report) +{ + /* Throw UnableToThrowError when param is unavailable. */ + if (report == NULL) { + /* Create report on this. */ + Report e; + Report_Create( + &e, + &error(UnableToThrowError, "Cannot perform throwing. Aborted."), + stderr, nameof(DEFAULT_ARGUE_STARTER), + REPORT_SENDING_PRIORITY_FATAL); + + /* Perform throwing. */ + (void)_throw(e); // Throw the report alone. + return 1; + } + + (void)_throw(*(Report *)report); // Lonely _throw, no catch will company. + return 0; +} + #endif /* COMPOUND_STATUS_H */ diff --git a/Status/src/status.c b/Status/src/status.c index fcb72be..1d08cb6 100644 --- a/Status/src/status.c +++ b/Status/src/status.c @@ -1,30 +1,174 @@ +#include #include -bool status_issueposition_compare(Location lc1, Location lc2) { +bool status_issuelocation_equal(Location lc1, Location lc2) { return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) && (!strcmp(lc1.func, lc2.func))); } -bool status_hasprev(Status stat) { return (stat.prev != NULL); } +bool status_hasprev(Status stat) { + /* Skip when stat is unavailable for accessing. */ + state(status_equal(stat, (Status){}), false); -bool status_isnormal(Status stat) { return (!stat.characteristic); } + return (stat.prev != NULL); +} + +bool status_isokay(Status stat) { return (!stat.characteristic); } + +bool status_isvalid(Status stat) { + return (!strcmp(stat.description, "") && stat.characteristic >= 0 && + stat.prev != NULL); +} bool status_recursive(Status stat) { return (stat.prev != NULL && stat.prev == &stat); } -void status_dump(Status stat, Status *statbuff, int idx) { - if (statbuff == NULL || !status_hasprev(stat) || idx < 0) { - return; - } +void status_dump(Status inst, Status *statbuff, int idx) { - statbuff[idx] = stat; + /* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */ + solve((statbuff == NULL || !status_hasprev(inst) || idx < 0), return;); - status_dump(*stat.prev, statbuff, ++idx); + statbuff[idx] = inst; + (void)printf("status_dump: Index %d has assigned with %p\n", idx, &inst); + + status_dump(*inst.prev, statbuff, ++idx); } -bool status_compare(Status stat1, Status stat2) { - return (!strcmp(stat1.description, stat2.description) && +bool status_equal(Status stat1, Status stat2) { + + /* 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); + + /* True for equality; False for inequality. */ + return ((stat1.value == stat2.value) && + (!strcmp(stat1.description, stat2.description)) && (stat1.characteristic == stat2.characteristic) && - (!status_compare(*stat1.prev, *stat2.prev))); + (status_equal(*stat1.prev, *stat2.prev))); +} + +int status_depth(Status *stat) { + /* Skip unavailable stat. */ + state((stat == NULL), -1); + + Status *p = stat; // Include this layer of Status. + int cnt = 1; + while (p != NULL) { + if (status_recursive(*p) || !status_hasprev(*stat)) break; + + p = p->prev; + cnt += 1; + } + + return cnt; +} + +Status report_create(Report *inst, Status *stat, FILE *dest, char *originator, + int priority) { + /* Skip unavailable parameters. */ + fails(inst, UnavailableInstance); + fails(stat, error(InvalidParameter, "Given originator was null.")); + fails(originator, error(InvalidParameter, "Given originator was null.")); + state(priority < 0, error(InvalidParameter, "Given priority was negative.")); + + /* Copy and assign. */ + inst->stat = *stat; + inst->originator = originator; + inst->time = time(NULL); + inst->priority = priority; + inst->status = REPORT_SENDING_TASK_STATUS_PENDING; + inst->dest = (dest == NULL ? stderr : dest); + + return NormalStatus; +} + +Status report_literalise(Report *inst, char *buff) { + /* Skip when inst or buff is unavailable. */ + fails(inst, UnavailableInstance); + fails(buff, error(InvalidParameter, "Given buffer was unavailable.")); + + const int depth = status_depth(&inst->stat); + char buff // TODO(william): HERE +} + +Status reportsender_create(ReportSender *inst, Report *report) { + fails(inst, UnavailableInstance); + fails(report, error(UnavailableParameter, "Given report was unavailable.")); + + thrd_create(&inst->thread, &HANDLER, report); + *inst->report = *report; + inst->elapsed = 0; + inst->result = REPORT_SENDER_RESULT_PENDING; + inst->successful = false; + + return NormalStatus; +} + +Status reportsender_send(ReportSender *inst, ReportSendingTask task) { + /* Skip when inst or task is unavailable. */ + fails(inst, + error(UnavailableInstance, "Report sender was given unavailable.")); + fails(task, InvalidReportTask); + + /* Assign for dest. */ + const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest); + // char buff[]; + // TODO(william): HERE, report_literalise + + /* Write/Send data. */ + inst->report->status = REPORT_SENDING_TASK_STATUS_PROCEEDING; + if (!fprintf(dest, buff)) { + } + + /* Sent successfully! Mark down properties. */ +} + +// bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2) +// { +// /* Skip when either inst1 or inst2 is unavailable. */ +// state(inst1 == NULL || inst2 == NULL, false); + +// return (inst1->argue_start == inst2->argue_start) +// || (inst1->external_param == inst2->external_param); +// } + +ReportSendingTaskID _throw(Report report, Location loc) { + // /* Create new a instance of ReportSender. */ + // ReportSender sender; + // reportsender_create(&sender, stderr); + + // /* Send message. */ + // /* Initialise sender's thread. */ + // thrd_t sending; + // /* Skip on failing on creating thread. */ + // if (!thrd_create(&sending, starter, NULL)) { + + // /* Conclude the session of sender. */ + // report.status = REPORT_SENDING_TASK_STATUS_FINISHED, + // report.result = (ARGUE_RESULT_FINALISED | ARGUE_RESULT_NEGATIVE); + + // sender.result = REPORT_SENDER_RESULT_FINISHED; + // sender.successful = false; + + // return -1; + // } + + // /* Perform sending. */ + // reportsender_send(&sender, NULL); + + /* Initialise sender. */ + ReportSender sender; + /* Return with -1 when initialisation failed. */ + state(!(status_isokay(reportsender_create(&sender, &report))), -1); + + /* Inject location information. Could be more elegant, though. */ + sender.report->stat.loc = loc; + + /* Send. */ /* Return -1 when failed on sending. */ + state(!status_isokay(reportsender_send(&sender, HANDLER)), -1); + + } diff --git a/String/include/char.h b/String/include/char.h new file mode 100644 index 0000000..1cf242f --- /dev/null +++ b/String/include/char.h @@ -0,0 +1,9 @@ +#ifndef COMPOUND_CHAR_H +# define COMPOUND_CHAR_H + +typedef struct { + int value; + int width; +} Char; // 8 Bytes + +#endif /* COMPOUND_CHAR_H */ diff --git a/String/include/string.h b/String/include/string.h new file mode 100644 index 0000000..fb45682 --- /dev/null +++ b/String/include/string.h @@ -0,0 +1,97 @@ +#ifndef COMPOUND_STRING_H +# define COMPOUND_STRING_H + +# include +# include + +# include +# include + +typedef enum { + ASCII, + UTF8, + /* etc. */ +} StringEncoding; + +typedef Array(Char) String; + +/* Elementary. */ +Status String_Create(String *inst, int len); +Status String_CopyOf(String *inst, String *other); +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); +Status String_Encode(String *inst, StringEncoding encoding) + throws(UnsupportedEncoding EncodingError DecodingError); +Status String_Decode(String *inst, StringEncoding encoding); + throws(UnsupportedEncoding EncodingError DecodingError); +bool String_Equal(String *arr1, String *arr2); + +/* Extensional. */ +Status StringUtils_FromInteger(String *inst, int value); +Status StringUtils_FromShortInteger(String *inst, short int value); +Status StringUtils_FromLongInteger(String *inst, long int value); +Status StringUtils_FromLongLongInteger(String *inst, long long int value); +Status StringUtils_FromFloat(String *inst, float value); +Status StringUtils_FromDouble(String *inst, double value); +Status StringUtils_FromLongDouble(String *inst, long double value); +Status StringUtils_FromComplexInteger(String *inst, _Complex int value); +Status StringUtils_FromComplexShortInteger(String *inst, _Complex short int value); +Status StringUtils_FromComplexLongInteger(String *inst, _Complex long int value); +Status StringUtils_FromComplexLongLongInteger(String *inst, _Complex long long value); +Status StringUtils_FromComplexFloat(String *inst, _Complex float value); +Status StringUtils_FromComplexDouble(String *inst, _Complex double value); +Status StringUtils_FromComplexLongDouble(String *inst, _Complex long double value); +Status StringUtils_FromUnsignedInteger(String *inst, unsigned int value); +Status StringUtils_FromUnsignedShortInteger(String *inst, unsigned short int value); +Status StringUtils_FromUnsignedLongInteger(String *inst, unsigned long int value); +Status StringUtils_FromUnsignedLongLongInteger(String *inst, unsigned long long int value); +Status StringUtils_FromUnsignedComplexInteger(String *inst, unsigned _Complex int value); +Status StringUtils_FromUnsignedComplexShortInteger(String *inst, unsigned _Complex short int value); +Status StringUtils_FromUnsignedComplexLongInteger(String *inst, unsigned _Complex long int value); +Status StringUtils_FromUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long value); +Status StringUtils_FromAddress(String *inst, void *store); +Status StringUtils_FromCharBuff(String *inst, char const *buff, int base); +Status StringUtils_FromWideCharBuff(String *inst, wchar_t const *wbuff, int base); +Status StringUtils_ToInteger(String *inst, int *store); +Status StringUtils_ToShortInteger(String *inst, short int *store); +Status StringUtils_ToLongInteger(String *inst, long int *store); +Status StringUtils_ToLongLongInteger(String *inst, long long int *store); +Status StringUtils_ToFloat(String *inst, float *store); +Status StringUtils_ToDouble(String *inst, double *store); +Status StringUtils_ToLongDouble(String *inst, long double *store); +Status StringUtils_ToComplexInteger(String *inst, _Complex int *store); +Status StringUtils_ToComplexShortInteger(String *inst, _Complex short int *store); +Status StringUtils_ToComplexLongInteger(String *inst, _Complex long int *store); +Status StringUtils_ToComplexLongLongInteger(String *inst, _Complex long long *store); +Status StringUtils_ToComplexFloat(String *inst, _Complex float *store); +Status StringUtils_ToComplexDouble(String *inst, _Complex double *store); +Status StringUtils_ToUnsignedInteger(String *inst, unsigned int *store); +Status StringUtils_ToUnsignedShortInteger(String *inst, unsigned short int *store); +Status StringUtils_ToUnsignedLongInteger(String *inst, unsigned long int *store); +Status StringUtils_ToUnsignedLongLongInteger(String *inst, unsigned long long int *store); +Status StringUtils_ToUnsignedComplexInteger(String *inst, unsigned _Complex int *store); +Status StringUtils_ToUnsignedComplexShortInteger(String *inst, unsigned _Complex short int *store); +Status StringUtils_ToUnsignedComplexLongInteger(String *inst, unsigned _Complex long int *store); +Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long *store); +Status StringUtils_ToAddress(String *inst, void **store); +Status StringUtils_ToCharBuff(String *inst, char const *buff, int base); +Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff, int base); +Status StringUtils_Format(String *inst, const String *__restrict fmt, ...); +Status StringUtils_Tokenise(String *inst, const String *delim, String *store); +int StringUtils_Compare(String *a, String *b); + +static Status StringConversionPrecisionError = { + .description = "Unpreventable precision loss was found during conversion " + "between string and raw data.", + .characteristic = STATUS_ERROR, + .prev = &ImprecisionError +}; + +typedef Array(int) InfiniteInteger; +typedef Array(double) InfiniteFloatingPoint; +typedef Array(_Complex double) InfintieComplex; + + +#endif /* COMPOUND_STRING_H */ diff --git a/String/src/char.c b/String/src/char.c new file mode 100644 index 0000000..e69de29 diff --git a/String/src/string.c b/String/src/string.c new file mode 100644 index 0000000..b9c3f0d --- /dev/null +++ b/String/src/string.c @@ -0,0 +1,45 @@ +#include + +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; + }) + + return NormalStatus; +} + +Status String_CopyOf(String *inst, String *other) +{ + fails(inst, UnavailableInstance); +} + +Status String_Delete(String *inst) +{ + fails(inst, UnavailableInstance); +} + +Status String_GetIdx(String *inst, Char *store, int index) +{ + fails(inst, UnavailableInstance); +} + +Status String_SetIdx(String *inst, Char *source, int index) +{ + fails(inst, UnavailableInstance); +} + +Status String_Literalise(String *inst, String *store) +{ + fails(inst, UnavailableInstance); +} + +bool String_Equal(String *arr1, String *arr2) +{ + fails(inst, UnavailableInstance); +} + diff --git a/Utils/include/utils.h b/Utils/include/utils.h new file mode 100644 index 0000000..a28fffe --- /dev/null +++ b/Utils/include/utils.h @@ -0,0 +1,9 @@ +#ifndef COMPOUND_UTILS_H +# define COMPOUND_UTILS_H + +# include +# include + +int Utils_CalcDigits(long long n); + +#endif /* COMPOUND_UTILS_H */ diff --git a/Utils/src/utils.c b/Utils/src/utils.c new file mode 100644 index 0000000..e33f767 --- /dev/null +++ b/Utils/src/utils.c @@ -0,0 +1,16 @@ +#include + +int Utils_CalcDigits(long long n) +{ + if (n == 0) { + return 1; + } + + n = llabs(n); + + /* Accumulate. */ + register int i; + for (i = 0; n; i++) n /= 10; + + return i; +} diff --git a/Var/include/var.h b/Var/include/var.h index 71824a3..9a23f77 100644 --- a/Var/include/var.h +++ b/Var/include/var.h @@ -2,18 +2,52 @@ # define COMPOUND_VAR # include -# include -# include -# include + # include +# include + +# define VAR_IDENTITY_LENGTH 64 +# define VAR_LITERALISE_LENGTH (VAR_IDENTITY_LENGTH + 16 + 9 + 10) +# define VAR_LITERALISE_FORMAT ("%s @[%p]: %ld") +# define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ " + +static Status IllegalVarIdentity = { + .description = "Given identity does not fit the standard of Var Naming " + "convension.", + .characteristic = STATUS_ERROR, + .prev = &InvalidParameter +}; + +// static Status VarIdentityTooLong = { +// .description = "Given identity has longer length that the maximum length " +// "limitation.", +// .characteristic = STATUS_ERROR, +// .prev = &IllegalVarIdentity +// }; typedef struct { + + /* Data */ void *addr; - size_t sz; + size_t size; + + /* Identification */ + char *identity; // Maximum up to VAR_IDENTITY_LENGTH + } Var; -void var_swap(Var *v1, Var *v2); +// typedef struct { +// union { +// /* Self Pointing (Var) */ +// const Var *__this__; +// }; +// } _Var; -int var_literalise(Var v, wchar_t **wbuff); +Status Var_Create(Var *inst, void *addr, size_t size, char *identity); +Status Var_CopyOf(Var *inst, Var *other); +void Var_Delete(Var *inst); +Status VarUtils_Literalise(Var *inst, char *buff); +void VarUtils_Swap(Var *v1, Var *v2); +bool VarUtils_IsIdentityLegal(char *identity); #endif /* COMPOUND_VAR */ diff --git a/Var/src/var.c b/Var/src/var.c index 2325ee3..0f680f7 100644 --- a/Var/src/var.c +++ b/Var/src/var.c @@ -1,17 +1,94 @@ #include -void var_swap(Var *v1, Var *v2) +Status Var_Create(Var *inst, void *addr, size_t size, char *identity) { - Var v3 = { - .addr = v1->addr, - .sz = v1->sz - }; + /* Skip when inst is unavailable. */ + fails(inst, UnavailableInstance); + /* Skip when identity is unavailable. */ + fails(identity, NullPointerAccounted); + /* Skip when identity does not pass the examine. */ + state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity); + + inst->addr = addr; + inst->size = size; + *inst->identity = *identity; + return NormalStatus; +} + +Status Var_CopyOf(Var *inst, Var *other) +{ + /* Skip when inst or other is unavailable. */ + fails(inst, UnavailableInstance); + fails(other, NullPointerAccounted); + + /* Copy and assign. */ + inst->addr = other->addr; + inst->size = other->size; + *inst->identity = *other->identity; + + return NormalStatus; +} + +void Var_Delete(Var *inst) +{ + /* Skip when inst or inst->addr is unavailable. */ + svoid(inst == NULL || inst->addr == NULL); + + inst->addr = NULL; + inst->size = 0; + *inst->identity = 0; +} + +void VarUtils_Swap(Var *v1, Var *v2) +{ + /* Skip when v1 or v2 is unavailable. */ + svoid(v1 == NULL || v2 == NULL); + + Var v3 = *v1; *v1 = *v2; *v2 = v3; } -int var_literalise(Var v, wchar_t **wbuff) +Status VarUtils_Literalise(Var *inst, char *buff) { - return swprintf(*wbuff, (2*8 + 6), L"@[%p] +%u", v.addr, v.sz); + /* Skip when inst is unavailable. */ + state(inst == NULL, UnavailableInstance); + + /* Write into buffer. */ + state(!sprintf(buff, VAR_LITERALISE_FORMAT, inst->identity, + inst->addr, inst->size), + error(RuntimeError, "Sprintf returned 0 where it should never do.")); + + return NormalStatus; +} + +bool VarUtils_IsIdentityLegal(char *identity) +{ + /* Skip when identity is unavailable. */ + state(identity == NULL, false); + + const int len = strlen(identity); + + /* Skip when identity is empty. */ + state(len == 0, false); + + /* Skip when the first char is not within alphabet. */ + state(ATRANGE('a', 'z', identity[0]) + || ATRANGE('A', 'Z', identity[0]), false); + + /* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */ + state(len > VAR_IDENTITY_LENGTH, false); + + /* Skip when identity has space and illegal characters in it. */ + const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR); + for (register int i = 0; i < len; i++) { + for (register int j = 0; j < illegal_len; j++) { + if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) { + return false; + } + } + } + + return true; } diff --git a/attr.h b/attr.h new file mode 100644 index 0000000..2dd68df --- /dev/null +++ b/attr.h @@ -0,0 +1,27 @@ +#ifndef COMPOUND_ATTR_H +# define COMPOUND_ATTR_H + +# 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 *); + struct _Attribute *prev; +} attr(Executive) Attribute; + +/* The base of every attribute. */ +# define Attributable (Attribute){\ + .value = 0,\ + .exec = HANDLER /* Use report handler here. */\ +}; + +#endif /* COMPOUND_ATTR_H */ diff --git a/catlog.c b/catlog.c new file mode 100755 index 0000000..ab0e6bf --- /dev/null +++ b/catlog.c @@ -0,0 +1,105 @@ +#include +#include + +Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level, + char const *originator, char const *msg) +{ + /* Skip unavailable instances and parameters. */ + fails(inst, UnavailableInstance); + state((originator == NULL || msg == NULL), InvalidParameter); + + inst->time = time(NULL); + inst->level = level; + *inst->originator = *originator; + *inst->msg = *msg; + + return NormalStatus; +} + +Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other) +{ + /* Skip unavailable instances and parameters. */ + fails(inst, UnavailableInstance); + fails(other, InvalidParameter); + + *inst = *other; + + return NormalStatus; +} + +bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other) +{ + /* Skip unavailable instances and parameters. */ + state((inst == NULL || other == NULL), false); + + return ( + inst->time == other->time && + inst->level == other->level && + (!strcmp(inst->originator, other->originator)) && + (!strcmp(inst->msg, other->msg)) + ); +} + +Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst) +{ + /* Skip unavailable instances and parameters. */ + fails(inst, UnavailableInstance); + fails(msg, InvalidParameter); + + /* Copy and assign, with detections. */ + inst->msg = *msg; + inst->dst = (dst == NULL ? (stdout) : dst); + inst->successful = false; + inst->elapsed = (struct timespec){.tv_sec = 0, .tv_nsec = 0}; + + return NormalStatus; +} + +Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other) +{ + /* Skip unavailable instances and parameters. */ + fails(inst, UnavailableInstance); + fails(other, InvalidParameter); + + /* Copy and assign */ + inst->msg = other->msg; + inst->dst = other->dst; + inst->successful = other->successful; + inst->elapsed = other->elapsed; + + return NormalStatus; +} + +bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other) +{ + /* Skip unavailable instances and parameters. */ + state((inst == NULL || other == NULL), false); + + return ( + CatlogMsg_Equal(&inst->msg, &other->msg) && + inst->dst == other->dst && + inst->successful == other->successful && + ((inst->elapsed.tv_sec == other->elapsed.tv_sec) && + (inst->elapsed.tv_nsec == other->elapsed.tv_nsec)) + ); +} + +Status CatlogSender_Send(CatlogSender *inst, int *store, bool append) + throws(ReadWriteError) +{ + /* Skip unavailable instances and parameters. */ + fails(inst, UnavailableInstance); + fails(store, InvalidParameter); + + /* Open file. */ + ensure(CatlogUtils_OpenFile(inst->dst, "r"), "Unable to open file."); + ensure(CatlogMsg_Create(&(CatlogMsg){}, 0, "", ""), "Failed!"); + + /* Read file. */ + /* Creating buffer, */ + // TODO(william): Finish this function. +} + +Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); + +Status CatlogUtils_OpenFile(FILE *store, const char const *__restrict mode); diff --git a/catlog.h b/catlog.h new file mode 100755 index 0000000..1cf9dc6 --- /dev/null +++ b/catlog.h @@ -0,0 +1,45 @@ +#ifndef COMPOUND_CATLOG_H +# define COMPOUND_CATLOG_H + +# include +# include + +typedef enum { + CATLOG_LEVEL_ALL, // Least the value, most the information. + CATLOG_LEVEL_MINOR, + CATLOG_LEVEL_NORMAL, + CATLOG_LEVEL_MAJOR, + CATLOG_LEVEL_CRITICAL, + CATLOG_LEVEL_FATAL, + CATLOG_LEVEL_DEBUG, + CATLOG_LEVEL_NONE +} CatlogLevel; + +typedef struct { + time_t time; + CatlogLevel level; + char *originator; + char *msg; +} CatlogMsg; + +Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level, + char const *originator, char const *msg); +Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other); +bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other); + +typedef struct { + CatlogMsg msg; + FILE *dst; + bool successful; + struct timespec elapsed; +} CatlogSender; + +Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst); +Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other); +bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other); +Status CatlogSender_Send(CatlogSender *inst, int *store, bool append) + throws(ReadWriteError); +Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); +Status CatlogUtils_OpenFile(FILE *store, const char *__restrict mode); + +#endif /* COMPOUND_CATLOG_H */ diff --git a/common.h b/common.h index 76c702d..017604a 100644 --- a/common.h +++ b/common.h @@ -1,18 +1,9 @@ -#ifndef COMMON_H -# define COMMON_H +#ifndef COMPOUND_COMMON_h +# define COMPOUND_COMMON_h # include # include -# define _buffer_definition_without_assignment(type, length) \ - struct { type data[(length)]; const int len; } - -# define Buffer(type, length, var) \ - _buffer_definition_without_assignment(type, length) \ - var = { .data = {}, .len = length } - -# define Array(type, length, var) type var[(length)] - /** * @brief Return $n as the return value, once $o is NULL * @return given $n as the return value @@ -20,7 +11,7 @@ * @note 'o' stands for "Object" * @note 'n' stands for "Numeric on Return" */ -# define fails(o, n) {if ((o) == NULL) return (n);} +# define fails(o, n) { if ((o) == NULL) return (n); } /** * @brief Return $e as the return value, once $v equals $e @@ -29,16 +20,100 @@ * @note 'v' stands for "Value" * @note 'e' stands for "Error Code" */ -# define trans(v, e) {if ((v) == (e)) return (e);} +# define trans(v, e) { if ((v) == (e)) return (e); } -///** -// * @brief Evaluate given statement while the ptr to $s is not NULL -// * @return given $n as the return value -// * @note "state" stands for "Statement Evaluation" -// * @note 's' stands for "Statement" -// * @note 'n' stands for "Numeric on Return" -// */ -//# define state(s, n) {if ((#s)) return (n);} +/** + * @brief Evaluate given statement while the ptr to $s is not NULL + * @return given $n as the return value + * @note "state" stands for "Statement Evaluation" + * @note 's' stands for "Statement" + * @note 'n' stands for "Numeric on Return" + */ +# define state(s, n) { if ((s)) return (n); } + +/** + * @brief Evaluate given statement while the ptr to $s is not NULL + * @return nothing. + * @note "svoid" stands for "Statement Evaluation in Void" + * @note 's' stands for "Statement" + */ +# define svoid(s) { if ((s)) return; } + +/** + * @brief Return an Error Status with given parameter $c as the + * comment or description. + * @return A instance of Error Status customised. + * @note "error" stands for "Error in Status" + * @note 'e' stands for "Error" + * @note 'c' stands for "Comment" + */ +# define error(e, c) ((Status) {\ + .description = c,\ + .characteristic = e.characteristic,\ + .prev = e.prev\ +}) + +/** + * @brief Return an Error Status with given parameter $p as the + * predecessor. + * @return A instance of Error Status inherited. + * @note "extend" stands for "Extend from Predecessor" + * @note 'i' stands for 'Instance' + * @note 'p' stands for "Predecessor" + */ +# define extend(i, p) ((Status)) {\ + .prev = p\ +} + +# define modify(e, s, c) ((Status)) {\ + .description = s,\ + .characteristic = c,\ + .prev = e.prev\ +} + +/** @brief Create a report in place. + * @return A instance of Status Report customised. + * @note "stamp" stands for "Report Stamp" + * @note 'e' stands for "Exception" + * @note 'c' stands for "Char String of Originator" + */ +# define stamp(e, c) ((Report) {\ + .stat = e,\ + .originator = c,\ + .time = time(NULL),\ + .priority = REPORT_SENDING_PRIORITY_NORMAL,\ + .status = REPORT_SENDING_TASK_STATUS_PENDING\ +}) + +/** + * @brief Another way to handle if statements more cleanly. + * @note "solve" stands for "Solve with Statements." + * @note 's' stands for "Statement" + * @note 'b' stands for "Block of Forks" + */ +# define solve(s, b) if (s) b + +// /** +// * @brief Forcibly return desired value $v once $s is not $k. +// * @return $v once state for $s is false. +// * @note "force" stands for "Forcible value" +// * @note 's' stands for "Statement" +// * @note 'k' stands for "Key Value", the value that is targeted to detect. +// * @note 'v' stands for "Desire Value", the value that desires. +// */ +// # define force(s, k, v) solve((s) != (k), v) + +// # define sforce(s, k, v) solve((!status_equal(s, k)), v) + +/* Get the literal. */ +# define nameof(obj) #obj + +# define type(T) + +/* Only effects when Generic is defined. */ +# define Array(T) Array + +# define String(T) String typedef enum { COMMON_ERROR_NULLPTR = 1, @@ -73,4 +148,4 @@ typedef bool _Bit; # define ATRANGE(lf, rt, v) \ (INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt)) -#endif /* NO COMMON_H */ +#endif /* NO COMPOUND_COMMON_h */ diff --git a/const.h b/const.h new file mode 100644 index 0000000..bd77d30 --- /dev/null +++ b/const.h @@ -0,0 +1,17 @@ +#ifndef COMPOUND_CONST_H +# define COMPOUND_CONST_H + +# define INT32_DIGITS_DEC 10 +# define INT32_DIGITS_HEX 8 + +# define INT64_DIGITS_DEC 19 +# define INT64_DIGITS_HEX 16 + + +// # define UINT32_DIGITS_DEC 10 +// # define UINT32_DIGITS_HEX + +// # define UINT64_DIGITS_DEC 20 +// # define UINT64_DIGITS_HEX 16 + +#endif /* COMPOUND_CONST_H */ diff --git a/install b/install index 7c48827..6edf7c2 100755 --- a/install +++ b/install @@ -11,7 +11,8 @@ fi SRC="$PWD" DST=/usr/include/Compound -PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan") +PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan" "Stack" "Utils"\ + "String") PROJLEN=${#PROJ[*]} echo "======== $PROJLEN projects in total ========" @@ -32,5 +33,7 @@ while :; do echo done -cp -v "common.h" "$DST" +cp -v "common.h" "const.h" "platform.h"\ + "name.h" "type.h" "catlog.h"\ + "attr.h" "$DST" printf "\nDone\n" diff --git a/name.c b/name.c new file mode 100644 index 0000000..2ad646a --- /dev/null +++ b/name.c @@ -0,0 +1,71 @@ +#include + +Status NameSpace_Create(NameSpace *inst) +{ + fails(inst, UnavailableInstance); + + /* Create instances for members from inst. */ + state(status_isokay(NameSpace_EmptyName(&inst->latest)), + error(RuntimeError, "Failed to initialise latest from NameSpace")); + state(status_isokay(NameSpace_EmptyName(&inst->idx)), + error(RuntimeError, "Failed to initialise idx from NameSpace")); + state(status_isokay(NameSpace_EmptyName(inst->occupied)), + error(RuntimeError, "Failed to initialise occupied from NameSpace")); + + return NormalStatus; +} + +Status NameSpace_CopyOf(NameSpace *inst, NameSpace *other) +{ + fails(inst, UnavailableInstance); + fails(other, UnavailableParameter); + + /* Copy and assign. */ + other->latest = inst->latest; + other->idx = inst->idx; + + const Name len = NameSpace_CalcNameArrayLength(&other->occupied); + for (Name i = (Name){0}; (NameSpace_CompareName(i, len) < 0);) { + + // TODO(william): HERE + + /* i++ */ + state((!status_isokay(NameSpace_CountUp(&i))), + error(RuntimeError, "Error occurred during calculations of Name.")); + } +} + +Status NameSpace_CreateName(NameSpace *inst, Name *buff); + +Status NameSpace_RemoveName(NameSpace *inst, Name idx); + +Status NameSpace_EmptyName(Name *inst); + +Status NameSpace_CountUp(Name *inst); + +Status NameSpace_CountDown(Name *inst); + +Status NameSpace_CountUpFor(Name *inst, Name amount); + +Status NameSpace_CountDownFor(Name *inst, Name amount); + +Status NameSpace_UpdateLatest(NameSpace *inst, Name idx); + +Status NameSpace_FormatTrim(Name *inst); + +Status NameSpace_FormatInflate(Name *inst); + +Name NameSpace_CalcNameArrayLength(Name **arr); + +bool NameSpace_IsAvailable(NameSpace *inst, Name idx); + +bool NameSpace_IsValidName(Name *inst); + +int NameSpace_CompareName(Name *a, Name *b) +{ + /* Validation comes the first. --William */ + if (!NameSpace_IsValidName(a) || !NameSpace_IsValidName(b)) { + Report e; ArgueStartParam h; + throw(stamp(&InvalidName)); + } +} diff --git a/name.h b/name.h new file mode 100644 index 0000000..e35fe99 --- /dev/null +++ b/name.h @@ -0,0 +1,88 @@ +#ifndef COMPOUND_NAME_H +# define COMPOUND_NAME_H + +# include +# include +# include + +// Name, is a base of numeral counting. +// It uses 63 as the base, lasts for 63 times. +// At the head of each Name, 8 pilots stores for its type. +// In total, ((26*2+10+1)^63)*8 +// = 63^63*8 +// = 1.82618429078e+114 +// Nice. :3 +// William, Sun 12 May, 2024, 02:29:36 + +# define NAME_LENGTH_MAXIMUM 64 +# define NAME_LEGAL_CHARACTERS "abcdefghijklmnopqrstuvwxyz"\ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\ + "1234567890" + +typedef struct { + char *identifier; + Array(int) attributions; +} Name; + +static const Name NullName = { + .identifier = + "_000000000000000000000000000000000000000000000000000000000000000", + .attributions = NULL +}; + +// typedef struct { +// Name value; +// Name idx; +// Name *occupied; +// } NameSpace; // Size: 8+8+8 =8*3 =24 Bytes (x64) + +/* + * Example: + * Var variable_from_namespace_Utils_in_class_Calculation_in_function_C; + * // Not enough room for representation. + * // Must use another more efficient method to store the name. + * Become (roughly): + * Var v0000000000000000000000000000000000000000000000000000000000001g3; + * Var v1g3; // Trimmed. + * PILOT: v, f, c, e, i, s, u, a + * v: Variable + * f: Function + * c: Class + * e: Enumeration + * i: Interface + * s: Struct + * u: Union + * a: Attribution + * ID: [a-zA-Z0-9_] + * MAXIMUM STORING SIZE: 63 Bytes + * TOTAL POSSIBILITIES: ((26*2+10+1)^63)*8 = 1.82618429078e+114 + * Definitely enough. + * + * Please note, numeral symbols cannot lead the name. + * They must have indexer that greater than ZERO. + */ + +Status Name_CountDown(Name *inst); +Status Name_CountDownFor(Name *inst, Name amount); +Status Name_CountUp(Name *inst); +Status Name_CountUpFor(Name *inst, Name amount); +Status Name_EmptyName(Name *inst); +Status Name_FormatInflate(Name *inst); +Status Name_FormatTrim(Name *inst); +Name Name_CalcNameArrayLength(Name **arr); +bool Name_IsValid(Name *inst); +int Name_Compare(Name *a, Name *b) throws(InvalidName); + +static Status NameOverFlowError = { + .description = "An overflow occurred while calculating Name.", + .characteristic = STATUS_ERROR, + .prev = &ArithmeticError +}; + +static Status InvalidName = { + .description = "Given Name was invalid.", + .characteristic = STATUS_ERROR, + .prev = &InvalidParameter +}; + +#endif /* COMPOUND_NAME_H */ diff --git a/namescope.c b/namescope.c new file mode 100644 index 0000000..e69de29 diff --git a/namescope.h b/namescope.h new file mode 100644 index 0000000..0cf091a --- /dev/null +++ b/namescope.h @@ -0,0 +1,26 @@ +#ifndef COMPOUND_NAMESCOPE_H +# define COMPOUND_NAMESCOPE_H + +# include +# include + +typedef struct { + Array(Name) name_data; + +} NameScope; + +# define NameScope(T) NameScope + +Status NameScope_Create(NameScope *inst); +Status NameScope_CopyOf(NameScope *inst, NameScope *other); +Status NameScope_CreateName(NameScope *inst, Name *buff); +Status NameScope_RemoveName(NameScope *inst, Name idx); +Status NameScope_UpdateLatest(NameScope *inst, Name idx); +bool NameScope_Equal(NameScope *inst, NameScope *other); +bool NameScope_IsAvailable(NameScope *inst, Name idx); + +/* Universal Attribute NameScope. (U.A.N.) */ +NameScope(Attribute) UniversalAttributeNameScope; +NameScope MemoryAllocationRegistry; + +#endif /* COMPOUND_NAMESCOPE_H */ diff --git a/platform.h b/platform.h new file mode 100644 index 0000000..c1c3b1a --- /dev/null +++ b/platform.h @@ -0,0 +1,14 @@ +#ifndef COMPOUND_PLATFORM_H +# define COMPOUND_PLATFORM_H + +# if defined __x86_64__ || defined __x86_64 +# define __COMPOUND_64__ +# define __COMPOUND_PRODUCT__ compound64 +# elif defined __i386__ || __i486__ || __i586__ || __i686__ || _X86_ || __X86__ +# define __COMPOUND_32__ +# define __COMPOUND_PRODUCT__ compound32 +# else +# error Platform not supported. Please issue this on github.com/Wilhelm-Lee/Compound --William +# endif + +#endif /* COMPOUND_PLATFORM_H */ diff --git a/registry.h b/registry.h new file mode 100644 index 0000000..abb25ae --- /dev/null +++ b/registry.h @@ -0,0 +1,54 @@ +#ifndef COMPOUND_SECURITY_REGISTRY_H +# define COMPOUND_SECURITY_REGISTRY_H + +# include + +/* + By calculating SHA256, we can identify whether the original data has been + modified maliciously or not. + However, In current particular cases, it is contradictive that we would + wish to use the same approach to validate and protect the data that we used + for validating and protecting other data. + Thus, it is not practical to use current existing methods to create + a way that is 100% perfect for data safety and computation security. + What we actually need is to ensure that our data from either struct or + union wouldn't be modifies easily, not in C, but in Classify, the language + that rely on this very project, Compound. + */ + +typedef struct { + Memory data; + char SHA256[256]; +} RegItem; // 276 Bytes + +typedef union { + RegItem items[256]; +} RegTable256; // 4416 Bytes | 4.3125 KiB + +typedef union { + RegItem items[128]; +} RegTable128; // 2208 Bytes | 2.15625 KiB + +typedef union { + RegItem items[64]; +} RegTable64; // 1104 Bytes | 1.078125 KiB + +typedef union { + RegItem items[32]; +} RegTable32; // 552 Bytes + +typedef union { + RegItem items[16]; +} RegTable16; // 276 Bytes + +typedef union { + RegItem items[8]; +} RegTable8; // 138 Bytes + +bool Registry_Validate(const RegItem const *item, const RegResult const *result); +bool Registry_Calculate(const RegItem const *item, const RegResult const *result); +bool RegistryTable64_ + + + +#endif /* COMPOUND_SECURITY_REGISTRY_H */ diff --git a/type.h b/type.h new file mode 100644 index 0000000..d93f238 --- /dev/null +++ b/type.h @@ -0,0 +1,11 @@ +#ifndef COMPOUND_TYPE_H +# define COMPOUND_TYPE_H + +# include + +typedef struct { + char *identity; + Var data; +} Type; + +#endif /* COMPOUND_TYPE_H */