(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:
William
2024-05-16 00:04:42 +08:00
parent 989e512f8f
commit 5f7a6c6f93
32 changed files with 1694 additions and 195 deletions

46
Array/include/array.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef ARRAY_H
# define ARRAY_H
# include <Compound/var.h>
typedef struct {
int len;
Var *members;
} Array;
static Status ArrayIndexOutOfBound = {
.description = "Given index was accessing illegal address.",
.characteristic = STATUS_ERROR,
.prev = &MemoryViolation
};
static Status InvalidArrayLength = {
.description = "Given length is invalid.",
.characteristic = STATUS_ERROR,
.prev = &ErrorStatus
};
/* Elementary. */
Status Array_Create(Array *inst, int len);
Status Array_CopyOf(Array *inst, Array *other);
Status Array_Delete(Array *inst);
Status Array_GetIdx(Array *inst, Var *store, int index);
Status Array_SetIdx(Array *inst, Var *source, int index);
Status Array_Literalise(Array *inst, char const *store);
bool Array_Equal(Array *arr1, Array *arr2);
/* Extensional. */
Status ArrayUtils_Insert(Array *inst, Var *item, int index);
Status ArrayUtils_InsertArray(Array *inst, Array *items, int index);
Status ArrayUtils_Remove(Array *inst, int index);
Status ArrayUtils_RemoveArray(Array *inst, int off, int len);
Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len);
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len);
Status ArrayUtils_Search(Array *inst, Var *item, int *store);
Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store);
Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
Status ArrayUtils_Revert(Array *inst);
bool ArrayUtils_IsEmpty(Array *inst);
bool ArrayUtils_IsBlank(Array *inst);
#endif /* ARRAY_H */

83
Array/src/array.c Normal file
View File

@@ -0,0 +1,83 @@
#include <Compound/array.h>
Status Array_Create(Array *inst, int len)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
state((len < 0), InvalidArrayLength);
solve((!len), { inst->len = 0; inst->members = NULL; return NormalStatus; })
}
Status Array_CopyOf(Array *inst, Array *other)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
}
Status Array_Delete(Array *inst)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
}
Status Array_GetIdx(Array *inst, Var *store, int index)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
}
Status Array_SetIdx(Array *inst, Var *source, int index)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
}
Status Array_Literalise(Array *inst, char const *store)
{
/* Skip unavailable inst and invalid param. */
fails(inst, UnavailableInstance);
}
bool Array_Equal(Array *arr1, Array *arr2)
{
/* Skip unavailable inst and invalid param. */
state((arr1 == NULL || arr2 == NULL), false);
}
// Status Array_Create(Array *inst, int len)
// {
// fails(inst, UnavailableInstance);
// state(len < 0, InvalidArrayLength);
// Var arr[len] = {};
// *inst = (Array) {
// .len = len,
// .members = arr
// };
// /* Initialise members. */
// for (register int i = 0; i < inst->len; i++) {
// state(!(StatusUtils_IsOkay(Var_Create(&inst->members[i], NULL, 0, NULL))),
// error(RuntimeError,
// "Failed initialisations on var_create for array_create."));
// }
// return NormalStatus;
// }
// Status Array_Delete(Array *inst);
// bool ArrayUtils_IsEmpty(Array *inst);
// bool Array_Equal(Array *arr1, Array *arr2);

View File

@@ -1,5 +1,14 @@
cmake_minimum_required (VERSION 2.8) cmake_minimum_required (VERSION 3.5)
project (Compound) project (Compound)
add_executable(CompoundTest test.c) add_compile_options(-g -std=c99 -Wall -Wextra -Wformat)
add_executable(CompoundTest test.c
Var/src/var.c
Status/src/status.c
Stack/src/stack.c
Array/src/array.c
Utils/src/utils.c
catlog.c
name.c)

View File

@@ -1,8 +1,8 @@
#ifndef MEMMAN_H #ifndef COMPOUND_MEMMAN_H
#define MEMMAN_H # define COMPOUND_MEMMAN_H
#include <Compound/common.h> # include <Compound/common.h>
#include <Compound/status.h> # include <Compound/status.h>
/* /*
Higher the priority it is, the less time for lifespan it has. Higher the priority it is, the less time for lifespan it has.
@@ -10,48 +10,44 @@
typedef struct { typedef struct {
void *addr; void *addr;
int priority; // -1 for manual size_t length;
} Memory; int priority; // Negative for manual; Higher than 0 it is,
// higher the priority is.
} Memory; // 20 Bytes
typedef struct { typedef struct {
Memory *members; Memory *members;
size_t poolsize; size_t volume;
int priority; int priority;
} MemoryPool; } MemoryPool;
typedef struct { typedef struct {
MemoryPool *members; MemoryPool *members;
void *(*allocator)(size_t sz); void *(*allocator)(size_t sz);
void (*delocator)(void *addr); void (*deallocator)(void *addr);
} MemoryPoolManager; } MemoryPoolManager;
Status memman_memory_allocate(Memory *inst, size_t sz); Status MemMan_Memory_Allocate(Memory *inst, size_t length);
Status memman_memory_reallocate(Memory *inst, size_t sz); Status MemMan_Memory_Reallocate(Memory *inst, size_t length);
void memman_memory_release(Memory *inst); void MemMan_Memory_Release(Memory *inst);
Status MemMan_Memory_Prioritise(Memory *inst);
Status MemMan_Memory_Deprioritise(Memory *inst);
bool MemMan_Memory_Equal(Memory *inst, Memory *other);
Status memman_memorypool_create(MemoryPool *inst, Memory **members, Status MemMan_MemoryPool_Create(MemoryPool *inst, size_t volume);
size_t poolsize); Status MemMan_MemoryPool_Constr(MemoryPool *inst, size_t volume, int priority);
Status memman_memorypool_constr(MemoryPool *inst, Memory **members, Status MemMan_MemoryPool_AllocateAt(MemoryPool *inst, int idx, size_t sz);
size_t poolsize, int priority); Status MemMan_MemoryPool_ReallocateAt(MemoryPool *inst, int idx, size_t sz);
Status memman_memorypool_allocate(MemoryPool *inst, int idx, size_t sz); Status MemMan_MemoryPool_ReleaseAt(MemoryPool *inst, int idx);
Status memman_memorypool_reallocate(MemoryPool *inst, int idx, size_t sz); void MemMan_MemoryPool_Delete(MemoryPool *inst);
Status memman_memorypool_release(MemoryPool *inst, int idx);
Status memman_memorypool_prioritise(MemoryPool *inst, int idx);
Status memman_memorypool_deprioritise(MemoryPool *inst, int idx);
void memman_memorypool_delete(MemoryPool *inst);
Status memman_memorypoolmanager_create(MemoryPoolManager *inst, Status MemMan_MemoryPoolManager_Create(MemoryPoolManager *inst,
MemoryPool **membersptr); MemoryPool **members);
Status memman_memorypoolmanager_constr(MemoryPoolManager *inst, Status MemMan_MemoryPoolManager_Constr(MemoryPoolManager *inst,
MemoryPool **membersptr, MemoryPool **members,
void *(*allocator)(size_t sz), void *(*allocator)(size_t sz),
void (*delocator)(void *addr)); void (*deallocator)(void *addr));
Status memman_memorypoolmanager_addmember(MemoryPoolManager *inst, Status MemMan_MemoryPoolManager_Merge(MemoryPool *pool1, MemoryPool *pool2);
MemoryPool *newmember); Status MemMan_MemoryPoolManager_Divide(MemoryPool *src, int off, int len);
Status memman_memorypoolmanager_removemember(MemoryPoolManager *inst, int idx);
Status memman_memorypoolmanager_allocate(MemoryPoolManager *inst,
ArrayIndexerRange selected, size_t sz);
Status memman_memorypoolmanager_release(MemoryPoolManager *inst,
ArrayIndexerRange selected);
#endif /* MEMMAN_H */ #endif /* COMPOUND_MEMMAN_H */

