Compare commits

..

9 Commits

Author SHA1 Message Date
8c056d1a39 (MOD) Changed returning type of Var_Delete and Array_Delete from "void" to "Status": It requires more plaination when encountering non-alive instances.
(MOD) Implemented Array_Equals.

(MOD) Replaced struct member "description" from InstanceStillAlive from "Given instance was yet alive." to "Given instance was still alive.".

(MOD) Removed String_GetIdx and String_SetIdx:  Meaningless functions.

(MOD) Changed the assignment value of struct member "identity" of macro unknown, normal and error from "nameof(e)" to "e.identity".
2024-06-28 13:32:48 +08:00
9f2b44bf99 (MOD) Fixed 1 bug in Memory_Reallocate: Now the size of inst is updating with the given size used for reallocation.
(MOD) Replaced struct member prev from UnknownStatus, NormalStatus and ErrorStatus from NULL to &UnknownStatus, &NormalStatus and &ErrorStatus.

(MOD) Rewrote Status_Equal, StatusUtils_Dump, StatusUtils_IsRecursive and StatusUtils_Depth in response to the change of struct member prev from UnknownStatus, NormalStatus and ErrorStatus.

(MOD) Defined 1 more macro "shift".
2024-06-27 16:01:01 +08:00
310586ab86 (MOD) Removed Array_GetIdx and Array_SetIdx due to better approach was discovered.
(MOD) Defined 2 more statuses:  InvalidOperation, InvalidOperationBetweenAliveAndNonAlive.

(MOD) Defined 1 more macro:  assign.
2024-06-26 20:20:04 +08:00
a63063de42 (MOD) Defined 1 more macro "cast". 2024-06-26 17:20:36 +08:00
8870e5e7db (MOD) Reordered struct member "members" from "Array" from 2nd to 1st for a more convenient accessing to "Var.addr in Array.member[0]".
(MOD) Modified test.c.
2024-06-26 16:54:21 +08:00
f5d82983a4 (MOD) Added Array into cmake building list. 2024-06-26 16:43:26 +08:00
bc4be4e295 (MOD) Implemented Array_Create, Array_CopyOf and Array_Delete
(MOD) Replaced project compiler from "gcc" with "clang" due to out-of-order execution keep happening after running with Array.

(MOD) Removed certain functions from Utils due to insufficiencies of usage.

(MOD) Defined 1 more macro "fail".

(MOD) Fixed 1 bug from "var.c":  Struct member "alive" was not under supervision from the entire programme cycle.

(MOD) Removed 1 useless usage for "Utils_LiteraliseInteger".

(MOD) Removed 1 useless block of commented code.
2024-06-26 15:20:47 +08:00
d19256621b (MOD) Modified several places to adapt the extraction of Report. 2024-06-26 11:19:11 +08:00
8696b89c2e (ADD) Extracted Report from "status.h" into "report.h". 2024-06-26 10:51:09 +08:00
18 changed files with 749 additions and 662 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ CompoundTest
ccwarn ccwarn
genwarn.sh genwarn.sh
test.sh test.sh
expansion_formatted.txt

View File

@@ -4,53 +4,28 @@
# include <Compound/var.h> # include <Compound/var.h>
typedef struct { typedef struct {
int len;
Var *members; Var *members;
int len;
bool alive;
} Array; } Array;
# define ArrayIndexOutOfBound = (Status){\ DEFSTATUS(ArrayIndexOutOfBound, 1, "Given index was accessing illegal address.", STATUS_ERROR, &MemoryViolation);
.identity = nameof(ArrayIndexOutOfBound),\ DEFSTATUS(InvalidArrayLength, 1, "Given length is invalid.", STATUS_ERROR, &ErrorStatus);
.value = 1,\
.description = "Given index was accessing illegal address.",\
.characteristic = STATUS_ERROR,\
.prev = &MemoryViolation\
}
# define InvalidArrayLength (Status){\ Status Array_Create(Array *inst, int len, size_t size);
.value = 1,\
.description = "Given length is invalid.",\
.characteristic = STATUS_ERROR,\
.prev = &ErrorStatus\
}
/* Elementary. */
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);
throws(ArrayIndexOutOfBound);
Status Array_SetIdx(Array *inst, Var *source, int index);
throws(ArrayIndexOutOfBound);
bool Array_Equals(Array *arr1, Array *arr2); bool Array_Equals(Array *arr1, Array *arr2);
/* 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

@@ -3,155 +3,164 @@
Status Array_Create(Array *inst, int len, size_t size) Status Array_Create(Array *inst, int len, size_t size)
{ {
/* Skip unavailable inst and invalid param. */
nonull(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state((len < 0), apply(InvalidArrayLength));
solve((!len), { inst->len = 0; inst->members = NULL; return apply(NormalStatus); })
inst->len = len; /* Skip the living instances. */
inst->members = calloc(len, sizeof(Var)); state(inst && inst->alive, apply(InstanceStillAlive));
/* Allocate for members from the inst. */
state(!(inst->members = calloc(len, sizeof(Var))), apply(InsufficientMemory));
/* Create for each item from members. */
int erridx = -1; int erridx = -1;
Status errstat = EMPTY;
for (register int i = 0; i < len; i++) { for (register int i = 0; i < len; i++) {
// TODO(william): Throw InsufficientMemory at following line. notok(Var_Create(&inst->members[i], size), {
// DONE(william): ensure(Var_Create(&inst->members[i], size), "Failed to create a new var.");
notok((Var_Create(&inst->members[i], size)), {
#ifdef __DEBUG__
cat("Var_Create failed!\n")
#endif
erridx = i; erridx = i;
errstat = apply(_);
break; break;
} else {
#ifdef __DEBUG__
cat("Var_Create success!\n")
#endif
}) })
} }
/* Review on erridx. Release data that allocated. */ /* Got problem during allocations. */
if (erridx != -1) { if (erridx >= 0) {
for (register int i = erridx; i >= 0; i--) { /* Release members allocated backwardly. */
for (register int i = erridx - 1; i >= 0; i--) {
Var_Delete(&inst->members[i]); Var_Delete(&inst->members[i]);
#ifdef __DEBUG__
cat("Deleted var from InsufficientMemory from Array_Create!")
#endif
} }
/* Release array itself. */ /* Release the array inst. */
free(inst->members); free(inst->members);
return apply(InsufficientMemory); return errstat;
} }
/* Assign rest of the struct members. */
inst->len = len;
inst->alive = true;
return apply(NormalStatus); return apply(NormalStatus);
} }
Status Array_CopyOf(Array *inst, Array *other) Status Array_CopyOf(Array *inst, Array *other)
{ {
// /* Skip unavailable inst and invalid param. */ /* Skip unavailble parameters. */
// nonull(inst, apply(UnavailableInstance)); nonull(other,
// nonull(other, error(InvalidParameter, "Given other was unavailable.")); apply(annot(UnavailableInstance,
"Given object for copying to inst was unavailable.")));
// /* Assign value for len. */ /* Skip invalid parameters and instances. */
// inst->len = other->len; state(inst && inst->alive,
apply(annot(InstanceStillAlive,
"Given inst for being copied was still alive.")));
// if (inst->members == NULL) return apply(NormalStatus); state(!other->alive,
// match(RuntimeError, Array_Create(inst, other->len), "Failed on recreating " apply(annot(InstanceNotAlive,
// "array."); "Given object for copying to inst was not alive.")));
// /* Copy and assign for each member from other to inst. */ state(!other->len,
// for (register int i = 0; i < inst->len; i++) { apply(annot(InvalidArrayLength,
// inst[i] = other[i]; "Given object for copying to inst has length of ZERO.")));
// }
// return apply(NormalStatus); /* Allocate for members from the inst. */
state(!(inst->members = calloc(other->len, sizeof(Var))),
apply(InsufficientMemory));
/* Create for each item from members. */
int erridx = -1;
Status errstat = EMPTY;
/*
if (other == NULL) return 1;
String_Create(inst, other->len);
for (register int i = 0; i < other->len; i++) { for (register int i = 0; i < other->len; i++) {
inst->arr[i] = other->arr[i]; notok(Var_Create(&inst->members[i], other->members[0].size), {
erridx = i;
errstat = apply(_);
break;
})
notok(Var_CopyOf(&inst->members[i], &other->members[i]), {
erridx = i;
errstat = apply(_);
break;
})
} }
return 0; /* Got problem during allocations. */
if (erridx >= 0) {
/* Release members allocated backwardly. */
for (register int i = erridx - 1; i >= 0; i--) {
Var_Delete(&inst->members[i]);
}
/* Release the array inst. */
free(inst->members);
*/ return apply(errstat);
}
/* Assign rest of the struct members. */
inst->len = other->len;
inst->alive = true;
return apply(NormalStatus);
} }
Status Array_Delete(Array *inst) Status Array_Delete(Array *inst)
{ {
/* Skip unavailable inst and invalid param. */ nonull(!inst, apply(UnavailableInstance));
nonull(inst, apply(UnavailableInstance)); state(!inst->alive, apply(InstanceNotAlive));
solve((inst->members == NULL), return apply(NormalStatus));
/* Iterate through each member and delete them. */
for (register int i = 0; i < inst->len; i++) {
fail(Var_Delete(&inst->members[i]));
}
inst->len = 0;
free(inst->members); free(inst->members);
inst->members = NULL; inst->members = NULL;
inst->alive = false;
inst->len = 0;
return apply(NormalStatus); return apply(NormalStatus);
} }
Status Array_GetIdx(Array *inst, Var *store, int index) bool Array_Equals(Array *arr1, Array *arr2)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable instance and parameter. */
nonull(inst, apply(UnavailableInstance)); state(!arr1 || !arr2, false);
nonull(store,
apply(error(InvalidParameter, "Given reference to store was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
*store = inst->members[index]; /* Skip when arr1 and arr2 have different length. */
state(arr1->len != arr2->len, false);
return apply(NormalStatus); /* Skip when operation is not supported. */
} state(!arr1->alive || !arr2->alive, false);
Status Array_SetIdx(Array *inst, Var *source, int index) /* Iterate through each member for comparison. */
{ for (register int i = 0; i < arr1->len; i++) {
/* Skip unavailable inst and invalid param. */ if (!Var_Equals(&arr1->members[i], &arr2->members[i])) {
nonull(inst, apply(UnavailableInstance));
nonull(source,
apply(
error(InvalidParameter, "Given reference to source was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
inst->members[index] = *source;
return apply(NormalStatus);
}
bool Array_Equals(Array *a, Array *b)
{
/* Skip unavailable inst and invalid param. */
state((a == NULL || b == NULL), false);
state((a->len != b->len), false);
for (register int i = 0; i < a->len; i++) {
if (!Var_Equals(&a->members[i], &b->members[i])) {
return false; return false;
} }
} }
return true; /* Compare rest of the struct member. */
return (arr1->alive == arr2->alive);
} }
Status ArrayUtils_Insert(Array *inst, Var *item, int index);
Status ArrayUtils_InsertArray(Array *inst, Array *items, int index);
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len) Status ArrayUtils_Remove(Array *inst, int index);
{
nonull(inst, apply(UnavailableInstance));
nonull(elem,
apply(error(InvalidParameter, "Given reference to elem was unavailable.")));
state((off + len > inst->len) || (off < 0) || (len < 0),
apply(ArrayIndexOutOfBound));
/* Copy elem into each specified members from inst with off and len. */ Status ArrayUtils_RemoveArray(Array *inst, int off, int len);
for (register int i = off; i < (off + len); i++) {
inst->members[i] = *elem;
}
return apply(NormalStatus); Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len);
}
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len);
Status ArrayUtils_Search(Array *inst, Var *item, int *store);
Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store);
Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
Status ArrayUtils_Revert(Array *inst);
bool ArrayUtils_IsEmpty(Array *inst);

