Compare commits

...

2 Commits

18 changed files with 545 additions and 396 deletions

3
.gitignore vendored
View File

@@ -21,3 +21,6 @@ compile
todo todo
vsc* vsc*
libcompound.so libcompound.so
ccwarn
CMakeLists_default.txt
genwarn.sh

View File

@@ -4,7 +4,7 @@
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. */ /* Skip unavailable inst and invalid param. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state((len < 0), apply(InvalidArrayLength)); state((len < 0), apply(InvalidArrayLength));
solve((!len), { inst->len = 0; inst->members = NULL; return apply(NormalStatus); }) solve((!len), { inst->len = 0; inst->members = NULL; return apply(NormalStatus); })
@@ -49,8 +49,8 @@ Status Array_Create(Array *inst, int len, size_t size)
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, apply(UnavailableInstance)); // nonull(inst, apply(UnavailableInstance));
// fails(other, error(InvalidParameter, "Given other was unavailable.")); // nonull(other, error(InvalidParameter, "Given other was unavailable."));
// /* Assign value for len. */ // /* Assign value for len. */
// inst->len = other->len; // inst->len = other->len;
@@ -86,7 +86,7 @@ Status Array_CopyOf(Array *inst, Array *other)
Status Array_Delete(Array *inst) Status Array_Delete(Array *inst)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
solve((inst->members == NULL), return apply(NormalStatus)); solve((inst->members == NULL), return apply(NormalStatus));
inst->len = 0; inst->len = 0;
@@ -99,8 +99,8 @@ Status Array_Delete(Array *inst)
Status Array_GetIdx(Array *inst, Var *store, int index) Status Array_GetIdx(Array *inst, Var *store, int index)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(store, nonull(store,
apply(error(InvalidParameter, "Given reference to store was unavailable."))); apply(error(InvalidParameter, "Given reference to store was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound)); state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
@@ -112,8 +112,8 @@ Status Array_GetIdx(Array *inst, Var *store, int index)
Status Array_SetIdx(Array *inst, Var *source, int index) Status Array_SetIdx(Array *inst, Var *source, int index)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable inst and invalid param. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(source, nonull(source,
apply( apply(
error(InvalidParameter, "Given reference to source was unavailable."))); error(InvalidParameter, "Given reference to source was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound)); state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
@@ -142,8 +142,8 @@ bool Array_Equals(Array *a, Array *b)
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len) Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(elem, nonull(elem,
apply(error(InvalidParameter, "Given reference to elem was unavailable."))); apply(error(InvalidParameter, "Given reference to elem was unavailable.")));
state((off + len > inst->len) || (off < 0) || (len < 0), state((off + len > inst->len) || (off < 0) || (len < 0),
apply(ArrayIndexOutOfBound)); apply(ArrayIndexOutOfBound));

View File

@@ -2,7 +2,76 @@ cmake_minimum_required (VERSION 3.5)
project (Compound) project (Compound)
add_compile_options(-g -std=c99 -Wall -Wextra -Wformat) set(CMAKE_C_COMPILER gcc)
set(WALL -Waddress
-Warray-compare
-Warray-parameter=2
-Wbool-compare
-Wbool-operation
-Wchar-subscripts
-Wcomment
-Wdangling-else
-Wdangling-pointer=2
-Wenum-compare
-Wenum-int-mismatch
-Wformat=1
-Wformat-contains-nul
-Wformat-diag
-Wformat-extra-args
-Wformat-overflow=1
-Wformat-truncation=1
-Wformat-zero-length
-Wframe-address
-Wimplicit
-Wimplicit-function-declaration
-Wimplicit-int
-Winfinite-recursion
-Wint-in-bool-context
-Wlogical-not-parentheses
-Wmain
-Wmaybe-uninitialized
-Wmemset-elt-size
-Wmemset-transposed-args
-Wmisleading-indentation
-Wmismatched-dealloc
-Wmissing-attributes
-Wmissing-braces
-Wmultistatement-macros
-Wnonnull
-Wnonnull-compare
-Wopenmp-simd
-Wpacked-not-aligned
-Wparentheses
-Wpointer-sign
-Wrestrict
-Wreturn-type
-Wsequence-point
-Wsizeof-array-div
-Wsizeof-pointer-div
-Wsizeof-pointer-memaccess
-Wstrict-aliasing
-Wstrict-overflow=1
-Wswitch
-Wtautological-compare
-Wtrigraphs
-Wuninitialized
-Wunknown-pragmas
-Wunused
-Wunused-but-set-variable
-Wunused-const-variable=1
-Wunused-function
-Wunused-label
-Wunused-local-typedefs
-Wunused-value
-Wunused-variable
-Wuse-after-free=2
-Wvla-parameter
-Wvolatile-register-var
-Wzero-length-bounds
)
add_compile_options(-g -std=c99 ${WALL} -Wextra -D__DEBUG__)
set(SHARED_SOURCE set(SHARED_SOURCE
MemMan/src/memman.c MemMan/src/memman.c

View File

@@ -2,7 +2,7 @@
Status Memory_Create(Memory *inst, size_t size) Status Memory_Create(Memory *inst, size_t size)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
*inst = (Memory) { *inst = (Memory) {
.addr = NULL, .addr = NULL,
@@ -16,7 +16,7 @@ Status Memory_Create(Memory *inst, size_t size)
Status Memory_Allocate(Memory *inst) Status Memory_Allocate(Memory *inst)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state(inst->alive, apply(InstanceStillAlive)); state(inst->alive, apply(InstanceStillAlive));
/* When failed on allocating. */ /* When failed on allocating. */
@@ -28,7 +28,7 @@ Status Memory_Allocate(Memory *inst)
Status Memory_Reallocate(Memory *inst, size_t size) Status Memory_Reallocate(Memory *inst, size_t size)
{ {
fails(inst, apply(UnavailableBuffer)); nonull(inst, apply(UnavailableBuffer));
state(!inst->alive, apply(InstanceNotAlive)); state(!inst->alive, apply(InstanceNotAlive));
/* When failed on reallocating. */ /* When failed on reallocating. */
@@ -40,7 +40,7 @@ Status Memory_Reallocate(Memory *inst, size_t size)
Status Memory_Release(Memory *inst) Status Memory_Release(Memory *inst)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state(!inst->alive, state(!inst->alive,
apply(error(InstanceNotAlive, "Cannot release a non-alive instance."))); apply(error(InstanceNotAlive, "Cannot release a non-alive instance.")));
@@ -52,7 +52,7 @@ Status Memory_Release(Memory *inst)
Status Memory_Delete(Memory *inst) Status Memory_Delete(Memory *inst)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state(inst->alive, state(inst->alive,
apply( apply(
error(InstanceStillAlive, "Cannot deinitialise a instance still alive."))); error(InstanceStillAlive, "Cannot deinitialise a instance still alive.")));

View File

@@ -63,46 +63,18 @@ typedef struct _Status {
struct _Status *prev; struct _Status *prev;
} Status; } Status;
# define DEFSTATUS(i, v, d, c, p)\ # define DEFSTATUS(i, v, d, c, p) \
static const Status i = {\ static const Status i = { \
.identity = nameof(i),\ .identity = nameof(i), \
.value = v,\ .value = v, \
.description = d,\ .description = d, \
.characteristic = c,\ .characteristic = c, \
.loc = __GLOBAL__,\ .loc = __GLOBAL__, \
.prev = (Status *)p\ .prev = (Status *)p \
} }
/*
{value "description" characteristic prev}
"%d \"%s\" %d %p"
*/
/* line, func, file */
// # define LOCATION_LITERALISE_FORMAT "at line %d, in %s, %s"
/* file, line, func */
# define LOCATION_LITERALISE_FORMAT "at %s:%d, in function `%s\'" # define LOCATION_LITERALISE_FORMAT "at %s:%d, in function `%s\'"
# define LOCATION_LITERALISE_FORMAT_LENGTH 20
/* value, description, characteristic, prev */
// # define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p"
/* identity, prev->identity, value, characteristic, description, <loc> */
// # define STATUS_LITERALISE_FORMAT "%s (prev: %s): $=%d @=%d\n\t\"%s\"\n\t%s"
// MaximumLiteralisationLengthExceeded (prev: MaximumLengthExceeded): $=1 @=1
/*
MaximumLengthExceeded: "Buffer was too long."
predecessor=<ArrayLengthError> value=(1) characteristic=[1]
at line 40, in Main, /home/william/Documents/Projects/Compound/test.c
*/
// identity, description, prev->identity, value, characteristic, <loc>
# define STATUS_LITERALISE_FORMAT \ # 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"
@@ -116,7 +88,7 @@ typedef enum {
REPORT_SENDING_PRIORITY_MINOR, REPORT_SENDING_PRIORITY_MINOR,
REPORT_SENDING_PRIORITY_DEBUG, REPORT_SENDING_PRIORITY_DEBUG,
REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value. REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value.
} ReportSendingPriority; } ReportLevel;
typedef enum { typedef enum {
REPORT_SENDING_TASK_STATUS_FINISHED = 0, REPORT_SENDING_TASK_STATUS_FINISHED = 0,
@@ -124,21 +96,20 @@ typedef enum {
REPORT_SENDING_TASK_STATUS_PROCEEDING, REPORT_SENDING_TASK_STATUS_PROCEEDING,
REPORT_SENDING_TASK_STATUS_PAUSED, REPORT_SENDING_TASK_STATUS_PAUSED,
REPORT_SENDING_TASK_STATUS_NOTFOUND REPORT_SENDING_TASK_STATUS_NOTFOUND
} ReportSendingTaskStatus; } ReportStatus;
/* "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 status; Status content;
char *initiator; char *initiator;
time_t time; time_t time;
ReportSendingPriority priority; ReportLevel level;
ReportSendingTaskStatus taskprint_status; ReportStatus status;
FILE *dest; // The destination where the report is sending to. FILE *dst; // The destination where the report is sending to.
} Report; } Report;
/* /*
DATETIME [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
@@ -146,7 +117,7 @@ DATETIME [PRIORITY] STATUSNAME (ORIGINATOR): STATUS.DESCRIPTION
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buffer was unavailable. 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:104, Report_Literalise
at /external/Documents/Projects/Compound/Status/src/status.c:114, ReportSender_Send 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/Status/src/status.c:69, _throw
@@ -155,33 +126,29 @@ Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buf
*/ */
# define REPORT_LITERALISE_HEADER_FORMAT "%s [%s] %s (%s): %s" // DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
# define REPORT_LITERALISE_CHAINS_FORMAT " at %s:%d, %s" # define REPORT_LITERALISE_FORMAT_HEADER "%s [%d] %s (%s): %s\n\tat %s:%d, %s\n%s"
# define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT "!!!!at %s:%d, %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 { typedef enum {
REPORT_SENDER_RESULT_FINISHED, REPORT_RESULT_SUCCEEDED,
REPORT_SENDER_RESULT_PROGRESSING, REPORT_RESULT_FAILED,
REPORT_SENDER_RESULT_PENDING REPORT_RESULT_PROGRESSING,
} ReportSenderResult; REPORT_RESULT_PENDING,
} ReportResult;
typedef struct { typedef struct {
thrd_t thread; thrd_t thread;
Report *report; // The report for sending. Report report;
time_t elapsed; // The individual elapsed time for each report. (Array) time_t elapsed;
ReportSenderResult result; ReportResult result;
bool successful;
} ReportSender; } ReportSender;
typedef int (*ReportSendingTask)(Report *rep); typedef int (*ReportTask)(Report *);
typedef int ReportSendingTaskID; typedef int ReportTaskID;
typedef struct {
ReportSendingTask *tasks; // Array Ref
int sendercount;
int finishedcount;
int *results; // Array
} ReportSendingManager;
// typedef thrd_start_t ArgueStart; // typedef thrd_start_t ArgueStart;
@@ -218,8 +185,10 @@ typedef struct {
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);
bool StatusUtils_HasPrev(Status inst); bool StatusUtils_HasPrev(Status inst);
bool StatusUtils_IsOkay(Status inst); bool StatusUtils_IsOkay(Status inst);
bool StatusUtils_IsRecursive(Status inst); bool StatusUtils_IsRecursive(Status inst);
@@ -232,16 +201,12 @@ Status Report_Literalise(Report *inst, char *buff);
void Report_Delete(Report *inst); void Report_Delete(Report *inst);
bool Report_Equals(Report repo1, Report repo2); 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_Create(ReportSender *inst, Report *report);
Status ReportSender_Send(ReportSender *inst, ReportSendingTask task); Status ReportSender_Send(ReportSender *inst, ReportTask task);
// ReportSendingTaskStatus
// ReportSender_GetStatus(ReportSender *inst);
ReportSendingTaskID // ReportTaskStatus
ReportSenderManager_AppendTask(ReportSendingManager *inst, // ReportSender_GetStatus(ReportSender *inst);
ReportSendingTask task);
Status ReportSenderManager_RemoveTask(ReportSendingManager *inst,
ReportSendingTaskID taskid);
// Status // Status
// arguestarter_create(ArgueStartParam *inst, void *external_param); // arguestarter_create(ArgueStartParam *inst, void *external_param);
@@ -315,6 +280,10 @@ DEFSTATUS(RuntimeError, 1,
"A runtime error occurred.", "A runtime error occurred.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceCreatingFailure, 1,
"Cannot create the instance.",
STATUS_ERROR, &RuntimeError);
DEFSTATUS(ArrayLengthError, 1, DEFSTATUS(ArrayLengthError, 1,
"Given array length does not meet the requirement.", "Given array length does not meet the requirement.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
@@ -403,72 +372,89 @@ DEFSTATUS(InvalidLiteralisingBuffer, 1,
"Given buffer does not have a good integrity on its length.", "Given buffer does not have a good integrity on its length.",
STATUS_ERROR, &InvalidObject); STATUS_ERROR, &InvalidObject);
DEFSTATUS(NoBytesWereRead, 1,
"Called function had returned ZERO indicating no bytes were read.",
STATUS_ERROR, &ReadWriteError);
DEFSTATUS(NoBytesWereWritten, 1,
"Called function had returned ZERO indicating no bytes were written.",
STATUS_ERROR, &ReadWriteError);
// DEFSTATUS(ProgrammeConstructionError, 1,
// "Failed on constructing programme at the entrance.",
// STATUS_ERROR, &RuntimeError);
// ======================================================== // ========================================================
static inline Status PrintStatus(Status s) static inline Status PrintStatus(Status s)
{ {
/* Literalise. */
char buff[LITERALISATION_LENGTH_MAXIMUM]; char buff[LITERALISATION_LENGTH_MAXIMUM];
(void)Status_Literalise(&s, buff);
/* Handle returning value. */
/* No bytes were written to buffer. */
unsure(Status_Literalise(&s, buff), !_.value, {
return apply(NoBytesWereWritten);
})
/* Output. */
where(fprintf(stderr, "%s\n", buff), { where(fprintf(stderr, "%s\n", buff), {
/* Pass on returning value. */
return apply(value(TraditionalFunctionReturn, _)); return apply(value(TraditionalFunctionReturn, _));
}) })
} }
static inline void PrintStatusDump(Status s) static inline void PrintStatusDump(Status s)
{ {
Status stat = s; /* Create dump. */
const int dump_len = StatusUtils_Depth(&stat); const int dump_len = StatusUtils_Depth(&s);
Status dump[dump_len]; Status dump[dump_len];
StatusUtils_Dump(&stat, dump, 0); Status current = s;
/* TODO(william): Replace following line with coloured-term-output function. */ dump[0] = current; // Put self at leading.
(void)printf("\e[1m======== STATUS STACK DUMP: %s ========\e[0m\n", for (register int i = 1; i < dump_len; i++) {
stat.identity); // StatusUtils_Dump will only access (storage) the prev.
// It does not include this status itself.
StatusUtils_Dump(&current, &dump[i]);
current = *current.prev;
}
/* Output by iterating. */
for (register int i = 0; i < dump_len; i++) { for (register int i = 0; i < dump_len; i++) {
/* TODO(william): Replace following line with coloured-term-output function. */
(void)printf("\e[1m[%d/%d]\e[0m\n", (dump_len - i), dump_len); unsure(PrintStatus(dump[i]), !_.value, {
seek(PrintStatus(dump[i]), { (void)fprintf(stderr, "Unable to literalise.\n");
solve(!_.value, {
(void)fprintf(stderr, "\e[38;5;9m!!!!!!!! PRINT DUMP FAILED !!!!!!!!"
"\e[0m\n");
(void)PrintStatus(_);
})
}) })
// 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;
// }));
// });
} }
} }
// ======================================================== // ========================================================
/* Throw the report created with $e if $e is abnormal, commented with $c. */
# define ensure(e, c) { \
Status stat = e; \
solve(!(StatusUtils_IsOkay(stat)), { \
Report rep = stamp(error(stat, c), (char *)__func__); \
(void)throw(rep); \
return ReportThrown; \
}) \
}
/* Throw the report created with $s if $e is abnormal, commented with $c. */
# define match(s, e, c) { \
Status stat = s; \
solve(!(StatusUtils_IsOkay(e)), { \
Report rep = stamp(error(stat, c), (char *)__func__); \
(void)throw(rep); \
return ReportThrown; \
}) \
}
/* Add location parameter requirement in order to give proper information /* Add location parameter requirement in order to give proper information
* before throwing the report out. */ * before throwing the report out. */
# define throw(report) THROW(report, __HERE__) // # define throw(report) THROW(report, __HERE__)
/* Useless in C, only for human to see. /* Useless in C, only for human to see.
Probably rewrite this in Classify. */ Probably rewrite this in Classify. */
# define throws(e) # define throws(e)
ReportSendingTaskID THROW(Report report, Location loc); // ReportTaskID THROW(Report report, Location loc);
Report CATCH(ReportSendingTaskID taskid); // Report CATCH(ReportTaskID taskid, Status (*handler)());
int HANDLER(void *report); int HANDLER(void *report);
#endif /* COMPOUND_STATUS_H */ #endif /* COMPOUND_STATUS_H */

View File

@@ -2,30 +2,18 @@
Status Location_Literalise(Location *inst, char *buff) Status Location_Literalise(Location *inst, char *buff)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(buff, apply(UnavailableBuffer)); nonull(buff, apply(UnavailableBuffer));
/* Literalise line. */ /* Literalise line. */
char line_buff[LITERALISATION_LENGTH_MAXIMUM]; char line_buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
Utils_LiteraliseInteger(inst->line, line_buff); Utils_LiteraliseInteger(inst->line, line_buff);
/* Concatenate every buff. */
const long total_len = strlen(strnil(inst->file)) + strlen(strnil(line_buff))
+ strlen(strnil(inst->func))
+ LOCATION_LITERALISE_FORMAT_LENGTH;
state(total_len > LITERALISATION_LENGTH_MAXIMUM, where(
apply(MaximumLiteralisationLengthExceeded)); snprintf(buff, LITERALISATION_LENGTH_MAXIMUM,
LOCATION_LITERALISE_FORMAT,inst->file,inst->line,inst->func),
/* Copy and assign. */ return apply(value(TraditionalFunctionReturn, _));
// return value(UnknownStatus, );
// !sprintf(buff, LOCATION_LITERALISE_FORMAT,
// inst->file, inst->line, inst->func));
const int written =
sprintf(buff, LOCATION_LITERALISE_FORMAT,inst->file,inst->line,inst->func);
// written in "value" is absolutely ZERO.
state(!written, apply(value(UnknownStatus, written)));
return apply(NormalStatus); return apply(NormalStatus);
} }
@@ -56,12 +44,14 @@ bool Status_Equal(Status *stat1, Status *stat2)
Status Status_Literalise(Status *inst, char *buff) Status Status_Literalise(Status *inst, char *buff)
{ {
/* Skip unavailable instance and invalid parameter. */ /* Skip unavailable instance and invalid parameter. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(buff, apply(UnavailableBuffer)); nonull(buff, apply(UnavailableBuffer));
/* Literalise loc. */ /* Literalise loc. */
char loc_buff[LITERALISATION_LENGTH_MAXIMUM]; char loc_buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
notok(Location_Literalise(&inst->loc, loc_buff), { (void)printf("%s\n", loc_buff);
unsure(Location_Literalise(&inst->loc, loc_buff), !_.value, {
(void)printf("failed on loc liter.\n");
return apply(_); return apply(_);
}); });
@@ -80,13 +70,28 @@ Status Status_Literalise(Status *inst, char *buff)
} }
/* Concatenate every buffer. */ /* Concatenate every buffer. */
where(sprintf(buff, fmt, inst->identity, inst->description, where(
(!inst->prev snprintf(buff, LITERALISATION_LENGTH_MAXIMUM, fmt, inst->identity,
? "(null)" inst->description,
: (inst->prev->identity)), (!inst->prev ? "(null)" : (inst->prev->identity)),
inst->value, inst->characteristic, loc_buff), { inst->value, inst->characteristic, loc_buff), {
return apply(value(TraditionalFunctionReturn, _)); return apply(value(TraditionalFunctionReturn, _));
}) });
}
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)
@@ -104,64 +109,96 @@ bool StatusUtils_IsRecursive(Status stat)
return (stat.prev && stat.prev == &stat); return (stat.prev && stat.prev == &stat);
} }
void StatusUtils_Dump(Status *inst, Status *store, int idx) void StatusUtils_Dump(Status *inst, Status *store)
{ {
/* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */ /* Skip when store is unavailable, or, inst is unavailable,
svoid((!inst || !store || idx < 0)); recursive or does not have any predecessor. */
svoid(!inst || !store
store[idx] = *inst; || StatusUtils_IsRecursive(*inst) || !StatusUtils_HasPrev(*inst));
StatusUtils_Dump(inst->prev, store, ++idx); *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. */
state((!stat || !stat->prev), -1); state((!stat || !stat->prev), -1);
Status *p = stat; // Include this layer of Status. /* Set up counter. */
register int cnt; int cnt = 1;
for (cnt = 0; (!StatusUtils_IsRecursive(*p) /* Set up current status indication representor. */
&& StatusUtils_HasPrev(*p)); cnt++) { Status current = *stat;
p = p->prev; /* Iterate to accumulate. */
while (current.prev) {
current = *current.prev;
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, Status Report_Create(Report *inst, Status *stat, FILE *dest, char *initiator,
int priority) int priority)
{ {
/* Skip unavailable parameters. */ /* Skip unavailable parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(stat, apply(error(InvalidParameter, "Given stat was null."))); nonull(stat, apply(error(InvalidParameter, "Given stat was null.")));
fails(initiator, apply(error(InvalidParameter, "Given initiator was null."))); nonull(initiator, apply(error(InvalidParameter, "Given initiator was null.")));
state(priority < 0, apply(error(InvalidParameter, "Given priority was negative."))); state(priority < 0, apply(error(InvalidParameter, "Given priority was negative.")));
/* Copy and assign. */ /* Copy and assign. */
inst->status = *stat; inst->content = *stat;
inst->initiator = calloc(strlen(initiator), sizeof(char)); inst->initiator = calloc(strlen(initiator), sizeof(char));
(void)strcpy(inst->initiator, initiator); (void)strcpy(inst->initiator, initiator);
inst->time = time(NULL); inst->time = time(NULL);
inst->priority = priority; inst->level = priority;
inst->taskprint_status = REPORT_SENDING_TASK_STATUS_PENDING; inst->status = REPORT_SENDING_TASK_STATUS_PENDING;
inst->dest = (dest == NULL ? stdout : dest); inst->dst = (dest == NULL ? stdout : dest);
return apply(NormalStatus); return apply(NormalStatus);
} }
Status Report_CopyOf(Report *inst, Report *other) Status Report_CopyOf(Report *inst, Report *other)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(other, apply(error(InvalidParameter, "Given report is unavailable."))); nonull(other, apply(error(InvalidParameter, "Given report is unavailable.")));
// Status status; // Status status;
// char *initiator; // char *initiator;
// time_t time; // time_t time;
// ReportSendingPriority priority; // ReportLevel priority;
// ReportSendingTaskStatus taskprint_status; // ReportTaskStatus taskprint_status;
// FILE *dest; // FILE *dest;
inst->status = other->status; inst->content = other->content;
return apply(NormalStatus); return apply(NormalStatus);
} }
@@ -172,94 +209,98 @@ void Report_Delete(Report *inst)
free(inst->initiator); free(inst->initiator);
inst->initiator = NULL; inst->initiator = NULL;
inst->dest = NULL; inst->dst = NULL;
inst->priority = 0; inst->level = 0;
inst->status = (Status){}; inst->content = (Status){};
inst->taskprint_status = REPORT_SENDING_TASK_STATUS_NOTFOUND; inst->status = REPORT_SENDING_TASK_STATUS_NOTFOUND;
inst->time = 0; inst->time = 0;
inst = NULL; inst = NULL;
} }
/*
Status status;
char *initiator;
time_t time;
ReportLevel priority;
ReportTaskStatus taskprint_status;
FILE *dest;
*/
Status Report_Literalise(Report *inst, char *buff) Status Report_Literalise(Report *inst, char *buff)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(buff, apply(UnavailableBuffer)); nonull(buff, apply(UnavailableBuffer));
// state(strlen(buff) != LITERALISATION_LENGTH_MAXIMUM,
// InvalidLiteralisingBuffer);
/* Report literalisation. */
int idx = 0;
char report_literalising[LITERALISATION_LENGTH_MAXIMUM];
/** Status literalisation. **/
char status_literalising[LITERALISATION_LENGTH_MAXIMUM];
(void)Status_Literalise(&inst->status, status_literalising);
idx += strlen(status_literalising);
/** fin **/
/** Initiator literalisation. **/
idx += strlen(inst->initiator);
/** fin **/
/** Time literalisation. **/
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 **/
/** Taskprint_status literalisation. **/
char taskprint_status_literalising[LITERALISATION_LENGTH_MAXIMUM];
idx += Utils_LiteraliseInteger(inst->taskprint_status, taskprint_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;
}
strcpy(report_literalising, status_literalising); /* Report literalisation. */
strcpy(report_literalising, time_literalising); char report_literalising[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
strcpy(report_literalising, priority_literalising);
strcpy(report_literalising, taskprint_status_literalising); /** Status literalisation. **/
strcpy(report_literalising, dest_literalising); 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)), )
strcpy(buff, report_literalising); // DATETIME [LEVEL] STATUS.IDENTITY (INITIATOR): STATUS.DESCRIPTION
/* fin */ 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); return apply(NormalStatus);
} }
/*
thrd_t thread;
Report report;
time_t elapsed;
ReportResult result;
*/
Status ReportSender_Create(ReportSender *inst, Report *report) Status ReportSender_Create(ReportSender *inst, Report *report)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(report, error(UnavailableParameter, "Given report was unavailable.")); nonull(report, error(UnavailableParameter, "Given report was unavailable."));
thrd_create(&inst->thread, &HANDLER, report); thrd_create(&inst->thread, &HANDLER, report);
notok(Report_CopyOf(inst->report, report), notok(Report_CopyOf(&inst->report, report),
return error(ErrorStatus, "Cannot copy to create new instance of report."); return apply(annot(InstanceCreatingFailure,
) // *inst->report = *report; "Cannot copy to create new instance of report."));
);
inst->report = *report;
inst->elapsed = 0; inst->elapsed = 0;
inst->result = REPORT_SENDER_RESULT_PENDING; inst->result = REPORT_RESULT_PENDING;
inst->successful = false;
return apply(NormalStatus); return apply(NormalStatus);
} }
Status ReportSender_Send(ReportSender *inst, ReportSendingTask task) Status ReportSender_Send(ReportSender *inst, ReportTask task)
{ {
// /* Skip when inst or task is unavailable. */ // /* Skip when inst or task is unavailable. */
// fails(inst, // nonull(inst,
// error(UnavailableInstance, "Report sender was given unavailable.")); // error(UnavailableInstance, "Report sender was given unavailable."));
// fails(task, InvalidReportTask); // nonull(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);
@@ -284,7 +325,7 @@ 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) ReportTaskID THROW(Report report, Location loc)
{ {
// // /* Create new a instance of ReportSender. */ // // /* Create new a instance of ReportSender. */
// // ReportSender sender; // // ReportSender sender;

View File

@@ -13,7 +13,11 @@ typedef enum {
/* etc. */ /* etc. */
} StringEncoding; } StringEncoding;
typedef Array(Char) String; // typedef Array(Char) String;
typedef struct {
Array type(Char) data;
StringEncoding encoding;
} String;
/* Elementary. */ /* Elementary. */
Status String_Create(String *inst, int len); Status String_Create(String *inst, int len);
@@ -24,71 +28,75 @@ Status String_SetIdx(String *inst, Char *item, int index);
Status String_Literalise(String *inst, String *store); Status String_Literalise(String *inst, String *store);
/* Extensional. */ /* Extensional. */
Status StringUtils_FromInteger(String *inst, int value); Status StringUtils_FromInteger(String *inst, int value, int base);
Status StringUtils_FromShortInteger(String *inst, short int value); Status StringUtils_FromShortInteger(String *inst, short int value, int base);
Status StringUtils_FromLongInteger(String *inst, long int value); Status StringUtils_FromLongInteger(String *inst, long int value, int base);
Status StringUtils_FromLongLongInteger(String *inst, long long int value); Status StringUtils_FromLongLongInteger(String *inst, long long int value, int base);
Status StringUtils_FromFloat(String *inst, float value); Status StringUtils_FromFloat(String *inst, float value, int base);
Status StringUtils_FromDouble(String *inst, double value); Status StringUtils_FromDouble(String *inst, double value, int base);
Status StringUtils_FromLongDouble(String *inst, long double value); Status StringUtils_FromLongDouble(String *inst, long double value, int base);
Status StringUtils_FromComplexInteger(String *inst, _Complex int value); Status StringUtils_FromComplexInteger(String *inst, _Complex int value, int base);
Status StringUtils_FromComplexShortInteger(String *inst, _Complex short int value); Status StringUtils_FromComplexShortInteger(String *inst, _Complex short int value, int base);
Status StringUtils_FromComplexLongInteger(String *inst, _Complex long int value); Status StringUtils_FromComplexLongInteger(String *inst, _Complex long int value, int base);
Status StringUtils_FromComplexLongLongInteger(String *inst, _Complex long long value); Status StringUtils_FromComplexLongLongInteger(String *inst, _Complex long long value, int base);
Status StringUtils_FromComplexFloat(String *inst, _Complex float value); Status StringUtils_FromComplexFloat(String *inst, _Complex float value, int base);
Status StringUtils_FromComplexDouble(String *inst, _Complex double value); Status StringUtils_FromComplexDouble(String *inst, _Complex double value, int base);
Status StringUtils_FromComplexLongDouble(String *inst, _Complex long double value); Status StringUtils_FromComplexLongDouble(String *inst, _Complex long double value, int base);
Status StringUtils_FromUnsignedInteger(String *inst, unsigned int value); Status StringUtils_FromUnsignedInteger(String *inst, unsigned int value, int base);
Status StringUtils_FromUnsignedShortInteger(String *inst, unsigned short int value); Status StringUtils_FromUnsignedShortInteger(String *inst, unsigned short int value, int base);
Status StringUtils_FromUnsignedLongInteger(String *inst, unsigned long int value); Status StringUtils_FromUnsignedLongInteger(String *inst, unsigned long int value, int base);
Status StringUtils_FromUnsignedLongLongInteger(String *inst, unsigned long long int value); Status StringUtils_FromUnsignedLongLongInteger(String *inst, unsigned long long int value, int base);
Status StringUtils_FromUnsignedComplexInteger(String *inst, unsigned _Complex int value); Status StringUtils_FromUnsignedComplexInteger(String *inst, unsigned _Complex int value, int base);
Status StringUtils_FromUnsignedComplexShortInteger(String *inst, unsigned _Complex short int value); Status StringUtils_FromUnsignedComplexShortInteger(String *inst, unsigned _Complex short int value, int base);
Status StringUtils_FromUnsignedComplexLongInteger(String *inst, unsigned _Complex long int value); Status StringUtils_FromUnsignedComplexLongInteger(String *inst, unsigned _Complex long int value, int base);
Status StringUtils_FromUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long value); Status StringUtils_FromUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long value, int base);
Status StringUtils_FromAddress(String *inst, void *store); Status StringUtils_FromAddress(String *inst, void *store);
Status StringUtils_FromCharBuff(String *inst, char const *buff, int base); Status StringUtils_FromCharBuff(String *inst, char const *buff);
Status StringUtils_FromWideCharBuff(String *inst, wchar_t const *wbuff, int base); Status StringUtils_FromWideCharBuff(String *inst, wchar_t const *wbuff);
Status StringUtils_ToInteger(String *inst, int *store); Status StringUtils_ToInteger(String *inst, int *store, int base);
Status StringUtils_ToShortInteger(String *inst, short int *store); Status StringUtils_ToShortInteger(String *inst, short int *store, int base);
Status StringUtils_ToLongInteger(String *inst, long int *store); Status StringUtils_ToLongInteger(String *inst, long int *store, int base);
Status StringUtils_ToLongLongInteger(String *inst, long long int *store); Status StringUtils_ToLongLongInteger(String *inst, long long int *store, int base);
Status StringUtils_ToFloat(String *inst, float *store); Status StringUtils_ToFloat(String *inst, float *store, int base);
Status StringUtils_ToDouble(String *inst, double *store); Status StringUtils_ToDouble(String *inst, double *store, int base);
Status StringUtils_ToLongDouble(String *inst, long double *store); Status StringUtils_ToLongDouble(String *inst, long double *store, int base);
Status StringUtils_ToComplexInteger(String *inst, _Complex int *store); Status StringUtils_ToComplexInteger(String *inst, _Complex int *store, int base);
Status StringUtils_ToComplexShortInteger(String *inst, _Complex short int *store); Status StringUtils_ToComplexShortInteger(String *inst, _Complex short int *store, int base);
Status StringUtils_ToComplexLongInteger(String *inst, _Complex long int *store); Status StringUtils_ToComplexLongInteger(String *inst, _Complex long int *store, int base);
Status StringUtils_ToComplexLongLongInteger(String *inst, _Complex long long *store); Status StringUtils_ToComplexLongLongInteger(String *inst, _Complex long long *store, int base);
Status StringUtils_ToComplexFloat(String *inst, _Complex float *store); Status StringUtils_ToComplexFloat(String *inst, _Complex float *store, int base);
Status StringUtils_ToComplexDouble(String *inst, _Complex double *store); Status StringUtils_ToComplexDouble(String *inst, _Complex double *store, int base);
Status StringUtils_ToUnsignedInteger(String *inst, unsigned int *store); Status StringUtils_ToUnsignedInteger(String *inst, unsigned int *store, int base);
Status StringUtils_ToUnsignedShortInteger(String *inst, unsigned short int *store); Status StringUtils_ToUnsignedShortInteger(String *inst, unsigned short int *store, int base);
Status StringUtils_ToUnsignedLongInteger(String *inst, unsigned long int *store); Status StringUtils_ToUnsignedLongInteger(String *inst, unsigned long int *store, int base);
Status StringUtils_ToUnsignedLongLongInteger(String *inst, unsigned long long int *store); Status StringUtils_ToUnsignedLongLongInteger(String *inst, unsigned long long int *store, int base);
Status StringUtils_ToUnsignedComplexInteger(String *inst, unsigned _Complex int *store); Status StringUtils_ToUnsignedComplexInteger(String *inst, unsigned _Complex int *store, int base);
Status StringUtils_ToUnsignedComplexShortInteger(String *inst, unsigned _Complex short int *store); Status StringUtils_ToUnsignedComplexShortInteger(String *inst, unsigned _Complex short int *store, int base);
Status StringUtils_ToUnsignedComplexLongInteger(String *inst, unsigned _Complex long int *store); Status StringUtils_ToUnsignedComplexLongInteger(String *inst, unsigned _Complex long int *store, int base);
Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long *store); Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long *store, int base);
Status StringUtils_ToAddress(String *inst, void **store); Status StringUtils_ToAddress(String *inst, void **store);
Status StringUtils_ToCharBuff(String *inst, char const *buff, int base); Status StringUtils_ToCharBuff(String *inst, char const *buff);
Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff, int base); Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff);
Status StringUtils_Format(String *inst, const String *restrict fmt, ...); // 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) Status String_Encode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError);
throws(UnsupportedEncoding EncodingError DecodingError); Status String_Decode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError);
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 = {
.identity = nameof(StringConversionPrecisionError),
.value = 1, .value = 1,
.description = "Unpreventable precision loss was found during conversion " .description = "Unpreventable precision loss was found during conversion "
"between string and raw data.", "between string and raw data.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ImprecisionError .loc = __GLOBAL__,
.prev = (Status *)&ImprecisionError
}; };
// # define string(str) ((String) {\
// .data =
// })
typedef Array(int) InfiniteInteger; typedef Array(int) InfiniteInteger;
typedef Array(double) InfiniteFloatingPoint; typedef Array(double) InfiniteFloatingPoint;
typedef Array(_Complex double) InfintieComplex; typedef Array(_Complex double) InfintieComplex;