110
Object/include/object.h Normal file
View File

@@ -0,0 +1,110 @@
#ifndef COMPOUND_OBJECT_H
# define COMPOUND_OBJECT_H
# include <Compound/array.h>
# include <Compound/namespace.h>
# include <Compound/type.h>
typedef struct { // interface
Var *data;
Array buffer;
int (*Literalise)(void);
int (*Correspond)(Var *other);
} Object;
# define OBJECT_IMPLEMENTATION Var *data; Array buffer;\
int (*Literalise)(void); int (*Correspond)(Var *other);
// private final String IDENTITY = ":D";
// public static final void main(String[] args) {}
typedef enum {
EXPOSURE_PUBLIC = 0,
EXPOSURE_PROTECTED,
EXPOSURE_PACKAGE,
EXPOSURE_PRIVATE
} Exposure;
typedef struct {
Type type;
Name identity;
} Parameter;
typedef struct {
Type type;
Name identity;
Array parameters;
} Function;
typedef struct {
Exposure prefix;
bool dynamic;
bool constant;
Type type;
Name identity;
Array type(Parameter) parameters;
} Member;
typedef struct {
Exposure prefix;
Name identity;
Array type(Parameter) parameters;
} Constructor;
/* As for destructors, they don't have prefixes or parameters,
because at the time you need destructors, you're already talking
in a environment that is private, private to this class alone.
And you also won't need any parameters, because to destruct, everything
you store in this class is bound to be vanished, and whatever you do to
modify them, the results are the same.
However, if you'd like to change something else that is not belong to
this class, why don't you just do them before calling destructors?
Therefor, in real practices, you won't find anything meaningful to let
a destructor having a prefix or a parameter.
Summary.
Prefixes are fixed to be "Private";
Parameters are fixed to be void.
*/
typedef struct {
Name identity;
} Destructor;
typedef struct {
OBJECT_IMPLEMENTATION
char *identity;
Array type(Member type(Constructor)) constructors; // Array<Member<Constructor>>
Member type(Destructor) destructor; // Member<Destructor>
Array type(Member type(?)) fields; // Array<Member<?>>
Array type(Member type(?)) methods; // Array<Member<?>>
} Class;
typedef enum {
MEMBER_ACCESS_READ = 0b001,
MEMBER_ACCESS_WRITE = 0b010,
MEMBER_ACCESS_EXEC = 0b100,
} MemberAccessMode;
Status Extern(Class *inst, Class *extrn);
Status Implement(Class *inst, Class *impl);
Status Class_Create(Class *inst, char *identity);
Status Class_CopyOf(Class *inst, Class *other);
Status Class_Constr(Class *inst, Array buffer, int (*Literalise)(void),
int (*Correspond)(Var*));
Status Class_Delete(Class *inst);
Status Class_GetIdentity(Class *inst, char *store);
Status Class_GetObject(Class *inst, Object *store);
Status Class_GetFieldByIdentity(Class *inst, Name *identity, Member *store)
throws(MemberNotFound);
Status Class_GetMethodByIdentity(Class *inst, Name *identity, Member *store)
throws(MemberNotFound);
Status Class_GetMembers(Class *inst, Array *store);
Status Class_MemberAccess(Class *inst, MemberAccessMode mode, Member *store);
Status Class_AddMember(Class *inst, int index, Member *target);
Status Class_RemoveMember(Class *inst, int index);
#endif /* COMPOUND_OBJECT_H */

0
Object/src/object.c Normal file
View File

46
README.md Normal file
View File

@@ -0,0 +1,46 @@
# YOU NEED COMPOUND
Generally, Compound is a library for general-purposes programming which you will find essential for higher level of abstraction based on c.
It is worth noticing that, this library is completely aimed for creating another language. That means, every feature update is supposedly to serve the language.
---
## BUILDING
To build Compound, all you need is to type as follow in a terminal:
```shell
cmake . # Generate "Makefile"
make # Build
```
> *PLEASE NOTICE*
> *Compound is originally designed for GNU/Linux and other Unix-like operating systems.*
> *Support for MS Windows will be possible in the future.*
### Platform specifications
```C
/* Copied on Fri 10 May 16:24:09 CST 2024 */
# if defined __x86_64__ || defined __x86_64 // For 64-bits operating systems.
# define __COMPOUND_64__
# define __COMPOUND_PRODUCT__ compound64
# elif defined __i386__ || __i486__ || __i586__ || __i686__ || _X86_ || __X86__ // For 32-bits operating systems.
# define __COMPOUND_32__
# define __COMPOUND_PRODUCT__ compound32
# else
# error Platform not supported. Please issue this on github.com/Wilhelm-Lee/Compound --William
# endif
```
Compound, now, roughly divides platform compatibilities into 2 major parts, the 64-bits and the 32-bits.
This idea is ready for refinements, you can put up such suggestions and they're welcomed.
## Installation
To install Compound, all you need to do is to run `install`, something like below.
```shell
./install # (Require root privilege)
```
If you cannot execute ./install script, try to add permission for execution:
```shell
chmod +x ./install # (Require root privilege)
```

18
Stack/include/stack.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef STACK_H
# define STACK_H
# include <Compound/var.h>
# include <Compound/status.h>
typedef struct {
Var *members;
int len;
} Stack;
Status Stack_Create(Stack *inst, int len);
Status Stack_CopyOf(Stack *inst, Stack *other);
Status Stack_Push(Stack *inst, Var *item);
Status Stack_Pop(Stack *inst);
bool Stack_IsEmpty(Stack *inst);
#endif /* STACK_H */