View File

@@ -2,14 +2,14 @@ cmake_minimum_required (VERSION 3.5)
project (Compound) project (Compound)
set(CMAKE_C_COMPILER gcc) set(CMAKE_C_COMPILER clang)
add_compile_options(-g -std=c99 -Wall -Wextra -D__DEBUG__) add_compile_options(-g -std=c99 -Wall -Wextra -D__DEBUG__)
set(SHARED_SOURCE set(SHARED_SOURCE
MemMan/src/memman.c MemMan/src/memman.c
Status/src/status.c Status/src/status.c
Utils/src/utils.c Array/src/array.c
Var/src/var.c Var/src/var.c
catlog.c) catlog.c)
@@ -32,5 +32,6 @@ add_executable(CompoundTest
test.c test.c
MemMan/src/memman.c MemMan/src/memman.c
Status/src/status.c Status/src/status.c
Utils/src/utils.c Array/src/array.c
Var/src/var.c
catlog.c) catlog.c)

View File

@@ -33,7 +33,10 @@ Status Memory_Reallocate(Memory *inst, size_t size)
/* When failed on reallocating. */ /* When failed on reallocating. */
state(!(inst->addr = realloc(inst->addr, size)), state(!(inst->addr = realloc(inst->addr, size)),
apply(error(InsufficientMemory, "Unsuccessful reallocation was received."))); apply(error(InsufficientMemory, "Cannot successfully reallocate.")));
/* Update size from inst. */
inst->size = size;
return apply(NormalStatus); return apply(NormalStatus);
} }

View File