View File

@@ -10,35 +10,35 @@ Status String_Create(String *inst, int len)
Status String_CopyOf(String *inst, String *other) Status String_CopyOf(String *inst, String *other)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
return apply(NormalStatus); return apply(NormalStatus);
} }
Status String_Delete(String *inst) Status String_Delete(String *inst)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
return apply(NormalStatus); return apply(NormalStatus);
} }
Status String_GetAt(String *inst, Char *store, int index) Status String_GetAt(String *inst, Char *store, int index)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
return apply(NormalStatus); return apply(NormalStatus);
} }
Status String_SetAt(String *inst, Char *source, int index) Status String_SetAt(String *inst, Char *source, int index)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
return apply(NormalStatus); return apply(NormalStatus);
} }
Status String_Literalise(String *inst, String *store) Status String_Literalise(String *inst, String *store)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
return apply(NormalStatus); return apply(NormalStatus);
} }

View File

@@ -19,6 +19,8 @@ int Utils_CalcDigits(long long int n);
int Utils_LiteraliseInteger(long long int n, char *buff); int Utils_LiteraliseInteger(long long int n, char *buff);
int Utils_DateTimeLiteralise(time_t t, char *buff); // int Utils_DateTimeLiteralise(time_t t, char *buff);
int Utils_DateTimeLiteralise(time_t timer, char *buff,
const char *__restrict format);
#endif /* COMPOUND_UTILS_H */ #endif /* COMPOUND_UTILS_H */