28
Stack/src/stack.c Normal file
View File

@@ -0,0 +1,28 @@
#include <Compound/stack.h>
Status Stack_Create(Stack *inst, int len)
{
// /* Skip once len is negative. */
// state((len < 0), InvalidParameter);
// /* Initialise before access. */
// if (inst == NULL) {
// *inst = (Stack) {
// .members = NULL,
// .len = len
// };
// /* Assign for each member. */
// inst->members = malloc(len * sizeof(Var));
// for (register int i = 0; i < len; i++) {
// inst->members[i] = (Var) {
// .addr = NULL,
// .sz = 0
// };
// }
// }
}
Status Stack_CopyOf(Stack *inst, Stack *other);
Status Stack_Push(Stack *inst, Var *item);
Status Stack_Pop(Stack *inst);
bool Stack_IsEmpty(Stack *inst);

View File

@@ -9,7 +9,9 @@
# include <time.h> # include <time.h>
# include <stdio.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 */ /* Status characteristics */
typedef enum { typedef enum {
@@ -18,22 +20,30 @@ typedef enum {
STATUS_ERROR = 1 STATUS_ERROR = 1
} StatusCharacteristics; } StatusCharacteristics;
//!!! UNKNOWN ENTITY !!!
// enum {
// ARGUE_FINALISED = 0b01,
// ARGUE_UNSETTLED =-0b01,
// ARGUE_POSITIVE = 0b10, typedef enum {
// ARGUE_NEGATIVE = -0b10, /* 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. */ /* Indicated the exact location where the "issue" was occurred at. */
typedef struct { typedef struct {
const char *file; char *file;
int line; int line;
const char *func; char *func;
} Location; } Location;
# define __HERE__ (Location){ \
.file = (char *)__FILE__, \
.line = __LINE__, \
.func = (char *)__func__ \
}
/* Common return type for reporting functions that require to give more /* Common return type for reporting functions that require to give more
information about the procedure. */ information about the procedure. */
typedef struct _Status { typedef struct _Status {
@@ -43,36 +53,41 @@ typedef struct _Status {
Otherwise, the function would just return the structure Status. */ Otherwise, the function would just return the structure Status. */
char *description; char *description;
int characteristic; int characteristic;
Location loc;
struct _Status *prev; struct _Status *prev;
} Status; } 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 { {value "description" characteristic prev}
FILE **dests_ref;
Report **reports_ref;
int totalreports;
int reportsent;
struct timespec elapsed;
} ReportSender;
typedef Status (*ReportSendingTask) (FILE **, Report *); "%d \"%s\" %d %p"
typedef int ReportSendingTaskID;
typedef struct { */
ReportSendingTask *tasks_ref;
int sendercount; # ifdef __COMPOUND_32__
int finishedcount; # define STATUS_LITERALISE_LENGTH(stat) \
Status *senderreturn; (utils_calc_digits(stat.value) + strlen(stat.description) + 2 + \
} ReportSendingManager; 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 { typedef enum {
REPORT_SENDING_TASK_STATUS_FINISHED = 0, REPORT_SENDING_TASK_STATUS_FINISHED = 0,
@@ -82,30 +97,97 @@ typedef enum {
REPORT_SENDING_TASK_STATUS_NOTFOUND REPORT_SENDING_TASK_STATUS_NOTFOUND
} ReportSendingTaskStatus; } 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 { typedef struct {
Argue argue_start; // Implicitly converting thrd_start_t to Argue Status stat;
void *external_param; char *originator;
} ArgueStarter; 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 { typedef enum {
ARGUMENT_NONE = 0, REPORT_SENDER_RESULT_FINISHED,
ARGUMENT_MINOR, REPORT_SENDER_RESULT_PROGRESSING,
ARGUMENT_NORMAL, REPORT_SENDER_RESULT_PENDING
ARGUMENT_MAJOR, } ReportSenderResult;
ARGUMENT_CRITICAL,
ARGUMENT_SEVERE,
ARGUMENT_ALL,
} ArgumentLevel;
typedef struct { typedef struct {
ReportSender *streams; thrd_t thread;
ArgueStarter handler; Report *report; // The report for sending.
ArgumentLevel level; time_t elapsed; // The individual elapsed time for each report. (Array)
bool muted; ReportSenderResult result;
} Argument; 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 { // typedef struct {
// Argument *members; // Argument *members;
@@ -114,73 +196,58 @@ typedef struct {
# define STATUS_BUFFER_MAXIMUM_LENGTH UINT32_MAX # 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 bool
status_issueposition_compare(Location lc1, Location lc2); Report_Equal(Report repo1, Report repo2);
bool Status
status_hasprev(Status stat); Report_Literalise(Report *inst, char *buff);
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 Status
reportsender_create(ReportSender *inst, FILE **dests_ref, ReportSender_Create(ReportSender *inst, Report *report);
ReportSendingTask *tasks_ref);
Status Status
reportsender_send(ReportSender sender, ReportSendingTask *tasks_ref); ReportSender_Send(ReportSender *inst, ReportSendingTask task);
ReportSendingTaskStatus
ReportSender_GetStatus(ReportSender *inst);
ReportSendingTaskID ReportSendingTaskID
reportsendingmanager_appendtask(ReportSendingManager *inst, ReportSenderManager_AppendTask(ReportSendingManager *inst,
ReportSendingTask task); ReportSendingTask task);
Status Status ReportSenderManager_RemoveTask(ReportSendingManager *inst,
reportsendingmanager_removetask(ReportSendingManager *inst, ReportSendingTaskID taskid);
ReportSendingTaskID taskid);
ReportSendingTaskStatus // Status
reportsendingmanager_taskstatus(ReportSendingManager *inst, // arguestarter_create(ArgueStartParam *inst, void *external_param);
ReportSendingTaskID taskid); // 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 // Status
arguestarter_create(ArgueStarter *inst, void *external_param); // argument_create(Argument *inst, ReportSender *streams, ArgueStartParam handler,
Status // int level, bool muted);
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);
// ---------------------ELEMENTARY-------------------------
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 = { static Status UnknownStatus = {
.description = "An unknown status.", .description = "An unknown status.",
@@ -200,12 +267,18 @@ static Status ErrorStatus = {
.prev = NULL .prev = NULL
}; };
// -------------------------------------------------------- // ----------------------EXTENDED--------------------------
static Status MemoryViolation = {
.description = "Illegal access on certain memory address.",
.characteristic = STATUS_ERROR,
.prev = &ErrorStatus
};
static Status NullPointerAccounted = { static Status NullPointerAccounted = {
.description = "An involving null pointer was not accepted.", .description = "An involving null pointer was not accepted.",
.characteristic = STATUS_ERROR, .characteristic = STATUS_ERROR,
.prev = &ErrorStatus .prev = &MemoryViolation
}; };
static Status InvalidParameter = { static Status InvalidParameter = {
@@ -226,4 +299,127 @@ static Status ArithmeticError = {
.prev = &ErrorStatus .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 */ #endif /* COMPOUND_STATUS_H */

View File

@@ -1,30 +1,174 @@
#include <Compound/common.h>
#include <Compound/status.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) && return ((!strcmp(lc1.file, lc2.file)) && (lc1.line == lc2.line) &&
(!strcmp(lc1.func, lc2.func))); (!strcmp(lc1.func, lc2.func)));
} }
bool status_hasprev(Status stat) { 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) { bool status_recursive(Status stat) {
return (stat.prev != NULL && stat.prev == &stat); return (stat.prev != NULL && stat.prev == &stat);
} }
void status_dump(Status stat, Status *statbuff, int idx) { void status_dump(Status inst, Status *statbuff, int idx) {
if (statbuff == NULL || !status_hasprev(stat) || idx < 0) {
return; /* Skip when either stat or stat.prev is unavailable, or, idx is invalid. */
solve((statbuff == NULL || !status_hasprev(inst) || idx < 0), return;);
statbuff[idx] = inst;
(void)printf("status_dump: Index %d has assigned with %p\n", idx, &inst);
status_dump(*inst.prev, statbuff, ++idx);
}
bool status_equal(Status stat1, Status stat2) {
/* Skip when both stat1 and stat2 are empty. */
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_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;
} }
statbuff[idx] = stat; return cnt;
status_dump(*stat.prev, statbuff, ++idx);
} }
bool status_compare(Status stat1, Status stat2) { Status report_create(Report *inst, Status *stat, FILE *dest, char *originator,
return (!strcmp(stat1.description, stat2.description) && int priority) {
(stat1.characteristic == stat2.characteristic) && /* Skip unavailable parameters. */
(!status_compare(*stat1.prev, *stat2.prev))); 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);
} }

9
String/include/char.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef COMPOUND_CHAR_H
# define COMPOUND_CHAR_H
typedef struct {
int value;
int width;
} Char; // 8 Bytes
#endif /* COMPOUND_CHAR_H */

97
String/include/string.h Normal file
View File

@@ -0,0 +1,97 @@
#ifndef COMPOUND_STRING_H
# define COMPOUND_STRING_H
# include <complex.h>
# include <wchar.h>
# include <Compound/char.h>
# include <Compound/array.h>
typedef enum {
ASCII,
UTF8,
/* etc. */
} StringEncoding;
typedef Array(Char) String;
/* Elementary. */
Status String_Create(String *inst, int len);
Status String_CopyOf(String *inst, String *other);
Status String_Delete(String *inst);
Status String_GetIdx(String *inst, Char *item, int index);
Status String_SetIdx(String *inst, Char *item, int index);
Status String_Literalise(String *inst, String *store);
Status String_Encode(String *inst, StringEncoding encoding)
throws(UnsupportedEncoding EncodingError DecodingError);
Status String_Decode(String *inst, StringEncoding encoding);
throws(UnsupportedEncoding EncodingError DecodingError);
bool String_Equal(String *arr1, String *arr2);
/* Extensional. */
Status StringUtils_FromInteger(String *inst, int value);
Status StringUtils_FromShortInteger(String *inst, short int value);
Status StringUtils_FromLongInteger(String *inst, long int value);
Status StringUtils_FromLongLongInteger(String *inst, long long int value);
Status StringUtils_FromFloat(String *inst, float value);
Status StringUtils_FromDouble(String *inst, double value);
Status StringUtils_FromLongDouble(String *inst, long double value);
Status StringUtils_FromComplexInteger(String *inst, _Complex int value);
Status StringUtils_FromComplexShortInteger(String *inst, _Complex short int value);
Status StringUtils_FromComplexLongInteger(String *inst, _Complex long int value);
Status StringUtils_FromComplexLongLongInteger(String *inst, _Complex long long value);
Status StringUtils_FromComplexFloat(String *inst, _Complex float value);
Status StringUtils_FromComplexDouble(String *inst, _Complex double value);
Status StringUtils_FromComplexLongDouble(String *inst, _Complex long double value);
Status StringUtils_FromUnsignedInteger(String *inst, unsigned int value);
Status StringUtils_FromUnsignedShortInteger(String *inst, unsigned short int value);
Status StringUtils_FromUnsignedLongInteger(String *inst, unsigned long int value);
Status StringUtils_FromUnsignedLongLongInteger(String *inst, unsigned long long int value);
Status StringUtils_FromUnsignedComplexInteger(String *inst, unsigned _Complex int value);
Status StringUtils_FromUnsignedComplexShortInteger(String *inst, unsigned _Complex short int value);
Status StringUtils_FromUnsignedComplexLongInteger(String *inst, unsigned _Complex long int value);
Status StringUtils_FromUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long value);
Status StringUtils_FromAddress(String *inst, void *store);
Status StringUtils_FromCharBuff(String *inst, char const *buff, int base);
Status StringUtils_FromWideCharBuff(String *inst, wchar_t const *wbuff, int base);
Status StringUtils_ToInteger(String *inst, int *store);
Status StringUtils_ToShortInteger(String *inst, short int *store);
Status StringUtils_ToLongInteger(String *inst, long int *store);
Status StringUtils_ToLongLongInteger(String *inst, long long int *store);
Status StringUtils_ToFloat(String *inst, float *store);
Status StringUtils_ToDouble(String *inst, double *store);
Status StringUtils_ToLongDouble(String *inst, long double *store);
Status StringUtils_ToComplexInteger(String *inst, _Complex int *store);
Status StringUtils_ToComplexShortInteger(String *inst, _Complex short int *store);
Status StringUtils_ToComplexLongInteger(String *inst, _Complex long int *store);
Status StringUtils_ToComplexLongLongInteger(String *inst, _Complex long long *store);
Status StringUtils_ToComplexFloat(String *inst, _Complex float *store);
Status StringUtils_ToComplexDouble(String *inst, _Complex double *store);
Status StringUtils_ToUnsignedInteger(String *inst, unsigned int *store);
Status StringUtils_ToUnsignedShortInteger(String *inst, unsigned short int *store);
Status StringUtils_ToUnsignedLongInteger(String *inst, unsigned long int *store);
Status StringUtils_ToUnsignedLongLongInteger(String *inst, unsigned long long int *store);
Status StringUtils_ToUnsignedComplexInteger(String *inst, unsigned _Complex int *store);
Status StringUtils_ToUnsignedComplexShortInteger(String *inst, unsigned _Complex short int *store);
Status StringUtils_ToUnsignedComplexLongInteger(String *inst, unsigned _Complex long int *store);
Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Complex long long *store);
Status StringUtils_ToAddress(String *inst, void **store);
Status StringUtils_ToCharBuff(String *inst, char const *buff, int base);
Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff, int base);
Status StringUtils_Format(String *inst, const String *__restrict fmt, ...);
Status StringUtils_Tokenise(String *inst, const String *delim, String *store);
int StringUtils_Compare(String *a, String *b);
static Status StringConversionPrecisionError = {
.description = "Unpreventable precision loss was found during conversion "
"between string and raw data.",
.characteristic = STATUS_ERROR,
.prev = &ImprecisionError
};
typedef Array(int) InfiniteInteger;
typedef Array(double) InfiniteFloatingPoint;
typedef Array(_Complex double) InfintieComplex;
#endif /* COMPOUND_STRING_H */

0
String/src/char.c Normal file
View File

45
String/src/string.c Normal file
View File

@@ -0,0 +1,45 @@
#include <Compound/string.h>
Status String_Create(String *inst, int len)
{
Status create = Array_Create(inst, len);
solve(!(StatusUtils_IsOkay(create)), {
Report e = stamp(error(create, "Failed to create a string."),
nameof(Array_Create));
(void)_throw(e);
return ReportThrown;
})
return NormalStatus;
}
Status String_CopyOf(String *inst, String *other)
{
fails(inst, UnavailableInstance);
}
Status String_Delete(String *inst)
{
fails(inst, UnavailableInstance);
}
Status String_GetIdx(String *inst, Char *store, int index)
{
fails(inst, UnavailableInstance);
}
Status String_SetIdx(String *inst, Char *source, int index)
{
fails(inst, UnavailableInstance);
}
Status String_Literalise(String *inst, String *store)
{
fails(inst, UnavailableInstance);
}
bool String_Equal(String *arr1, String *arr2)
{
fails(inst, UnavailableInstance);
}

9
Utils/include/utils.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef COMPOUND_UTILS_H
# define COMPOUND_UTILS_H
# include <Compound/common.h>
# include <Compound/const.h>
int Utils_CalcDigits(long long n);
#endif /* COMPOUND_UTILS_H */

16
Utils/src/utils.c Normal file
View File

@@ -0,0 +1,16 @@
#include <Compound/utils.h>
int Utils_CalcDigits(long long n)
{
if (n == 0) {
return 1;
}
n = llabs(n);
/* Accumulate. */
register int i;
for (i = 0; n; i++) n /= 10;
return i;
}

View File

@@ -2,18 +2,52 @@
# define COMPOUND_VAR # define COMPOUND_VAR
# include <stdio.h> # include <stdio.h>
# include <stdlib.h>
# include <wchar.h>
# include <stdint.h>
# include <Compound/common.h> # include <Compound/common.h>
# include <Compound/status.h>
# define VAR_IDENTITY_LENGTH 64
# define VAR_LITERALISE_LENGTH (VAR_IDENTITY_LENGTH + 16 + 9 + 10)
# define VAR_LITERALISE_FORMAT ("%s @[%p]: %ld")
# define VAR_IDENTITY_ILLEGAL_CHAR "!@#$%^*()-=+;\'\"\\|,./<>?[]{}`~ "
static Status IllegalVarIdentity = {
.description = "Given identity does not fit the standard of Var Naming "
"convension.",
.characteristic = STATUS_ERROR,
.prev = &InvalidParameter
};
// static Status VarIdentityTooLong = {
// .description = "Given identity has longer length that the maximum length "
// "limitation.",
// .characteristic = STATUS_ERROR,
// .prev = &IllegalVarIdentity
// };
typedef struct { typedef struct {
/* Data */
void *addr; void *addr;
size_t sz; size_t size;
/* Identification */
char *identity; // Maximum up to VAR_IDENTITY_LENGTH
} Var; } Var;
void var_swap(Var *v1, Var *v2); // typedef struct {
// union {
// /* Self Pointing (Var) */
// const Var *__this__;
// };
// } _Var;
int var_literalise(Var v, wchar_t **wbuff); Status Var_Create(Var *inst, void *addr, size_t size, char *identity);
Status Var_CopyOf(Var *inst, Var *other);
void Var_Delete(Var *inst);
Status VarUtils_Literalise(Var *inst, char *buff);
void VarUtils_Swap(Var *v1, Var *v2);
bool VarUtils_IsIdentityLegal(char *identity);
#endif /* COMPOUND_VAR */ #endif /* COMPOUND_VAR */

View File

@@ -1,17 +1,94 @@
#include <Compound/var.h> #include <Compound/var.h>
void var_swap(Var *v1, Var *v2) Status Var_Create(Var *inst, void *addr, size_t size, char *identity)
{ {
Var v3 = { /* Skip when inst is unavailable. */
.addr = v1->addr, fails(inst, UnavailableInstance);
.sz = v1->sz /* Skip when identity is unavailable. */
}; fails(identity, NullPointerAccounted);
/* Skip when identity does not pass the examine. */
state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity);
inst->addr = addr;
inst->size = size;
*inst->identity = *identity;
return NormalStatus;
}
Status Var_CopyOf(Var *inst, Var *other)
{
/* Skip when inst or other is unavailable. */
fails(inst, UnavailableInstance);
fails(other, NullPointerAccounted);
/* Copy and assign. */
inst->addr = other->addr;
inst->size = other->size;
*inst->identity = *other->identity;
return NormalStatus;
}
void Var_Delete(Var *inst)
{
/* Skip when inst or inst->addr is unavailable. */
svoid(inst == NULL || inst->addr == NULL);
inst->addr = NULL;
inst->size = 0;
*inst->identity = 0;
}
void VarUtils_Swap(Var *v1, Var *v2)
{
/* Skip when v1 or v2 is unavailable. */
svoid(v1 == NULL || v2 == NULL);
Var v3 = *v1;
*v1 = *v2; *v1 = *v2;
*v2 = v3; *v2 = v3;
} }
int var_literalise(Var v, wchar_t **wbuff) Status VarUtils_Literalise(Var *inst, char *buff)
{ {
return swprintf(*wbuff, (2*8 + 6), L"@[%p] +%u", v.addr, v.sz); /* Skip when inst is unavailable. */
state(inst == NULL, UnavailableInstance);
/* Write into buffer. */
state(!sprintf(buff, VAR_LITERALISE_FORMAT, inst->identity,
inst->addr, inst->size),
error(RuntimeError, "Sprintf returned 0 where it should never do."));
return NormalStatus;
}
bool VarUtils_IsIdentityLegal(char *identity)
{
/* Skip when identity is unavailable. */
state(identity == NULL, false);
const int len = strlen(identity);
/* Skip when identity is empty. */
state(len == 0, false);
/* Skip when the first char is not within alphabet. */
state(ATRANGE('a', 'z', identity[0])
|| ATRANGE('A', 'Z', identity[0]), false);
/* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */
state(len > VAR_IDENTITY_LENGTH, false);
/* Skip when identity has space and illegal characters in it. */
const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR);
for (register int i = 0; i < len; i++) {
for (register int j = 0; j < illegal_len; j++) {
if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) {
return false;
}
}
}
return true;
} }