@@ -78,78 +78,6 @@ typedef struct _Status {
# define STATUS_LITERALISE_FORMAT \ # define STATUS_LITERALISE_FORMAT \
"%s: \"%s\"\n\tpredecessor=<%s> value=(%d) characteristic=(%d)\n\t%s\n" "%s: \"%s\"\n\tpredecessor=<%s> value=(%d) characteristic=(%d)\n\t%s\n"
typedef enum {
REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value.
REPORT_SENDING_PRIORITY_FATAL,
REPORT_SENDING_PRIORITY_EXCEPTIONAL,
REPORT_SENDING_PRIORITY_CRITICAL,
REPORT_SENDING_PRIORITY_MAJOR,
REPORT_SENDING_PRIORITY_NORMAL,
REPORT_SENDING_PRIORITY_MINOR,
REPORT_SENDING_PRIORITY_DEBUG,
REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value.
} ReportLevel;
typedef enum {
REPORT_SENDING_TASK_STATUS_FINISHED = 0,
REPORT_SENDING_TASK_STATUS_PENDING,
REPORT_SENDING_TASK_STATUS_PROCEEDING,
REPORT_SENDING_TASK_STATUS_PAUSED,
REPORT_SENDING_TASK_STATUS_NOTFOUND
} ReportStatus;
/* "Report" recollects essential informations, included but not limited to
Status and others for making an report for debugging and such. */
typedef struct {
Status content;
char *initiator;
time_t time;
ReportLevel level;
ReportStatus status;
FILE *dst; // The destination where the report is sending to.
} Report;
/*
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
Fri 10 May 03:02:37 CST 2024 [URGENT] InvalidParameter (Nullity): Given buffer was unavailable.
at /external/Documents/Projects/Compound/Status/src/status.c:104, Report_Literalise
at /external/Documents/Projects/Compound/Status/src/status.c:114, ReportSender_Send
at /external/Documents/Projects/Compound/Status/src/status.c:69, _throw
!!!!at /external/Documents/Projects/Compound/Array/src/array.c:16, array_create
at /external/Documents/Projects/Compound/test.c:24, main
*/
// DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
# define REPORT_LITERALISE_FORMAT_HEADER "%s [%d] %s (%s): %s\n\tat %s:%d, %s\n%s"
// STATUS.IDENTITY, STATUS.PREV.IDENTITY, STATUS.VALUE, STATUS.CHARACTERISTIC,
// FILE, LINE, FUNC
# define REPORT_LITERALISE_FORMAT_DETAIL "\t%s(%s, %d, %d) at %s:%d, %s\n"
typedef enum {
REPORT_RESULT_SUCCEEDED,
REPORT_RESULT_FAILED,
REPORT_RESULT_PROGRESSING,
REPORT_RESULT_PENDING,
} ReportResult;
typedef struct {
thrd_t thread;
Report report;
time_t elapsed;
ReportResult result;
} ReportSender;
typedef int (*ReportTask)(Report *);
typedef int ReportTaskID;
// typedef thrd_start_t ArgueStart; // typedef thrd_start_t ArgueStart;
// typedef struct { // typedef struct {
@@ -185,7 +113,6 @@ typedef int ReportTaskID;
Status Location_Literalise(Location *inst, char *buff); 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);
Status Status_LiteraliseForReport(Status *inst, char *buff);
bool Status_Equal(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);
void StatusUtils_Dump(Status *inst, Status *store); void StatusUtils_Dump(Status *inst, Status *store);
@@ -194,20 +121,6 @@ bool StatusUtils_IsOkay(Status inst);
bool StatusUtils_IsRecursive(Status inst); bool StatusUtils_IsRecursive(Status inst);
int StatusUtils_Depth(Status *inst); int StatusUtils_Depth(Status *inst);
Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority);
Status Report_CopyOf(Report *inst, Report *other);
Status Report_Literalise(Report *inst, char *buff);
void Report_Delete(Report *inst);
bool Report_Equals(Report repo1, Report repo2);
// Status ReportSender_Create(ReportSender *inst, Report *report, thrd_start_t *handler);
Status ReportSender_Create(ReportSender *inst, Report *report);
Status ReportSender_Send(ReportSender *inst, ReportTask task);
// ReportTaskStatus
// ReportSender_GetStatus(ReportSender *inst);
// Status // Status
// arguestarter_create(ArgueStartParam *inst, void *external_param); // arguestarter_create(ArgueStartParam *inst, void *external_param);
// Status // Status
@@ -230,9 +143,9 @@ Status ReportSender_Send(ReportSender *inst, ReportTask task);
// ---------------------ELEMENTARY------------------------- // ---------------------ELEMENTARY-------------------------
DEFSTATUS(UnknownStatus, -1, "An unknown status.", STATUS_UNKNOWN, NULL); DEFSTATUS(UnknownStatus, -1, "An unknown status.", STATUS_UNKNOWN, &UnknownStatus);
DEFSTATUS(NormalStatus, 0, "A normal status.", STATUS_NORMAL, NULL); DEFSTATUS(NormalStatus, 0, "A normal status.", STATUS_NORMAL, &NormalStatus);
DEFSTATUS(ErrorStatus, 1, "An error status.", STATUS_ERROR, NULL); DEFSTATUS(ErrorStatus, 1, "An error status.", STATUS_ERROR, &ErrorStatus);
// ----------------------EXTENDED-------------------------- // ----------------------EXTENDED--------------------------
@@ -252,14 +165,6 @@ DEFSTATUS(UnavailableObject, 1,
"An unavailable object was presented.", "An unavailable object was presented.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceStillAlive, 1,
"Given instance was yet alive.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceNotAlive, 1,
"Given instance for reallocation was not alive.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InvalidParameter, 1, DEFSTATUS(InvalidParameter, 1,
"An invalid parameter was presented.", "An invalid parameter was presented.",
STATUS_ERROR, &InvalidObject); STATUS_ERROR, &InvalidObject);
@@ -276,10 +181,26 @@ DEFSTATUS(IntegerOverFlow, 1,
"An integer had overflowed.", "An integer had overflowed.",
STATUS_ERROR, &ArithmeticError); STATUS_ERROR, &ArithmeticError);
DEFSTATUS(InvalidOperation, 1,
"An invalid operation was detected.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(RuntimeError, 1, DEFSTATUS(RuntimeError, 1,
"A runtime error occurred.", "A runtime error occurred.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceStillAlive, 1,
"Given instance was still alive.",
STATUS_ERROR, &RuntimeError);
DEFSTATUS(InstanceNotAlive, 1,
"Given instance for reallocation was not alive.",
STATUS_ERROR, &RuntimeError);
DEFSTATUS(InvalidOperationBetweenAliveAndNonAlive, 1,
"Given two instances were incompatible with each other for any operation.",
STATUS_ERROR, &InvalidOperation);
DEFSTATUS(InstanceCreatingFailure, 1, DEFSTATUS(InstanceCreatingFailure, 1,
"Cannot create the instance.", "Cannot create the instance.",
STATUS_ERROR, &RuntimeError); STATUS_ERROR, &RuntimeError);
@@ -407,7 +328,15 @@ static inline Status PrintStatus(Status s)
static inline void PrintStatusDump(Status s) static inline void PrintStatusDump(Status s)
{ {
/* Create dump. */ /* Create dump. */
/* Calculate depth for dumping. */
const int dump_len = StatusUtils_Depth(&s); const int dump_len = StatusUtils_Depth(&s);
/* Skip when "s" is either unavailable or is at the buttom of status stack. */
if (dump_len == -1) {
PrintStatus(s);
return;
}
Status dump[dump_len]; Status dump[dump_len];
Status current = s; Status current = s;
dump[0] = current; // Put self at leading. dump[0] = current; // Put self at leading.
@@ -415,6 +344,7 @@ static inline void PrintStatusDump(Status s)
// StatusUtils_Dump will only access (storage) the prev. // StatusUtils_Dump will only access (storage) the prev.
// It does not include this status itself. // It does not include this status itself.
StatusUtils_Dump(&current, &dump[i]); StatusUtils_Dump(&current, &dump[i]);
current = *current.prev; current = *current.prev;
} }
@@ -427,37 +357,7 @@ static inline void PrintStatusDump(Status s)
unsure(PrintStatus(dump[i]), !_.value, { unsure(PrintStatus(dump[i]), !_.value, {
(void)fprintf(stderr, "Unable to literalise.\n"); (void)fprintf(stderr, "Unable to literalise.\n");
}) })
// seek(PrintStatus(dump[i]), { // Get returning status.
// /* Handle TraditionalFunctionReturn. */
// nest(_, __, unsure(__, !__.value, { // No bytes were written to buffer.
// (void)fprintf(stderr, "Unable to literalise.\n");
// return;
// }));
// // Handle abnormal status.
// nest(_, __, notok(__, {
// /* Output the description as explanation. */
// (void)fprintf(stderr, "%s\n", __.description);
// return;
// }));
// });
} }
} }
// ========================================================
/* Add location parameter requirement in order to give proper information
* before throwing the report out. */
// # define throw(report) THROW(report, __HERE__)
/* Useless in C, only for human to see.
Probably rewrite this in Classify. */
# define throws(e)
// ReportTaskID THROW(Report report, Location loc);
// Report CATCH(ReportTaskID taskid, Status (*handler)());
int HANDLER(void *report);
#endif /* COMPOUND_STATUS_H */ #endif /* COMPOUND_STATUS_H */

View File

