(MOD) Refined Var, Array, CatlogMsg, CatlogSender, Status

This is the very first version that pass the compiler.  Though it has lots things were made for testing, such as commenting problematic source code to avoid irrelevant errors.  For test.c, everything is working fine.  Congrats!
This commit is contained in:
William
2024-05-20 04:47:39 +08:00
parent e73f3af436
commit e2f8dceda7
23 changed files with 656 additions and 393 deletions

1
.gitignore vendored
View File

@@ -13,3 +13,4 @@ todo_stack
getReady.sh getReady.sh
base_type.c base_type.c
sample sample
compile

View File

@@ -21,23 +21,33 @@ static Status InvalidArrayLength = {
}; };
/* Elementary. */ /* Elementary. */
Status Array_Create(Array *inst, int len); Status Array_Create(Array *inst, int len, size_t size)
throws(InsufficientMemory InvalidArrayLength);
Status Array_CopyOf(Array *inst, Array *other); Status Array_CopyOf(Array *inst, Array *other);
Status Array_Delete(Array *inst); Status Array_Delete(Array *inst);
Status Array_GetIdx(Array *inst, Var *store, int index); Status Array_GetIdx(Array *inst, Var *store, int index);
throws(ArrayIndexOutOfBound);
Status Array_SetIdx(Array *inst, Var *source, int index); Status Array_SetIdx(Array *inst, Var *source, int index);
bool Array_Equal(Array *arr1, Array *arr2); throws(ArrayIndexOutOfBound);
bool Array_Equals(Array *arr1, Array *arr2);
/* Extensional. */ /* Extensional. */
Status ArrayUtils_Insert(Array *inst, Var *item, int index); Status ArrayUtils_Insert(Array *inst, Var *item, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_InsertArray(Array *inst, Array *items, int index); Status ArrayUtils_InsertArray(Array *inst, Array *items, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_Remove(Array *inst, int index); Status ArrayUtils_Remove(Array *inst, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_RemoveArray(Array *inst, int off, int len); Status ArrayUtils_RemoveArray(Array *inst, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len); Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len); Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Search(Array *inst, Var *item, int *store); Status ArrayUtils_Search(Array *inst, Var *item, int *store);
Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store); Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store);
Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index); Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_Revert(Array *inst); Status ArrayUtils_Revert(Array *inst);
bool ArrayUtils_IsEmpty(Array *inst); bool ArrayUtils_IsEmpty(Array *inst);
bool ArrayUtils_IsBlank(Array *inst); bool ArrayUtils_IsBlank(Array *inst);

View File

@@ -1,7 +1,7 @@
#include <Compound/array.h> #include <Compound/array.h>
#include <Compound/status.h> #include <Compound/status.h>
Status Array_Create(Array *inst, int len) Status Array_Create(Array *inst, int len, size_t size)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
@@ -10,29 +10,75 @@ Status Array_Create(Array *inst, int len)
inst->len = len; inst->len = len;
inst->members = calloc(len, sizeof(Var)); inst->members = calloc(len, sizeof(Var));
int erridx = -1;
for (register int i = 0; i < len; i++) {
// TODO(william): Throw InsufficientMemory at following line.
solve(!StatusUtils_IsOkay(Var_Create(&inst->members[i], size)), {
#ifdef __DEBUG__
cat("Var_Create failed!\n")
#endif
erridx = i;
break;
} else {
#ifdef __DEBUG__
cat("Var_Create success!\n")
#endif
})
}
/* Review on erridx. Release data that allocated. */
if (erridx != -1) {
for (register int i = erridx; i >= 0; i--) {
Var_Delete(&inst->members[i]);
#ifdef __DEBUG__
cat("Deleted var from InsufficientMemory from Array_Create!")
#endif
}
/* Release array itself. */
free(inst->members);
return InsufficientMemory;
}
return NormalStatus;
} }
Status Array_CopyOf(Array *inst, Array *other) Status Array_CopyOf(Array *inst, Array *other)
{ {
/* Skip unavailable inst and invalid param. */ // /* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance); // fails(inst, UnavailableInstance);
fails(other, error(InvalidParameter, "Given other was unavailable.")); // fails(other, error(InvalidParameter, "Given other was unavailable."));
/* Assign value for len. */ // /* Assign value for len. */
inst->len = other->len; // inst->len = other->len;
/* Recreate array. */ // if (inst->members == NULL) return NormalStatus;
if (inst->members == NULL) return NormalStatus; // match(RuntimeError, Array_Create(inst, other->len), "Failed on recreating "
match(RuntimeError, Array_Delete(inst), "Failed on deleting array."); // "array.");
match(RuntimeError, Array_Create(inst, other->len), "Failed on recreating "
"array.");
/* Copy and assign for each member from other to inst. */ // /* Copy and assign for each member from other to inst. */
for (register int i = 0; i < inst->len; i++) { // for (register int i = 0; i < inst->len; i++) {
inst[i] = other[i]; // inst[i] = other[i];
// }
// return NormalStatus;
/*
if (other == NULL) return 1;
String_Create(inst, other->len);
for (register int i = 0; i < other->len; i++) {
inst->arr[i] = other->arr[i];
} }
return NormalStatus; return 0;
*/
} }
Status Array_Delete(Array *inst) Status Array_Delete(Array *inst)
@@ -74,14 +120,14 @@ Status Array_SetIdx(Array *inst, Var *source, int index)
return NormalStatus; return NormalStatus;
} }
bool Array_Equal(Array *a, Array *b) bool Array_Equals(Array *a, Array *b)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
state((a == NULL || b == NULL), false); state((a == NULL || b == NULL), false);
state((a->len != b->len), false); state((a->len != b->len), false);
for (register int i = 0; i < a->len; i++) { for (register int i = 0; i < a->len; i++) {
if (!Var_Equal(&a->members[i], &b->members[i])) { if (!Var_Equals(&a->members[i], &b->members[i])) {
return false; return false;
} }
} }

View File

@@ -3,6 +3,7 @@ cmake_minimum_required (VERSION 3.5)
project (Compound) project (Compound)
add_compile_options(-g -std=c99 -Wall -Wextra -Wformat) add_compile_options(-g -std=c99 -Wall -Wextra -Wformat)
LINK_LIBRARIES(m)
# add_executable(CompoundTest test.c # add_executable(CompoundTest test.c
# Var/src/var.c # Var/src/var.c
@@ -13,7 +14,10 @@ add_compile_options(-g -std=c99 -Wall -Wextra -Wformat)
# catlog.c # catlog.c
# name.c) # name.c)
add_executable(CompoundTest test.c add_executable(CompoundTest
test.c
Var/src/var.c Var/src/var.c
Array/src/array.c Array/src/array.c
Status/src/status.c) Status/src/status.c
Utils/src/utils.c
catlog.c)