27
attr.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef COMPOUND_ATTR_H
# define COMPOUND_ATTR_H
# include <Compound/name.h>
/* Only effect (probably) when formal Attribute is defined.
* __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
* eventually will.
*/
# define __ATTRIBUTABLE
# define __ATTRIBUTABLE__
# define attr(a)
typedef struct _Attribute{
int serialNo;
int (*exec)(void *);
struct _Attribute *prev;
} attr(Executive) Attribute;
/* The base of every attribute. */
# define Attributable (Attribute){\
.value = 0,\
.exec = HANDLER /* Use report handler here. */\
};
#endif /* COMPOUND_ATTR_H */

105
catlog.c Executable file
View File

@@ -0,0 +1,105 @@
#include <Compound/catlog.h>
#include <Compound/status.h>
Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
char const *originator, char const *msg)
{
/* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance);
state((originator == NULL || msg == NULL), InvalidParameter);
inst->time = time(NULL);
inst->level = level;
*inst->originator = *originator;
*inst->msg = *msg;
return NormalStatus;
}
Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other)
{
/* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance);
fails(other, InvalidParameter);
*inst = *other;
return NormalStatus;
}
bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other)
{
/* Skip unavailable instances and parameters. */
state((inst == NULL || other == NULL), false);
return (
inst->time == other->time &&
inst->level == other->level &&
(!strcmp(inst->originator, other->originator)) &&
(!strcmp(inst->msg, other->msg))
);
}
Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst)
{
/* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance);
fails(msg, InvalidParameter);
/* Copy and assign, with detections. */
inst->msg = *msg;
inst->dst = (dst == NULL ? (stdout) : dst);
inst->successful = false;
inst->elapsed = (struct timespec){.tv_sec = 0, .tv_nsec = 0};
return NormalStatus;
}
Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other)
{
/* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance);
fails(other, InvalidParameter);
/* Copy and assign */
inst->msg = other->msg;
inst->dst = other->dst;
inst->successful = other->successful;
inst->elapsed = other->elapsed;
return NormalStatus;
}
bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other)
{
/* Skip unavailable instances and parameters. */
state((inst == NULL || other == NULL), false);
return (
CatlogMsg_Equal(&inst->msg, &other->msg) &&
inst->dst == other->dst &&
inst->successful == other->successful &&
((inst->elapsed.tv_sec == other->elapsed.tv_sec) &&
(inst->elapsed.tv_nsec == other->elapsed.tv_nsec))
);
}
Status CatlogSender_Send(CatlogSender *inst, int *store, bool append)
throws(ReadWriteError)
{
/* Skip unavailable instances and parameters. */
fails(inst, UnavailableInstance);
fails(store, InvalidParameter);
/* Open file. */
ensure(CatlogUtils_OpenFile(inst->dst, "r"), "Unable to open file.");
ensure(CatlogMsg_Create(&(CatlogMsg){}, 0, "", ""), "Failed!");
/* Read file. */
/* Creating buffer, */
// TODO(william): Finish this function.
}
Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2);
Status CatlogUtils_OpenFile(FILE *store, const char const *__restrict mode);

