(FEA) Featured for Location_Literalisation, Status_Literalisation etc.

This commit is contained in:
William
2024-06-06 02:22:54 +08:00
parent df073877cc
commit 54042cf2cf
28 changed files with 744 additions and 358 deletions

3
.gitignore vendored
View File

@@ -17,3 +17,6 @@ sample
compile compile
======= =======
>>>>>>> refs/remotes/master/master >>>>>>> refs/remotes/master/master
.vscode/
todo
vsc*

View File

@@ -8,17 +8,20 @@ typedef struct {
Var *members; Var *members;
} Array; } Array;
static Status ArrayIndexOutOfBound = { # define ArrayIndexOutOfBound = (Status){\
.description = "Given index was accessing illegal address.", .identity = nameof(ArrayIndexOutOfBound),\
.characteristic = STATUS_ERROR, .value = 1,\
.prev = &MemoryViolation .description = "Given index was accessing illegal address.",\
}; .characteristic = STATUS_ERROR,\
.prev = &MemoryViolation\
}
static Status InvalidArrayLength = { # define InvalidArrayLength (Status){\
.description = "Given length is invalid.", .value = 1,\
.characteristic = STATUS_ERROR, .description = "Given length is invalid.",\
.prev = &ErrorStatus .characteristic = STATUS_ERROR,\
}; .prev = &ErrorStatus\
}
/* Elementary. */ /* Elementary. */
Status Array_Create(Array *inst, int len, size_t size) Status Array_Create(Array *inst, int len, size_t size)

View File

