(SOC) Storage Only Commit
(ADD) Name, NameScope, Catlog, Object, String, Attribute, Char, Registry, Utils, Type, <Platform Support>, <Global Constants>, README (MOD) Array, Var, Status, MemMan, <Common>
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
# include <time.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# define __HERE__ { .file = __FILE__, .line = __LINE__, .func = __func__ }
|
||||
# include <Compound/common.h>
|
||||
# include <Compound/utils.h>
|
||||
# include <Compound/platform.h>
|
||||
|
||||
/* Status characteristics */
|
||||
typedef enum {
|
||||
@@ -18,22 +20,30 @@ typedef enum {
|
||||
STATUS_ERROR = 1
|
||||
} StatusCharacteristics;
|
||||
|
||||
//!!! UNKNOWN ENTITY !!!
|
||||
// enum {
|
||||
// ARGUE_FINALISED = 0b01,
|
||||
// ARGUE_UNSETTLED =-0b01,
|
||||
|
||||
// ARGUE_POSITIVE = 0b10,
|
||||
// ARGUE_NEGATIVE = -0b10,
|
||||
// };
|
||||
typedef enum {
|
||||
/* Settlement. */
|
||||
ARGUE_RESULT_FINALISED = 0b01,
|
||||
ARGUE_RESULT_UNSETTLED = -0b01,
|
||||
|
||||
/* Nature. */
|
||||
ARGUE_RESULT_POSITIVE = 0b10,
|
||||
ARGUE_RESULT_NEGATIVE = -0b10,
|
||||
} ArgueResult;
|
||||
|
||||
/* Indicated the exact location where the "issue" was occurred at. */
|
||||
typedef struct {
|
||||
const char *file;
|
||||
char *file;
|
||||
int line;
|
||||
const char *func;
|
||||
char *func;
|
||||
} Location;
|
||||
|
||||
# define __HERE__ (Location){ \
|
||||
.file = (char *)__FILE__, \
|
||||
.line = __LINE__, \
|
||||
.func = (char *)__func__ \
|
||||
}
|
||||
|
||||
/* Common return type for reporting functions that require to give more
|
||||
information about the procedure. */
|
||||
typedef struct _Status {
|
||||
@@ -43,36 +53,41 @@ typedef struct _Status {
|
||||
Otherwise, the function would just return the structure Status. */
|
||||
char *description;
|
||||
int characteristic;
|
||||
Location loc;
|
||||
struct _Status *prev;
|
||||
} Status;
|
||||
|
||||
/* "Report" recollects essential informations, included but not limited to
|
||||
Status and others for making an report for debugging and such. */
|
||||
typedef struct {
|
||||
Status stat;
|
||||
Location pos;
|
||||
char *originator;
|
||||
struct tm time;
|
||||
int priority;
|
||||
} Report;
|
||||
/*
|
||||
|
||||
typedef struct {
|
||||
FILE **dests_ref;
|
||||
Report **reports_ref;
|
||||
int totalreports;
|
||||
int reportsent;
|
||||
struct timespec elapsed;
|
||||
} ReportSender;
|
||||
{value "description" characteristic prev}
|
||||
|
||||
typedef Status (*ReportSendingTask) (FILE **, Report *);
|
||||
typedef int ReportSendingTaskID;
|
||||
"%d \"%s\" %d %p"
|
||||
|
||||
typedef struct {
|
||||
ReportSendingTask *tasks_ref;
|
||||
int sendercount;
|
||||
int finishedcount;
|
||||
Status *senderreturn;
|
||||
} ReportSendingManager;
|
||||
*/
|
||||
|
||||
# ifdef __COMPOUND_32__
|
||||
# define STATUS_LITERALISE_LENGTH(stat) \
|
||||
(utils_calc_digits(stat.value) + strlen(stat.description) + 2 + \
|
||||
utils_calc_digits(INT32_DIGITS_DEC))
|
||||
# elif defined __COMPOUND_64__
|
||||
# define STATUS_LITERALISE_LENGTH(stat) \
|
||||
(utils_calc_digits(stat.value) + strlen(stat.description) + 2 + \
|
||||
utils_calc_digits(INT64_DIGITS_DEC))
|
||||
# endif
|
||||
|
||||
# define STATUS_LITERALISE_FORMAT "%d \"%s\" %d %p"
|
||||
|
||||
typedef enum {
|
||||
REPORT_SENDING_PRIORITY_ALL = 0, // Highest level; least value.
|
||||
REPORT_SENDING_PRIORITY_FATAL,
|
||||
REPORT_SENDING_PRIORITY_EXCEPTIONAL,
|
||||
REPORT_SENDING_PRIORITY_CRITICAL,
|
||||
REPORT_SENDING_PRIORITY_MAJOR,
|
||||
REPORT_SENDING_PRIORITY_NORMAL,
|
||||
REPORT_SENDING_PRIORITY_MINOR,
|
||||
REPORT_SENDING_PRIORITY_DEBUG,
|
||||
REPORT_SENDING_PRIORITY_NONE, // Lowest level, greatest value.
|
||||
} ReportSendingPriority;
|
||||
|
||||
typedef enum {
|
||||
REPORT_SENDING_TASK_STATUS_FINISHED = 0,
|
||||
@@ -82,30 +97,97 @@ typedef enum {
|
||||
REPORT_SENDING_TASK_STATUS_NOTFOUND
|
||||
} ReportSendingTaskStatus;
|
||||
|
||||
typedef Status (*Argue) (Report);
|
||||
|
||||
/* "Report" recollects essential informations, included but not limited to
|
||||
Status and others for making an report for debugging and such. */
|
||||
typedef struct {
|
||||
Argue argue_start; // Implicitly converting thrd_start_t to Argue
|
||||
void *external_param;
|
||||
} ArgueStarter;
|
||||
Status stat;
|
||||
char *originator;
|
||||
time_t time;
|
||||
ReportSendingPriority priority;
|
||||
ReportSendingTaskStatus status;
|
||||
FILE *dest; // The destination where the report is sending to.
|
||||
} Report;
|
||||
|
||||
/*
|
||||
|
||||
TIME [PRIORITY] STATUSNAME (ORIGINATOR): STATUS.DESCRIPTION
|
||||
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
|
||||
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
|
||||
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
|
||||
at LOCATION.FILE:LOCATION.LINE, LOCATION.FUNC
|
||||
|
||||
|
||||
Fri 10 May 03:02:37 CST 2024 [EXCEPTIONAL] InvalidParameter (Nullity): Given buffer was unavailable.
|
||||
at /external/Documents/Projects/Compound/Status/src/status.c:104, report_literalise
|
||||
at /external/Documents/Projects/Compound/Status/src/status.c:114, reportsender_send
|
||||
at /external/Documents/Projects/Compound/Status/src/status.c:69, _throw
|
||||
!!!!at /external/Documents/Projects/Compound/Array/src/array.c:16, array_create
|
||||
at /external/Documents/Projects/Compound/test.c:24, main
|
||||
|
||||
*/
|
||||
|
||||
# define REPORT_LITERALISE_HEADER_FORMAT "%ld [%s] %s (%s): %s"
|
||||
# define REPORT_LITERALISE_CHAINS_FORMAT " at %s:%d, %s"
|
||||
# define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT "!!!!at %s:%d, %s"
|
||||
|
||||
# define REPORT_LITERALISE_HEADER_FORMAT_LENGTH(PRIORITY, STATUSNAME, \
|
||||
ORIGINATOR, DESCRIPTION) \
|
||||
(INT64_DIGITS_DEC + strlen(PRIORITY) + strlen(STATUSNAME) + \
|
||||
strlen(ORIGINATOR) + strlen(DESCRIPTION) + 9) // Does not count '\0'
|
||||
# define REPORT_LITERALISE_CHAINS_FORMAT_LENGTH(FILEPATH, LINE, FUNCNAME) \
|
||||
(strlen(FILEPATH) + utils_calc_digits(LINE) + \
|
||||
strlen(FUNCNAME) + 10) // Does not count '\0'
|
||||
# define REPORT_LITERALISE_CHAINS_EXCLAIM_FORMAT_LENGTH \
|
||||
REPORT_LITERALISE_CHAINS_FORMAT_LENGTH
|
||||
|
||||
/* Argument levels (qualities) */
|
||||
typedef enum {
|
||||
ARGUMENT_NONE = 0,
|
||||
ARGUMENT_MINOR,
|
||||
ARGUMENT_NORMAL,
|
||||
ARGUMENT_MAJOR,
|
||||
ARGUMENT_CRITICAL,
|
||||
ARGUMENT_SEVERE,
|
||||
ARGUMENT_ALL,
|
||||
} ArgumentLevel;
|
||||
REPORT_SENDER_RESULT_FINISHED,
|
||||
REPORT_SENDER_RESULT_PROGRESSING,
|
||||
REPORT_SENDER_RESULT_PENDING
|
||||
} ReportSenderResult;
|
||||
|
||||
typedef struct {
|
||||
ReportSender *streams;
|
||||
ArgueStarter handler;
|
||||
ArgumentLevel level;
|
||||
bool muted;
|
||||
} Argument;
|
||||
thrd_t thread;
|
||||
Report *report; // The report for sending.
|
||||
time_t elapsed; // The individual elapsed time for each report. (Array)
|
||||
ReportSenderResult result;
|
||||
bool successful;
|
||||
} ReportSender;
|
||||
|
||||
typedef int (*ReportSendingTask)(Report *rep);
|
||||
typedef int ReportSendingTaskID;
|
||||
|
||||
typedef struct {
|
||||
ReportSendingTask *tasks; // Array Ref
|
||||
int sendercount;
|
||||
int finishedcount;
|
||||
int *results; // Array
|
||||
} ReportSendingManager;
|
||||
|
||||
// typedef thrd_start_t ArgueStart;
|
||||
|
||||
// typedef struct {
|
||||
// ArgueStart handler;
|
||||
// void *external_param;
|
||||
// } ArgueStartParam;
|
||||
|
||||
// /* Argument levels (qualities) */
|
||||
// typedef enum {
|
||||
// ARGUMENT_NONE = 0,
|
||||
// ARGUMENT_MINOR,
|
||||
// ARGUMENT_NORMAL,
|
||||
// ARGUMENT_MAJOR,
|
||||
// ARGUMENT_CRITICAL,
|
||||
// ARGUMENT_SEVERE,
|
||||
// ARGUMENT_ALL,
|
||||
// } ArgumentLevel;
|
||||
|
||||
// typedef struct {
|
||||
// ReportSender stream;
|
||||
// ArgueStartParam handler; // Obsolete?
|
||||
// ArgumentLevel level;
|
||||
// bool muted;
|
||||
// } Argument;
|
||||
|
||||
// typedef struct {
|
||||
// Argument *members;
|
||||
@@ -114,73 +196,58 @@ typedef struct {
|
||||
|
||||
# define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX
|
||||
|
||||
bool Location_Equal(Location lc1, Location lc2);
|
||||
void Status_Dump(Status stat, Status *statbuff, int idx);
|
||||
bool Status_Equal(Status stat1, Status stat2);
|
||||
bool StatusUtils_HasPrev(Status stat);
|
||||
bool StatusUtils_IsOkay(Status stat);
|
||||
bool StatusUtils_IsValid(Status stat);
|
||||
bool StatusUtils_IsRecursive(Status stat);
|
||||
int StatusUtils_Depth(Status *stat);
|
||||
|
||||
Status
|
||||
Report_Create(Report *inst, Status *stat, FILE *dest, char *originator,
|
||||
int priority);
|
||||
bool
|
||||
status_issueposition_compare(Location lc1, Location lc2);
|
||||
bool
|
||||
status_hasprev(Status stat);
|
||||
bool
|
||||
status_isnormal(Status stat);
|
||||
bool
|
||||
status_isvalid(Status stat);
|
||||
bool
|
||||
status_recursive(Status stat);
|
||||
void
|
||||
status_dump(Status stat, Status *statbuff, int idx);
|
||||
bool
|
||||
status_compare(Status stat1, Status stat2);
|
||||
|
||||
|
||||
bool
|
||||
report_compare(Report repo1, Report repo2);
|
||||
Report_Equal(Report repo1, Report repo2);
|
||||
Status
|
||||
Report_Literalise(Report *inst, char *buff);
|
||||
|
||||
|
||||
Status
|
||||
reportsender_create(ReportSender *inst, FILE **dests_ref,
|
||||
ReportSendingTask *tasks_ref);
|
||||
ReportSender_Create(ReportSender *inst, Report *report);
|
||||
Status
|
||||
reportsender_send(ReportSender sender, ReportSendingTask *tasks_ref);
|
||||
|
||||
ReportSender_Send(ReportSender *inst, ReportSendingTask task);
|
||||
ReportSendingTaskStatus
|
||||
ReportSender_GetStatus(ReportSender *inst);
|
||||
|
||||
ReportSendingTaskID
|
||||
reportsendingmanager_appendtask(ReportSendingManager *inst,
|
||||
ReportSenderManager_AppendTask(ReportSendingManager *inst,
|
||||
ReportSendingTask task);
|
||||
Status
|
||||
reportsendingmanager_removetask(ReportSendingManager *inst,
|
||||
ReportSendingTaskID taskid);
|
||||
ReportSendingTaskStatus
|
||||
reportsendingmanager_taskstatus(ReportSendingManager *inst,
|
||||
ReportSendingTaskID taskid);
|
||||
Status ReportSenderManager_RemoveTask(ReportSendingManager *inst,
|
||||
ReportSendingTaskID taskid);
|
||||
|
||||
// Status
|
||||
// arguestarter_create(ArgueStartParam *inst, void *external_param);
|
||||
// Status
|
||||
// arguestarter_constr(ArgueStartParam *inst, ArgueStart argue_start,
|
||||
// void *external_param);
|
||||
// Status
|
||||
// arguestarter_start(ArgueStartParam *inst);
|
||||
// bool
|
||||
// arguestarter_equal(ArgueStartParam *inst1, ArgueStartParam *inst2);
|
||||
// Status arguestarter_current(void);
|
||||
// Status arguestarter_sleep(const struct timespec *time_point,
|
||||
// struct timespec *remaining);
|
||||
// void arguestarter_exit(int code) __attribute__ ((__noreturn__));
|
||||
// Status arguestarter_join(ArgueStart thrd);
|
||||
|
||||
|
||||
Status
|
||||
arguestarter_create(ArgueStarter *inst, void *external_param);
|
||||
Status
|
||||
arguestarter_constr(ArgueStarter *inst, Argue argue_start,
|
||||
void *external_param);
|
||||
Status
|
||||
arguestarter_start(ArgueStarter *inst);
|
||||
static inline int
|
||||
arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2)
|
||||
{
|
||||
return (inst1->argue_start == inst2->argue_start)
|
||||
|| (inst1->external_param == inst2->external_param);
|
||||
}
|
||||
Status arguestarter_current(void);
|
||||
Status arguestarter_sleep(const struct timespec *time_point,
|
||||
struct timespec *remaining);
|
||||
void arguestarter_exit(int code) __attribute__ ((__noreturn__));
|
||||
Status arguestarter_join(Argue thrd);
|
||||
// Status
|
||||
// argument_create(Argument *inst, ReportSender *streams, ArgueStartParam handler,
|
||||
// int level, bool muted);
|
||||
|
||||
|
||||
Status
|
||||
argument_create(Argument *inst, ReportSender *streams, ArgueStarter handler);
|
||||
Status
|
||||
argument_constr(Argument *inst, ReportSender *streams, ArgueStarter handler,
|
||||
int level, bool muted);
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// ---------------------ELEMENTARY-------------------------
|
||||
|
||||
static Status UnknownStatus = {
|
||||
.description = "An unknown status.",
|
||||
@@ -200,12 +267,18 @@ static Status ErrorStatus = {
|
||||
.prev = NULL
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
// ----------------------EXTENDED--------------------------
|
||||
|
||||
static Status MemoryViolation = {
|
||||
.description = "Illegal access on certain memory address.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status NullPointerAccounted = {
|
||||
.description = "An involving null pointer was not accepted.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
.prev = &MemoryViolation
|
||||
};
|
||||
|
||||
static Status InvalidParameter = {
|
||||
@@ -226,4 +299,127 @@ static Status ArithmeticError = {
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status RuntimeError = {
|
||||
.description = "A runtime error occurred.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status ArrayLengthError = {
|
||||
.description = "Given array length does not meet the requirement.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status VariableFormatMismatch = {
|
||||
.description = "Given format does not match with given subjects.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status ImprecisionError = {
|
||||
.description = "Precision was not enough for handling the calculation.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &RuntimeError
|
||||
};
|
||||
|
||||
// ---------------USER DEFINED | RUNTIME-------------------
|
||||
|
||||
static Status UnavailableInstance = {
|
||||
.description = "An unavailable instance was given for initialisation.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &NullPointerAccounted
|
||||
};
|
||||
|
||||
static Status UnavailableParameter = {
|
||||
.description = "An unavailable instance was given as a parameter.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &UnavailableInstance
|
||||
};
|
||||
|
||||
static Status InvalidReportTask = {
|
||||
.description = "An unavailable or illegal report task was given.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &InvalidParameter
|
||||
};
|
||||
|
||||
static Status UnableToThrowError = {
|
||||
.description = "Unable to report an exceptional situation.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &RuntimeError
|
||||
};
|
||||
|
||||
static Status ReadWriteError = {
|
||||
.description = "Error occurred during IO session.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &RuntimeError
|
||||
};
|
||||
|
||||
static Status FileNotFound = {
|
||||
.description = "Target file was unavailable and unable to find.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ReadWriteError
|
||||
};
|
||||
|
||||
static Status InvalidFileName = {
|
||||
.description = "Given file name was invalid.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ReadWriteError
|
||||
};
|
||||
|
||||
static Status ReportThrown = {
|
||||
.description = "This function has thrown a report, "
|
||||
"following instructions aborted.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &RuntimeError
|
||||
};
|
||||
|
||||
static Status ReportMessageLengthTooLong = {
|
||||
.description = "Given message is too long.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ArrayLengthError
|
||||
};
|
||||
|
||||
// ========================================================
|
||||
|
||||
# define ensure(e, c) { \
|
||||
Status stat = e; \
|
||||
solve(!(StatusUtils_IsOkay(stat)), { \
|
||||
Report rep = stamp(error(stat, c), (char *)__func__); \
|
||||
(void)throw(rep); \
|
||||
return ReportThrown; \
|
||||
}) \
|
||||
}
|
||||
|
||||
/* Add location parameter requirement in order to give proper information
|
||||
* before throwing the report out. */
|
||||
# define throw(report) __throw(report, __HERE__)
|
||||
|
||||
/* Useless in C, only for human to see.
|
||||
Probably rewrite this in Classify. */
|
||||
# define throws(e)
|
||||
|
||||
ReportSendingTaskID __throw(Report report, Location loc);
|
||||
Report catch(ReportSendingTaskID taskid);
|
||||
static int HANDLER(void *report)
|
||||
{
|
||||
/* Throw UnableToThrowError when param is unavailable. */
|
||||
if (report == NULL) {
|
||||
/* Create report on this. */
|
||||
Report e;
|
||||
Report_Create(
|
||||
&e,
|
||||
&error(UnableToThrowError, "Cannot perform throwing. Aborted."),
|
||||
stderr, nameof(DEFAULT_ARGUE_STARTER),
|
||||
REPORT_SENDING_PRIORITY_FATAL);
|
||||
|
||||
/* Perform throwing. */
|
||||
(void)_throw(e); // Throw the report alone.
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void)_throw(*(Report *)report); // Lonely _throw, no catch will company.
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* COMPOUND_STATUS_H */
|
||||
|
@@ -1,30 +1,174 @@
|
||||
#include <Compound/common.h>
|
||||
#include <Compound/status.h>
|
||||
|
||||
bool status_issueposition_compare(Location lc1, Location lc2) {
|
||||
bool status_issuelocation_equal(Location lc1, Location lc2) {
|
||||
return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) &&
|
||||
(!strcmp(lc1.func, lc2.func)));
|
||||
}
|
||||
|
||||
bool status_hasprev(Status stat) { return (stat.prev != NULL); }
|
||||
bool status_hasprev(Status stat) {
|
||||
/* Skip when stat is unavailable for accessing. */
|
||||
state(status_equal(stat, (Status){}), false);
|
||||
|
||||
bool status_isnormal(Status stat) { return (!stat.characteristic); }
|
||||
return (stat.prev != NULL);
|
||||
}
|
||||
|
||||
bool status_isokay(Status stat) { return (!stat.characteristic); }
|
||||
|
||||
bool status_isvalid(Status stat) {
|
||||
return (!strcmp(stat.description, "") && stat.characteristic >= 0 &&
|
||||
stat.prev != NULL);
|
||||
}
|
||||
|
||||
bool status_recursive(Status stat) {
|
||||
return (stat.prev != NULL && stat.prev == &stat);
|
||||
}
|
||||
|
||||
void status_dump(Status stat, Status *statbuff, int idx) {
|
||||
if (statbuff == NULL || !status_hasprev(stat) || idx < 0) {
|
||||
return;
|
||||
}
|
||||
void status_dump(Status inst, Status *statbuff, int idx) {
|
||||
|
||||
statbuff[idx] = stat;
|
||||
/* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */
|
||||
solve((statbuff == NULL || !status_hasprev(inst) || idx < 0), return;);
|
||||
|
||||
status_dump(*stat.prev, statbuff, ++idx);
|
||||
statbuff[idx] = inst;
|
||||
(void)printf("status_dump: Index %d has assigned with %p\n", idx, &inst);
|
||||
|
||||
status_dump(*inst.prev, statbuff, ++idx);
|
||||
}
|
||||
|
||||
bool status_compare(Status stat1, Status stat2) {
|
||||
return (!strcmp(stat1.description, stat2.description) &&
|
||||
bool status_equal(Status stat1, Status stat2) {
|
||||
|
||||
/* Skip when both stat1 and stat2 are empty. */
|
||||
state((stat1.value == 0 && stat2.value == 0 && stat1.description == 0x0 &&
|
||||
stat2.description == 0x0 && stat1.characteristic == 0 &&
|
||||
stat2.characteristic == 0 && stat1.prev == 0x0 && stat2.prev == 0x0),
|
||||
true);
|
||||
|
||||
/* True for equality; False for inequality. */
|
||||
return ((stat1.value == stat2.value) &&
|
||||
(!strcmp(stat1.description, stat2.description)) &&
|
||||
(stat1.characteristic == stat2.characteristic) &&
|
||||
(!status_compare(*stat1.prev, *stat2.prev)));
|
||||
(status_equal(*stat1.prev, *stat2.prev)));
|
||||
}
|
||||
|
||||
int status_depth(Status *stat) {
|
||||
/* Skip unavailable stat. */
|
||||
state((stat == NULL), -1);
|
||||
|
||||
Status *p = stat; // Include this layer of Status.
|
||||
int cnt = 1;
|
||||
while (p != NULL) {
|
||||
if (status_recursive(*p) || !status_hasprev(*stat)) break;
|
||||
|
||||
p = p->prev;
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
Status report_create(Report *inst, Status *stat, FILE *dest, char *originator,
|
||||
int priority) {
|
||||
/* Skip unavailable parameters. */
|
||||
fails(inst, UnavailableInstance);
|
||||
fails(stat, error(InvalidParameter, "Given originator was null."));
|
||||
fails(originator, error(InvalidParameter, "Given originator was null."));
|
||||
state(priority < 0, error(InvalidParameter, "Given priority was negative."));
|
||||
|
||||
/* Copy and assign. */
|
||||
inst->stat = *stat;
|
||||
inst->originator = originator;
|
||||
inst->time = time(NULL);
|
||||
inst->priority = priority;
|
||||
inst->status = REPORT_SENDING_TASK_STATUS_PENDING;
|
||||
inst->dest = (dest == NULL ? stderr : dest);
|
||||
|
||||
return NormalStatus;
|
||||
}
|
||||
|
||||
Status report_literalise(Report *inst, char *buff) {
|
||||
/* Skip when inst or buff is unavailable. */
|
||||
fails(inst, UnavailableInstance);
|
||||
fails(buff, error(InvalidParameter, "Given buffer was unavailable."));
|
||||
|
||||
const int depth = status_depth(&inst->stat);
|
||||
char buff // TODO(william): HERE
|
||||
}
|
||||
|
||||
Status reportsender_create(ReportSender *inst, Report *report) {
|
||||
fails(inst, UnavailableInstance);
|
||||
fails(report, error(UnavailableParameter, "Given report was unavailable."));
|
||||
|
||||
thrd_create(&inst->thread, &HANDLER, report);
|
||||
*inst->report = *report;
|
||||
inst->elapsed = 0;
|
||||
inst->result = REPORT_SENDER_RESULT_PENDING;
|
||||
inst->successful = false;
|
||||
|
||||
return NormalStatus;
|
||||
}
|
||||
|
||||
Status reportsender_send(ReportSender *inst, ReportSendingTask task) {
|
||||
/* Skip when inst or task is unavailable. */
|
||||
fails(inst,
|
||||
error(UnavailableInstance, "Report sender was given unavailable."));
|
||||
fails(task, InvalidReportTask);
|
||||
|
||||
/* Assign for dest. */
|
||||
const FILE *dest = (inst->report->dest == NULL ? stdout : inst->report->dest);
|
||||
// char buff[];
|
||||
// TODO(william): HERE, report_literalise
|
||||
|
||||
/* Write/Send data. */
|
||||
inst->report->status = REPORT_SENDING_TASK_STATUS_PROCEEDING;
|
||||
if (!fprintf(dest, buff)) {
|
||||
}
|
||||
|
||||
/* Sent successfully! Mark down properties. */
|
||||
}
|
||||
|
||||
// bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2)
|
||||
// {
|
||||
// /* Skip when either inst1 or inst2 is unavailable. */
|
||||
// state(inst1 == NULL || inst2 == NULL, false);
|
||||
|
||||
// return (inst1->argue_start == inst2->argue_start)
|
||||
// || (inst1->external_param == inst2->external_param);
|
||||
// }
|
||||
|
||||
ReportSendingTaskID _throw(Report report, Location loc) {
|
||||
// /* Create new a instance of ReportSender. */
|
||||
// ReportSender sender;
|
||||
// reportsender_create(&sender, stderr);
|
||||
|
||||
// /* Send message. */
|
||||
// /* Initialise sender's thread. */
|
||||
// thrd_t sending;
|
||||
// /* Skip on failing on creating thread. */
|
||||
// if (!thrd_create(&sending, starter, NULL)) {
|
||||
|
||||
// /* Conclude the session of sender. */
|
||||
// report.status = REPORT_SENDING_TASK_STATUS_FINISHED,
|
||||
// report.result = (ARGUE_RESULT_FINALISED | ARGUE_RESULT_NEGATIVE);
|
||||
|
||||
// sender.result = REPORT_SENDER_RESULT_FINISHED;
|
||||
// sender.successful = false;
|
||||
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// /* Perform sending. */
|
||||
// reportsender_send(&sender, NULL);
|
||||
|
||||
/* Initialise sender. */
|
||||
ReportSender sender;
|
||||
/* Return with -1 when initialisation failed. */
|
||||
state(!(status_isokay(reportsender_create(&sender, &report))), -1);
|
||||
|
||||
/* Inject location information. Could be more elegant, though. */
|
||||
sender.report->stat.loc = loc;
|
||||
|
||||
/* Send. */ /* Return -1 when failed on sending. */
|
||||
state(!status_isokay(reportsender_send(&sender, HANDLER)), -1);
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user