(INI) Initiated MemMan
(MOD) Extended abtilities of Status (ADD) Introduced CMake building system for Compound
This commit is contained in:
1
Status/.gitignore
vendored
Normal file
1
Status/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
obj/
|
86
Status/doc/STATUS
Normal file
86
Status/doc/STATUS
Normal file
@@ -0,0 +1,86 @@
|
||||
#PROJECT "Compound - Status" DOCUMENTATION WRITTEN BY WILLIAM PASCAL
|
||||
#
|
||||
#THIS PROJECT IS COMPILED UNDER "C99 ISO/IEC 9899:1999" WITH
|
||||
#"gcc (GCC) 13.2.1 20230801"
|
||||
#PLEASE NOTE THAT THE VERSION TO THE COMPILER MAY CHANGE DURING PROJECT
|
||||
#DEVELOPMENT, IT IS UNCERTAIN, SO FAR, THAT EVERY COMPILER OLDER/NEWER THAT
|
||||
#THIS VERSION COULD COMPILE PROPERLY. MS WINDOWS SUPPORT IS UNDER
|
||||
#CONSIDERATION WHILE DEVELOPMENT FOR GNU/LINUX HAS HIGHER PRIORITY.
|
||||
|
||||
LICENSE NOTICE:
|
||||
This file is part of Compound.
|
||||
Compound is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
Compound is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Compound. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BRIEF:
|
||||
"STATUS" REPRESENT THE ACTUAL PROCESS STATUS OF THE FUNCTION APPLIED TO USE
|
||||
THIS STRUCTURE AS THE RETURNING TYPE.
|
||||
|
||||
DECLARATION:
|
||||
STRUCTURE - STATUS
|
||||
IT COMES WITH FOLLOWING MEMBERS:
|
||||
i. value: int
|
||||
|
||||
"VALUE" INDICATES THE VALUE THAT FUNCTION RETURNS. MORE USUALLY, THIS
|
||||
VALUE IS IGNORED WHEN "CHARACTERISTIC" IS NOT "STATUS_UNKNOWN" AS AN
|
||||
ALTERNATIVE FOR LEGACY FUNCTIONS WHICH DO NOT USE "int" FOR THEIR
|
||||
RETURNING.
|
||||
|
||||
ii. description: char*
|
||||
|
||||
"DESCRIPTION" TELLS THE SITUATION, USUALLY NOT NORMAL, WHERE THE FUNCTION
|
||||
HAD RUN INTO CERTAIN PROBLEMS DURING THE PROCESS. IT CAN BE USEFUL WHEN
|
||||
DEBUGGING AND SUCH.
|
||||
|
||||
*PLEASE NOTE, AN EMPTY DESCRIPTION ALONG WITH A NULL DESCRIPTION IS
|
||||
REGARDED AS "MEANINGLESS ONE" WHICH DOES NOT DOING ANYTHING EFFECTIVE FOR
|
||||
ANYONE. DESCRIPTIONS CAN BE VALIDATED WITH FUNCTION `status_isvalid`.
|
||||
|
||||
iii. characteristic: int
|
||||
|
||||
"CHARACTERISTIC" INDICATED THE BASIC NATURE OF CURRENT "STATUS".
|
||||
|
||||
*GO SEE enum StatusCharacteristics FOR AVAILABLE "CHARACTERISTICS".
|
||||
|
||||
iv. prev: struct _Status*
|
||||
|
||||
"PREV" STANDS FOR "PREVIOUS STATUS". JUST AS THE NAME TELLS, THIS MEMBER
|
||||
POINTS AT THE PREVIOUS STRUCTURE OF STATUS WHERE THIS STATUS IS BASED ON.
|
||||
|
||||
THIS MEMBER IS USUALLY USED FOR PRINTING CALLING STACKS.
|
||||
|
||||
IN SOME CASES, THIS MEMBER COULD POINT AT IT SELF, MEANING IT COULD MAKE
|
||||
A RECURSIVE SITUATION WHERE IT REQUIRE EXTRA EXAMINATIONS BEFORE GOING TO
|
||||
THE ADDRESS IT POINTS AT. THESE PROBLEMS CAN BE AVOIDED WITH FUNCTION
|
||||
`status_recursive` CALLED AHEAD.
|
||||
|
||||
*GO SEE status_dump FOR DETAILS ABOUT DUMPING CALLING STACKS.
|
||||
*GO SEE status_recursive FOR DETERRING RECURSIVE "PREV".
|
||||
|
||||
SYNONYM:
|
||||
Status funcname1(void *param);
|
||||
Status *funcname2(void);
|
||||
|
||||
VARIANT SYNONYM:
|
||||
int funcname1(Status stat);
|
||||
void funcname2(Status *stats);
|
||||
|
||||
|
||||
|
||||
typedef struct _Status {
|
||||
int value; /* Traditional returning data "int". Only used when the function
|
||||
called and received legacy functions that uses "int" as the
|
||||
returning type that wish to have place to hold the value.
|
||||
Otherwise, the function would just return the structure Status. */
|
||||
char *description;
|
||||
int characteristic;
|
||||
struct _Status *prev;
|
||||
} Status;
|
229
Status/include/status.h
Normal file
229
Status/include/status.h
Normal file
@@ -0,0 +1,229 @@
|
||||
#ifndef COMPOUND_STATUS_H
|
||||
# define COMPOUND_STATUS_H
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stdint.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <threads.h>
|
||||
# include <time.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# define __HERE__ { .file = __FILE__, .line = __LINE__, .func = __func__ }
|
||||
|
||||
/* Status characteristics */
|
||||
typedef enum {
|
||||
STATUS_UNKNOWN = -1,
|
||||
STATUS_NORMAL = 0,
|
||||
STATUS_ERROR = 1
|
||||
} StatusCharacteristics;
|
||||
|
||||
//!!! UNKNOWN ENTITY !!!
|
||||
// enum {
|
||||
// ARGUE_FINALISED = 0b01,
|
||||
// ARGUE_UNSETTLED =-0b01,
|
||||
|
||||
// ARGUE_POSITIVE = 0b10,
|
||||
// ARGUE_NEGATIVE = -0b10,
|
||||
// };
|
||||
|
||||
/* Indicated the exact location where the "issue" was occurred at. */
|
||||
typedef struct {
|
||||
const char *file;
|
||||
int line;
|
||||
const char *func;
|
||||
} Location;
|
||||
|
||||
/* Common return type for reporting functions that require to give more
|
||||
information about the procedure. */
|
||||
typedef struct _Status {
|
||||
int value; /* Traditional returning data "int". Only used when the function
|
||||
called and received legacy functions that uses "int" as the
|
||||
returning type that wish to have place to hold the value.
|
||||
Otherwise, the function would just return the structure Status. */
|
||||
char *description;
|
||||
int characteristic;
|
||||
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;
|
||||
|
||||
typedef Status (*ReportSendingTask) (FILE **, Report *);
|
||||
typedef int ReportSendingTaskID;
|
||||
|
||||
typedef struct {
|
||||
ReportSendingTask *tasks_ref;
|
||||
int sendercount;
|
||||
int finishedcount;
|
||||
Status *senderreturn;
|
||||
} ReportSendingManager;
|
||||
|
||||
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
|
||||
} ReportSendingTaskStatus;
|
||||
|
||||
typedef Status (*Argue) (Report);
|
||||
|
||||
typedef struct {
|
||||
Argue argue_start; // Implicitly converting thrd_start_t to Argue
|
||||
void *external_param;
|
||||
} ArgueStarter;
|
||||
|
||||
/* Argument levels (qualities) */
|
||||
typedef enum {
|
||||
ARGUMENT_NONE = 0,
|
||||
ARGUMENT_MINOR,
|
||||
ARGUMENT_NORMAL,
|
||||
ARGUMENT_MAJOR,
|
||||
ARGUMENT_CRITICAL,
|
||||
ARGUMENT_SEVERE,
|
||||
ARGUMENT_ALL,
|
||||
} ArgumentLevel;
|
||||
|
||||
typedef struct {
|
||||
ReportSender *streams;
|
||||
ArgueStarter handler;
|
||||
ArgumentLevel level;
|
||||
bool muted;
|
||||
} Argument;
|
||||
|
||||
// typedef struct {
|
||||
// Argument *members;
|
||||
// int (*announcer) (Argument);
|
||||
// } ArgumentAnnouncer;
|
||||
|
||||
# define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
Status
|
||||
reportsender_create(ReportSender *inst, FILE **dests_ref,
|
||||
ReportSendingTask *tasks_ref);
|
||||
Status
|
||||
reportsender_send(ReportSender sender, ReportSendingTask *tasks_ref);
|
||||
|
||||
|
||||
ReportSendingTaskID
|
||||
reportsendingmanager_appendtask(ReportSendingManager *inst,
|
||||
ReportSendingTask task);
|
||||
Status
|
||||
reportsendingmanager_removetask(ReportSendingManager *inst,
|
||||
ReportSendingTaskID taskid);
|
||||
ReportSendingTaskStatus
|
||||
reportsendingmanager_taskstatus(ReportSendingManager *inst,
|
||||
ReportSendingTaskID taskid);
|
||||
|
||||
|
||||
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, ArgueStarter handler);
|
||||
Status
|
||||
argument_constr(Argument *inst, ReportSender *streams, ArgueStarter handler,
|
||||
int level, bool muted);
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
static Status UnknownStatus = {
|
||||
.description = "An unknown status.",
|
||||
.characteristic = STATUS_UNKNOWN,
|
||||
.prev = NULL
|
||||
};
|
||||
|
||||
static Status NormalStatus = {
|
||||
.description = "A normal status.",
|
||||
.characteristic = STATUS_NORMAL,
|
||||
.prev = NULL
|
||||
};
|
||||
|
||||
static Status ErrorStatus = {
|
||||
.description = "An error status.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = NULL
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
static Status NullPointerAccounted = {
|
||||
.description = "An involving null pointer was not accepted.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status InvalidParameter = {
|
||||
.description = "An invalid parameter was presented.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status InsufficientMemory = {
|
||||
.description = "Not enough room for further memory allocations.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
static Status ArithmeticError = {
|
||||
.description = "An arithmetic error occurred.",
|
||||
.characteristic = STATUS_ERROR,
|
||||
.prev = &ErrorStatus
|
||||
};
|
||||
|
||||
#endif /* COMPOUND_STATUS_H */
|
30
Status/src/status.c
Normal file
30
Status/src/status.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <Compound/status.h>
|
||||
|
||||
bool status_issueposition_compare(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_isnormal(Status stat) { return (!stat.characteristic); }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
statbuff[idx] = stat;
|
||||
|
||||
status_dump(*stat.prev, statbuff, ++idx);
|
||||
}
|
||||
|
||||
bool status_compare(Status stat1, Status stat2) {
|
||||
return (!strcmp(stat1.description, stat2.description) &&
|
||||
(stat1.characteristic == stat2.characteristic) &&
|
||||
(!status_compare(*stat1.prev, *stat2.prev)));
|
||||
}
|
Reference in New Issue
Block a user