@@ -13,7 +13,9 @@ Status Array_Create(Array *inst, int len, size_t size)
int erridx = -1; int erridx = -1;
for (register int i = 0; i < len; i++) { for (register int i = 0; i < len; i++) {
// TODO(william): Throw InsufficientMemory at following line. // TODO(william): Throw InsufficientMemory at following line.
solve(!StatusUtils_IsOkay(Var_Create(&inst->members[i], size)), { // DONE(william): ensure(Var_Create(&inst->members[i], size), "Failed to create a new var.");
notok((Var_Create(&inst->members[i], size)), {
#ifdef __DEBUG__ #ifdef __DEBUG__
cat("Var_Create failed!\n") cat("Var_Create failed!\n")
#endif #endif
@@ -99,7 +101,7 @@ Status Array_GetIdx(Array *inst, Var *store, int index)
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(store, error(InvalidParameter, "Given reference to store was " fails(store, error(InvalidParameter, "Given reference to store was "
"unavailable.")); "unavailable."));
state((index < 0 || index >= inst->len), ArrayIndexOutOfBound); state((index < 0 || index >= inst->len), ArrayIndexOutOfBound);
*store = inst->members[index]; *store = inst->members[index];

View File

@@ -16,8 +16,7 @@ LINK_LIBRARIES(m)
add_executable(CompoundTest add_executable(CompoundTest
test.c test.c
Var/src/var.c MemMan/src/memman.c
Array/src/array.c
Status/src/status.c Status/src/status.c
Utils/src/utils.c Utils/src/utils.c
catlog.c) catlog.c)

50
Classes/integer.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef COMPOUND_CLASSES_INTEGER_H
# define COMPOUND_CLASSES_INTEGER_H
# include <Compound/class.h>
typedef Class Integer;
/*
typedef struct {
String identity;
Array type(DynStruct) structs;
Array type(DynUnion) unions;
Array type(DynEnum) enums;
Array type(FunctionPointer) functionptrs;
Array type(Field) fields;
// Interface[] *implementations
Array type(Var type(Interface)) *implementations;
// Class *predecessor
Var type(Class) *predecessor;
} Class;
*/
/* STATIC INSTANCE OPERATIONS. */
Status Integer_Create(Integer *inst, Var *value);
Status Integer_FromInt(Integer *inst, int *value);
Status Integer_FromUnsignedInt(Integer *inst, unsigned int *value);
Status Integer_ToInt(Integer *inst, int *store);
Status Integer_ToUnsignedInt(Integer *inst, unsigned int *store);
Status Integer_CopyOf(Integer *inst, Integer *other);
Status Integer_Delete(Integer *inst);
bool Integer_Equal(Integer *inst, Integer *other);
/* DYNAMIC INSTANCE OPERATIONS. */
Status Integer_Generate(Integer *inst,
Array *structs type(dynStruct),
Array *unions type(DynUnion),
Array *enums type(DynEnum),
Array *functionptrs type(FunctionPointer),
Array *fields type(Field),
Array *implementations type(Var type(Interface)),
Var *predecessor type(Class));
Status Integer_Demolish(Integer *inst);
Status Integer_Literalise(Integer *inst, String *buff);
/* INSTANCE UTILITIES. */
Status IntegerUtils_Cast(Integer *inst, Integer *store, size_t sizeInBytes);
#endif /* COMPOUND_CLASSES_INTEGER_H */

View File

View File

View File

@@ -4,15 +4,14 @@
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/status.h> # include <Compound/status.h>
/* /* Higher the priority it is, the less lifespan it has. */
Higher the priority it is, the less time for lifespan it has.
*/
typedef struct { typedef struct {
void *addr; void *addr;
size_t length; size_t size;
int priority; // Negative for manual; Higher than 0 it is, int priority; // Negative for manual; Higher than 0 it is,
// higher the priority is. // higher the priority is.
bool alive;
} Memory; // 20 Bytes } Memory; // 20 Bytes
typedef struct { typedef struct {
@@ -27,27 +26,27 @@ typedef struct {
void (*deallocator)(void *addr); void (*deallocator)(void *addr);
} MemoryPoolManager; } MemoryPoolManager;
Status MemMan_Memory_Allocate(Memory *inst, size_t length); Status Memory_Create(Memory *inst, size_t size);
Status MemMan_Memory_Reallocate(Memory *inst, size_t length); Status Memory_Delete(Memory *inst);
void MemMan_Memory_Release(Memory *inst); Status Memory_Allocate(Memory *inst);
Status MemMan_Memory_Prioritise(Memory *inst); Status Memory_Reallocate(Memory *inst, size_t size);
Status MemMan_Memory_Deprioritise(Memory *inst); Status Memory_Release(Memory *inst);
bool MemMan_Memory_Equals(Memory *inst, Memory *other); bool Memory_Equals(Memory *inst, Memory *other);
Status MemMan_MemoryPool_Create(MemoryPool *inst, size_t volume); Status MemoryPool_Create(MemoryPool *inst, size_t volume);
Status MemMan_MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority); Status MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority);
Status MemMan_MemoryPool_AllocateAt(MemoryPool *inst, int idx, size_t sz); Status MemoryPool_AllocateAt(MemoryPool *inst, int idx, size_t sz);
Status MemMan_MemoryPool_ReallocateAt(MemoryPool *inst, int idx, size_t sz); Status MemoryPool_ReallocateAt(MemoryPool *inst, int idx, size_t sz);
Status MemMan_MemoryPool_ReleaseAt(MemoryPool *inst, int idx); Status MemoryPool_ReleaseAt(MemoryPool *inst, int idx);
void MemMan_MemoryPool_Delete(MemoryPool *inst); void MemoryPool_Delete(MemoryPool *inst);
Status MemMan_MemoryPoolManager_Create(MemoryPoolManager *inst, Status MemoryPoolManager_Create(MemoryPoolManager *inst,
MemoryPool **members); MemoryPool **members);
Status MemMan_MemoryPoolManager_Constr(MemoryPoolManager *inst, Status MemoryPoolManager_Constr(MemoryPoolManager *inst,
MemoryPool **members, MemoryPool **members,
void *(*allocator)(size_t sz), void *(*allocator)(size_t sz),
void (*deallocator)(void *addr)); void (*deallocator)(void *addr));
Status MemMan_MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2); Status MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2);
Status MemMan_MemoryPoolManager_Divide(MemoryPool *src, int off, int len); Status MemoryPoolManager_Divide(MemoryPool *src, int off, int len);
#endif /* COMPOUND_MEMMAN_H */ #endif /* COMPOUND_MEMMAN_H */

View File

@@ -1,35 +1,75 @@
#include <Compound/common.h>
#include <Compound/memman.h> #include <Compound/memman.h>
/* Status Memory_Create(Memory *inst, size_t size)
enum { {
MEMMAN_RELEASE_LEVEL_INSTANTAL = 0, fails(inst, UnavailableInstance);
MEMMAN_RELEASE_LEVEL_STACK = 1,
MEMMAN_RELEASE_LEVEL_HEAP = 2 *inst = (Memory) {
.addr = NULL,
.size = size,
.priority = 0,
.alive = false
}; };
typedef struct { return NormalStatus;
void *addr; }
int release_level;
} Memory; Status Memory_Allocate(Memory *inst)
{
typedef struct { fails(inst, UnavailableInstance);
Memory *members; state(inst->alive, InstanceStillAlive);
int release_level;
} MemoryPool; /* When failed on allocating. */
state(!(inst->addr = malloc(inst->size)), InsufficientMemory);
typedef struct { inst->alive = true;
MemoryPool *members;
void *(*allocator)(size_t sz); return NormalStatus;
void (*delocator)(void *addr); }
} MemoryPoolManager;
*/ Status Memory_Reallocate(Memory *inst, size_t size)
{
int memman_memorypoolmanager_create(MemoryPoolManager *inst, fails(inst, UnavailableBuffer);
MemoryPool **membersptr) state(!inst->alive, InstanceNotAlive);
{
fails(inst, COMMON_ERROR_INVALID_ARGUMENT); /* When failed on reallocating. */
fails(membersptr, COMMON_ERROR_INVALID_ARGUMENT); state(!(inst->addr = realloc(inst->addr, size)),
error(InsufficientMemory, "Unsuccessful reallocation was received."))
return NormalStatus;
}
Status Memory_Release(Memory *inst)
{
fails(inst, UnavailableInstance);
state(!inst->alive, error(InstanceNotAlive, "Cannot release a non-alive "
"instance."));
free(inst->addr);
inst->alive = false;
return NormalStatus;
}
Status Memory_Delete(Memory *inst)
{
fails(inst, UnavailableInstance);
state(inst->alive, error(InstanceStillAlive, "Cannot deinitialise a instance "
"still alive."));
inst->addr = NULL;
inst->priority = 0;
inst->size = 0;
inst = NULL;
return NormalStatus;
}
bool Memory_Equals(Memory *inst, Memory *other)
{
state(!inst || !other, false);
return (inst->addr == other->addr
&& inst->size == other->size
&& inst->priority == other->priority
&& inst->alive == other->alive);
} }

View File

@@ -4,19 +4,20 @@
# include <Compound/array.h> # include <Compound/array.h>
# include <Compound/name.h> # include <Compound/name.h>
# include <Compound/type.h> # include <Compound/type.h>
# include <Compound/string.h>
typedef struct { // interface // typedef struct { // interface
Var *data; // Var *data;
Array buffer; // Array buffer;
Var *(*Literalise)(void); // Var *(*Literalise)(void);
int (*Correspond)(Var *other); // int (*Correspond)(Var *other);
} Object; // } Object;
# define OBJECT_IMPLEMENTATION Var *data; Array buffer;\ // # define OBJECT_IMPLEMENTATION Var *data; Array buffer;\
int (*Literalise)(void); int (*Correspond)(Var *other); // int (*Literalise)(void); int (*Correspond)(Var *other);
// private final String IDENTITY = ":D"; // // private final String IDENTITY = ":D";
// public static final void main(String[] args) {} // // public static final void main(String[] args) {}
typedef enum { typedef enum {
EXPOSURE_PUBLIC = 0, EXPOSURE_PUBLIC = 0,
@@ -33,80 +34,100 @@ typedef struct {
typedef struct { typedef struct {
Type type; Type type;
Name identity; Name identity;
Array parameters; Array type(Parameter) parameters;
} Function; } FunctionPointer;
// typedef struct {
// Exposure prefix;
// bool dynamic;
// bool constant;
// Type type;
// Name identity;
// Array type(Parameter) parameters;
// } Member;
typedef struct { typedef struct {
Exposure prefix; Exposure prefix;
bool dynamic; bool is_static;
bool constant; bool is_constant;
Type type; Type type;
Name identity; Name internal_identity;
Array type(Parameter) parameters; String identity;
} Member; Var value;
} Field;
// typedef struct {
// Exposure prefix;
// Name identity;
// Array type(Parameter) parameters;
// } Constructor;
// /* As for destructors, they don't have prefixes or parameters,
// because at the time you need destructors, you're already talking
// in a environment that is private, private to this class alone.
// And you also won't need any parameters, because to destruct, everything
// you store in this class is bound to be vanished, and whatever you do to
// modify them, the results are the same.
// However, if you'd like to change something else that is not belong to
// this class, why don't you just do them before calling destructors?
// Therefor, in real practices, you won't find anything meaningful to let
// a destructor having a prefix or a parameter.
// Summary.
// Prefixes are fixed to be "Private";
// Parameters are fixed to be void.
// */
// typedef struct {
// Name identity;
// } Destructor;
// typedef struct {
// // OBJECT_IMPLEMENTATION
// Object this;
// 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);
typedef struct { typedef struct {
Exposure prefix;
Name identity;
Array type(Parameter) parameters;
} Constructor;
/* As for destructors, they don't have prefixes or parameters, } Pointer;
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 { typedef struct {
// OBJECT_IMPLEMENTATION
Object this; } FunctionPointer;
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 */ #endif /* COMPOUND_OBJECT_H */

View File

@@ -6,7 +6,7 @@ Status Stack_Create(Stack *inst, int len)
// state((len < 0), InvalidParameter); // state((len < 0), InvalidParameter);
// /* Initialise before access. */ // /* Initialise before access. */
// if (inst == NULL) { // if (!inst) {
// *inst = (Stack) { // *inst = (Stack) {
// .members = NULL, // .members = NULL,
// .len = len // .len = len

View File

@@ -3,16 +3,15 @@
# include <stdbool.h> # include <stdbool.h>
# include <stdint.h> # include <stdint.h>
# include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
# include <threads.h> # include <threads.h>
# include <time.h> # include <time.h>
# include <stdio.h>
# include <math.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/utils.h>
# include <Compound/platform.h> # include <Compound/platform.h>
# include <Compound/utils.h>
/* Status characteristics */ /* Status characteristics */
typedef enum { typedef enum {
@@ -39,14 +38,21 @@ typedef struct {
} Location; } Location;
# define __HERE__ (Location){ \ # define __HERE__ (Location){ \
.file = (char *)__FILE__, \ .file = (char *)__FILE__, \
.line = __LINE__, \ .line = __LINE__, \
.func = (char *)__func__ \ .func = (char *)__func__ \
}
# define __GLOBAL__ (Location){ \
.file = (char *)__FILE__, \
.line = __LINE__, \
.func = (char *)"(GLOBAL)" \
} }
/* Common return type for reporting functions that require to give more /* Common return type for reporting functions that require to give more
information about the procedure. */ information about the procedure. */
typedef struct _Status { typedef struct _Status {
char *identity;
int value; /* Traditional returning data "int". Only used when the function int value; /* Traditional returning data "int". Only used when the function
called and received legacy functions that uses "int" as the called and received legacy functions that uses "int" as the
returning type that wish to have place to hold the value. returning type that wish to have place to hold the value.
@@ -65,17 +71,30 @@ typedef struct _Status {
*/ */
# ifdef __COMPOUND_32__ /* line, func, file */
# define STATUS_LITERALISE_LENGTH(stat) \ // # define LOCATION_LITERALISE_FORMAT "at line %d, in %s, %s"
(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" /* file, line, func */
# define LOCATION_LITERALISE_FORMAT "at %s:%d, in function `%s\'"
# define LOCATION_LITERALISE_FORMAT_LENGTH 20
/* value, description, characteristic, prev */
// # define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p"
/* identity, prev->identity, value, characteristic, description, <loc> */
// # define STATUS_LITERALISE_FORMAT "%s (prev: %s): $=%d @=%d\n\t\"%s\"\n\t%s"
// MaximumLiteralisationLengthExceeded (prev: MaximumLengthExceeded): $=1 @=1
/*
MaximumLengthExceeded: "Buffer was too long."
predecessor=<ArrayLengthError> value=(1) characteristic=[1]
at line 40, in Main, /home/william/Documents/Projects/Compound/test.c
*/
// identity, description, prev->identity, value, characteristic, <loc>
# define STATUS_LITERALISE_FORMAT \
"%s: \"%s\"\n\tpredecessor=<%s> value=(%d) characteristic=[%d]\n\t%s\n"
typedef enum { typedef enum {
REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value. REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value.
@@ -130,20 +149,6 @@ Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buf
# define REPORT_LITERALISE_CHAINS_FORMAT " at %s:%d, %s" # define REPORT_LITERALISE_CHAINS_FORMAT " at %s:%d, %s"
# define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT "!!!!at %s:%d, %s" # define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT "!!!!at %s:%d, %s"
// # define REPORT_LITERALISE_HEADER_FORMAT_LENGTH(buff, PRIORITY, STATUSNAME, \
// ORIGINATOR, DESCRIPTION) \
// { \
// const time_t now = time(NULL); \
// (void)strflen(buff, 28, DATETIME_FORMAT, localtime(&now)); \
// *length = strlen(buff); \
// }
// # define REPORT_LITERALISE_CHAINS_FORMAT_LENGTH(FILEPATH, LINE, FUNCNAME) \
// (strlen(FILEPATH) + utils_calc_digits(LINE) + \
// strlen(FUNCNAME) + 10) // Does not count '\0'
// # define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT_LENGTH \
// REPORT_LITERALISE_CHAINS_FORMAT_LENGTH
typedef enum { typedef enum {
REPORT_SENDER_RESULT_FINISHED, REPORT_SENDER_RESULT_FINISHED,
REPORT_SENDER_RESULT_PROGRESSING, REPORT_SENDER_RESULT_PROGRESSING,
@@ -200,29 +205,26 @@ typedef struct {
# define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX # define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX
Status Location_Literalise(Location *inst, char *buff);
bool Location_Equals(Location lc1, Location lc2); bool Location_Equals(Location lc1, Location lc2);
Status Status_Literalise(Status *inst, char *buff); Status Status_Literalise(Status *inst, char *buff);
bool Status_Equals(Status stat1, Status stat2); bool Status_Equal(Status *stat1, Status *stat2);
void StatusUtils_Dump(Status *inst, Status *store, int idx); void StatusUtils_Dump(Status *inst, Status *store, int idx);
bool StatusUtils_HasPrev(Status *inst); bool StatusUtils_HasPrev(Status inst);
bool StatusUtils_IsOkay(Status inst); bool StatusUtils_IsOkay(Status inst);
bool StatusUtils_IsValid(Status inst); bool StatusUtils_IsValid(Status inst);
bool StatusUtils_IsRecursive(Status inst); bool StatusUtils_IsRecursive(Status inst);
int StatusUtils_Depth(Status *inst); int StatusUtils_Depth(Status *inst);
Status Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator, int priority);
int priority); Status Report_CopyOf(Report *inst, Report *other);
bool Status Report_Literalise(Report *inst, char *buff);
Report_Equals(Report repo1, Report repo2); void Report_Delete(Report *inst);
Status bool Report_Equals(Report repo1, Report repo2);
Report_Literalise(Report *inst, char *buff);
Status ReportSender_Create(ReportSender *inst, Report *report);
Status Status ReportSender_Send(ReportSender *inst, ReportSendingTask task);
ReportSender_Create(ReportSender *inst, Report *report);
Status
ReportSender_Send(ReportSender *inst, ReportSendingTask task);
// ReportSendingTaskStatus // ReportSendingTaskStatus
// ReportSender_GetStatus(ReportSender *inst); // ReportSender_GetStatus(ReportSender *inst);
@@ -254,177 +256,309 @@ Status ReportSenderManager_RemoveTask(ReportSendingManager *inst,
// ---------------------ELEMENTARY------------------------- // ---------------------ELEMENTARY-------------------------
static Status UnknownStatus = { /*
typedef struct _Status {
char *identity;
int value;
char *description;
int characteristic;
Location loc;
struct _Status *prev;
} Status;
*/
static const Status UnknownStatus = {
.identity = nameof(UnknownStatus),
.value = -1,
.description = "An unknown status.", .description = "An unknown status.",
.characteristic = STATUS_UNKNOWN, .characteristic = STATUS_UNKNOWN,
.loc = __GLOBAL__,
.prev = NULL .prev = NULL
}; };
static Status NormalStatus = { static const Status NormalStatus = {
.identity = nameof(NormalStatus),
.value = 0,
.description = "A normal status.", .description = "A normal status.",
.characteristic = STATUS_NORMAL, .characteristic = STATUS_NORMAL,
.loc = __GLOBAL__,
.prev = NULL .prev = NULL
}; };
static Status ErrorStatus = { static const Status ErrorStatus = {
.identity = nameof(ErrorStatus),
.value = 1,
.description = "An error status.", .description = "An error status.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.loc = __GLOBAL__,
.prev = NULL .prev = NULL
}; };
// ----------------------EXTENDED-------------------------- // ----------------------EXTENDED--------------------------
static Status MemoryViolation = { static const Status MemoryViolation = (Status){
.identity = nameof(MemoryViolation),
.value = 1,
.description = "Illegal access on certain memory address.", .description = "Illegal access on certain memory address.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status NullPointerAccounted = { static const Status NullPointerAccounted = (Status){
.identity = nameof(NullPointerAccounted),
.value = 1,
.description = "An involving null pointer was not accepted.", .description = "An involving null pointer was not accepted.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &MemoryViolation .loc = __GLOBAL__,
.prev = (Status *)&MemoryViolation
}; };
static Status InvalidObject = { static const Status InvalidObject = (Status){
.identity = nameof(InvalidObject),
.value = 1,
.description = "An invalid object was presented.", .description = "An invalid object was presented.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status UnavailableObject = { static const Status UnavailableObject = (Status){
.identity = nameof(UnavailableObject),
.value = 1,
.description = "An unavailable object was presented.", .description = "An unavailable object was presented.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status InvalidParameter = { static const Status InstanceStillAlive = (Status){
.identity = nameof(InstanceStillAlive),
.value = 1,
.description = "Given instance was yet alive.",
.characteristic = STATUS_ERROR,
.loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
};
static const Status InstanceNotAlive = (Status){
.identity = nameof(InstanceNotAlive),
.value = 1,
.description = "Given instance for reallocation was not alive.",
.characteristic = STATUS_ERROR,
.loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
};
static const Status InvalidParameter = (Status){
.identity = nameof(InvalidParameter),
.value = 1,
.description = "An invalid parameter was presented.", .description = "An invalid parameter was presented.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &InvalidObject .loc = __GLOBAL__,
.prev = (Status *)&InvalidObject
}; };
static Status InsufficientMemory = { static const Status InsufficientMemory = (Status){
.identity = nameof(InsufficientMemory),
.value = 1,
.description = "Not enough room for further memory allocations.", .description = "Not enough room for further memory allocations.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status ArithmeticError = { static const Status ArithmeticError = (Status){
.identity = nameof(ArithmeticError),
.value = 1,
.description = "An arithmetic error occurred.", .description = "An arithmetic error occurred.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status RuntimeError = { static const Status IntegerOverFlow = (Status){
.identity = nameof(IntegerOverFlow),
.value = 1,
.description = "An integer had overflowed.",
.characteristic = STATUS_ERROR,
.loc = __GLOBAL__,
.prev = (Status *)&ArithmeticError
};
static const Status RuntimeError = (Status){
.identity = nameof(RuntimeError),
.value = 1,
.description = "A runtime error occurred.", .description = "A runtime error occurred.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status ArrayLengthError = { static const Status ArrayLengthError = (Status){
.identity = nameof(ArrayLengthError),
.value = 1,
.description = "Given array length does not meet the requirement.", .description = "Given array length does not meet the requirement.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status VariableFormatMismatch = { static const Status VariableFormatMismatch = (Status){
.identity = nameof(VariableFormatMismatch),
.value = 1,
.description = "Given format does not match with given subjects.", .description = "Given format does not match with given subjects.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .loc = __GLOBAL__,
.prev = (Status *)&ErrorStatus
}; };
static Status ImprecisionError = { static const Status ImprecisionError = (Status){
.identity = nameof(ImprecisionError),
.value = 1,
.description = "Precision was not enough for handling the calculation.", .description = "Precision was not enough for handling the calculation.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &RuntimeError .loc = __GLOBAL__,
.prev = (Status *)&RuntimeError
}; };
// ---------------------USER DEFINED----------------------- // ---------------------USER DEFINED-----------------------
static Status UnavailableInstance = { static const Status UnavailableInstance = (Status){
.identity = nameof(UnavailableInstance),
.value = 1,
.description = "An unavailable instance was given for initialisation.", .description = "An unavailable instance was given for initialisation.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &NullPointerAccounted .loc = __GLOBAL__,
.prev = (Status *)&NullPointerAccounted
}; };
static Status UnavailableParameter = { static const Status RecreationOnInstanceStillAlive = (Status){
.identity = nameof(RecreationOnInstanceStillAlive),
.value = 1,
.description = "Given instance was still alive, yet, was sent for another "
"session of recreation.",
.characteristic = STATUS_ERROR,
.loc = __GLOBAL__,
.prev = (Status *)&InstanceStillAlive\
};
static const Status UnavailableParameter = (Status){
.identity = nameof(UnavailableParameter),
.value = 1,
.description = "An unavailable instance was given as a parameter.", .description = "An unavailable instance was given as a parameter.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &UnavailableInstance .loc = __GLOBAL__,
.prev = (Status *)&UnavailableInstance
}; };
static Status InvalidReportTask = { static const Status InvalidReportTask = (Status){
.identity = nameof(InvalidReportTask),
.value = 1,
.description = "An unavailable or illegal report task was given.", .description = "An unavailable or illegal report task was given.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &InvalidParameter .loc = __GLOBAL__,
.prev = (Status *)&InvalidParameter
}; };
static Status UnableToThrowError = { static const Status UnableToThrowError = (Status){
.identity = nameof(UnableToThrowError),
.value = 1,
.description = "Unable to report an exceptional situation.", .description = "Unable to report an exceptional situation.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &RuntimeError .loc = __GLOBAL__,
.prev = (Status *)&RuntimeError
}; };
static Status ReadWriteError = { static const Status ReadWriteError = (Status){
.identity = nameof(ReadWriteError),
.value = 1,
.description = "Error occurred during IO session.", .description = "Error occurred during IO session.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &RuntimeError .loc = __GLOBAL__,
.prev = (Status *)&RuntimeError
}; };
static Status FileNotFound = { static const Status FileNotFound = (Status){
.identity = nameof(FileNotFound),
.value = 1,
.description = "Target file was unavailable and unable to find.", .description = "Target file was unavailable and unable to find.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ReadWriteError .loc = __GLOBAL__,
.prev = (Status *)&ReadWriteError
}; };
static Status InvalidFileName = { static const Status InvalidFileName = (Status){
.identity = nameof(InvalidFileName),
.value = 1,
.description = "Given file name was invalid.", .description = "Given file name was invalid.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ReadWriteError .loc = __GLOBAL__,
.prev = (Status *)&ReadWriteError
}; };
static Status UnavailableFileName = { static const Status UnavailableFileName = (Status){
.identity = nameof(UnavailableFileName),
.value = 1,
.description = "Given file name was unavailable", .description = "Given file name was unavailable",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &UnavailableObject .loc = __GLOBAL__,
.prev = (Status *)&UnavailableObject
}; };
static Status ReportThrown = { static const Status ReportThrown = (Status){
.identity = nameof(ReportThrown),
.value = 1,
.description = "This function has thrown a report, " .description = "This function has thrown a report, "
"following instructions aborted.", "following instructions aborted.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &RuntimeError .loc = __GLOBAL__,
.prev = (Status *)&RuntimeError\
}; };
static Status ReportMessageTooLong = { static const Status ReportMessageTooLong = (Status){
.identity = nameof(ReportMessageTooLong),
.value = 1,
.description = "Given message is too long.", .description = "Given message is too long.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ArrayLengthError .loc = __GLOBAL__,
.prev = (Status *)&ArrayLengthError
}; };
static Status MaximumLengthExceeded = { static const Status MaximumLengthExceeded = (Status){
.identity = nameof(MaximumLengthExceeded),
.value = 1,
.description = "Buffer was too long.", .description = "Buffer was too long.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ArrayLengthError .loc = __GLOBAL__,
.prev = (Status *)&ArrayLengthError
}; };
static Status MaximumLiteralisationLengthExceeded = { static const Status MaximumLiteralisationLengthExceeded = (Status){
.identity = nameof(MaximumLiteralisationLengthExceeded),
.value = 1,
.description = "Literalisation was too long.", .description = "Literalisation was too long.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &MaximumLengthExceeded .loc = __GLOBAL__,
.prev = (Status *)&MaximumLengthExceeded
}; };
static Status UnavailableBuffer = { static const Status UnavailableBuffer = (Status){
.identity = nameof(UnavailableBuffer),
.value = 1,
.description = "Given buffer was unavailable.", .description = "Given buffer was unavailable.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &UnavailableInstance .loc = __GLOBAL__,
.prev = (Status *)&UnavailableInstance
}; };
static Status InvalidLiteralisingBuffer = { static const Status InvalidLiteralisingBuffer = (Status){
.identity = nameof(InvalidLiteralisingBuffer),
.value = 1,
.description = "Given buffer does not have a good integrity on its length.", .description = "Given buffer does not have a good integrity on its length.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &InvalidObject .loc = __GLOBAL__,
.prev = (Status *)&InvalidObject
}; };
// ======================================================== // ========================================================

View File

@@ -2,69 +2,89 @@
#include <Compound/status.h> #include <Compound/status.h>
#include <Compound/utils.h> #include <Compound/utils.h>
bool Location_Equal(Location lc1, Location lc2) /*
typedef struct {
char *file;
int line;
char *func;
} Location;
*/
Status Location_Literalise(Location *inst, char *buff)
{ {
return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) && fails(inst, UnavailableInstance);
(!strcmp(lc1.func, lc2.func))); fails(buff, UnavailableBuffer);
/* Literalise line. */
char line_buff[LITERALISATION_LENGTH_MAXIMUM];
Utils_LiteraliseInteger(inst->line, line_buff);
/* Concatenate every buff. */
const long total_len = strlen(inst->file) + strlen(line_buff)
+ strlen(inst->func)
+ LOCATION_LITERALISE_FORMAT_LENGTH;
state(total_len > LITERALISATION_LENGTH_MAXIMUM,
MaximumLiteralisationLengthExceeded);
/* Copy and assign. */
return (Status) {
.value = !sprintf(buff, LOCATION_LITERALISE_FORMAT,
inst->file, inst->line, inst->func),
.description = NormalStatus.description,
.characteristic = NormalStatus.characteristic,
.loc = __HERE__,
.prev = NormalStatus.prev
};
} }
bool Status_Equals(Status stat1, Status stat2) bool Location_Equal(Location *lc1, Location *lc2)
{ {
state(lc1 == NULL || lc2 == NULL, false);
/* Skip when both stat1 and stat2 are empty. */ return ((!strcmp(lc1->file, lc2->file)) && (lc1->line == lc2->line) &&
state((stat1.value == 0 && stat2.value == 0 && stat1.description == 0x0 && (!strcmp(lc1->func, lc2->func)));
stat2.description == 0x0 && stat1.characteristic == 0 && }
stat2.characteristic == 0 && stat1.prev == 0x0 && stat2.prev == 0x0),
true);
/* True for equality; False for inequality. */ bool Status_Equal(Status *stat1, Status *stat2)
return ((stat1.value == stat2.value) && {
(!strcmp(stat1.description, stat2.description)) && state(stat1 == NULL || stat2 == NULL, false);
(stat1.characteristic == stat2.characteristic) &&
(Status_Equals(*stat1.prev, *stat2.prev))); return (
stat1->value == stat2->value &&
!strcmp(stat1->description, stat2->description) &&
stat1->characteristic == stat2->characteristic &&
Location_Equal(&stat1->loc, &stat2->loc) &&
((StatusUtils_HasPrev(*stat1) && StatusUtils_HasPrev(*stat2))
? Status_Equal(stat1->prev, stat2->prev)
: true)
);
} }
Status Status_Literalise(Status *inst, char *buff) Status Status_Literalise(Status *inst, char *buff)
{ {
/* Skip unavailable or invalid parameters. */ /* Skip unavailable instance and invalid parameter. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(buff, UnavailableBuffer); fails(buff, UnavailableBuffer);
// state(strlen(buff) != LITERALISATION_LENGTH_MAXIMUM,
// InvalidLiteralisingBuffer);
/* Set up idx for counting final literalisation length to ensure the /* Literalise loc. */
string copying is index access safe. */ char loc_buff[LITERALISATION_LENGTH_MAXIMUM];
int idx = 0; notok(Location_Literalise(&inst->loc, loc_buff), {
const int status_dump_buffer_len = StatusUtils_Depth(inst); return error(_, "Failed on literalising the \"loc\" of a status.");
});
Status status_dump_buffer[status_dump_buffer_len]; /* Concatenate every buffer. */
state(!sprintf(buff, STATUS_LITERALISE_FORMAT,
/* Literalise every status that flattened on status_dump_buffer. */ inst->identity, inst->description,
for (register int i = 0; i < status_dump_buffer_len; i++) { (!inst->prev ? "(null)" : (inst->prev->identity)),
char status_literalising_buffer[LITERALISATION_LENGTH_MAXIMUM]; inst->value, inst->characteristic, loc_buff),
(void)Status_Literalise(&status_dump_buffer[i], status_literalising_buffer); error(RuntimeError, "Returned 0 byte written on concatenating buffers "
"during literalisation of a status using \"sprintf\"."));
/* Append to buff. */
/* Prevent buffer-out-of-bound access. */
const int status_literalising_buffer_len = strlen(status_literalising_buffer);
if (idx + status_literalising_buffer_len >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL;
return MaximumLiteralisationLengthExceeded;
}
idx += status_literalising_buffer_len;
(void)strcat(buff, status_literalising_buffer);
}
return NormalStatus; return NormalStatus;
} }
bool StatusUtils_HasPrev(Status *stat) bool StatusUtils_HasPrev(Status stat)
{ {
/* Skip when stat is unavailable for accessing. */ return (stat.prev != NULL);
state(Status_Equals(*stat, (Status){}), false);
return (stat->prev != NULL);
} }
bool StatusUtils_IsOkay(Status stat) bool StatusUtils_IsOkay(Status stat)
@@ -74,20 +94,20 @@ bool StatusUtils_IsOkay(Status stat)
bool StatusUtils_IsValid(Status stat) bool StatusUtils_IsValid(Status stat)
{ {
return (!strcmp(stat.description, "") && stat.characteristic >= 0 && return (!strcmp(stat.description, "") && stat.characteristic >= 0
stat.prev != NULL); && !stat.prev);
} }
bool StatusUtils_IsRecursive(Status stat) bool StatusUtils_IsRecursive(Status stat)
{ {
return (stat.prev != NULL && stat.prev == &stat); return (stat.prev && stat.prev == &stat);
} }
void StatusUtils_Dump(Status *inst, Status *store, int idx) void StatusUtils_Dump(Status *inst, Status *store, int idx)
{ {
/* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */ /* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */
solve((store == NULL || !StatusUtils_HasPrev(inst) || idx < 0), return;); solve((!store || !StatusUtils_HasPrev(*inst) || idx < 0), return;);
store[idx] = *inst; store[idx] = *inst;
@@ -97,16 +117,12 @@ void StatusUtils_Dump(Status *inst, Status *store, int idx)
int StatusUtils_Depth(Status *stat) int StatusUtils_Depth(Status *stat)
{ {
/* Skip unavailable stat. */ /* Skip unavailable stat. */
state((stat == NULL), -1); state((!stat || !stat->prev), -1);
Status *p = stat; // Include this layer of Status. Status *p = stat; // Include this layer of Status.
int cnt = 1; register int cnt;
while (p != NULL) { for (cnt = 0; (!StatusUtils_IsRecursive(*p)
if (StatusUtils_IsRecursive(*p) || !StatusUtils_HasPrev(stat)) break; && StatusUtils_HasPrev(*p)); cnt++) p = p->prev;
p = p->prev;
cnt += 1;
}
return cnt; return cnt;
} }
@@ -116,21 +132,51 @@ Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
{ {
/* Skip unavailable parameters. */ /* Skip unavailable parameters. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(stat, error(InvalidParameter, "Given initiator was null.")); fails(stat, error(InvalidParameter, "Given stat was null."));
fails(initiator, error(InvalidParameter, "Given initiator was null.")); fails(initiator, error(InvalidParameter, "Given initiator was null."));
state(priority < 0, error(InvalidParameter, "Given priority was negative.")); state(priority < 0, error(InvalidParameter, "Given priority was negative."));
/* Copy and assign. */ /* Copy and assign. */
inst->status = *stat; inst->status = *stat;
inst->initiator = initiator; inst->initiator = calloc(strlen(initiator), sizeof(char));
(void)strcpy(inst->initiator, initiator);
inst->time = time(NULL); inst->time = time(NULL);
inst->priority = priority; inst->priority = priority;
inst->task_status = REPORT_SENDING_TASK_STATUS_PENDING; inst->task_status = REPORT_SENDING_TASK_STATUS_PENDING;
inst->dest = (dest == NULL ? stderr : dest); inst->dest = (dest == NULL ? stdout : dest);
return NormalStatus; return NormalStatus;
} }
Status Report_CopyOf(Report *inst, Report *other)
{
fails(inst, UnavailableInstance);
fails(other, error(InvalidParameter, "Given report is unavailable."));
// Status status;
// char *initiator;
// time_t time;
// ReportSendingPriority priority;
// ReportSendingTaskStatus task_status;
// FILE *dest;
inst->status = other->status;
}
void Report_Delete(Report *inst)
{
svoid(inst);
free(inst->initiator);
inst->initiator = NULL;
inst->dest = NULL;
inst->priority = 0;
inst->status = (Status){};
inst->task_status = REPORT_SENDING_TASK_STATUS_NOTFOUND;
inst->time = 0;
inst = NULL;
}
Status Report_Literalise(Report *inst, char *buff) Status Report_Literalise(Report *inst, char *buff)
{ {
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
@@ -195,7 +241,9 @@ Status ReportSender_Create(ReportSender *inst, Report *report)
fails(report, error(UnavailableParameter, "Given report was unavailable.")); fails(report, error(UnavailableParameter, "Given report was unavailable."));
thrd_create(&inst->thread, &HANDLER, report); thrd_create(&inst->thread, &HANDLER, report);
*inst->report = *report; notok(Report_CopyOf(inst->report, report),
return error(ErrorStatus, "Cannot copy to create new instance of report.");
) // *inst->report = *report;
inst->elapsed = 0; inst->elapsed = 0;
inst->result = REPORT_SENDER_RESULT_PENDING; inst->result = REPORT_SENDER_RESULT_PENDING;
inst->successful = false; inst->successful = false;
@@ -294,4 +342,3 @@ int HANDLER(void *report)
return 0; return 0;
} }

View File

@@ -22,7 +22,6 @@ Status String_Delete(String *inst);
Status String_GetIdx(String *inst, Char *item, int index); Status String_GetIdx(String *inst, Char *item, int index);
Status String_SetIdx(String *inst, Char *item, int index); Status String_SetIdx(String *inst, Char *item, int index);
Status String_Literalise(String *inst, String *store); Status String_Literalise(String *inst, String *store);
bool String_Equals(String *arr1, String *arr2);
/* Extensional. */ /* Extensional. */
Status StringUtils_FromInteger(String *inst, int value); Status StringUtils_FromInteger(String *inst, int value);
@@ -83,6 +82,7 @@ Status String_Decode(String *inst, StringEncoding encoding);
int StringUtils_Compare(String *a, String *b); int StringUtils_Compare(String *a, String *b);
static Status StringConversionPrecisionError = { static Status StringConversionPrecisionError = {
.value = 1,
.description = "Unpreventable precision loss was found during conversion " .description = "Unpreventable precision loss was found during conversion "
"between string and raw data.", "between string and raw data.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,

View File

@@ -2,13 +2,8 @@
Status String_Create(String *inst, int len) Status String_Create(String *inst, int len)
{ {
Status create = Array_Create(inst, len); /* Create an array has length len + 1, for termination character in string. */
solve(!(StatusUtils_IsOkay(create)), { ensure(Array_Create(inst, len + 1, sizeof(int)), "Failed to create a string.");
Report e = stamp(error(create, "Failed to create a string."),
nameof(Array_Create));
(void)_throw(e);
return ReportThrown;
})
return NormalStatus; return NormalStatus;
} }
@@ -23,12 +18,12 @@ Status String_Delete(String *inst)
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }
Status String_GetIdx(String *inst, Char *store, int index) Status String_GetAt(String *inst, Char *store, int index)
{ {
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }
Status String_SetIdx(String *inst, Char *source, int index) Status String_SetAt(String *inst, Char *source, int index)
{ {
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }
@@ -38,8 +33,30 @@ Status String_Literalise(String *inst, String *store)
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }
bool String_Equals(String *arr1, String *arr2) int StringUtils_Compare(String *a, String *b)
{ {
fails(inst, UnavailableInstance); /* Both being null is counted as equal. */
} state(a == NULL && b == NULL, 0);
/* Compare by iterating through each element to calculate differing
values between a[i] and b[i]. */
const int len = max(a->len, b->len);
for (register int i = 0; i < len; i++) {
const int comp =
(*(char *)(a->members[i].addr) - *(char *)(b->members[i].addr));
/*
If values from both side does not equal, return the differential value.
*/
if (!comp) {
return comp;
}
}
/* Even the previous elements are same, but the length must be compared
because we haven't really done this.
The reason that we don't compare it earlier is though we can know whether
the lengths are the same or not, we, however, cannot give a precise value
telling which content from string is "greater" or "less". */
return (a->len != b->len);
}

View File

@@ -5,10 +5,14 @@
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
# include <math.h> # include <math.h>
# include <stdint.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/const.h> # include <Compound/const.h>
# define max(a, b) (a >= b ? a : b)
# define min(a, b) (a <= b ? a : b)
# define DATETIME_FORMAT "%a %d %b %X %Z %Y" # define DATETIME_FORMAT "%a %d %b %X %Z %Y"
int Utils_CalcDigits(long long int n); int Utils_CalcDigits(long long int n);

View File

@@ -46,3 +46,4 @@ int Utils_DateTimeLiteralise(time_t t, char *buff)
{ {
return 0; return 0;
} }

View File

@@ -15,6 +15,7 @@
// # define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ " // # define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ "
// static Status IllegalVarIdentity = { // static Status IllegalVarIdentity = {
// .value = 1,
// .description = "Given identity does not fit the standard of Var Naming " // .description = "Given identity does not fit the standard of Var Naming "
// "convention.", // "convention.",
// .characteristic = STATUS_ERROR, // .characteristic = STATUS_ERROR,
@@ -22,6 +23,7 @@
// }; // };
// static Status VarIdentityTooLong = { // static Status VarIdentityTooLong = {
// .value = 1,
// .description = "Given identity has longer length that the maximum length " // .description = "Given identity has longer length that the maximum length "
// "limitation.", // "limitation.",
// .characteristic = STATUS_ERROR, // .characteristic = STATUS_ERROR,
@@ -34,6 +36,8 @@ typedef struct {
void *addr; void *addr;
size_t size; size_t size;
bool alive;
// /* Identification */ // /* Identification */
// char *identity; // Maximum up to VAR_IDENTITY_LENGTH // char *identity; // Maximum up to VAR_IDENTITY_LENGTH

View File

@@ -2,14 +2,14 @@
Status Var_Create(Var *inst, size_t size) Status Var_Create(Var *inst, size_t size)
{ {
*inst = (Var) { fails(inst, UnavailableInstance);
.addr = malloc(size), state(inst->alive, InstanceStillAlive);
.size = size state(!size, normal(NormalStatus, "Exited with given parameter"
}; "size as ZERO."));
if (inst->addr == NULL) { state(((inst->addr = malloc(size)) == NULL), InsufficientMemory);
return InsufficientMemory; inst->size = size;
} inst->alive = true;
return NormalStatus; return NormalStatus;
} }
@@ -34,18 +34,20 @@ Status Var_CopyOf(Var *inst, Var *other)
{ {
/* Skip when inst or other is unavailable. */ /* Skip when inst or other is unavailable. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
state(inst->alive, InstanceStillAlive);
fails(other, InvalidParameter); fails(other, InvalidParameter);
/* Copy members from other. Only has to apply size, no addr is needed. */ /* Copy members from other. Only has to apply size, no addr is needed. */
inst->addr = malloc(other->size); state(!((inst->addr = malloc(other->size))), InsufficientMemory);
inst->size = other->size; inst->size = other->size;
inst->alive = true;
return NormalStatus; return NormalStatus;
} }
void Var_Delete(Var *inst) void Var_Delete(Var *inst)
{ {
if (inst == NULL) return; svoid(!inst);
free(inst->addr); free(inst->addr);
inst->addr = NULL; inst->addr = NULL;
@@ -55,7 +57,7 @@ void Var_Delete(Var *inst)
// void Var_Delete(Var *inst) // void Var_Delete(Var *inst)
// { // {
// /* Skip when inst or inst->addr is unavailable. */ // /* Skip when inst or inst->addr is unavailable. */
// svoid(inst == NULL || inst->addr == NULL); // svoid(!inst || inst->addr == NULL);
// inst->addr = NULL; // inst->addr = NULL;
// inst->size = 0; // inst->size = 0;
@@ -65,7 +67,7 @@ void Var_Delete(Var *inst)
void VarUtils_Swap(Var *v1, Var *v2) void VarUtils_Swap(Var *v1, Var *v2)
{ {
/* Skip when v1 or v2 is unavailable. */ /* Skip when v1 or v2 is unavailable. */
svoid(v1 == NULL || v2 == NULL); svoid(!v1 || !v2);
Var v3 = *v1; Var v3 = *v1;
*v1 = *v2; *v1 = *v2;
@@ -75,7 +77,7 @@ void VarUtils_Swap(Var *v1, Var *v2)
Status Var_Literalise(Var *inst, char *buff) Status Var_Literalise(Var *inst, char *buff)
{ {
/* Skip when inst is unavailable. */ /* Skip when inst is unavailable. */
state(inst == NULL, UnavailableInstance); state(!inst, UnavailableInstance);
/* Write into buffer. */ /* Write into buffer. */
state(!sprintf(buff, VAR_LITERALISE_FORMAT"\n", inst->addr, inst->size), state(!sprintf(buff, VAR_LITERALISE_FORMAT"\n", inst->addr, inst->size),
@@ -87,7 +89,7 @@ Status Var_Literalise(Var *inst, char *buff)
bool Var_Equals(Var *a, Var *b) bool Var_Equals(Var *a, Var *b)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
state((a == NULL || b == NULL), false); state((!a || !b), false);
return (a->addr == b->addr && a->size == b->size); return (a->addr == b->addr && a->size == b->size);
} }

9
attr.h
View File

@@ -3,15 +3,6 @@
# include <Compound/name.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{ typedef struct _Attribute{
int serialNo; int serialNo;
int (*exec)(void *); int (*exec)(void *);

View File

@@ -30,7 +30,7 @@ Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other)
bool CatlogMsg_Equals(CatlogMsg *inst, CatlogMsg *other) bool CatlogMsg_Equals(CatlogMsg *inst, CatlogMsg *other)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
state((inst == NULL || other == NULL), false); state((!inst || other == NULL), false);
return ( return (
inst->time == other->time && inst->time == other->time &&
@@ -73,7 +73,7 @@ Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other)
bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other) bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
state((inst == NULL || other == NULL), false); state((!inst || other == NULL), false);
return ( return (
CatlogMsg_Equals(&inst->msg, &other->msg) && CatlogMsg_Equals(&inst->msg, &other->msg) &&
@@ -97,7 +97,7 @@ Status CatlogSender_Send(CatlogSender *inst, char *filepath, bool append)
(void)CatlogUtils_OpenFile(inst->dst, filepath, (append ? "a" : "w")); (void)CatlogUtils_OpenFile(inst->dst, filepath, (append ? "a" : "w"));
/* Write msg. */ /* Write msg. */
return normal(NormalStatus, "", fprintf(inst->dst, "%s", inst->msg.content)); return unknown(NormalStatus, "", !fprintf(inst->dst, "%s", inst->msg.content));
} }
Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2);

33
class.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef COMPOUND_CLASS_H
# define COMPOUND_CLASS_H
# include <Compound/object.h>
typedef struct {} _Interface;
typedef struct {
String identity;
Array type(DynStruct) structs;
Array type(DynUnion) unions;
Array type(DynEnum) enums;
Array type(FunctionPointer) functionptrs;
Array type(Field) fields;
// Interface[] *implementations
Array type(Var type(Interface)) *implementations;
// Class *predecessor
Var type(Class) *predecessor;
} Class;
Status Class_Create(Class *inst, Array type(DynStruct) structs,
Array type(DynUnion) unions,
Array type(DynEnum) enums,
Array type(FunctionPointer) functionptrs,
Array type(Field) fields);
Status Class_CreateEmpty(Class *inst);
Status Class_CopyOf(Class *inst, Class *other);
Status Class_Implement(Class *inst, _Interface *interface);
Status Class_Extern(Class *inst, Class *)
#endif /* COMPOUND_CLASS_H */

View File

@@ -43,33 +43,43 @@
/* Create a new UnknownStatus on the fly. */ /* Create a new UnknownStatus on the fly. */
# define unknown(e, c, v) ((Status) {\ # define unknown(e, c, v) ((Status) {\
.identity = nameof(UnknownStatus),\
.value = v,\ .value = v,\
.description = c,\ .description = c,\
.characteristic = STATUS_UNKNOWN,\ .characteristic = STATUS_UNKNOWN,\
.loc = __HERE__,\
.prev = e.prev\ .prev = e.prev\
}) })
/* Create a new NormalStatus on the fly. */ /* Create a new NormalStatus on the fly. */
# define normal(e, c, v) ((Status) {\ # define normal(e, c) ((Status) {\
.value = v,\ .identity = nameof(NormalStatus),\
.value = 0,\
.description = c,\ .description = c,\
.characteristic = STATUS_NORMAL,\ .characteristic = STATUS_NORMAL,\
.loc = __HERE__,\
.prev = e.prev\ .prev = e.prev\
}) })
/* Create a new ErrorStatus on the fly. */ /* Create a new ErrorStatus on the fly. */
# define error(e, c) ((Status) {\ # define error(e, c) ((Status) {\
.identity = nameof(ErrorStatus),\
.value = e.value,\
.description = c,\ .description = c,\
.characteristic = STATUS_ERROR,\ .characteristic = STATUS_ERROR,\
.loc = __HERE__,\
.prev = e.prev\ .prev = e.prev\
}) })
/* Extend the Status chain by giving 'p' for "predecessor" /* Extend the Status chain by giving 'p' for "predecessor"
and 'c' for "comment/description". */ and 'e' for "Eval-Status". */
# define extend(p, c) ((Status) {\ # define extend(p, e) ((Status) {\
.description = c,\ .identity = e.identity,\
.value = p.value,\
.description = e.description,\
.characteristic = p.characteristic,\ .characteristic = p.characteristic,\
.prev = p\ .loc = e.loc,\
.prev = &p\
}) })
/** @brief Create a report in place. /** @brief Create a report in place.
@@ -83,7 +93,7 @@
.initiator = c,\ .initiator = c,\
.time = time(NULL),\ .time = time(NULL),\
.priority = REPORT_SENDING_PRIORITY_NORMAL,\ .priority = REPORT_SENDING_PRIORITY_NORMAL,\
.status = REPORT_SENDING_TASK_STATUS_PENDING\ .task_status = REPORT_SENDING_TASK_STATUS_PENDING\
}) })
/** /**
@@ -104,7 +114,7 @@
// */ // */
// # define force(s, k, v) solve((s) != (k), v) // # define force(s, k, v) solve((s) != (k), v)
// # define sforce(s, k, v) solve((!Status_Equals(s, k)), v) // # define sforce(s, k, v) solve((!Status_Equal(s, k)), v)
/* Get the literal. */ /* Get the literal. */
# define nameof(obj) #obj # define nameof(obj) #obj
@@ -124,6 +134,13 @@
CatlogSender_Send(&sender, "stdout", false);\ CatlogSender_Send(&sender, "stdout", false);\
} }
# define _status(s) {\
const Status _ = s;\
char buff[LITERALISATION_LENGTH_MAXIMUM];\
(void)Status_Literalise((Status *)&_, buff);\
(void)printf("%s\n", buff);\
}
# define ok(s, b) {\ # define ok(s, b) {\
const Status _ = s;\ const Status _ = s;\
if (StatusUtils_IsOkay(_)) b\ if (StatusUtils_IsOkay(_)) b\
@@ -162,11 +179,21 @@ typedef bool _Bit;
# define WHICH_MIN(a, b) # define WHICH_MIN(a, b)
# define INRANGE(lf, inclf, rt, incrt, v) \ # define INRANGE(lf, inclf, rt, incrt, v) \
(! ((lf > rt) || ((v <= lf && !inclf) || (v >= rt && !incrt)))) (!((lf > rt) || ((v <= lf && !inclf) || (v >= rt && !incrt))))
# define ATRANGE(lf, rt, v) \ # define ATRANGE(lf, rt, v) \
(INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt)) (INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt))
# define LITERALISATION_LENGTH_MAXIMUM 0xFFFF # define LITERALISATION_LENGTH_MAXIMUM 0xFFFFL
/* Only effect (probably) when formal Attribute is defined.
* __ATTRIBUTABLE indicates this field is used for further process by Attribute.
* Or, to put this way, this field has attributions not used so far, but
* eventually will.
*/
# define __ATTRIBUTABLE
# define __ATTRIBUTABLE__
# define attr(a)
#endif /* NO COMPOUND_COMMON_h */ #endif /* NO COMPOUND_COMMON_h */