@@ -5,10 +5,6 @@ Status Location_Literalise(Location *inst, char *buff)
nonull(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
nonull(buff, apply(UnavailableBuffer)); nonull(buff, apply(UnavailableBuffer));
/* Literalise line. */
char line_buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
Utils_LiteraliseInteger(inst->line, line_buff);
where( where(
snprintf(buff, LITERALISATION_LENGTH_MAXIMUM, snprintf(buff, LITERALISATION_LENGTH_MAXIMUM,
LOCATION_LITERALISE_FORMAT,inst->file,inst->line,inst->func), LOCATION_LITERALISE_FORMAT,inst->file,inst->line,inst->func),
@@ -31,13 +27,12 @@ bool Status_Equal(Status *stat1, Status *stat2)
state(stat1 == NULL || stat2 == NULL, false); state(stat1 == NULL || stat2 == NULL, false);
return ( return (
!strcmp(stat1->identity, stat2->identity) &&
stat1->value == stat2->value && stat1->value == stat2->value &&
!strcmp(stat1->description, stat2->description) && !strcmp(stat1->description, stat2->description) &&
stat1->characteristic == stat2->characteristic && stat1->characteristic == stat2->characteristic &&
Location_Equal(&stat1->loc, &stat2->loc) && Location_Equal(&stat1->loc, &stat2->loc) &&
((StatusUtils_HasPrev(*stat1) && StatusUtils_HasPrev(*stat2)) stat1->prev == stat2->prev
? Status_Equal(stat1->prev, stat2->prev)
: true)
); );
} }
@@ -79,21 +74,6 @@ Status Status_Literalise(Status *inst, char *buff)
}); });
} }
Status Status_LiteraliseForReport(Status *inst, char *buff)
{
/* Skip unavailable instance and invalid parameter. */
nonull(inst, apply(UnavailableInstance));
nonull(buff, apply(UnavailableBuffer));
where(
snprintf(buff, LITERALISATION_LENGTH_MAXIMUM, REPORT_LITERALISE_FORMAT_DETAIL,
strnil(inst->identity), strnil(inst->prev->identity),
inst->value, inst->characteristic, inst->loc.file, inst->loc.line,
inst->loc.func), {
return apply(value(TraditionalFunctionReturn, _));
});
}
bool StatusUtils_HasPrev(Status stat) bool StatusUtils_HasPrev(Status stat)
{ {
return (stat.prev != NULL); return (stat.prev != NULL);
@@ -106,7 +86,8 @@ bool StatusUtils_IsOkay(Status stat)
bool StatusUtils_IsRecursive(Status stat) bool StatusUtils_IsRecursive(Status stat)
{ {
return (stat.prev && stat.prev == &stat); // return (stat.prev && stat.prev == stat.prev->prev);
return (stat.prev && Status_Equal(&stat, stat.prev));
} }
void StatusUtils_Dump(Status *inst, Status *store) void StatusUtils_Dump(Status *inst, Status *store)
@@ -119,26 +100,6 @@ void StatusUtils_Dump(Status *inst, Status *store)
*store = *inst->prev; *store = *inst->prev;
} }
// void StatusUtils_Dump(Status *inst, Status **store, int idx)
// {
// /* Skip when having invalid inst, store or idx. */
// svoid(!inst || !store || idx < 0 || StatusUtils_IsRecursive(*inst));
// // store[idx] = *inst;
// *store[idx] = (Status){
// .identity = inst->identity,
// .value = inst->value,
// .description = inst->description,
// .characteristic = inst->characteristic,
// .loc = inst->loc,
// .prev = inst->prev
// };
// (void)printf("idx: %d\n", idx);
// StatusUtils_Dump(inst->prev, store, (idx - 1));
// }
int StatusUtils_Depth(Status *stat) int StatusUtils_Depth(Status *stat)
{ {
/* Skip unavailable stat. */ /* Skip unavailable stat. */
@@ -150,170 +111,14 @@ int StatusUtils_Depth(Status *stat)
Status current = *stat; Status current = *stat;
/* Iterate to accumulate. */ /* Iterate to accumulate. */
while (current.prev) { while (current.prev) {
/* Skip recursive status. */
if (StatusUtils_IsRecursive(current)) break;
current = *current.prev; current = *current.prev;
cnt += 1; cnt += 1;
} }
return cnt; return cnt;
// Status *current = stat; // Include this layer of Status.
// register int cnt;
// for (cnt = 0; (!StatusUtils_IsRecursive(*current)
// && StatusUtils_HasPrev(*current)); cnt++) {
// current = current->prev;
// }
// return cnt;
}
Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority)
{
/* Skip unavailable parameters. */
nonull(inst, apply(UnavailableInstance));
nonull(stat, apply(error(InvalidParameter, "Given stat was null.")));
nonull(initiator, apply(error(InvalidParameter, "Given initiator was null.")));
state(priority < 0, apply(error(InvalidParameter, "Given priority was negative.")));
/* Copy and assign. */
inst->content = *stat;
inst->initiator = calloc(strlen(initiator), sizeof(char));
(void)strcpy(inst->initiator, initiator);
inst->time = time(NULL);
inst->level = priority;
inst->status = REPORT_SENDING_TASK_STATUS_PENDING;
inst->dst = (dest == NULL ? stdout : dest);
return apply(NormalStatus);
}
Status Report_CopyOf(Report *inst, Report *other)
{
nonull(inst, apply(UnavailableInstance));
nonull(other, apply(error(InvalidParameter, "Given report is unavailable.")));
// Status status;
// char *initiator;
// time_t time;
// ReportLevel priority;
// ReportTaskStatus taskprint_status;
// FILE *dest;
inst->content = other->content;
return apply(NormalStatus);
}
void Report_Delete(Report *inst)
{
svoid(inst);
free(inst->initiator);
inst->initiator = NULL;
inst->dst = NULL;
inst->level = 0;
inst->content = (Status){};
inst->status = REPORT_SENDING_TASK_STATUS_NOTFOUND;
inst->time = 0;
inst = NULL;
}
/*
Status status;
char *initiator;
time_t time;
ReportLevel priority;
ReportTaskStatus taskprint_status;
FILE *dest;
*/
Status Report_Literalise(Report *inst, char *buff)
{
nonull(inst, apply(UnavailableInstance));
nonull(buff, apply(UnavailableBuffer));
/* Report literalisation. */
char report_literalising[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
/** Status literalisation. **/
char status_literalising[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
/* Fault detection on status literalisation. */
// settle(Status_LiteraliseForReport(&inst->status, status_literalising),
// _.characteristic == STATUS_UNKNOWN, {
// nest(_, __, {
// /* Skip when ZERO byte were written. (failed to write) */
// state(!__.value, apply(
// error(value(TraditionalFunctionReturn, __.value),
// "ZERO byte were written.")
// ));
// })
// });
/* Traditional function returning handling. */
settle(Status_LiteraliseForReport(&inst->content, status_literalising),
!_.value, {
return apply(annot(RuntimeError, "Failed to literalise status for report."));
});
/* Write result to buffer. */
/* Write the report "header". */
/* Literalise current time and date. */
char datetime[LITERALISATION_LENGTH_MAXIMUM];
// settle(strftime(datetime, 64, "%c", localtime(&inst->time)), )
// DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
state(!snprintf(report_literalising, LITERALISATION_LENGTH_MAXIMUM,
REPORT_LITERALISE_FORMAT_HEADER, datetime, inst->level,
inst->content.identity, inst->initiator, inst->content.description),
apply(annot(NoBytesWereWritten, "Failed to literalise date and time."))
);
/* Write the report "detail". */
return apply(NormalStatus);
}
/*
thrd_t thread;
Report report;
time_t elapsed;
ReportResult result;
*/
Status ReportSender_Create(ReportSender *inst, Report *report)
{
nonull(inst, apply(UnavailableInstance));
nonull(report, error(UnavailableParameter, "Given report was unavailable."));
thrd_create(&inst->thread, &HANDLER, report);
notok(Report_CopyOf(&inst->report, report),
return apply(annot(InstanceCreatingFailure,
"Cannot copy to create new instance of report."));
);
inst->report = *report;
inst->elapsed = 0;
inst->result = REPORT_RESULT_PENDING;
return apply(NormalStatus);
}
Status ReportSender_Send(ReportSender *inst, ReportTask task)
{
// /* Skip when inst or task is unavailable. */
// nonull(inst,
// error(UnavailableInstance, "Report sender was given unavailable."));
// nonull(task, InvalidReportTask);
// /* Assign for dest. */
// const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest);
// // char buff[];
// // TODO(william): HERE, Report_Literalise
// /* Write/Send data. */
// inst->report->taskprint_status = REPORT_SENDING_TASK_STATUS_PROCEEDING;
// if (!fprintf(dest, buff)) {
// }
// /* Sent successfully! Mark down properties. */
return apply(NormalStatus);
} }
// bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2) // bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2)
@@ -324,65 +129,3 @@ Status ReportSender_Send(ReportSender *inst, ReportTask task)
// return (inst1->argue_start == inst2->argue_start) // return (inst1->argue_start == inst2->argue_start)
// || (inst1->external_param == inst2->external_param); // || (inst1->external_param == inst2->external_param);
// } // }
ReportTaskID THROW(Report report, Location loc)
{
// // /* Create new a instance of ReportSender. */
// // ReportSender sender;
// // ReportSender_Create(&sender, stderr);
// // /* Send message. */
// // /* Initialise sender's thread. */
// // thrd_t sending;
// // /* Skip on failing on creating thread. */
// // if (!thrd_create(&sending, starter, NULL)) {
// // /* Conclude the session of sender. */
// // report.status = REPORT_SENDING_TASK_STATUS_FINISHED,
// // report.result = (ARGUE_RESULT_FINALISED | ARGUE_RESULT_NEGATIVE);
// // sender.result = REPORT_SENDER_RESULT_FINISHED;
// // sender.successful = false;
// // return -1;
// // }
// // /* Perform sending. */
// // ReportSender_Send(&sender, NULL);
// /* Initialise sender. */
// ReportSender sender;
// /* Return with -1 when initialisation failed. */
// state(!(StatusUtils_IsOkay(ReportSender_Create(&sender, &report))), -1);
// /* Inject location information. Could be more elegant, though. */
// sender.report->status.loc = loc;
// /* Send. */ /* Return -1 when failed on sending. */
// state(!StatusUtils_IsOkay(ReportSender_Send(&sender, HANDLER)), -1);
return 0;
}
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;
return 0;
}