View File

@@ -42,8 +42,8 @@ int Utils_LiteraliseInteger(long long int n, char *buff)
return literalising_len; return literalising_len;
} }
int Utils_DateTimeLiteralise(time_t t, char *buff) int Utils_DateTimeLiteralise(time_t timer, char *buff,
const char *__restrict format)
{ {
return 0;
} }

View File

@@ -2,7 +2,7 @@
Status Var_Create(Var *inst, size_t size) Status Var_Create(Var *inst, size_t size)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state(inst->alive, apply(InstanceStillAlive)); state(inst->alive, apply(InstanceStillAlive));
state(!size, state(!size,
apply(normal(NormalStatus, "Exited with given parameter size as ZERO."))); apply(normal(NormalStatus, "Exited with given parameter size as ZERO.")));
@@ -17,9 +17,9 @@ Status Var_Create(Var *inst, size_t size)
// Status Var_Create(Var *inst, void *addr, size_t size, char *identity) // Status Var_Create(Var *inst, void *addr, size_t size, char *identity)
// { // {
// /* Skip when inst is unavailable. */ // /* Skip when inst is unavailable. */
// fails(inst, apply(UnavailableInstance)); // nonull(inst, apply(UnavailableInstance));
// /* Skip when identity is unavailable. */ // /* Skip when identity is unavailable. */
// fails(identity, NullPointerAccounted); // nonull(identity, NullPointerAccounted);
// /* Skip when identity does not pass the examine. */ // /* Skip when identity does not pass the examine. */
// state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity); // state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity);
@@ -33,9 +33,9 @@ Status Var_Create(Var *inst, size_t size)
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, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state(inst->alive, apply(InstanceStillAlive)); state(inst->alive, apply(InstanceStillAlive));
fails(other, apply(InvalidParameter)); nonull(other, apply(InvalidParameter));
/* Copy members from other. Only has to apply size, no addr is needed. */ /* Copy members from other. Only has to apply size, no addr is needed. */
state(!((inst->addr = malloc(other->size))), apply(InsufficientMemory)); state(!((inst->addr = malloc(other->size))), apply(InsufficientMemory));