View File

@@ -32,7 +32,7 @@ Status MemMan_Memory_Reallocate(Memory *inst, size_t length);
void MemMan_Memory_Release(Memory *inst); void MemMan_Memory_Release(Memory *inst);
Status MemMan_Memory_Prioritise(Memory *inst); Status MemMan_Memory_Prioritise(Memory *inst);
Status MemMan_Memory_Deprioritise(Memory *inst); Status MemMan_Memory_Deprioritise(Memory *inst);
bool MemMan_Memory_Equal(Memory *inst, Memory *other); bool MemMan_Memory_Equals(Memory *inst, Memory *other);
Status MemMan_MemoryPool_Create(MemoryPool *inst, size_t volume); Status MemMan_MemoryPool_Create(MemoryPool *inst, size_t volume);
Status MemMan_MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority); Status MemMan_MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority);

View File

@@ -2,13 +2,13 @@
# define COMPOUND_OBJECT_H # define COMPOUND_OBJECT_H
# include <Compound/array.h> # include <Compound/array.h>
# include <Compound/namespace.h> # include <Compound/name.h>
# include <Compound/type.h> # include <Compound/type.h>
typedef struct { // interface typedef struct { // interface
Var *data; Var *data;
Array buffer; Array buffer;
int (*Literalise)(void); Var *(*Literalise)(void);
int (*Correspond)(Var *other); int (*Correspond)(Var *other);
} Object; } Object;
@@ -71,7 +71,9 @@ typedef struct {
} Destructor; } Destructor;
typedef struct { typedef struct {
OBJECT_IMPLEMENTATION // OBJECT_IMPLEMENTATION
Object this;
char *identity; char *identity;

View File

@@ -42,7 +42,7 @@ DECLARATION:
*PLEASE NOTE, AN EMPTY DESCRIPTION ALONG WITH A NULL DESCRIPTION IS *PLEASE NOTE, AN EMPTY DESCRIPTION ALONG WITH A NULL DESCRIPTION IS
REGARDED AS "MEANINGLESS ONE" WHICH DOES NOT DOING ANYTHING EFFECTIVE FOR REGARDED AS "MEANINGLESS ONE" WHICH DOES NOT DOING ANYTHING EFFECTIVE FOR
ANYONE. DESCRIPTIONS CAN BE VALIDATED WITH FUNCTION `status_isvalid`. ANYONE. DESCRIPTIONS CAN BE VALIDATED WITH FUNCTION `StatusUtils_IsValid`.
iii. characteristic: int iii. characteristic: int
@@ -60,10 +60,11 @@ DECLARATION:
IN SOME CASES, THIS MEMBER COULD POINT AT IT SELF, MEANING IT COULD MAKE IN SOME CASES, THIS MEMBER COULD POINT AT IT SELF, MEANING IT COULD MAKE
A RECURSIVE SITUATION WHERE IT REQUIRE EXTRA EXAMINATIONS BEFORE GOING TO A RECURSIVE SITUATION WHERE IT REQUIRE EXTRA EXAMINATIONS BEFORE GOING TO
THE ADDRESS IT POINTS AT. THESE PROBLEMS CAN BE AVOIDED WITH FUNCTION THE ADDRESS IT POINTS AT. THESE PROBLEMS CAN BE AVOIDED WITH FUNCTION
`status_recursive` CALLED AHEAD. `StatusUtils_IsRecursive` CALLED AHEAD.
*GO SEE status_dump FOR DETAILS ABOUT DUMPING CALLING STACKS. *GO SEE StatusUtils_Dump
*GO SEE status_recursive FOR DETERRING RECURSIVE "PREV". StatusUtils_Dump FOR DETAILS ABOUT DUMPING CALLING STACKS.
*GO SEE StatusUtils_IsRecursive FOR DETERRING RECURSIVE "PREV".
SYNONYM: SYNONYM:
Status funcname1(void *param); Status funcname1(void *param);

View File

@@ -8,6 +8,7 @@
# include <threads.h> # include <threads.h>
# include <time.h> # include <time.h>
# include <stdio.h> # include <stdio.h>
# include <math.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/utils.h> # include <Compound/utils.h>
@@ -20,7 +21,6 @@ typedef enum {
STATUS_ERROR = 1 STATUS_ERROR = 1
} StatusCharacteristics; } StatusCharacteristics;
typedef enum { typedef enum {
/* Settlement. */ /* Settlement. */
ARGUE_RESULT_FINALISED = 0b01, ARGUE_RESULT_FINALISED = 0b01,
@@ -100,17 +100,17 @@ typedef enum {
/* "Report" recollects essential informations, included but not limited to /* "Report" recollects essential informations, included but not limited to
Status and others for making an report for debugging and such. */ Status and others for making an report for debugging and such. */
typedef struct { typedef struct {
Status stat; Status status;
char *originator; char *initiator;
time_t time; time_t time;
ReportSendingPriority priority; ReportSendingPriority priority;
ReportSendingTaskStatus status; ReportSendingTaskStatus task_status;
FILE *dest; // The destination where the report is sending to. FILE *dest; // The destination where the report is sending to.
} Report; } Report;
/* /*
TIME [PRIORITY] STATUSNAME (ORIGINATOR): STATUS.DESCRIPTION DATETIME [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
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
@@ -126,23 +126,23 @@ Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buf
*/ */
# define REPORT_LITERALISE_HEADER_FORMAT "%ld [%s] %s (%s): %s" # define REPORT_LITERALISE_HEADER_FORMAT "%s [%s] %s (%s): %s"
# 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, \ // # define REPORT_LITERALISE_HEADER_FORMAT_LENGTH(buff, PRIORITY, STATUSNAME, \
ORIGINATOR, DESCRIPTION) \ // ORIGINATOR, DESCRIPTION) \
{ \ // { \
const time_t now = time(NULL); \ // const time_t now = time(NULL); \
(void)strflen(buff, 28, DATETIME_FORMAT, localtime(&now)); \ // (void)strflen(buff, 28, DATETIME_FORMAT, localtime(&now)); \
*length = strlen(buff); \ // *length = strlen(buff); \
} // }
# define REPORT_LITERALISE_CHAINS_FORMAT_LENGTH(FILEPATH, LINE, FUNCNAME) \ // # define REPORT_LITERALISE_CHAINS_FORMAT_LENGTH(FILEPATH, LINE, FUNCNAME) \
(strlen(FILEPATH) + utils_calc_digits(LINE) + \ // (strlen(FILEPATH) + utils_calc_digits(LINE) + \
strlen(FUNCNAME) + 10) // Does not count '\0' // strlen(FUNCNAME) + 10) // Does not count '\0'
# define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT_LENGTH \ // # define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT_LENGTH \
REPORT_LITERALISE_CHAINS_FORMAT_LENGTH // REPORT_LITERALISE_CHAINS_FORMAT_LENGTH
typedef enum { typedef enum {
REPORT_SENDER_RESULT_FINISHED, REPORT_SENDER_RESULT_FINISHED,
@@ -200,21 +200,21 @@ typedef struct {
# define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX # define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX
bool Location_Equal(Location lc1, Location lc2); bool Location_Equals(Location lc1, Location lc2);
bool Status_Equal(Status stat1, Status stat2);
Status Status_Literalise(Status *inst, char *buff); Status Status_Literalise(Status *inst, char *buff);
void StatusUtils_Dump(Status *stat, Status *statbuff, int idx); bool Status_Equals(Status stat1, Status stat2);
bool StatusUtils_HasPrev(Status *stat); void StatusUtils_Dump(Status *inst, Status *store, int idx);
bool StatusUtils_IsOkay(Status stat); bool StatusUtils_HasPrev(Status *inst);
bool StatusUtils_IsValid(Status stat); bool StatusUtils_IsOkay(Status inst);
bool StatusUtils_IsRecursive(Status stat); bool StatusUtils_IsValid(Status inst);
int StatusUtils_Depth(Status *stat); bool StatusUtils_IsRecursive(Status inst);
int StatusUtils_Depth(Status *inst);
Status Status
Report_Create(Report *inst, Status *stat, FILE *dest, char *originator, Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority); int priority);
bool bool
Report_Equal(Report repo1, Report repo2); Report_Equals(Report repo1, Report repo2);
Status Status
Report_Literalise(Report *inst, char *buff); Report_Literalise(Report *inst, char *buff);
@@ -223,8 +223,8 @@ Status
ReportSender_Create(ReportSender *inst, Report *report); ReportSender_Create(ReportSender *inst, Report *report);
Status Status
ReportSender_Send(ReportSender *inst, ReportSendingTask task); ReportSender_Send(ReportSender *inst, ReportSendingTask task);
ReportSendingTaskStatus // ReportSendingTaskStatus
ReportSender_GetStatus(ReportSender *inst); // ReportSender_GetStatus(ReportSender *inst);
ReportSendingTaskID ReportSendingTaskID
ReportSenderManager_AppendTask(ReportSendingManager *inst, ReportSenderManager_AppendTask(ReportSendingManager *inst,
@@ -286,10 +286,22 @@ static Status NullPointerAccounted = {
.prev = &MemoryViolation .prev = &MemoryViolation
}; };
static Status InvalidObject = {
.description = "An invalid object was presented.",
.characteristic = STATUS_ERROR,
.prev = &ErrorStatus
};
static Status UnavailableObject = {
.description = "An unavailable object was presented.",
.characteristic = STATUS_ERROR,
.prev = &ErrorStatus
};
static Status InvalidParameter = { static Status InvalidParameter = {
.description = "An invalid parameter was presented.", .description = "An invalid parameter was presented.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .prev = &InvalidObject
}; };
static Status InsufficientMemory = { static Status InsufficientMemory = {
@@ -328,7 +340,7 @@ static Status ImprecisionError = {
.prev = &RuntimeError .prev = &RuntimeError
}; };
// ---------------USER DEFINED | RUNTIME------------------- // ---------------------USER DEFINED-----------------------
static Status UnavailableInstance = { static Status UnavailableInstance = {
.description = "An unavailable instance was given for initialisation.", .description = "An unavailable instance was given for initialisation.",
@@ -372,6 +384,12 @@ static Status InvalidFileName = {
.prev = &ReadWriteError .prev = &ReadWriteError
}; };
static Status UnavailableFileName = {
.description = "Given file name was unavailable",
.characteristic = STATUS_ERROR,
.prev = &UnavailableObject
};
static Status ReportThrown = { static Status ReportThrown = {
.description = "This function has thrown a report, " .description = "This function has thrown a report, "
"following instructions aborted.", "following instructions aborted.",
@@ -379,12 +397,36 @@ static Status ReportThrown = {
.prev = &RuntimeError .prev = &RuntimeError
}; };
static Status ReportMessageLengthTooLong = { static Status ReportMessageTooLong = {
.description = "Given message is too long.", .description = "Given message is too long.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ArrayLengthError .prev = &ArrayLengthError
}; };
static Status MaximumLengthExceeded = {
.description = "Buffer was too long.",
.characteristic = STATUS_ERROR,
.prev = &ArrayLengthError
};
static Status MaximumLiteralisationLengthExceeded = {
.description = "Literalisation was too long.",
.characteristic = STATUS_ERROR,
.prev = &MaximumLengthExceeded
};
static Status UnavailableBuffer = {
.description = "Given buffer was unavailable.",
.characteristic = STATUS_ERROR,
.prev = &UnavailableInstance
};
static Status InvalidLiteralisingBuffer = {
.description = "Given buffer does not have a good integrity on its length.",
.characteristic = STATUS_ERROR,
.prev = &InvalidObject
};
// ======================================================== // ========================================================
/* Throw the report created with $e if $e is abnormal, commented with $c. */ /* Throw the report created with $e if $e is abnormal, commented with $c. */
@@ -417,25 +459,6 @@ static Status ReportMessageLengthTooLong = {
ReportSendingTaskID __throw(Report report, Location loc); ReportSendingTaskID __throw(Report report, Location loc);
Report catch(ReportSendingTaskID taskid); Report catch(ReportSendingTaskID taskid);
static int HANDLER(void *report) 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 */ #endif /* COMPOUND_STATUS_H */

View File

@@ -1,42 +1,15 @@
#include <Compound/common.h> #include <Compound/common.h>
#include <Compound/status.h> #include <Compound/status.h>
#include <Compound/var.h> #include <Compound/utils.h>
bool status_issuelocation_equal(Location lc1, Location lc2) { bool Location_Equal(Location lc1, Location lc2)
{
return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) && return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) &&
(!strcmp(lc1.func, lc2.func))); (!strcmp(lc1.func, lc2.func)));
} }
bool status_hasprev(Status stat) { bool Status_Equals(Status stat1, Status stat2)
/* Skip when stat is unavailable for accessing. */ {
state(Status_Equal(stat, (Status){}), false);
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 *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. */ /* Skip when both stat1 and stat2 are empty. */
state((stat1.value == 0 && stat2.value == 0 && stat1.description == 0x0 && state((stat1.value == 0 && stat2.value == 0 && stat1.description == 0x0 &&
@@ -48,22 +21,88 @@ bool Status_Equal(Status stat1, Status stat2) {
return ((stat1.value == stat2.value) && return ((stat1.value == stat2.value) &&
(!strcmp(stat1.description, stat2.description)) && (!strcmp(stat1.description, stat2.description)) &&
(stat1.characteristic == stat2.characteristic) && (stat1.characteristic == stat2.characteristic) &&
(Status_Equal(*stat1.prev, *stat2.prev))); (Status_Equals(*stat1.prev, *stat2.prev)));
} }
Status Status_Literalise(Status *inst, char *buff) Status Status_Literalise(Status *inst, char *buff)
{ {
/* Skip unavailable or invalid parameters. */
fails(inst, UnavailableInstance);
fails(buff, UnavailableBuffer);
// state(strlen(buff) != LITERALISATION_LENGTH_MAXIMUM,
// InvalidLiteralisingBuffer);
/* Set up idx for counting final literalisation length to ensure the
string copying is index access safe. */
int idx = 0;
const int status_dump_buffer_len = StatusUtils_Depth(inst);
Status status_dump_buffer[status_dump_buffer_len];
/* Literalise every status that flattened on status_dump_buffer. */
for (register int i = 0; i < status_dump_buffer_len; i++) {
char status_literalising_buffer[LITERALISATION_LENGTH_MAXIMUM];
(void)Status_Literalise(&status_dump_buffer[i], status_literalising_buffer);
/* Append to buff. */
/* Prevent buffer-out-of-bound access. */
const int status_literalising_buffer_len = strlen(status_literalising_buffer);
if (idx + status_literalising_buffer_len >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL;
return MaximumLiteralisationLengthExceeded;
}
idx += status_literalising_buffer_len;
(void)strcat(buff, status_literalising_buffer);
}
return NormalStatus;
} }
int StatusUtils_Depth(Status *stat) { bool StatusUtils_HasPrev(Status *stat)
{
/* Skip when stat is unavailable for accessing. */
state(Status_Equals(*stat, (Status){}), false);
return (stat->prev != NULL);
}
bool StatusUtils_IsOkay(Status stat)
{
return (!stat.characteristic);
}
bool StatusUtils_IsValid(Status stat)
{
return (!strcmp(stat.description, "") && stat.characteristic >= 0 &&
stat.prev != NULL);
}
bool StatusUtils_IsRecursive(Status stat)
{
return (stat.prev != NULL && stat.prev == &stat);
}
void StatusUtils_Dump(Status *inst, Status *store, int idx)
{
/* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */
solve((store == NULL || !StatusUtils_HasPrev(inst) || idx < 0), return;);
store[idx] = *inst;
StatusUtils_Dump(inst->prev, store, ++idx);
}
int StatusUtils_Depth(Status *stat)
{
/* Skip unavailable stat. */ /* Skip unavailable stat. */
state((stat == NULL), -1); state((stat == NULL), -1);
Status *p = stat; // Include this layer of Status. Status *p = stat; // Include this layer of Status.
int cnt = 1; int cnt = 1;
while (p != NULL) { while (p != NULL) {
if (status_recursive(*p) || !status_hasprev(*stat)) break; if (StatusUtils_IsRecursive(*p) || !StatusUtils_HasPrev(stat)) break;
p = p->prev; p = p->prev;
cnt += 1; cnt += 1;
@@ -72,20 +111,21 @@ int StatusUtils_Depth(Status *stat) {
return cnt; return cnt;
} }
Status report_create(Report *inst, Status *stat, FILE *dest, char *originator, Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority) { int priority)
{
/* Skip unavailable parameters. */ /* Skip unavailable parameters. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(stat, error(InvalidParameter, "Given originator was null.")); fails(stat, error(InvalidParameter, "Given initiator was null."));
fails(originator, error(InvalidParameter, "Given originator 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->stat = *stat; inst->status = *stat;
inst->originator = originator; inst->initiator = initiator;
inst->time = time(NULL); inst->time = time(NULL);
inst->priority = priority; inst->priority = priority;
inst->status = REPORT_SENDING_TASK_STATUS_PENDING; inst->task_status = REPORT_SENDING_TASK_STATUS_PENDING;
inst->dest = (dest == NULL ? stderr : dest); inst->dest = (dest == NULL ? stderr : dest);
return NormalStatus; return NormalStatus;
@@ -93,39 +133,64 @@ Status report_create(Report *inst, Status *stat, FILE *dest, char *originator,
Status Report_Literalise(Report *inst, char *buff) Status Report_Literalise(Report *inst, char *buff)
{ {
/* Skip when inst or buff is unavailable. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(buff, error(InvalidParameter, "Given buffer was unavailable.")); fails(buff, UnavailableBuffer);
// state(strlen(buff) != LITERALISATION_LENGTH_MAXIMUM,
// InvalidLiteralisingBuffer);
/* By calculating the depth of status, we can calculate the exact length of /* Report literalisation. */
literalisation of report. */ int idx = 0;
const int depth = StatusUtils_Depth(&inst->stat); char report_literalising[LITERALISATION_LENGTH_MAXIMUM];
/* Dump all the status. */ /** Status literalisation. **/
Status stats[depth]; char status_literalising[LITERALISATION_LENGTH_MAXIMUM];
StatusUtils_Dump(&inst->stat, stats, 0); (void)Status_Literalise(&inst->status, status_literalising);
idx += strlen(status_literalising);
/** fin **/
/* Literalise by iterating. */ /** Initiator literalisation. **/
int report_literalised_length = 0; idx += strlen(inst->initiator);
for (register int i = 0; i < depth; i++) { /** fin **/
/* Literalise individual status. */
char buff[strlen(stats[i].description) + 1 + ];
(void)Status_Literalise(&stats[i], buff); // Ignore the returning.
// Otherwise, if we throw the report once the returning status is abnormal,
// this function would be called again by the throw function.
/* Accumulate length of report literalisation. */ /** Time literalisation. **/
report_literalised_length += strlen(buff); char time_literalising[LITERALISATION_LENGTH_MAXIMUM];
idx += Utils_LiteraliseInteger(inst->time, time_literalising);
/** fin **/
/** Priority literalisation. **/
char priority_literalising[LITERALISATION_LENGTH_MAXIMUM];
idx += Utils_LiteraliseInteger(inst->priority, priority_literalising);
/** fin **/
/** Task_status literalisation. **/
char task_status_literalising[LITERALISATION_LENGTH_MAXIMUM];
idx += Utils_LiteraliseInteger(inst->task_status, task_status_literalising);
/** fin **/
/** Dest literalisation. **/
char dest_literalising[LITERALISATION_LENGTH_MAXIMUM];
idx += Utils_LiteraliseInteger((long long int)inst->dest, dest_literalising);
/** fin **/
if (idx >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL;
return MaximumLiteralisationLengthExceeded;
} }
/* Create report literalisation buffer according to strcpy(report_literalising, status_literalising);
report_literalised_length. */ strcpy(report_literalising, time_literalising);
char report_literalised_buffer[report_literalised_length]; strcpy(report_literalising, priority_literalising);
strcpy(report_literalising, task_status_literalising);
strcpy(report_literalising, dest_literalising);
/* */ strcpy(buff, report_literalising);
/* fin */
return NormalStatus;
} }
Status ReportSender_Create(ReportSender *inst, Report *report) { Status ReportSender_Create(ReportSender *inst, Report *report)
{
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(report, error(UnavailableParameter, "Given report was unavailable.")); fails(report, error(UnavailableParameter, "Given report was unavailable."));
@@ -138,23 +203,25 @@ Status ReportSender_Create(ReportSender *inst, Report *report) {
return NormalStatus; return NormalStatus;
} }
Status ReportSender_Send(ReportSender *inst, ReportSendingTask task) { Status ReportSender_Send(ReportSender *inst, ReportSendingTask task)
/* Skip when inst or task is unavailable. */ {
fails(inst, // /* Skip when inst or task is unavailable. */
error(UnavailableInstance, "Report sender was given unavailable.")); // fails(inst,
fails(task, InvalidReportTask); // error(UnavailableInstance, "Report sender was given unavailable."));
// fails(task, InvalidReportTask);
/* Assign for dest. */ // /* Assign for dest. */
const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest); // const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest);
// char buff[]; // // char buff[];
// TODO(william): HERE, Report_Literalise // // TODO(william): HERE, Report_Literalise
/* Write/Send data. */ // /* Write/Send data. */
inst->report->status = REPORT_SENDING_TASK_STATUS_PROCEEDING; // inst->report->task_status = REPORT_SENDING_TASK_STATUS_PROCEEDING;
if (!fprintf(dest, buff)) { // if (!fprintf(dest, buff)) {
} // }
/* Sent successfully! Mark down properties. */ // /* Sent successfully! Mark down properties. */
return NormalStatus;
} }
// bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2) // bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2)
@@ -166,40 +233,65 @@ Status ReportSender_Send(ReportSender *inst, ReportSendingTask task) {
// || (inst1->external_param == inst2->external_param); // || (inst1->external_param == inst2->external_param);
// } // }
ReportSendingTaskID _throw(Report report, Location loc) { ReportSendingTaskID _throw(Report report, Location loc)
// /* Create new a instance of ReportSender. */ {
// // /* 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; // ReportSender sender;
// ReportSender_Create(&sender, stderr); // /* Return with -1 when initialisation failed. */
// state(!(StatusUtils_IsOkay(ReportSender_Create(&sender, &report))), -1);
// /* Send message. */ // /* Inject location information. Could be more elegant, though. */
// /* Initialise sender's thread. */ // sender.report->status.loc = loc;
// thrd_t sending;
// /* Skip on failing on creating thread. */
// if (!thrd_create(&sending, starter, NULL)) {
// /* Conclude the session of sender. */ // /* Send. */ /* Return -1 when failed on sending. */
// report.status = REPORT_SENDING_TASK_STATUS_FINISHED, // state(!StatusUtils_IsOkay(ReportSender_Send(&sender, HANDLER)), -1);
// report.result = (ARGUE_RESULT_FINALISED | ARGUE_RESULT_NEGATIVE);
// sender.result = REPORT_SENDER_RESULT_FINISHED; return 0;
// sender.successful = false; }
// return -1; 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;
// } // }
// /* Perform sending. */ // (void)throw(*(Report *)report); // Lonely throw, no catch will company.
// ReportSender_Send(&sender, NULL); // return 0;
/* 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);
return 0;
} }

View File

@@ -22,7 +22,7 @@ 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_Equal(String *arr1, String *arr2); bool String_Equals(String *arr1, String *arr2);
/* Extensional. */ /* Extensional. */
Status StringUtils_FromInteger(String *inst, int value); Status StringUtils_FromInteger(String *inst, int value);

View File

@@ -38,7 +38,7 @@ Status String_Literalise(String *inst, String *store)
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }
bool String_Equal(String *arr1, String *arr2) bool String_Equals(String *arr1, String *arr2)
{ {
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
} }

View File

@@ -4,13 +4,17 @@
# include <time.h> # include <time.h>
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
# include <math.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/const.h> # include <Compound/const.h>
# define DATETIME_FORMAT "%a %d %b %X %Z %Y" # define DATETIME_FORMAT "%a %d %b %X %Z %Y"
int Utils_CalcDigits(long long n); int Utils_CalcDigits(long long int n);
int Utils_CalcDateTimeLiteralisationLength(char *buff);
int Utils_LiteraliseInteger(long long int n, char *buff);
int Utils_DateTimeLiteralise(time_t t, char *buff);
#endif /* COMPOUND_UTILS_H */ #endif /* COMPOUND_UTILS_H */

View File

@@ -1,6 +1,6 @@
#include <Compound/utils.h> #include <Compound/utils.h>
int Utils_CalcDigits(long long n) int Utils_CalcDigits(long long int n)
{ {
if (n == 0) { if (n == 0) {
return 1; return 1;
@@ -15,11 +15,34 @@ int Utils_CalcDigits(long long n)
return i; return i;
} }
int Utils_CalcDateTimeLiteralisationLength(char *buff) int Utils_LiteraliseInteger(long long int n, char *buff)
{ {
const time_t now = time(NULL); /* Invalid buffer was presented. */
if (strlen(buff) != LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL;
return 0;
}
(void)strftime(buff, 28, DATETIME_FORMAT, localtime(&now)); if (!n) {
buff = "0";
return 1;
}
return strlen(buff); const int literalising_len = Utils_CalcDigits(n);
if (literalising_len >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL;
return 0;
}
char literalising[literalising_len];
for (register int i = 0; i < literalising_len; i++) {
literalising[i] = (n / (int)pow(10, i));
}
return literalising_len;
}
int Utils_DateTimeLiteralise(time_t t, char *buff)
{
return 0;
} }

View File

@@ -5,18 +5,21 @@
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/status.h> # include <Compound/status.h>
# include <Compound/catlog.h>
# define VAR_IDENTITY_LENGTH 64 // # define VAR_IDENTITY_LENGTH 64
# define VAR_LITERALISE_LENGTH (VAR_IDENTITY_LENGTH + 16 + 9 + 10) // # define VAR_LITERALISE_LENGTH (VAR_IDENTITY_LENGTH + 16 + 9 + 10)
# define VAR_LITERALISE_FORMAT ("%s @[%p]: %ld") # define VAR_LITERALISE_LENGTH (16 + 9 + 10)
# define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ " // # define VAR_LITERALISE_FORMAT ("%s @[%p]: %ld")
# define VAR_LITERALISE_FORMAT "@[%p]: %ld"
// # define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ "
static Status IllegalVarIdentity = { // static Status IllegalVarIdentity = {
.description = "Given identity does not fit the standard of Var Naming " // .description = "Given identity does not fit the standard of Var Naming "
"convension.", // "convention.",
.characteristic = STATUS_ERROR, // .characteristic = STATUS_ERROR,
.prev = &InvalidParameter // .prev = &InvalidParameter
}; // };
// static Status VarIdentityTooLong = { // static Status VarIdentityTooLong = {
// .description = "Given identity has longer length that the maximum length " // .description = "Given identity has longer length that the maximum length "
@@ -31,8 +34,8 @@ typedef struct {
void *addr; void *addr;
size_t size; size_t size;
/* Identification */ // /* Identification */
char *identity; // Maximum up to VAR_IDENTITY_LENGTH // char *identity; // Maximum up to VAR_IDENTITY_LENGTH
} Var; } Var;
@@ -43,13 +46,13 @@ typedef struct {
// }; // };
// } _Var; // } _Var;
Status Var_Create(Var *inst, void *addr, size_t size, char *identity); Status Var_Create(Var *inst, size_t size) throws(InsufficientMemory);
Status Var_CopyOf(Var *inst, Var *other); Status Var_CopyOf(Var *inst, Var *other);
Status Var_Literalise(Var *inst, char *buff); Status Var_Literalise(Var *inst, char *buff);
bool Var_Equal(Var *a, Var *b); bool Var_Equals(Var *a, Var *b);
void Var_Delete(Var *inst); void Var_Delete(Var *inst);
void VarUtils_Swap(Var *v1, Var *v2); void VarUtils_Swap(Var *v1, Var *v2);
bool VarUtils_IsIdentityLegal(char *identity); // bool VarUtils_IsIdentityLegal(char *identity);
#endif /* COMPOUND_VAR */ #endif /* COMPOUND_VAR */

View File

@@ -1,45 +1,67 @@
#include <Compound/var.h> #include <Compound/var.h>
Status Var_Create(Var *inst, void *addr, size_t size, char *identity) Status Var_Create(Var *inst, size_t size)
{ {
/* Skip when inst is unavailable. */ *inst = (Var) {
fails(inst, UnavailableInstance); .addr = malloc(size),
/* Skip when identity is unavailable. */ .size = size
fails(identity, NullPointerAccounted); };
/* Skip when identity does not pass the examine. */
state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity);
inst->addr = addr; if (inst->addr == NULL) {
inst->size = size; return InsufficientMemory;
*inst->identity = *identity; }
return NormalStatus; return NormalStatus;
} }
// Status Var_Create(Var *inst, void *addr, size_t size, char *identity)
// {
// /* 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) 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);
fails(other, NullPointerAccounted); fails(other, InvalidParameter);
/* Copy and assign. */ /* Copy members from other. Only has to apply size, no addr is needed. */
inst->addr = other->addr; inst->addr = malloc(other->size);
inst->size = other->size; inst->size = other->size;
*inst->identity = *other->identity;
return NormalStatus; return NormalStatus;
} }
void Var_Delete(Var *inst) void Var_Delete(Var *inst)
{ {
/* Skip when inst or inst->addr is unavailable. */ if (inst == NULL) return;
svoid(inst == NULL || inst->addr == NULL);
free(inst->addr);
inst->addr = NULL; inst->addr = NULL;
inst->size = 0; inst->size = 0;
*inst->identity = 0;
} }
// 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) void VarUtils_Swap(Var *v1, Var *v2)
{ {
/* Skip when v1 or v2 is unavailable. */ /* Skip when v1 or v2 is unavailable. */
@@ -56,49 +78,46 @@ Status Var_Literalise(Var *inst, char *buff)
state(inst == NULL, UnavailableInstance); state(inst == NULL, UnavailableInstance);
/* Write into buffer. */ /* Write into buffer. */
state(!sprintf(buff, VAR_LITERALISE_FORMAT, inst->identity, state(!sprintf(buff, VAR_LITERALISE_FORMAT"\n", inst->addr, inst->size),
inst->addr, inst->size),
error(RuntimeError, "Sprintf returned 0 where it should never do.")); error(RuntimeError, "Sprintf returned 0 where it should never do."));
return NormalStatus; return NormalStatus;
} }
bool Var_Equal(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 == NULL || b == NULL), false);
return (a->addr == b->addr && return (a->addr == b->addr && a->size == b->size);
a->size == b->size &&
(!strcmp(a->identity, b->identity)));
} }
bool VarUtils_IsIdentityLegal(char *identity) // bool VarUtils_IsIdentityLegal(char *identity)
{ // {
/* Skip when identity is unavailable. */ // /* Skip when identity is unavailable. */
state(identity == NULL, false); // state(identity == NULL, false);
const int len = strlen(identity); // const int len = strlen(identity);
/* Skip when identity is empty. */ // /* Skip when identity is empty. */
state(len == 0, false); // state(len == 0, false);
/* Skip when the first char is not within alphabet. */ // /* Skip when the first char is not within alphabet. */
state(ATRANGE('a', 'z', identity[0]) // state(ATRANGE('a', 'z', identity[0])
|| ATRANGE('A', 'Z', identity[0]), false); // || ATRANGE('A', 'Z', identity[0]), false);
/* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */ // /* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */
state(len > VAR_IDENTITY_LENGTH, false); // state(len > VAR_IDENTITY_LENGTH, false);
/* Skip when identity has space and illegal characters in it. */ // /* Skip when identity has space and illegal characters in it. */
const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR); // const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR);
for (register int i = 0; i < len; i++) { // for (register int i = 0; i < len; i++) {
for (register int j = 0; j < illegal_len; j++) { // for (register int j = 0; j < illegal_len; j++) {
if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) { // if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) {
return false; // return false;
} // }
} // }
} // }
return true; // return true;
} // }

View File

@@ -2,16 +2,16 @@
#include <Compound/status.h> #include <Compound/status.h>
Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level, Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
char const *originator, char const *msg) char *initiator, char *msg)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
state((originator == NULL || msg == NULL), InvalidParameter); state((initiator == NULL || msg == NULL), InvalidParameter);
inst->time = time(NULL); inst->time = time(NULL);
inst->level = level; inst->level = level;
*inst->originator = *originator; inst->initiator = initiator;
*inst->content = *msg; inst->content = msg;
return NormalStatus; return NormalStatus;
} }
@@ -27,7 +27,7 @@ Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other)
return NormalStatus; return NormalStatus;
} }
bool CatlogMsg_Equal(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 == NULL || other == NULL), false);
@@ -35,7 +35,7 @@ bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other)
return ( return (
inst->time == other->time && inst->time == other->time &&
inst->level == other->level && inst->level == other->level &&
(!strcmp(inst->originator, other->originator)) && (!strcmp(inst->initiator, other->initiator)) &&
(!strcmp(inst->content, other->content)) (!strcmp(inst->content, other->content))
); );
} }
@@ -70,13 +70,13 @@ Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other)
return NormalStatus; return NormalStatus;
} }
bool CatlogSender_Equal(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 == NULL || other == NULL), false);
return ( return (
CatlogMsg_Equal(&inst->msg, &other->msg) && CatlogMsg_Equals(&inst->msg, &other->msg) &&
inst->dst == other->dst && inst->dst == other->dst &&
inst->successful == other->successful && inst->successful == other->successful &&
((inst->elapsed.tv_sec == other->elapsed.tv_sec) && ((inst->elapsed.tv_sec == other->elapsed.tv_sec) &&
@@ -84,23 +84,35 @@ bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other)
); );
} }
Status CatlogSender_Send(CatlogSender *inst, int *store, bool append) Status CatlogSender_Send(CatlogSender *inst, char *filepath, bool append)
throws(ReadWriteError) throws(ReadWriteError)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance); fails(inst, UnavailableInstance);
fails(store, InvalidParameter); fails(filepath, UnavailableFileName);
/* Open file. */ /* Open file. */
ensure(CatlogUtils_OpenFile(inst->dst, (append ? "a" : "w")), // ensure(CatlogUtils_OpenFile(inst->dst, (append ? "a" : "w")),
"Unable to open file."); // "Unable to open file.");
(void)CatlogUtils_OpenFile(inst->dst, filepath, (append ? "a" : "w"));
/* Write msg. */ /* Write msg. */
*store = fprintf(inst->dst, "%s", inst->msg.content); return normal(NormalStatus, "", fprintf(inst->dst, "%s", inst->msg.content));
return NormalStatus;
} }
Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2);
Status CatlogUtils_OpenFile(FILE *store, const char const *__restrict mode); Status CatlogUtils_OpenFile(FILE *store, char *filepath,
const char const *__restrict mode)
{
/* No need to open a system output stream. */
if (!strcmp(filepath, "stdin") ||
!strcmp(filepath, "stdout") ||
!strcmp(filepath, "stderr")) {
return NormalStatus;
}
store = fopen(filepath, mode);
return NormalStatus;
}