View File

@@ -19,15 +19,13 @@ typedef struct {
StringEncoding encoding; StringEncoding encoding;
} String; } String;
/* Elementary. */
Status String_Create(String *inst, int len); Status String_Create(String *inst, int len);
Status String_CopyOf(String *inst, String *other); Status String_CopyOf(String *inst, String *other);
Status String_Delete(String *inst); Status String_Delete(String *inst);
Status String_GetIdx(String *inst, Char *item, int index); Status String_Encode(String *inst, StringEncoding encoding);
Status String_SetIdx(String *inst, Char *item, int index); Status String_Decode(String *inst, StringEncoding encoding);
Status String_Literalise(String *inst, String *store); Status String_Literalise(String *inst, String *store);
/* Extensional. */
Status StringUtils_FromInteger(String *inst, int value, int base); Status StringUtils_FromInteger(String *inst, int value, int base);
Status StringUtils_FromShortInteger(String *inst, short int value, int base); Status StringUtils_FromShortInteger(String *inst, short int value, int base);
Status StringUtils_FromLongInteger(String *inst, long int value, int base); Status StringUtils_FromLongInteger(String *inst, long int value, int base);
@@ -77,10 +75,8 @@ Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Comp
Status StringUtils_ToAddress(String *inst, void **store); Status StringUtils_ToAddress(String *inst, void **store);
Status StringUtils_ToCharBuff(String *inst, char const *buff); Status StringUtils_ToCharBuff(String *inst, char const *buff);
Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff); Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff);
// Status StringUtils_Format(String *inst, const String *restrict fmt, ...);
Status StringUtils_Tokenise(String *inst, const String *delim, String *store); Status StringUtils_Tokenise(String *inst, const String *delim, String *store);
Status String_Encode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError); bool StringUtils_IsBlank(String *inst);
Status String_Decode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError);
int StringUtils_Compare(String *a, String *b); int StringUtils_Compare(String *a, String *b);
static Status StringConversionPrecisionError = { static Status StringConversionPrecisionError = {
@@ -93,13 +89,4 @@ static Status StringConversionPrecisionError = {
.prev = (Status *)&ImprecisionError .prev = (Status *)&ImprecisionError
}; };
// # define string(str) ((String) {\
// .data =
// })
typedef Array(int) InfiniteInteger;
typedef Array(double) InfiniteFloatingPoint;
typedef Array(_Complex double) InfintieComplex;
#endif /* COMPOUND_STRING_H */ #endif /* COMPOUND_STRING_H */

View File

@@ -1,49 +1,49 @@
#include <Compound/utils.h> #include <Compound/utils.h>
int Utils_CalcDigits(long long int n) // int Utils_CalcDigits(long long int n)
{ // {
if (n == 0) { // if (n == 0) {
return 1; // return 1;
} // }
n = llabs(n); // n = llabs(n);
/* Accumulate. */ // /* Accumulate. */
register int i; // register int i;
for (i = 0; n; i++) n /= 10; // for (i = 0; n; i++) n /= 10;
return i; // return i;
} // }
int Utils_LiteraliseInteger(long long int n, char *buff) // int Utils_LiteraliseInteger(long long int n, char *buff)
{ // {
/* Invalid buffer was presented. */ // /* Invalid buffer was presented. */
if (strlen(buff) != LITERALISATION_LENGTH_MAXIMUM) { // if (strlen(buff) != LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL; // buff = NULL;
return 0; // return 0;
} // }
if (!n) { // if (!n) {
buff = "0"; // buff = "0";
return 1; // return 1;
} // }
const int literalising_len = Utils_CalcDigits(n); // const int literalising_len = Utils_CalcDigits(n);
if (literalising_len >= LITERALISATION_LENGTH_MAXIMUM) { // if (literalising_len >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL; // buff = NULL;
return 0; // return 0;
} // }
char literalising[literalising_len]; // char literalising[literalising_len];
for (register int i = 0; i < literalising_len; i++) { // for (register int i = 0; i < literalising_len; i++) {
literalising[i] = (n / (int)pow(10, i)); // literalising[i] = (n / (int)pow(10, i));
} // }
return literalising_len; // return literalising_len;
} // }
int Utils_DateTimeLiteralise(time_t timer, char *buff, // int Utils_DateTimeLiteralise(time_t timer, char *buff,
const char *__restrict format) // const char *__restrict format)
{ // {
} // }

View File

@@ -52,9 +52,9 @@ typedef struct {
Status Var_Create(Var *inst, size_t size) throws(InsufficientMemory); 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_Delete(Var *inst);
Status Var_Literalise(Var *inst, char *buff); Status Var_Literalise(Var *inst, char *buff);
bool Var_Equals(Var *a, Var *b); bool Var_Equals(Var *a, Var *b);
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);

View File

@@ -1,3 +1,4 @@
#include <Compound/status.h>
#include <Compound/var.h> #include <Compound/var.h>
Status Var_Create(Var *inst, size_t size) Status Var_Create(Var *inst, size_t size)
@@ -14,22 +15,6 @@ Status Var_Create(Var *inst, size_t size)
return apply(NormalStatus); return apply(NormalStatus);
} }
// Status Var_Create(Var *inst, void *addr, size_t size, char *identity)
// {
// /* Skip when inst is unavailable. */
// nonull(inst, apply(UnavailableInstance));
// /* Skip when identity is unavailable. */
// nonull(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 apply(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. */
@@ -45,33 +30,17 @@ Status Var_CopyOf(Var *inst, Var *other)
return apply(NormalStatus); return apply(NormalStatus);
} }
void Var_Delete(Var *inst) Status Var_Delete(Var *inst)
{ {
svoid(!inst); nonull(!inst, apply(UnavailableInstance));
state(!inst->alive, apply(InstanceNotAlive));
free(inst->addr); free(inst->addr);
inst->alive = false;
inst->addr = NULL; inst->addr = NULL;
inst->size = 0; inst->size = 0;
}
// void Var_Delete(Var *inst) return apply(NormalStatus);
// {
// /* Skip when inst or inst->addr is unavailable. */
// svoid(!inst || inst->addr == NULL);
// inst->addr = NULL;
// inst->size = 0;
// *inst->identity = 0;
// }
void VarUtils_Swap(Var *v1, Var *v2)
{
/* Skip when v1 or v2 is unavailable. */
svoid(!v1 || !v2);
Var v3 = *v1;
*v1 = *v2;
*v2 = v3;
} }
Status Var_Literalise(Var *inst, char *buff) Status Var_Literalise(Var *inst, char *buff)
@@ -95,32 +64,12 @@ bool Var_Equals(Var *a, Var *b)
return (a->addr == b->addr && a->size == b->size); return (a->addr == b->addr && a->size == b->size);
} }
// bool VarUtils_IsIdentityLegal(char *identity) void VarUtils_Swap(Var *v1, Var *v2)
// { {
// /* Skip when identity is unavailable. */ /* Skip when v1 or v2 is unavailable. */
// state(identity == NULL, false); svoid(!v1 || !v2);
// const int len = strlen(identity); Var v3 = *v1;
*v1 = *v2;
// /* Skip when identity is empty. */ *v2 = v3;
// state(len == 0, false); }
// /* Skip when the first char is not within alphabet. */
// state(ATRANGE('a', 'z', identity[0])
// || ATRANGE('A', 'Z', identity[0]), false);
// /* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */
// state(len > VAR_IDENTITY_LENGTH, false);
// /* Skip when identity has space and illegal characters in it. */
// const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR);
// for (register int i = 0; i < len; i++) {
// for (register int j = 0; j < illegal_len; j++) {
// if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) {
// return false;
// }
// }
// }
// return true;
// }