4
attr.h
View File

@@ -3,8 +3,8 @@
# include <Compound/name.h> # include <Compound/name.h>
typedef struct _Attribute{ typedef struct _Attribute {
int serialNo; Name identity; // Numeral accumulative, not literal descriptive.
int (*exec)(void *); int (*exec)(void *);
struct _Attribute *prev; struct _Attribute *prev;
} attr(Executive) Attribute; } attr(Executive) Attribute;

View File

@@ -7,7 +7,7 @@ Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
char *initiator, char *msg) char *initiator, char *msg)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state((initiator == NULL || msg == NULL), apply(InvalidParameter)); state((initiator == NULL || msg == NULL), apply(InvalidParameter));
inst->time = time(NULL); inst->time = time(NULL);
@@ -21,8 +21,8 @@ Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other) Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(other, apply(InvalidParameter)); nonull(other, apply(InvalidParameter));
*inst = *other; *inst = *other;
@@ -45,8 +45,8 @@ bool CatlogMsg_Equals(CatlogMsg *inst, CatlogMsg *other)
Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst) Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(msg, apply(InvalidParameter)); nonull(msg, apply(InvalidParameter));
/* Copy and assign. */ /* Copy and assign. */
inst->msg = *msg; inst->msg = *msg;
@@ -60,8 +60,8 @@ Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst)
Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other) Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(other, apply(InvalidParameter)); nonull(other, apply(InvalidParameter));
/* Copy and assign */ /* Copy and assign */
inst->msg = other->msg; inst->msg = other->msg;
@@ -89,7 +89,7 @@ bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other)
Status CatlogSender_Send(CatlogSender *inst) Status CatlogSender_Send(CatlogSender *inst)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
const int written = fprintf(inst->dst, "%s\n", inst->msg.content); const int written = fprintf(inst->dst, "%s\n", inst->msg.content);
@@ -103,9 +103,9 @@ Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath,
const char const *restrict mode) const char const *restrict mode)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
fails(fileptr, apply(UnavailableBuffer)); nonull(fileptr, apply(UnavailableBuffer));
fails(filepath, apply(UnavailableFileName)); nonull(filepath, apply(UnavailableFileName));
fails(mode, apply(UnavailableFileAccessMode)); nonull(mode, apply(UnavailableFileAccessMode));
/* Open the file. Return CatCannotOpenFile once failed. */ /* Open the file. Return CatCannotOpenFile once failed. */
state(!(*fileptr = fopen(filepath, mode)), apply(CatCannotOpenFile)); state(!(*fileptr = fopen(filepath, mode)), apply(CatCannotOpenFile));