45
catlog.h Executable file
View File

@@ -0,0 +1,45 @@
#ifndef COMPOUND_CATLOG_H
# define COMPOUND_CATLOG_H
# include <Compound/status.h>
# include <Compound/common.h>
typedef enum {
CATLOG_LEVEL_ALL, // Least the value, most the information.
CATLOG_LEVEL_MINOR,
CATLOG_LEVEL_NORMAL,
CATLOG_LEVEL_MAJOR,
CATLOG_LEVEL_CRITICAL,
CATLOG_LEVEL_FATAL,
CATLOG_LEVEL_DEBUG,
CATLOG_LEVEL_NONE
} CatlogLevel;
typedef struct {
time_t time;
CatlogLevel level;
char *originator;
char *msg;
} CatlogMsg;
Status CatlogMsg_Create(CatlogMsg *inst, CatlogLevel level,
char const *originator, char const *msg);
Status CatlogMsg_CopyOf(CatlogMsg *inst, CatlogMsg *other);
bool CatlogMsg_Equal(CatlogMsg *inst, CatlogMsg *other);
typedef struct {
CatlogMsg msg;
FILE *dst;
bool successful;
struct timespec elapsed;
} CatlogSender;
Status CatlogSender_Create(CatlogSender *inst, CatlogMsg *msg, FILE *dst);
Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other);
bool CatlogSender_Equal(CatlogSender *inst, CatlogSender *other);
Status CatlogSender_Send(CatlogSender *inst, int *store, bool append)
throws(ReadWriteError);
Status CatlogUtils_CalcElapsed(struct timespec t1, struct timespec t2);
Status CatlogUtils_OpenFile(FILE *store, const char *__restrict mode);
#endif /* COMPOUND_CATLOG_H */