View File

@@ -99,7 +99,7 @@ Status CatlogSender_Send(CatlogSender *inst)
} }
Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath, Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath,
const char const *restrict mode) const char *restrict mode)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
nonull(fileptr, apply(UnavailableBuffer)); nonull(fileptr, apply(UnavailableBuffer));

View File

@@ -59,7 +59,7 @@ Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other);
Status CatlogSender_Send(CatlogSender *inst); Status CatlogSender_Send(CatlogSender *inst);
bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other); bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other);
Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath, Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath,
const char const *restrict mode); const char *restrict mode);
Status CatlogUtils_CloseFile(FILE **fileptr); Status CatlogUtils_CloseFile(FILE **fileptr);
#endif /* COMPOUND_CATLOG_H */ #endif /* COMPOUND_CATLOG_H */

View File

@@ -1,15 +1,18 @@
#ifndef COMPOUND_COMMON_H #ifndef COMPOUND_COMMON_H
# define COMPOUND_COMMON_H # define COMPOUND_COMMON_H
# ifdef __DEBUG__
# warning DEBUG IS ON
# endif /* __DEBUG__ */
# include <stdlib.h> # include <stdlib.h>
# include <stdbool.h> # include <stdbool.h>
# define EMPTY {0} # define EMPTY {0}
/*
PLEASE BE NOTICE:
MAGIC MACRO CANNOT USE "APPLY" AT RETURNING.
IT SHOULD ALWAYS RETURN THE LOCATION INDICATOR WHERE
IT CAME FROM.
*/
/* Get the literal. */ /* Get the literal. */
# define nameof(obj) #obj # define nameof(obj) #obj
@@ -40,10 +43,13 @@
/* Execute b whenever finds s is "NOT okay". */ /* Execute b whenever finds s is "NOT okay". */
# define notok(s, b) { Status _ = s; if (!StatusUtils_IsOkay(_)) b } # define notok(s, b) { Status _ = s; if (!StatusUtils_IsOkay(_)) b }
/* Return e when passing a failing e commented with c. */ /* Return e when passing a failing e. */
# define fails(e, c) { notok(e, return apply(annot(_, c));) } # define fail(e) { notok(e, return _;) }
/* Return v when passing a failing e. */ /* Return e when passing a failing e commented with c. */
# define fails(e, c) { notok(e, return annot(_, c);) }
/* Return value "v" when passing a failing e. */
# define vfail(e, v) { notok(e, return v;) } # define vfail(e, v) { notok(e, return v;) }
/* Execute b for handling UnknownStatus (TraditionalFunctionReturn). */ /* Execute b for handling UnknownStatus (TraditionalFunctionReturn). */
@@ -62,6 +68,13 @@
/* Allows different macros using "_" nested with each other. */ /* Allows different macros using "_" nested with each other. */
# define nest(v1, v2, b) { clone(v1, v2) b } # define nest(v1, v2, b) { clone(v1, v2) b }
/* Cast Var "var" into builtin type in C specified with "type". */
# define cast(var, type) (*(type *)var.addr)
/* Assign var with value under type "type".
REQUIRE BOTH VAR AND VALUE TO BE ALIVE. */
# define assign(var, value, type) { cast(var, type) = cast(value, type); }
// # define lambda(param, body, capfmt, ...) {\ // # define lambda(param, body, capfmt, ...) {\
// /* Duplicate everything from cap. */\ // /* Duplicate everything from cap. */\
// va_list ptr;\ // va_list ptr;\
@@ -72,7 +85,7 @@
/* 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(e),\ .identity = e.identity,\
.value = v,\ .value = v,\
.description = c,\ .description = c,\
.characteristic = STATUS_UNKNOWN,\ .characteristic = STATUS_UNKNOWN,\
@@ -82,7 +95,7 @@
/* Create a new NormalStatus on the fly. */ /* Create a new NormalStatus on the fly. */
# define normal(e, c) ((Status) {\ # define normal(e, c) ((Status) {\
.identity = nameof(e),\ .identity = e.identity,\
.value = 0,\ .value = 0,\
.description = c,\ .description = c,\
.characteristic = STATUS_NORMAL,\ .characteristic = STATUS_NORMAL,\
@@ -92,7 +105,7 @@
/* 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(e),\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\
.description = c,\ .description = c,\
.characteristic = STATUS_ERROR,\ .characteristic = STATUS_ERROR,\
@@ -100,7 +113,7 @@
.prev = e.prev\ .prev = e.prev\
}) })
/* Extend the Status chain by giving 'p' for "predecessor" and 'e' for "Eval-Status". */ /* Replace the prev of e with p. */
# define extend(p, e) ((Status) {\ # define extend(p, e) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = p.value,\ .value = p.value,\
@@ -110,6 +123,7 @@
.prev = (Status *)&p\ .prev = (Status *)&p\
}) })
/* Create a new Status with v as its value. */
# define value(e, v) ((Status) {\ # define value(e, v) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = v,\ .value = v,\
@@ -119,6 +133,17 @@
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
/* Change the characteristic of e. */
# define shift(e, c) ((Status) {\
.identity = e.identity,\
.value = e.value,\
.description = e.description,\
.characteristic = c,\
.loc = e.loc,\
.prev= (Status *)e.prev\
})
/* Apply a new location to e where this macro is called. */
# define apply(e) ((Status) {\ # define apply(e) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\
@@ -128,7 +153,7 @@
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
// Reannotate for e. /* Replace the description from e with c. */
# define annot(e, c) ((Status) {\ # define annot(e, c) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\
@@ -209,4 +234,8 @@ typedef bool _Bit;
# define __ATTRIBUTABLE__ # define __ATTRIBUTABLE__
# define attr(a) # define attr(a)
/* Useless in C, only for human to see.
Probably rewrite this in Classify. */
# define throws(e)
#endif /* COMPOUND_COMMON_H */ #endif /* COMPOUND_COMMON_H */