136
common.h
View File

@@ -1,67 +1,102 @@
#ifndef COMPOUND_COMMON_h #ifndef COMPOUND_COMMON_H
# define COMPOUND_COMMON_h # define COMPOUND_COMMON_H
// # define __DEBUG__ 1
# ifdef __DEBUG__
# warning DEBUG IS ON
# endif /* __DEBUG__ */
# include <stdlib.h> # include <stdlib.h>
# include <stdbool.h> # include <stdbool.h>
# define EMPTY {0}
/* Get the literal. */ /* Get the literal. */
# define nameof(obj) #obj # define nameof(obj) #obj
/* Return $n as the return value, once $o is NULL. */ /* Return n as the return value, once o is NULL. */
# define fails(o, n) { if (!o) return (n); } # define nonull(o, n) { if (!o) return (n); }
/* Return $e as the return value, once $v equals $e. */ /* Return e as the return value, once v equals e. */
# define trans(v, e) { if ((v) == (e)) return (e); } # define trans(v, e) { if ((v) == (e)) return (e); }
/* Evaluate given statement while the ptr to $s is not NULL. */ /* Evaluate given statement while the ptr to s is not NULL. */
# define state(s, n) { if ((s)) return (n); } # define state(s, n) { if ((s)) return (n); }
/* Evaluate given statement while the ptr to $s is not NULL. */ /* Evaluate given statement while the ptr to s is not NULL. */
# define svoid(s) { if ((s)) return; } # define svoid(s) { if ((s)) return; }
/* Another way to handle if statements more cleanly. */ /* Another way to handle if statements more cleanly. */
# define solve(s, b) { if (s) b } # define solve(s, b) { if (s) b }
/* Handling expression with its result. */ /* Handling expression with its result. */
# define when(expr, b) { int _ = expr; if (expr) b } # define when(expr, b) { int _ = expr; if (_) b }
/* Handling expression with its calculated result. */ /* Handling expression with its precalculated result. */
# define where(expr, b) { int _ = expr; b } # define where(expr, b) { int _ = expr; b }
/* Execute b whenever finds s is "okay". */
# define ok(s, b) { Status _ = s; if (StatusUtils_IsOkay(_)) b } # define ok(s, b) { Status _ = s; if (StatusUtils_IsOkay(_)) b }
/* 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. */
# define fails(e, c) { notok(e, return apply(annot(_, c));) }
/* Return v when passing a failing e. */
# define vfail(e, v) { notok(e, return v;) }
/* Execute b for handling UnknownStatus (TraditionalFunctionReturn). */
# define unsure(s, expr, b) { Status _ = s; \
if (_.characteristic < 0 && (expr)) b }
/* Execute b whatsoever with s stored. */
# define seek(s, b) { Status _ = s; b } # define seek(s, b) { Status _ = s; b }
/* Combinates seek and solve. */
# define settle(e, s, b) seek(e, solve(s, b))
/* Clone a new varaible "v2" with "v1". */
# define clone(v1, v2) __typeof__(v1) v2 = v1;
/* Allows different macros using "_" nested with each other. */
# define nest(v1, v2, b) { clone(v1, v2) b }
// # define lambda(param, body, capfmt, ...) {\
// /* Duplicate everything from cap. */\
// va_list ptr;\
// va_start(ptr, capfmt);\
// __typeof__(ptr) \
// va_end(ptr);\
// }
/* 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 = e.identity,\ .identity = nameof(e),\
.value = v,\ .value = v,\
.description = c,\ .description = c,\
.characteristic = STATUS_UNKNOWN,\ .characteristic = STATUS_UNKNOWN,\
.loc = __HERE__,\ .loc = e.loc,\
.prev = e.prev\ .prev = e.prev\
}) })
/* 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 = e.identity,\ .identity = nameof(e),\
.value = 0,\ .value = 0,\
.description = c,\ .description = c,\
.characteristic = STATUS_NORMAL,\ .characteristic = STATUS_NORMAL,\
.loc = __HERE__,\ .loc = e.loc,\
.prev = e.prev\ .prev = e.prev\
}) })
/* Create a new ErrorStatus on the fly. */ /* Create a new ErrorStatus on the fly. */
# define error(e, c) ((Status) {\ # define error(e, c) ((Status) {\
.identity = e.identity,\ .identity = nameof(e),\
.value = e.value,\ .value = e.value,\
.description = c,\ .description = c,\
.characteristic = STATUS_ERROR,\ .characteristic = STATUS_ERROR,\
.loc = __HERE__,\ .loc = e.loc,\
.prev = e.prev\ .prev = e.prev\
}) })
@@ -71,7 +106,7 @@
.value = p.value,\ .value = p.value,\
.description = e.description,\ .description = e.description,\
.characteristic = p.characteristic,\ .characteristic = p.characteristic,\
.loc = __HERE__,\ .loc = p.loc,\
.prev = (Status *)&p\ .prev = (Status *)&p\
}) })
@@ -80,7 +115,7 @@
.value = v,\ .value = v,\
.description = e.description,\ .description = e.description,\
.characteristic = e.characteristic,\ .characteristic = e.characteristic,\
.loc = __HERE__,\ .loc = e.loc,\
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
@@ -93,13 +128,24 @@
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
/* Create a report in place with $e for base and $c for initiator literal. */ // Reannotate for e.
# define stamp(e, c) ((Report) {\ # define annot(e, c) ((Status) {\
.status = e,\ .identity = e.identity,\
.initiator = c,\ .value = e.value,\
.description = c,\
.characteristic = e.characteristic,\
.loc = e.loc,\
.prev = (Status *)e.prev\
})
/* Create a report on the fly. */
# define stamp(e, ini) ((Report) {\
.content = e,\
.initiator = ini,\
.time = time(NULL),\ .time = time(NULL),\
.priority = REPORT_SENDING_PRIORITY_NORMAL,\ .level = REPORT_SENDING_PRIORITY_NORMAL,\
.taskprint_status = REPORT_SENDING_TASK_STATUS_PENDING\ .status = REPORT_SENDING_TASK_STATUS_PENDING,\
.dst = stdout\
}) })
# define cat(s) {\ # define cat(s) {\
@@ -110,45 +156,6 @@
CatlogSender_Send(&sender);\ CatlogSender_Send(&sender);\
} }
// /**
// * @brief Forcibly return desired value $v once $s is not $k.
// * @return $v once state for $s is false.
// * @note "force" stands for "Forcible value"
// * @note 's' stands for "Statement"
// * @note 'k' stands for "Key Value", the value that is targeted to detect.
// * @note 'v' stands for "Desire Value", the value that desires.
// */
// # define force(s, k, v) solve((s) != (k), v)
// # define sforce(s, k, v) solve((!Status_Equal(s, k)), v)
// # define print_status(s) {\
// Status _ = s;\
// char buff[LITERALISATION_LENGTH_MAXIMUM];\
// notok(Status_Literalise(&_, buff), {\
// (void)printf("Failed to literalise a status\n");\
// });\
// (void)printf("%s\n", buff);\
// }
// # define print_status(s) {\
// char buff[LITERALISATION_LENGTH_MAXIMUM];\
// (void)Status_Literalise(&s, buff);\
// (void)fprintf(stderr, "%s\n", buff);\
// }
// # define print_statusdump(s) {\
// Status _ = s;\
// const int dump_len = StatusUtils_Depth(&_);\
// Status dump[dump_len];\
// StatusUtils_Dump(&_, dump, 0);\
// for (register int i = 0; i < dump_len; i++) {\
// /* TODO(william): Replace following line with coloured-term-output function. */\
// (void)printf("\e[1m[%d/%d]\e[0m\n", i, dump_len - 1);\
// print_status(dump[i]);\
// }\
// }
# define strnil(s) (!s ? ("(null)") : s) # define strnil(s) (!s ? ("(null)") : s)
# define type(T) # define type(T)
@@ -193,7 +200,6 @@ typedef bool _Bit;
# define LITERALISATION_LENGTH_MAXIMUM 0xFFFFL # define LITERALISATION_LENGTH_MAXIMUM 0xFFFFL
/* Only effect (probably) when formal Attribute is defined. /* Only effect (probably) when formal Attribute is defined.
* __ATTRIBUTABLE indicates this field is used for further process by Attribute. * __ATTRIBUTABLE indicates this field is used for further process by Attribute.
* Or, to put this way, this field has attributions not used so far, but * Or, to put this way, this field has attributions not used so far, but
@@ -203,4 +209,4 @@ typedef bool _Bit;
# define __ATTRIBUTABLE__ # define __ATTRIBUTABLE__
# define attr(a) # define attr(a)
#endif /* NO COMPOUND_COMMON_h */ #endif /* COMPOUND_COMMON_H */