119
common.h
View File

@@ -1,18 +1,9 @@
#ifndef COMMON_H #ifndef COMPOUND_COMMON_h
# define COMMON_H # define COMPOUND_COMMON_h
# include <stdlib.h> # include <stdlib.h>
# include <stdbool.h> # include <stdbool.h>
# define _buffer_definition_without_assignment(type, length) \
struct { type data[(length)]; const int len; }
# define Buffer(type, length, var) \
_buffer_definition_without_assignment(type, length) \
var = { .data = {}, .len = length }
# define Array(type, length, var) type var[(length)]
/** /**
* @brief Return $n as the return value, once $o is NULL * @brief Return $n as the return value, once $o is NULL
* @return given $n as the return value * @return given $n as the return value
@@ -20,7 +11,7 @@
* @note 'o' stands for "Object" * @note 'o' stands for "Object"
* @note 'n' stands for "Numeric on Return" * @note 'n' stands for "Numeric on Return"
*/ */
# define fails(o, n) {if ((o) == NULL) return (n);} # define fails(o, n) { if ((o) == NULL) return (n); }
/** /**
* @brief Return $e as the return value, once $v equals $e * @brief Return $e as the return value, once $v equals $e
@@ -29,16 +20,100 @@
* @note 'v' stands for "Value" * @note 'v' stands for "Value"
* @note 'e' stands for "Error Code" * @note 'e' stands for "Error Code"
*/ */
# define trans(v, e) {if ((v) == (e)) return (e);} # define trans(v, e) { if ((v) == (e)) return (e); }
///** /**
// * @brief Evaluate given statement while the ptr to $s is not NULL * @brief Evaluate given statement while the ptr to $s is not NULL
// * @return given $n as the return value * @return given $n as the return value
// * @note "state" stands for "Statement Evaluation" * @note "state" stands for "Statement Evaluation"
// * @note 's' stands for "Statement" * @note 's' stands for "Statement"
// * @note 'n' stands for "Numeric on Return" * @note 'n' stands for "Numeric on Return"
// */ */
//# define state(s, n) {if ((#s)) return (n);} # define state(s, n) { if ((s)) return (n); }
/**
* @brief Evaluate given statement while the ptr to $s is not NULL
* @return nothing.
* @note "svoid" stands for "Statement Evaluation in Void"
* @note 's' stands for "Statement"
*/
# define svoid(s) { if ((s)) return; }
/**
* @brief Return an Error Status with given parameter $c as the
* comment or description.
* @return A instance of Error Status customised.
* @note "error" stands for "Error in Status"
* @note 'e' stands for "Error"
* @note 'c' stands for "Comment"
*/
# define error(e, c) ((Status) {\
.description = c,\
.characteristic = e.characteristic,\
.prev = e.prev\
})
/**
* @brief Return an Error Status with given parameter $p as the
* predecessor.
* @return A instance of Error Status inherited.
* @note "extend" stands for "Extend from Predecessor"
* @note 'i' stands for 'Instance'
* @note 'p' stands for "Predecessor"
*/
# define extend(i, p) ((Status)) {\
.prev = p\
}
# define modify(e, s, c) ((Status)) {\
.description = s,\
.characteristic = c,\
.prev = e.prev\
}
/** @brief Create a report in place.
* @return A instance of Status Report customised.
* @note "stamp" stands for "Report Stamp"
* @note 'e' stands for "Exception"
* @note 'c' stands for "Char String of Originator"
*/
# define stamp(e, c) ((Report) {\
.stat = e,\
.originator = c,\
.time = time(NULL),\
.priority = REPORT_SENDING_PRIORITY_NORMAL,\
.status = REPORT_SENDING_TASK_STATUS_PENDING\
})
/**
* @brief Another way to handle if statements more cleanly.
* @note "solve" stands for "Solve with Statements."
* @note 's' stands for "Statement"
* @note 'b' stands for "Block of Forks"
*/
# define solve(s, b) if (s) b
// /**
// * @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)
/* Get the literal. */
# define nameof(obj) #obj
# define type(T)
/* Only effects when Generic is defined. */
# define Array(T) Array
# define String(T) String
typedef enum { typedef enum {
COMMON_ERROR_NULLPTR = 1, COMMON_ERROR_NULLPTR = 1,
@@ -73,4 +148,4 @@ typedef bool _Bit;
# define ATRANGE(lf, rt, v) \ # define ATRANGE(lf, rt, v) \
(INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt)) (INRANGE(lf, true, rt, true, v)) ? 0 : ((v < lf) ? (v - lf) : (v - rt))
#endif /* NO COMMON_H */ #endif /* NO COMPOUND_COMMON_h */

17
const.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef COMPOUND_CONST_H
# define COMPOUND_CONST_H
# define INT32_DIGITS_DEC 10
# define INT32_DIGITS_HEX 8
# define INT64_DIGITS_DEC 19
# define INT64_DIGITS_HEX 16
// # define UINT32_DIGITS_DEC 10
// # define UINT32_DIGITS_HEX
// # define UINT64_DIGITS_DEC 20
// # define UINT64_DIGITS_HEX 16
#endif /* COMPOUND_CONST_H */

View File

@@ -11,7 +11,8 @@ fi
SRC="$PWD" SRC="$PWD"
DST=/usr/include/Compound DST=/usr/include/Compound
PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan") PROJ=("Array" "Paper" "Pen" "Render" "Status" "Var" "MemMan" "Stack" "Utils"\
"String")
PROJLEN=${#PROJ[*]} PROJLEN=${#PROJ[*]}
echo "======== $PROJLEN projects in total ========" echo "======== $PROJLEN projects in total ========"
@@ -32,5 +33,7 @@ while :; do
echo echo
done done
cp -v "common.h" "$DST" cp -v "common.h" "const.h" "platform.h"\
"name.h" "type.h" "catlog.h"\
"attr.h" "$DST"
printf "\nDone\n" printf "\nDone\n"

71
name.c Normal file
View File

@@ -0,0 +1,71 @@
#include <Compound/name.h>
Status NameSpace_Create(NameSpace *inst)
{
fails(inst, UnavailableInstance);
/* Create instances for members from inst. */
state(status_isokay(NameSpace_EmptyName(&inst->latest)),
error(RuntimeError, "Failed to initialise latest from NameSpace"));
state(status_isokay(NameSpace_EmptyName(&inst->idx)),
error(RuntimeError, "Failed to initialise idx from NameSpace"));
state(status_isokay(NameSpace_EmptyName(inst->occupied)),
error(RuntimeError, "Failed to initialise occupied from NameSpace"));
return NormalStatus;
}
Status NameSpace_CopyOf(NameSpace *inst, NameSpace *other)
{
fails(inst, UnavailableInstance);
fails(other, UnavailableParameter);
/* Copy and assign. */
other->latest = inst->latest;
other->idx = inst->idx;
const Name len = NameSpace_CalcNameArrayLength(&other->occupied);
for (Name i = (Name){0}; (NameSpace_CompareName(i, len) < 0);) {
// TODO(william): HERE
/* i++ */
state((!status_isokay(NameSpace_CountUp(&i))),
error(RuntimeError, "Error occurred during calculations of Name."));
}
}
Status NameSpace_CreateName(NameSpace *inst, Name *buff);
Status NameSpace_RemoveName(NameSpace *inst, Name idx);
Status NameSpace_EmptyName(Name *inst);
Status NameSpace_CountUp(Name *inst);
Status NameSpace_CountDown(Name *inst);
Status NameSpace_CountUpFor(Name *inst, Name amount);
Status NameSpace_CountDownFor(Name *inst, Name amount);
Status NameSpace_UpdateLatest(NameSpace *inst, Name idx);
Status NameSpace_FormatTrim(Name *inst);
Status NameSpace_FormatInflate(Name *inst);
Name NameSpace_CalcNameArrayLength(Name **arr);
bool NameSpace_IsAvailable(NameSpace *inst, Name idx);
bool NameSpace_IsValidName(Name *inst);
int NameSpace_CompareName(Name *a, Name *b)
{
/* Validation comes the first. --William */
if (!NameSpace_IsValidName(a) || !NameSpace_IsValidName(b)) {
Report e; ArgueStartParam h;
throw(stamp(&InvalidName));
}
}

88
name.h Normal file
View File

@@ -0,0 +1,88 @@
#ifndef COMPOUND_NAME_H
# define COMPOUND_NAME_H
# include <Compound/common.h>
# include <Compound/status.h>
# include <Compound/array.h>
// Name, is a base of numeral counting.
// It uses 63 as the base, lasts for 63 times.
// At the head of each Name, 8 pilots stores for its type.
// In total, ((26*2+10+1)^63)*8
// = 63^63*8
// = 1.82618429078e+114
// Nice. :3
// William, Sun 12 May, 2024, 02:29:36
# define NAME_LENGTH_MAXIMUM 64
# define NAME_LEGAL_CHARACTERS "abcdefghijklmnopqrstuvwxyz"\
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
"1234567890"
typedef struct {
char *identifier;
Array(int) attributions;
} Name;
static const Name NullName = {
.identifier =
"_000000000000000000000000000000000000000000000000000000000000000",
.attributions = NULL
};
// typedef struct {
// Name value;
// Name idx;
// Name *occupied;
// } NameSpace; // Size: 8+8+8 =8*3 =24 Bytes (x64)
/*
* Example:
* Var variable_from_namespace_Utils_in_class_Calculation_in_function_C;
* // Not enough room for representation.
* // Must use another more efficient method to store the name.
* Become (roughly):
* Var v0000000000000000000000000000000000000000000000000000000000001g3;
* Var v1g3; // Trimmed.
* PILOT: v, f, c, e, i, s, u, a
* v: Variable
* f: Function
* c: Class
* e: Enumeration
* i: Interface
* s: Struct
* u: Union
* a: Attribution
* ID: [a-zA-Z0-9_]
* MAXIMUM STORING SIZE: 63 Bytes
* TOTAL POSSIBILITIES: ((26*2+10+1)^63)*8 = 1.82618429078e+114
* Definitely enough.
*
* Please note, numeral symbols cannot lead the name.
* They must have indexer that greater than ZERO.
*/
Status Name_CountDown(Name *inst);
Status Name_CountDownFor(Name *inst, Name amount);
Status Name_CountUp(Name *inst);
Status Name_CountUpFor(Name *inst, Name amount);
Status Name_EmptyName(Name *inst);
Status Name_FormatInflate(Name *inst);
Status Name_FormatTrim(Name *inst);
Name Name_CalcNameArrayLength(Name **arr);
bool Name_IsValid(Name *inst);
int Name_Compare(Name *a, Name *b) throws(InvalidName);
static Status NameOverFlowError = {
.description = "An overflow occurred while calculating Name.",
.characteristic = STATUS_ERROR,
.prev = &ArithmeticError
};
static Status InvalidName = {
.description = "Given Name was invalid.",
.characteristic = STATUS_ERROR,
.prev = &InvalidParameter
};
#endif /* COMPOUND_NAME_H */

0
namescope.c Normal file
View File

26
namescope.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef COMPOUND_NAMESCOPE_H
# define COMPOUND_NAMESCOPE_H
# include <Compound/array.h>
# include <Compound/name.h>
typedef struct {
Array(Name) name_data;
} NameScope;
# define NameScope(T) NameScope
Status NameScope_Create(NameScope *inst);
Status NameScope_CopyOf(NameScope *inst, NameScope *other);
Status NameScope_CreateName(NameScope *inst, Name *buff);
Status NameScope_RemoveName(NameScope *inst, Name idx);
Status NameScope_UpdateLatest(NameScope *inst, Name idx);
bool NameScope_Equal(NameScope *inst, NameScope *other);
bool NameScope_IsAvailable(NameScope *inst, Name idx);
/* Universal Attribute NameScope. (U.A.N.) */
NameScope(Attribute) UniversalAttributeNameScope;
NameScope MemoryAllocationRegistry;
#endif /* COMPOUND_NAMESCOPE_H */

14
platform.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef COMPOUND_PLATFORM_H
# define COMPOUND_PLATFORM_H
# if defined __x86_64__ || defined __x86_64
# define __COMPOUND_64__
# define __COMPOUND_PRODUCT__ compound64
# elif defined __i386__ || __i486__ || __i586__ || __i686__ || _X86_ || __X86__
# define __COMPOUND_32__
# define __COMPOUND_PRODUCT__ compound32
# else
# error Platform not supported. Please issue this on github.com/Wilhelm-Lee/Compound --William
# endif
#endif /* COMPOUND_PLATFORM_H */

54
registry.h Normal file
View File

@@ -0,0 +1,54 @@
#ifndef COMPOUND_SECURITY_REGISTRY_H
# define COMPOUND_SECURITY_REGISTRY_H
# include <Compound/memman.h>
/*
By calculating SHA256, we can identify whether the original data has been
modified maliciously or not.
However, In current particular cases, it is contradictive that we would
wish to use the same approach to validate and protect the data that we used
for validating and protecting other data.
Thus, it is not practical to use current existing methods to create
a way that is 100% perfect for data safety and computation security.
What we actually need is to ensure that our data from either struct or
union wouldn't be modifies easily, not in C, but in Classify, the language
that rely on this very project, Compound.
*/
typedef struct {
Memory data;
char SHA256[256];
} RegItem; // 276 Bytes
typedef union {
RegItem items[256];
} RegTable256; // 4416 Bytes | 4.3125 KiB
typedef union {
RegItem items[128];
} RegTable128; // 2208 Bytes | 2.15625 KiB
typedef union {
RegItem items[64];
} RegTable64; // 1104 Bytes | 1.078125 KiB
typedef union {
RegItem items[32];
} RegTable32; // 552 Bytes
typedef union {
RegItem items[16];
} RegTable16; // 276 Bytes
typedef union {
RegItem items[8];
} RegTable8; // 138 Bytes
bool Registry_Validate(const RegItem const *item, const RegResult const *result);
bool Registry_Calculate(const RegItem const *item, const RegResult const *result);
bool RegistryTable64_
#endif /* COMPOUND_SECURITY_REGISTRY_H */

11
type.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef COMPOUND_TYPE_H
# define COMPOUND_TYPE_H
# include <Compound/var.h>
typedef struct {
char *identity;
Var data;
} Type;
#endif /* COMPOUND_TYPE_H */