View File

@@ -30,6 +30,6 @@ done
# Install individual headers. # Install individual headers.
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" "class.h" "function.h" "$DST" "attr.h" "registry.h" "class.h" "function.h" "report.h" "$DST"
printf "\nDone\n" printf "\nDone\n"

233
report.c Normal file
View File

@@ -0,0 +1,233 @@
#include <Compound/report.h>
Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority)
{
/* Skip unavailable parameters. */
nonull(inst, apply(UnavailableInstance));
nonull(stat, apply(error(InvalidParameter, "Given stat was null.")));
nonull(initiator, apply(error(InvalidParameter, "Given initiator was null.")));
state(priority < 0, apply(error(InvalidParameter, "Given priority was negative.")));
/* Copy and assign. */
inst->content = *stat;
inst->initiator = calloc(strlen(initiator), sizeof(char));
(void)strcpy(inst->initiator, initiator);
inst->time = time(NULL);
inst->level = priority;
inst->status = REPORT_SENDING_TASK_STATUS_PENDING;
inst->dst = (dest == NULL ? stdout : dest);
return apply(NormalStatus);
}
Status Report_CopyOf(Report *inst, Report *other)
{
nonull(inst, apply(UnavailableInstance));
nonull(other, apply(error(InvalidParameter, "Given report is unavailable.")));
// Status status;
// char *initiator;
// time_t time;
// ReportLevel priority;
// ReportTaskStatus taskprint_status;
// FILE *dest;
inst->content = other->content;
return apply(NormalStatus);
}
void Report_Delete(Report *inst)
{
svoid(inst);
free(inst->initiator);
inst->initiator = NULL;
inst->dst = NULL;
inst->level = 0;
inst->content = (Status){};
inst->status = REPORT_SENDING_TASK_STATUS_NOTFOUND;
inst->time = 0;
inst = NULL;
}
/*
Status status;
char *initiator;
time_t time;
ReportLevel priority;
ReportTaskStatus taskprint_status;
FILE *dest;
*/
Status Report_Literalise(Report *inst, char *buff)
{
// nonull(inst, apply(UnavailableInstance));
// nonull(buff, apply(UnavailableBuffer));
// /* Report literalisation. */
// char report_literalising[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
// /** Status literalisation. **/
// char status_literalising[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
// /* Fault detection on status literalisation. */
// // settle(Status_LiteraliseForReport(&inst->status, status_literalising),
// // _.characteristic == STATUS_UNKNOWN, {
// // nest(_, __, {
// // /* Skip when ZERO byte were written. (failed to write) */
// // state(!__.value, apply(
// // error(value(TraditionalFunctionReturn, __.value),
// // "ZERO byte were written.")
// // ));
// // })
// // });
// /* Traditional function returning handling. */
// // settle(Status_LiteraliseForReport(&inst->content, status_literalising),
// // !_.value, {
// // return apply(annot(RuntimeError, "Failed to literalise status for report."));
// // });
// where(
// snprintf(buff, LITERALISATION_LENGTH_MAXIMUM, REPORT_LITERALISE_FORMAT_DETAIL,
// strnil(inst->content.identity), strnil(inst->content.prev->identity),
// inst->content.value, inst->content.characteristic,
// inst->content.loc.file, inst->content.loc.line,
// inst->content.loc.func), {
// return apply(value(TraditionalFunctionReturn, _));
// });
// /* Write result to buffer. */
// /* Write the report "header". */
// /* Literalise current time and date. */
// char datetime[LITERALISATION_LENGTH_MAXIMUM];
// // settle(strftime(datetime, 64, "%c", localtime(&inst->time)), )
// // DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
// state(!snprintf(report_literalising, LITERALISATION_LENGTH_MAXIMUM,
// REPORT_LITERALISE_FORMAT_HEADER, datetime, inst->level,
// inst->content.identity, inst->initiator, inst->content.description),
// apply(annot(NoBytesWereWritten, "Failed to literalise date and time."))
// );
// /* Write the report "detail". */
return apply(NormalStatus);
}
/*
thrd_t thread;
Report report;
time_t elapsed;
ReportResult result;
*/
Status ReportSender_Create(ReportSender *inst, Report *report)
{
nonull(inst, apply(UnavailableInstance));
nonull(report, error(UnavailableParameter, "Given report was unavailable."));
thrd_create(&inst->thread, &HANDLER, report);
notok(Report_CopyOf(&inst->report, report),
return apply(annot(InstanceCreatingFailure,
"Cannot copy to create new instance of report."));
);
inst->report = *report;
inst->elapsed = 0;
inst->result = REPORT_RESULT_PENDING;
return apply(NormalStatus);
}
Status ReportSender_Send(ReportSender *inst, ReportTask task)
{
// /* Skip when inst or task is unavailable. */
// nonull(inst,
// error(UnavailableInstance, "Report sender was given unavailable."));
// nonull(task, InvalidReportTask);
// /* Assign for dest. */
// const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest);
// // char buff[];
// // TODO(william): HERE, Report_Literalise
// /* Write/Send data. */
// inst->report->taskprint_status = REPORT_SENDING_TASK_STATUS_PROCEEDING;
// if (!fprintf(dest, buff)) {
// }
// /* Sent successfully! Mark down properties. */
return apply(NormalStatus);
}
ReportTaskID THROW(Report report, Location loc)
{
// // /* Create new a instance of ReportSender. */
// // ReportSender sender;
// // ReportSender_Create(&sender, stderr);
// // /* Send message. */
// // /* Initialise sender's thread. */
// // thrd_t sending;
// // /* Skip on failing on creating thread. */
// // if (!thrd_create(&sending, starter, NULL)) {
// // /* Conclude the session of sender. */
// // report.status = REPORT_SENDING_TASK_STATUS_FINISHED,
// // report.result = (ARGUE_RESULT_FINALISED | ARGUE_RESULT_NEGATIVE);
// // sender.result = REPORT_SENDER_RESULT_FINISHED;
// // sender.successful = false;
// // return -1;
// // }
// // /* Perform sending. */
// // ReportSender_Send(&sender, NULL);
// /* Initialise sender. */
// ReportSender sender;
// /* Return with -1 when initialisation failed. */
// state(!(StatusUtils_IsOkay(ReportSender_Create(&sender, &report))), -1);
// /* Inject location information. Could be more elegant, though. */
// sender.report->status.loc = loc;
// /* Send. */ /* Return -1 when failed on sending. */
// state(!StatusUtils_IsOkay(ReportSender_Send(&sender, HANDLER)), -1);
return 0;
}
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;
return 0;
}

100
report.h Normal file
View File