View File

@@ -1,8 +1,8 @@
#ifndef COMPOUND_CATLOG_H #ifndef COMPOUND_CATLOG_H
# define COMPOUND_CATLOG_H # define COMPOUND_CATLOG_H
# include <Compound/status.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/status.h>
typedef enum { typedef enum {
CATLOG_LEVEL_ALL, // Least the value, most the information. CATLOG_LEVEL_ALL, // Least the value, most the information.
@@ -18,14 +18,14 @@ typedef enum {
typedef struct { typedef struct {
time_t time; time_t time;
CatlogLevel level; CatlogLevel level;
char *originator; char *initiator;
char *content; char *content;
} CatlogMsg; } CatlogMsg;
Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level, Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
char const *originator, char const *msg); char *initiator, char *msg);
Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other); Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other);
bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other); bool CatlogMsg_Equals(CatlogMsg *inst, CatlogMsg *other);
typedef struct { typedef struct {
CatlogMsg msg; CatlogMsg msg;
@@ -36,10 +36,11 @@ typedef struct {
Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst); Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst);
Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other); Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other);
bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other); bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other);
Status CatlogSender_Send(CatlogSender *inst, int *store, bool append) Status CatlogSender_Send(CatlogSender *inst, char *filepath, bool append)
throws(ReadWriteError); throws(ReadWriteError);
Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2); Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2);
Status CatlogUtils_OpenFile(FILE *store, const char *__restrict mode); Status CatlogUtils_OpenFile(FILE *store, char *filepath,
const char const *__restrict mode);
#endif /* COMPOUND_CATLOG_H */ #endif /* COMPOUND_CATLOG_H */

