(SOC) Storage Only Commit
(ADD) Name, NameScope, Catlog, Object, String, Attribute, Char, Registry, Utils, Type, <Platform Support>, <Global Constants>, README (MOD) Array, Var, Status, MemMan, <Common>
This commit is contained in:
46
Array/include/array.h
Normal file
46
Array/include/array.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef ARRAY_H
|
||||
# define ARRAY_H
|
||||
|
||||
# include <Compound/var.h>
|
||||
|
||||
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 */
|
83
Array/src/array.c
Normal file
83
Array/src/array.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <Compound/array.h>
|
||||
|
||||
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);
|
@@ -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)
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#ifndef MEMMAN_H
|
||||
#define MEMMAN_H
|
||||
#ifndef COMPOUND_MEMMAN_H
|
||||
# define COMPOUND_MEMMAN_H
|
||||
|
||||
#include <Compound/common.h>
|
||||
#include <Compound/status.h>
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/status.h>
|
||||
|
||||
/*
|
||||
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 */
|
||||
|
110
Object/include/object.h
Normal file
110
Object/include/object.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef COMPOUND_OBJECT_H
|
||||
# define COMPOUND_OBJECT_H
|
||||
|
||||
# include <Compound/array.h>
|
||||
# include <Compound/namespace.h>
|
||||
# include <Compound/type.h>
|
||||
|
||||
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<Constructor>>
|
||||
Member type(Destructor) destructor; // Member<Destructor>
|
||||
|
||||
Array type(Member type(?)) fields; // Array<Member<?>>
|
||||
Array type(Member type(?)) methods; // Array<Member<?>>
|
||||
} 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 */
|
0
Object/src/object.c
Normal file
0
Object/src/object.c
Normal file
46
README.md
Normal file
46
README.md
Normal file
@@ -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)
|
||||
```
|
18
Stack/include/stack.h
Normal file
18
Stack/include/stack.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef STACK_H
|
||||
# define STACK_H
|
||||
|
||||
# include <Compound/var.h>
|
||||
# include <Compound/status.h>
|
||||
|
||||
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 */
|
28
Stack/src/stack.c
Normal file
28
Stack/src/stack.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <Compound/stack.h>
|
||||
|
||||
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);
|
@@ -9,7 +9,9 @@
|
||||
# include <time.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# define __HERE__ { .file = __FILE__, .line = __LINE__, .func = __func__ }
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/utils.h>
|
||||
# include <Compound/platform.h>
|
||||
|
||||
/* 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 */
|
||||
|
@@ -1,30 +1,174 @@
|
||||
#include <Compound/common.h>
|
||||
#include <Compound/status.h>
|
||||
|
||||
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) {
|
||||
|
||||
/* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */
|
||||
solve((statbuff == NULL || !status_hasprev(inst) || idx < 0), return;);
|
||||
|
||||
statbuff[idx] = inst;
|
||||
(void)printf("status_dump: Index %d has assigned with %p\n", idx, &inst);
|
||||
|
||||
status_dump(*inst.prev, statbuff, ++idx);
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
statbuff[idx] = stat;
|
||||
|
||||
status_dump(*stat.prev, statbuff, ++idx);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
bool status_compare(Status stat1, Status stat2) {
|
||||
return (!strcmp(stat1.description, stat2.description) &&
|
||||
(stat1.characteristic == stat2.characteristic) &&
|
||||
(!status_compare(*stat1.prev, *stat2.prev)));
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
9
String/include/char.h
Normal file
9
String/include/char.h
Normal file
@@ -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 */
|
97
String/include/string.h
Normal file
97
String/include/string.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef COMPOUND_STRING_H
|
||||
# define COMPOUND_STRING_H
|
||||
|
||||
# include <complex.h>
|
||||
# include <wchar.h>
|
||||
|
||||
# include <Compound/char.h>
|
||||
# include <Compound/array.h>
|
||||
|
||||
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 */
|
0
String/src/char.c
Normal file
0
String/src/char.c
Normal file
45
String/src/string.c
Normal file
45
String/src/string.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <Compound/string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
9
Utils/include/utils.h
Normal file
9
Utils/include/utils.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef COMPOUND_UTILS_H
|
||||
# define COMPOUND_UTILS_H
|
||||
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/const.h>
|
||||
|
||||
int Utils_CalcDigits(long long n);
|
||||
|
||||
#endif /* COMPOUND_UTILS_H */
|
16
Utils/src/utils.c
Normal file
16
Utils/src/utils.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <Compound/utils.h>
|
||||
|
||||
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;
|
||||
}
|
@@ -2,18 +2,52 @@
|
||||
# define COMPOUND_VAR
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <wchar.h>
|
||||
# include <stdint.h>
|
||||
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/status.h>
|
||||
|
||||
# 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 */
|
||||
|
@@ -1,17 +1,94 @@
|
||||
#include <Compound/var.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
27
attr.h
Normal file
27
attr.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef COMPOUND_ATTR_H
|
||||
# define COMPOUND_ATTR_H
|
||||
|
||||
# include <Compound/name.h>
|
||||
|
||||
/* 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 */
|
105
catlog.c
Executable file
105
catlog.c
Executable file
@@ -0,0 +1,105 @@
|
||||
#include <Compound/catlog.h>
|
||||
#include <Compound/status.h>
|
||||
|
||||
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);
|
45
catlog.h
Executable file
45
catlog.h
Executable file
@@ -0,0 +1,45 @@
|
||||
#ifndef COMPOUND_CATLOG_H
|
||||
# define COMPOUND_CATLOG_H
|
||||
|
||||
# include <Compound/status.h>
|
||||
# include <Compound/common.h>
|
||||
|
||||
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 */
|
119
common.h
119
common.h
@@ -1,18 +1,9 @@
|
||||
#ifndef COMMON_H
|
||||
# define COMMON_H
|
||||
#ifndef COMPOUND_COMMON_h
|
||||
# define COMPOUND_COMMON_h
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
# 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 */
|
||||
|
17
const.h
Normal file
17
const.h
Normal file
@@ -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 */
|
7
install
7
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"
|
||||
|
71
name.c
Normal file
71
name.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <Compound/name.h>
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
88
name.h
Normal file
88
name.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef COMPOUND_NAME_H
|
||||
# define COMPOUND_NAME_H
|
||||
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/status.h>
|
||||
# include <Compound/array.h>
|
||||
|
||||
// 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 */
|
0
namescope.c
Normal file
0
namescope.c
Normal file
26
namescope.h
Normal file
26
namescope.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef COMPOUND_NAMESCOPE_H
|
||||
# define COMPOUND_NAMESCOPE_H
|
||||
|
||||
# include <Compound/array.h>
|
||||
# include <Compound/name.h>
|
||||
|
||||
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 */
|
14
platform.h
Normal file
14
platform.h
Normal file
@@ -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 */
|
54
registry.h
Normal file
54
registry.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef COMPOUND_SECURITY_REGISTRY_H
|
||||
# define COMPOUND_SECURITY_REGISTRY_H
|
||||
|
||||
# include <Compound/memman.h>
|
||||
|
||||
/*
|
||||
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 */
|
Reference in New Issue
Block a user