View File

@@ -12,7 +12,7 @@ fi
SRC="$PWD" SRC="$PWD"
DST=/usr/include/Compound DST=/usr/include/Compound
PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan" "Stack" "Utils"\ PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan" "Stack" "Utils"\
"String") "String" "Object")
PROJLEN=${#PROJ[*]} PROJLEN=${#PROJ[*]}
echo "======== $PROJLEN projects in total ========" echo "======== $PROJLEN projects in total ========"
@@ -35,5 +35,5 @@ done
cp -v "common.h" "const.h" "platform.h"\ cp -v "common.h" "const.h" "platform.h"\
"name.h" "namescope.h" "type.h" "catlog.h"\ "name.h" "namescope.h" "type.h" "catlog.h"\
"attr.h" "registry.h" "$DST" "attr.h" "registry.h" "class.h" "$DST"
printf "\nDone\n" printf "\nDone\n"

8
interface.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef COMPOUND_INTERFACE_H
# define COMPOUND_INTERFACE_H
typedef struct {
}
#endif /* COMPOUND_INTERFACE_H */

5
name.h
View File

@@ -5,8 +5,9 @@
# include <Compound/status.h> # include <Compound/status.h>
# include <Compound/array.h> # include <Compound/array.h>
// Name, is a base of numeral counting. // Name, is an interger.
// It uses 63 as the base, lasts for 63 times. // It contains 64 digits, each bit representing 63 possible characters.
// Possible characters: [a-zA-Z_]
// At the head of each Name, 8 pilots stores for its type. // At the head of each Name, 8 pilots stores for its type.
// In total, ((26*2+10+1)^63)*8 // In total, ((26*2+10+1)^63)*8
// = 63^63*8 // = 63^63*8

View File

@@ -24,7 +24,9 @@ Status NameScope_CopyOf(NameScope *inst, NameScope *other)
other->latest = inst->latest; other->latest = inst->latest;
other->idx = inst->idx; other->idx = inst->idx;
const Name len = NameScope_CalcNameArrayLength(&other->occupied); const Name len = `
`
NameScopeUtils_CalcNameArrayLength(&other->occupied);
for (Name i = (Name){0}; (NameScope_CompareName(i, len) < 0);) { for (Name i = (Name){0}; (NameScope_CompareName(i, len) < 0);) {
// TODO(william): HERE // TODO(william): HERE
@@ -41,21 +43,15 @@ Status NameScope_RemoveName(NameScope *inst, Name idx);
Status NameScope_EmptyName(Name *inst); Status NameScope_EmptyName(Name *inst);
Status NameScope_CountUp(Name *inst);
Status NameScope_CountDown(Name *inst);
Status NameScope_CountUpFor(Name *inst, Name amount);
Status NameScope_CountDownFor(Name *inst, Name amount);
Status NameScope_UpdateLatest(NameScope *inst, Name idx); Status NameScope_UpdateLatest(NameScope *inst, Name idx);
Status NameScope_FormatTrim(Name *inst); Status NameScope_FormatTrim(Name *inst);
Status NameScope_FormatInflate(Name *inst); Status NameScope_FormatInflate(Name *inst);
Name NameScope_CalcNameArrayLength(Name **arr); Name `
`
NameScopeUtils_CalcNameArrayLength(Name **arr);
bool NameScope_IsAvailable(NameScope *inst, Name idx); bool NameScope_IsAvailable(NameScope *inst, Name idx);

View File

@@ -13,11 +13,15 @@ typedef struct {
Status NameScope_Create(NameScope *inst); Status NameScope_Create(NameScope *inst);
Status NameScope_CopyOf(NameScope *inst, NameScope *other); Status NameScope_CopyOf(NameScope *inst, NameScope *other);
Status NameScope_EmptyName(Name *inst);
Status NameScope_CreateName(NameScope *inst, Name *buff); Status NameScope_CreateName(NameScope *inst, Name *buff);
Status NameScope_RemoveName(NameScope *inst, Name idx); Status NameScope_RemoveName(NameScope *inst, Name idx);
Status NameScope_UpdateLatest(NameScope *inst, Name idx); Status NameScope_UpdateLatest(NameScope *inst, Name idx);
Name NameScopeUtils_CalcNameArrayLength(Name **arr);
bool NameScope_Equals(NameScope *inst, NameScope *other); bool NameScope_Equals(NameScope *inst, NameScope *other);
bool NameScope_IsAvailable(NameScope *inst, Name idx); bool NameScope_IsAvailable(NameScope *inst, Name idx);
bool NameScope_IsValidName(Name *inst);
/* Universal Attribute NameScope. (U.A.N.) */ /* Universal Attribute NameScope. (U.A.N.) */
NameScope(Attribute) UniversalAttributeNameScope; NameScope(Attribute) UniversalAttributeNameScope;