View File

@@ -1,5 +1,6 @@
#ifndef COMPOUND_COMMON_h #ifndef COMPOUND_COMMON_h
# define COMPOUND_COMMON_h # define COMPOUND_COMMON_h
// # define __DEBUG__ 1
# include <stdlib.h> # include <stdlib.h>
# include <stdbool.h> # include <stdbool.h>
@@ -39,37 +40,37 @@
*/ */
# define svoid(s) { if ((s)) return; } # define svoid(s) { if ((s)) return; }
/**
* @brief Return an Error Status with given parameter $c as the /* Create a new UnknownStatus on the fly. */
* comment or description. # define unknown(e, c, v) ((Status) {\
* @return A instance of Error Status customised. .value = v,\
* @note "error" stands for "Error in Status"
* @note 'e' stands for "Error"
* @note 'c' stands for "Comment"
*/
# define error(e, c) ((Status) {\
.description = c,\ .description = c,\
.characteristic = e.characteristic,\ .characteristic = STATUS_UNKNOWN,\
.prev = e.prev\ .prev = e.prev\
}) })
/** /* Create a new NormalStatus on the fly. */
* @brief Return an Error Status with given parameter $p as the # define normal(e, c, v) ((Status) {\
* predecessor. .value = v,\
* @return A instance of Error Status inherited. .description = c,\
* @note "extend" stands for "Extend from Predecessor" .characteristic = STATUS_NORMAL,\
* @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\ .prev = e.prev\
} })
/* Create a new ErrorStatus on the fly. */
# define error(e, c) ((Status) {\
.description = c,\
.characteristic = STATUS_ERROR,\
.prev = e.prev\
})
/* Extend the Status chain by giving 'p' for "predecessor"
and 'c' for "comment/description". */
# define extend(p, c) ((Status) {\
.description = c,\
.characteristic = p.characteristic,\
.prev = p\
})
/** @brief Create a report in place. /** @brief Create a report in place.
* @return A instance of Status Report customised. * @return A instance of Status Report customised.
@@ -78,8 +79,8 @@
* @note 'c' stands for "Char String of Originator" * @note 'c' stands for "Char String of Originator"
*/ */
# define stamp(e, c) ((Report) {\ # define stamp(e, c) ((Report) {\
.stat = e,\ .status = e,\
.originator = 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\ .status = REPORT_SENDING_TASK_STATUS_PENDING\
@@ -103,7 +104,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_equal(s, k)), v) // # define sforce(s, k, v) solve((!Status_Equals(s, k)), v)
/* Get the literal. */ /* Get the literal. */
# define nameof(obj) #obj # define nameof(obj) #obj
@@ -115,6 +116,24 @@
# define String(T) String # define String(T) String
# define cat(s) {\
CatlogMsg msg;\
CatlogMsg_Create(&msg, CATLOG_LEVEL_DEBUG, "CAT", s);\
CatlogSender sender;\
CatlogSender_Create(&sender, &msg, stderr);\
CatlogSender_Send(&sender, "stdout", false);\
}
# define ok(s, b) {\
const Status _ = s;\
if (StatusUtils_IsOkay(_)) b\
}
# define notok(s, b) {\
const Status _ = s;\
if (!StatusUtils_IsOkay(_)) b\
}
typedef enum { typedef enum {
COMMON_ERROR_NULLPTR = 1, COMMON_ERROR_NULLPTR = 1,
COMMON_ERROR_INVALID_ARGUMENT, COMMON_ERROR_INVALID_ARGUMENT,
@@ -148,4 +167,6 @@ typedef bool _Bit;
# 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
#endif /* NO COMPOUND_COMMON_h */ #endif /* NO COMPOUND_COMMON_h */

View File

@@ -34,6 +34,6 @@ while :; do
done done
cp -v "common.h" "const.h" "platform.h"\ cp -v "common.h" "const.h" "platform.h"\
"name.h" "type.h" "catlog.h"\ "name.h" "namescope.h" "type.h" "catlog.h"\
"attr.h" "$DST" "attr.h" "registry.h" "$DST"
printf "\nDone\n" printf "\nDone\n"

70
name.c
View File

@@ -1,71 +1 @@
#include <Compound/name.h> #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));
}
}