@@ -0,0 +1,100 @@
#ifndef COMPOUND_REPORT_H
# define COMPOUND_REPORT_H
# include <Compound/status.h>
typedef enum {
REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value.
REPORT_SENDING_PRIORITY_FATAL,
REPORT_SENDING_PRIORITY_EXCEPTIONAL,
REPORT_SENDING_PRIORITY_CRITICAL,
REPORT_SENDING_PRIORITY_MAJOR,
REPORT_SENDING_PRIORITY_NORMAL,
REPORT_SENDING_PRIORITY_MINOR,
REPORT_SENDING_PRIORITY_DEBUG,
REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value.
} ReportLevel;
typedef enum {
REPORT_SENDING_TASK_STATUS_FINISHED = 0,
REPORT_SENDING_TASK_STATUS_PENDING,
REPORT_SENDING_TASK_STATUS_PROCEEDING,
REPORT_SENDING_TASK_STATUS_PAUSED,
REPORT_SENDING_TASK_STATUS_NOTFOUND
} ReportStatus;
/* "Report" recollects essential informations, included but not limited to
Status and others for making an report for debugging and such. */
typedef struct {
Status content;
char *initiator;
time_t time;
ReportLevel level;
ReportStatus status;
FILE *dst; // The destination where the report is sending to.
} Report;
/*
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
Fri 10 May 03:02:37 CST 2024 [URGENT] InvalidParameter (Nullity): Given buffer was unavailable.
at /external/Documents/Projects/Compound/Status/src/status.c:104, Report_Literalise
at /external/Documents/Projects/Compound/Status/src/status.c:114, ReportSender_Send
at /external/Documents/Projects/Compound/Status/src/status.c:69, _throw
!!!!at /external/Documents/Projects/Compound/Array/src/array.c:16, array_create
at /external/Documents/Projects/Compound/test.c:24, main
*/
// DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
# define REPORT_LITERALISE_FORMAT_HEADER "%s [%d] %s (%s): %s\n\tat %s:%d, %s\n%s"
// STATUS.IDENTITY, STATUS.PREV.IDENTITY, STATUS.VALUE, STATUS.CHARACTERISTIC,
// FILE, LINE, FUNC
# define REPORT_LITERALISE_FORMAT_DETAIL "\t%s(%s, %d, %d) at %s:%d, %s\n"
typedef enum {
REPORT_RESULT_SUCCEEDED,
REPORT_RESULT_FAILED,
REPORT_RESULT_PROGRESSING,
REPORT_RESULT_PENDING,
} ReportResult;
typedef struct {
thrd_t thread;
Report report;
time_t elapsed;
ReportResult result;
} ReportSender;
typedef int (*ReportTask)(Report *);
typedef int ReportTaskID;
Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority);
Status Report_CopyOf(Report *inst, Report *other);
Status Report_Literalise(Report *inst, char *buff);
void Report_Delete(Report *inst);
bool Report_Equals(Report repo1, Report repo2);
// Status ReportSender_Create(ReportSender *inst, Report *report, thrd_start_t *handler);
Status ReportSender_Create(ReportSender *inst, Report *report);
Status ReportSender_Send(ReportSender *inst, ReportTask task);
// ReportTaskStatus
// ReportSender_GetStatus(ReportSender *inst);
/* Add location parameter requirement in order to give proper information
* before throwing the report out. */
// # define throw(report) THROW(report, __HERE__)
// ReportTaskID THROW(Report report, Location loc);
// Report CATCH(ReportTaskID taskid, Status (*handler)());
int HANDLER(void *report);
#endif /* COMPOUND_REPORT_H */

161
test.c
View File

@@ -13,13 +13,164 @@ Status func(void)
__attribute__((constructor)) __attribute__((constructor))
void __CONSTRUCT__() { void __CONSTRUCT__() {
cat("Hello, Compound!\n"); cat("Hello, Compound!");
} }
__attribute__((destructor)) __attribute__((destructor))
void __DESTRUCT__() {} void __DESTRUCT__() {}
Status Main(void) Status Main(void)
{
return apply(NormalStatus);
}
Status MainArrayComparisonTest(void)
{
Array arr1 = EMPTY;
fail(Array_Create(&arr1, 10, 10));
Array arr2 = EMPTY;
fail(Array_Create(&arr2, 10, 10));
if (Array_Equals(&arr1, &arr2)) {
cat("Equal!");
} else {
cat("Not equal!");
}
Array_Delete(&arr2);
Array_Delete(&arr1);
return apply(NormalStatus);
}
Status MainMemoryOperationTest(void)
{
Memory mem = EMPTY;
fail(Memory_Create(&mem, sizeof(double)));
fail(Memory_Allocate(&mem));
(void)printf("%p:%ld\n", mem.addr, mem.size);
fail(Memory_Reallocate(&mem, sizeof(char)));
(void)printf("%p:%ld\n", mem.addr, mem.size);
fail(Memory_Release(&mem));
fail(Memory_Delete(&mem));
return apply(NormalStatus);
}
int tfunc(void)
{
vfail(apply(ErrorStatus), 1);
return 0;
}
Status MainMacroFailsTest(void)
{
unsure(apply(value(TraditionalFunctionReturn, tfunc())), _.value,
nest(_, __, fails(shift(__, STATUS_ERROR), "Failed on execution from tfunc.")));
return apply(NormalStatus);
}
Status MainArrayCreateAndDeleteWithModulatedMemberAccessing(void)
{
Array arr = EMPTY;
fail(Array_Create(&arr, 8, sizeof(int)));
for (register int i = 0; i < arr.len; i++) {
Var current = EMPTY;
// fails(Var_Create(&current, arr.members[0].size),
// "Failed to create Var current.");
state(!current.alive || !arr.members[i].alive,
apply(InvalidOperationBetweenAliveAndNonAlive));
assign(current, arr.members[i], int);
char buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
unsure(Var_Literalise(&current, buff), !_.value, {
return annot(_, "Failed to literalise Var current.");
})
(void)printf("%s\n", buff);
// Var_Delete(&current);
}
cat("Get:");
Var get = EMPTY;
fails(Var_Create(&get, arr.members[4].size), "Failed to create Var \"get\".");
state(!get.alive || !arr.members[4].alive,
apply(InvalidOperationBetweenAliveAndNonAlive));
assign(get, arr.members[4], int);
char buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
unsure(Var_Literalise(&get, buff), !_.value, {
return annot(_, "Failed to literalise Var current.");
})
Var_Delete(&get);
// Array_Delete(&arr);
return apply(NormalStatus);
}
Status MainArrayCreateAndDeleteWithTraditionalMemberAccessing(void)
{
// const int len = 8;
// int iarr[] = {
// 1, 2, 4, 8, 16, 32, 64, 128
// };
// Array arr;
// fails(Array_Create(&arr, len, sizeof(__typeof__(iarr[0]))),
// "Failed to create an array instance.");
// /* Array member assignments with iarr. */
// for (register int i = 0; i < arr.len; i++) {
// arr.members[i].addr = &iarr[i];
// }
// for (register int i = 0; i < arr.len; i++) {
// (void)printf("%d\n", i);
// for (register int j = 0; j < *(int *)arr.members[i].addr; j++) {
// (void)printf("#");
// }
// (void)printf("\n");
// }
// // Array_Delete(&arr);
Array arr = EMPTY;
fail(Array_Create(&arr, 8, sizeof(long long)));
for (register int i = 0; i < arr.len; i++) {
cast(arr.members[i], long long) = INT64_MAX;
(void)printf("%lld\n", cast(arr.members[i], long long));
}
Array_Delete(&arr);
return apply(NormalStatus);
}
Status MainStatus(void)
{ {
// Memory mem1; // Memory mem1;
// seek(Memory_Create(&mem1, INT64_MAX), { // seek(Memory_Create(&mem1, INT64_MAX), {
@@ -453,5 +604,11 @@ Status Main(void)
int main(void) int main(void)
{ {
return Main().value; int rtn = 0;
notok(Main(), {
rtn = _.value;
PrintStatusDump(_);
})
return rtn;
} }