0
function.c Normal file
View File

34
function.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef FUNCTION_H
# define FUNCTION_H
# include <Compound/string.h>
typedef Var Type;
typedef struct {
attr(registered 1) Type type;
attr(nullity false) String identity;
attr(alignwith 1)
attr(optional true) Type value;
} Parameter;
typedef void * Block;
typedef struct {
Type returns;
Array type(Parameter) params;
Var type(Block) body;
} Function;
Status Function_Create(Function *inst, Type returns,
Array type(Parameter) params, Var type(Block) body);
Status Function_CopyOf(Function *inst, Function *other);
Status Function_Delete(Function *inst);
Status Function_Literalise(Function *inst, String *buff);
Status Function_Overwrite(Function *inst, Function *other);
bool Function_Equal(Function *inst, Function *other);
bool FunctionUtils_IsVariadic(Function *inst);
#endif /* FUNCTION_H */

View File

@@ -35,7 +35,7 @@ done
cp -v "common.h" "const.h" "platform.h"\ cp -v "common.h" "const.h" "platform.h"\
"name.h" "namescope.h" "type.h" "catlog.h"\ "name.h" "namescope.h" "type.h" "catlog.h"\
"attr.h" "registry.h" "class.h" "$DST" "attr.h" "registry.h" "class.h" "function.h" "$DST"
echo "Installing libcompound:" echo "Installing libcompound:"
cp -v "libcompound.so" "/usr/lib" cp -v "libcompound.so" "/usr/lib"

View File

@@ -2,7 +2,7 @@
Status NameScope_Create(NameScope *inst) Status NameScope_Create(NameScope *inst)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
/* Create instances for members from inst. */ /* Create instances for members from inst. */
state(StatusUtils_IsOkay(NameScope_EmptyName(&inst->latest)), state(StatusUtils_IsOkay(NameScope_EmptyName(&inst->latest)),
@@ -17,8 +17,8 @@ Status NameScope_Create(NameScope *inst)
Status NameScope_CopyOf(NameScope *inst, NameScope *other) Status NameScope_CopyOf(NameScope *inst, NameScope *other)
{ {
fails(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
fails(other, apply(UnavailableParameter)); nonull(other, apply(UnavailableParameter));
/* Copy and assign. */ /* Copy and assign. */
other->latest = inst->latest; other->latest = inst->latest;