4
name.h
View File

@@ -34,11 +34,11 @@ static const Name NullName = {
// Name value; // Name value;
// Name idx; // Name idx;
// Name *occupied; // Name *occupied;
// } NameSpace; // Size: 8+8+8 =8*3 =24 Bytes (x64) // } NameScope; // Size: 8+8+8 =8*3 =24 Bytes (x64)
/* /*
* Example: * Example:
* Var variable_from_namespace_Utils_in_class_Calculation_in_function_C; * Var variable_from_namescope_Utils_in_class_Calculation_in_function_C;
* // Not enough room for representation. * // Not enough room for representation.
* // Must use another more efficient method to store the name. * // Must use another more efficient method to store the name.
* Become (roughly): * Become (roughly):

View File

@@ -0,0 +1,71 @@
#include <Compound/namescope.h>
Status NameScope_Create(NameScope *inst)
{
fails(inst, UnavailableInstance);
/* Create instances for members from inst. */
state(StatusUtils_IsOkay(NameScope_EmptyName(&inst->latest)),
error(RuntimeError, "Failed to initialise latest from NameScope"));
state(StatusUtils_IsOkay(NameScope_EmptyName(&inst->idx)),
error(RuntimeError, "Failed to initialise idx from NameScope"));
state(StatusUtils_IsOkay(NameScope_EmptyName(inst->occupied)),
error(RuntimeError, "Failed to initialise occupied from NameScope"));
return NormalStatus;
}
Status NameScope_CopyOf(NameScope *inst, NameScope *other)
{
fails(inst, UnavailableInstance);
fails(other, UnavailableParameter);
/* Copy and assign. */
other->latest = inst->latest;
other->idx = inst->idx;
const Name len = NameScope_CalcNameArrayLength(&other->occupied);
for (Name i = (Name){0}; (NameScope_CompareName(i, len) < 0);) {
// TODO(william): HERE
/* i++ */
state((!StatusUtils_IsOkay(NameScope_CountUp(&i))),
error(RuntimeError, "Error occurred during calculations of Name."));
}
}
Status NameScope_CreateName(NameScope *inst, Name *buff);
Status NameScope_RemoveName(NameScope *inst, Name idx);
Status NameScope_EmptyName(Name *inst);
Status NameScope_CountUp(Name *inst);
Status NameScope_CountDown(Name *inst);
Status NameScope_CountUpFor(Name *inst, Name amount);
Status NameScope_CountDownFor(Name *inst, Name amount);
Status NameScope_UpdateLatest(NameScope *inst, Name idx);
Status NameScope_FormatTrim(Name *inst);
Status NameScope_FormatInflate(Name *inst);
Name NameScope_CalcNameArrayLength(Name **arr);
bool NameScope_IsAvailable(NameScope *inst, Name idx);
bool NameScope_IsValidName(Name *inst);
int NameScope_CompareName(Name *a, Name *b)
{
/* Validation comes the first. --William */
if (!NameScope_IsValidName(a) || !NameScope_IsValidName(b)) {
Report e; ArgueStartParam h;
throw(stamp(&InvalidName));
}
}

View File

@@ -16,7 +16,7 @@ Status NameScope_CopyOf(NameScope *inst, NameScope *other);
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);
bool NameScope_Equal(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);
/* Universal Attribute NameScope. (U.A.N.) */ /* Universal Attribute NameScope. (U.A.N.) */