xtandard/xtandard.c
2023-11-03 08:25:15 -04:00

916 lines
23 KiB
C

/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
Xtandard is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/
#ifndef XTANDARD_SOURCE
#define XTANDARD_SOURCE
#include <xolatile/xtandard.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
static char * log_notify = NULL;
static int argument_count = 0;
static char * * argument_nick = NULL;
static char * * argument_name = NULL;
static char * argument_input = NULL;
static char * argument_output = NULL;
static void (* * argument_function) (void) = NULL;
static int file_list_active = 0;
static int file_list_count = 0;
static int * file_list_mark = NULL;
static int * file_list_size = NULL;
static char * * file_list_name = NULL;
static char * * file_list_data = NULL;
void in (void * data, int size) {
fatal_failure (data == NULL, "in: Failed to read from standard input, data is null pointer.");
fatal_failure (size == 0, "in: Failed to read from standard input, size is zero.");
(void) read (STDIN_FILENO, data, (unsigned long int) size);
}
void out (void * data, int size) {
fatal_failure (data == NULL, "out: Failed to write to standard output, data is null pointer.");
fatal_failure (size == 0, "out: Failed to write to standard output, size is zero.");
(void) write (STDOUT_FILENO, data, (unsigned long int) size);
}
void log_in (int type, int flag, char * data) {
int start;
char * type_mark [LOG_COUNT] = {
"[\033[1;32mSuccess\033[0m] ",
"[\033[1;33mWarning\033[0m] ",
"[\033[1;31mFailure\033[0m] ",
"[\033[1;30mComment\033[0m] "
};
if ((flag == 0) || (type <= -1) || (type >= LOG_COUNT)) {
return;
}
start = string_length (log_notify);
log_notify = reallocate (log_notify, start + string_length (type_mark [type]) + string_length (data) + 2);
log_notify [start] = '\0';
string_concatenate (log_notify, type_mark [type]);
string_concatenate (log_notify, data);
string_concatenate (log_notify, "\n");
}
void log_out (char * name) {
dump (name, log_notify);
log_notify = deallocate (log_notify);
}
void echo (char * data) {
if (data == NULL) {
return;
}
out (data, string_length (data));
}
void dump (char * name, char * data) {
int file = -1;
if (name == NULL) {
echo (data);
return;
}
if (data == NULL) {
return;
}
file = file_open (name, O_RDWR | O_CREAT | O_APPEND);
file_write (file, data, string_length (data));
file = file_close (file);
}
void echo_byte (int byte) {
out ("0123456789ABCDEF" + (byte % 256) / 16, 1);
out ("0123456789ABCDEF" + (byte % 256) % 16, 1);
out (" ", 1);
}
void fatal_failure (int condition, char * message) {
if (condition != 0) {
echo ("[\033[1;31mExiting\033[0m] ");
echo (message);
echo ("\n");
exit (EXIT_FAILURE);
}
}
void limit (int * value, int minimum, int maximum) {
if (value == NULL) {
return;
}
if (* value <= minimum) {
* value = minimum;
}
if (* value >= maximum) {
* value = maximum;
}
}
void * allocate (int size) {
char * data = NULL;
if (size <= 0) {
return (NULL);
}
data = calloc ((unsigned long int) size, sizeof (* data));
fatal_failure (data == NULL, "standard : allocate : Failed to allocate memory, internal function 'calloc' returned null pointer.");
return ((void *) data);
}
void * reallocate (void * data, int size) {
if (size <= 0) {
return (data);
}
data = realloc (data, (unsigned long int) size);
fatal_failure (data == NULL, "standard : reallocate: Failed to reallocate memory, internal function 'realloc' returned null pointer.");
/* Set new data to 0. */
return (data);
}
void * deallocate (void * data) {
if (data != NULL) {
free (data);
}
return (NULL);
}
void * memorize (int size) { /* I broke this for testing something out... */
static char * buffer = NULL;
char * points = NULL;
static int length = 0;
static int chunks = 0;
static int loling = 1024;
if (size == 0) {
free (buffer);
buffer = NULL;
length = 0;
chunks = 0;
return (NULL);
}
for (; length + size > chunks * loling; ) {
int i;
++chunks;
buffer = realloc (buffer, (unsigned long int) (chunks * loling));
fatal_failure (buffer == NULL, "memorize: Oh no...");
for (i = (chunks - 1) * loling; i != chunks * loling; ++i) {
buffer [i] = '\0';
}
}
points = & buffer [length];
length += size;
return ((void *) points);
}
void * record (void) {
char * buffer = NULL;
int offset = 0;
int loling = 1024;
buffer = reallocate (buffer, loling);
do {
if ((offset + 1) % loling == 0) {
buffer = reallocate (buffer, ((offset + 1) / loling + 1) * loling);
}
buffer [offset] = '\0';
in (& buffer [offset], (int) sizeof (* buffer));
++offset;
} while (buffer [offset - 1] != '\0');
buffer [offset - 1] = '\0';
return (buffer);
}
void argument_define (char * nick, char * name, void (* function) (void)) {
fatal_failure (nick == NULL, "argument_define: Failed to define an argument, nick is null pointer.");
fatal_failure (name == NULL, "argument_define: Failed to define an argument, name is null pointer.");
fatal_failure (function == NULL, "argument_define: Failed to define an argument, function is null pointer.");
++argument_count;
argument_nick = reallocate (argument_nick, argument_count * (int) sizeof (* argument_nick));
argument_name = reallocate (argument_name, argument_count * (int) sizeof (* argument_name));
argument_function = reallocate (argument_function, argument_count * (int) sizeof (* argument_function));
argument_nick [argument_count - 1] = allocate (string_length (nick) + 1);
argument_name [argument_count - 1] = allocate (string_length (name) + 1);
string_copy (argument_nick [argument_count - 1], nick);
string_copy (argument_name [argument_count - 1], name);
argument_function [argument_count - 1] = function;
}
void argument_select (int count, char * * array) {
int index_a = 0;
int index_b = 0;
if ((count == 1) || (array == NULL)) {
return;
}
for (index_a = 1; index_a != count; ++index_a) {
for (index_b = 0; index_b != argument_count; ++index_b) {
if ((string_compare (array [index_a], "-h") != 0) || (string_compare (array [index_a], "--help") != 0)) {
for (index_b = 0; index_b != argument_count; ++index_b) {
echo ("\t"); echo (argument_nick [index_b]);
echo (" "); echo (argument_name [index_b]);
echo ("\n");
}
} else if ((string_compare (array [index_a], "-i") != 0) || (string_compare (array [index_a], "--input") != 0)) {
++index_a;
argument_input = array [index_a];
break;
} else if ((string_compare (array [index_a], "-o") != 0) || (string_compare (array [index_a], "--output") != 0)) {
++index_a;
argument_output = array [index_a];
break;
} else if ((string_compare (array [index_a], argument_nick [index_b]) != 0) || (string_compare (array [index_a], argument_name [index_b]) != 0)) {
argument_function [index_b] ();
break;
}
}
}
}
void argument_delete (void) {
int index;
for (index = 0; index != argument_count; ++index) {
argument_nick [index] = deallocate (argument_nick [index]);
argument_name [index] = deallocate (argument_name [index]);
}
argument_nick = deallocate (argument_nick);
argument_name = deallocate (argument_name);
argument_function = deallocate (argument_function);
}
int file_open (char * name, int mode) {
int descriptor = -1;
fatal_failure (name == NULL, "file_open: Failed to open file, name is null pointer.");
descriptor = open (name, mode);
fatal_failure (descriptor == -1, "file_open: Failed to open file, function open returned invalid descriptor.");
return (descriptor);
}
int file_close (int file) {
fatal_failure (file == -1, "file_close: Failed to close file, invalid file descriptor.");
fatal_failure (close (file) == -1, "file_close: Failed to close file, function close returned invalid code.");
return (-1);
}
void file_read (int file, void * data, int size) {
fatal_failure (file == -1, "file_read: Failed to read from file, invalid descriptor.");
fatal_failure (data == NULL, "file_read: Failed to read from file, data is null pointer.");
fatal_failure (size == 0, "file_read: Failed to read from file, size is zero.");
(void) read (file, data, (unsigned long int) size);
}
void file_write (int file, void * data, int size) {
fatal_failure (file == -1, "file_write: Failed to write to file, invalid descriptor.");
fatal_failure (data == NULL, "file_write: Failed to write to file, data is null pointer.");
fatal_failure (size == 0, "file_write: Failed to write to file, size is zero.");
(void) write (file, data, (unsigned long int) size);
}
int file_seek (int file, int whence) {
fatal_failure (file == -1, "file_seek: Failed to seek in file, invalid descriptor.");
return ((int) lseek (file, 0, whence));
}
int file_size (char * name) {
int size = -1;
int file = -1;
file = file_open (name, O_RDONLY);
size = lseek (file, 0, SEEK_END);
fatal_failure (size == -1, "file_size: Failed to get size of file, invalid file size.");
file = file_close (file);
return (size);
}
int file_type (char * name) {
char * file_type_data [FILE_TYPE_COUNT] = {
".txt", ".s", ".fasm", ".gasm", ".nasm", ".yasm", ".c", ".h",
".adb", ".ads", ".cpp", ".hpp"
};
int type = 0;
while (* name != '.') {
++name;
}
for (type = 0; type != FILE_TYPE_COUNT; ++type) {
if (string_compare (name, file_type_data [type]) != 0) {
return (type);
}
}
return (-1);
}
void * file_record (char * name) {
int file = -1;
int size = -1;
char * data = NULL;
fatal_failure (name == NULL, "file_import: Failed to import file, name is null pointer.");
file = file_open (name, O_RDONLY);
size = file_size (name);
data = allocate (size);
file_read (file, data, size);
file = file_close (file);
return (data);
}
char * file_import (char * name) {
int file = -1;
int size = -1;
char * data = NULL;
fatal_failure (name == NULL, "file_import: Failed to import file, name is null pointer.");
file = file_open (name, O_RDONLY);
size = file_size (name) + 1;
data = allocate (size);
file_read (file, data, size - 1);
data [size - 1] = '\0';
file = file_close (file);
return (data);
}
void file_export (char * name, void * data) {
(void) name;
(void) data;
}
void file_list_import (char * name) {
fatal_failure (name == NULL, "file_list_import: Failed to import file, name is null pointer.");
++file_list_count;
file_list_active = file_list_count - 1;
file_list_mark = reallocate (file_list_mark, (int) sizeof (* file_list_mark) * file_list_count);
file_list_size = reallocate (file_list_size, (int) sizeof (* file_list_size) * file_list_count);
file_list_name = reallocate (file_list_name, (int) sizeof (* file_list_name) * file_list_count);
file_list_data = reallocate (file_list_data, (int) sizeof (* file_list_data) * file_list_count);
file_list_mark [file_list_active] = -1;
file_list_size [file_list_active] = -1;
file_list_name [file_list_active] = NULL;
file_list_data [file_list_active] = NULL;
file_list_name [file_list_active] = allocate (string_length (name) + 1);
(void) string_copy_limit (file_list_name [file_list_active], name, string_length (name) + 1);
file_list_mark [file_list_active] = open (name, O_RDWR);
fatal_failure (file_list_mark [file_list_active] == -1, "file_list_import: Failed to open file, function open returned invalid descriptor.");
file_list_size [file_list_active] = (int) lseek (file_list_mark [file_list_active], 0, SEEK_END) + 1;
(void) lseek (file_list_mark [file_list_active], 0, SEEK_SET);
file_list_data [file_list_active] = allocate (file_list_size [file_list_active]);
(void) read (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) (file_list_size [file_list_active] - 1));
close (file_list_mark [file_list_active]);
file_list_data [file_list_active] [file_list_size [file_list_active] - 1] = '\0';
}
void file_list_export (char * name) {
fatal_failure (name == NULL, "file_list_export: Failed to export file, name is null pointer.");
file_list_mark [file_list_active] = open (name, O_WRONLY | O_CREAT | O_TRUNC);
(void) write (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) file_list_size [file_list_active]);
close (file_list_mark [file_list_active]);
}
void file_list_insert_character (char character, int position) {
int offset;
++file_list_size [file_list_active];
if (file_list_size [file_list_active] < string_length (file_list_data [file_list_active])) {
file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]);
}
file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]);
for (offset = file_list_size [file_list_active] - 1; offset != position; --offset) {
file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset - 1];
}
file_list_data [file_list_active] [position] = character;
}
void file_list_remove_character (int position) {
int offset;
if (position == 0) {
return;
}
--file_list_size [file_list_active];
for (offset = position - 1; offset != file_list_size [file_list_active] - 1; ++offset) {
file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset + 1];
}
file_list_data [file_list_active] [offset] = '\0';
}
void file_list_delete (void) {
int i;
for (i = 0; i != file_list_count; ++i) {
file_list_name [i] = deallocate (file_list_name [i]);
file_list_data [i] = deallocate (file_list_data [i]);
}
file_list_mark = deallocate (file_list_mark);
file_list_size = deallocate (file_list_size);
file_list_name = deallocate (file_list_name);
file_list_data = deallocate (file_list_data);
}
int character_is_uppercase (char character) {
return ((int) ((character >= 'A') && (character <= 'Z')));
}
int character_is_lowercase (char character) {
return ((int) ((character >= 'a') && (character <= 'z')));
}
int character_is_digit (char character) {
return ((int) ((character >= '0') && (character <= '9')));
}
int character_is_blank (char character) {
return ((int) ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n')));
}
int character_is_alpha (char character) {
return ((character_is_uppercase (character) != 0) || (character_is_lowercase (character) != 0));
}
int character_is_symbol (char character) {
char * symbols = "~!@#$%^&*()+{}|:\"<>?`-=[]\\;',./";
return (character_compare_array (character, symbols));
}
int character_is_visible (char character) {
return ((int) ((character >= ' ') && (character <= '~')));
}
int character_is_invisible (char character) {
return (character_is_visible (character) == 0);
}
int character_is_escape (char character) {
return ((int) (character == '\033'));
}
int character_is_underscore (char character) {
return ((int) (character == '_'));
}
int character_is_hexadecimal (char character) {
char * hexadecimals = "0123456789ABCDEF";
return (character_compare_array (character, hexadecimals));
}
int character_compare_array (char character, char * character_array) {
int i = 0;
do {
if (character == character_array [i]) {
return (1);
}
} while (++i != string_length (character_array));
return (0);
}
int character_count (char * string, char this, int from, int to, char stop) {
int count;
for (count = 0; (from != to) && (string [from] != stop); from += (int) ((to < from) ? -1 : 1)) {
count += (int) ((string [from] == this) || (this == '\0'));
}
/*
if (to < from) {
for (count = 0; (to < from) && (string [from] != stop); --from) {
count += (int) ((string [from] == this) || (this == '\0'));
}
} else if (from < to) {
for (count = 0; (from < to) && (string [from] != stop); ++from) {
count += (int) ((string [from] == this) || (this == '\0'));
}
} else {
count = 0;
}
*/
return (count);
}
int string_length (char * string) {
int length;
if (string == NULL) {
return (0);
}
for (length = 0; string [length] != '\0'; ++length);
return (length);
}
char * string_reverse_limit (char * string, int limit) {
int i;
fatal_failure (string == NULL, "string_reverse: String is null pointer.");
for (i = 0; i < limit / 2; ++i) {
char temporary = string [i];
string [i] = string [limit - 1 - i];
string [limit - 1 - i] = temporary;
}
return (string);
}
char * string_reverse (char * string) {
return (string_reverse_limit (string, string_length (string)));
}
char * string_delete (char * string, int length) {
int i;
if ((string == NULL) || (length <= 0)) {
return (string);
}
for (i = 0; i != length; ++i) {
string [i] = '\0';
}
return (string);
}
int string_compare (char * string_0, char * string_1) {
int i = 0;
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer.");
for (i = 0; (string_0 [i] != '\0') && (string_1 [i] != '\0'); ++i) {
if (string_0 [i] != string_1 [i]) {
return (0);
}
}
return (1);
}
char * string_copy (char * string_0, char * string_1) {
int i = 0;
fatal_failure (string_0 == NULL, "string_copy: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_copy: Source string is null pointer.");
for (i = 0; i != string_length (string_1) + 1; ++i) {
string_0 [i] = string_1 [i];
}
return (string_0);
}
char * string_concatenate (char * string_0, char * string_1) {
fatal_failure (string_0 == NULL, "string_concatenate: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_concatenate: Source string is null pointer.");
string_0 += string_length (string_0);
while (* string_1 != '\0') {
* string_0++ = * string_1++;
/*++string_0;
++string_1;*/
}
* string_0 = '\0';
return (string_0);
}
int string_compare_limit (char * string_0, char * string_1, int limit) {
int i = 0;
fatal_failure (string_0 == NULL, "string_compare_limit: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_compare_limit: Source string is null pointer.");
for (i = 0; i != limit; ++i) {
if (string_0 [i] != string_1 [i]) {
return (0);
}
}
return (1);
}
char * string_copy_limit (char * string_0, char * string_1, int limit) {
int i = 0;
fatal_failure (string_0 == NULL, "string_copy_limit: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_copy_limit: Source string is null pointer.");
if (limit <= 0) {
return (string_0);
}
for (i = 0; i != limit; ++i) {
string_0 [i] = string_1 [i];
}
return (string_0);
}
char * string_concatenate_limit (char * string_0, char * string_1, int limit) {
int i = 0;
int length_0 = 0;
int length_1 = 0;
fatal_failure (string_0 == NULL, "string_concatenate_limit: Destination string is null pointer.");
fatal_failure (string_1 == NULL, "string_concatenate_limit: Source string is null pointer.");
if (limit <= 0) {
return (string_0);
}
length_0 = string_length (string_0);
length_1 = string_length (string_1);
for (i = 0; (i != length_1) && (i != limit); ++i) {
string_0 [length_0 + i] = string_1 [i];
}
return (string_0);
}
int string_split_space (char * string) {
int i = 0;
int count = 0;
fatal_failure (string == NULL, "string_split_space: Source string is null pointer.");
for (i = 0; string [i] != '\0'; ++i) {
if ((string [i] == ' ') || (string [i] == '\t') || (string [i] == '\n')) {
string [i] = '\0';
++count;
}
}
return (++count);
}
char * string_realign (char * string, int amount, char character) {
int offset, length;
length = string_length (string);
for (offset = 0; offset != length; ++offset) {
string [amount - offset - 1] = string [length - offset - 1];
}
for (offset = 0; offset != amount - length; ++offset) {
string [offset] = character;
}
string [amount] = '\0';
return (string);
}
void memory_delete (void * memory, int length) {
int i = 0;
char * cast = (char *) memory;
fatal_failure (memory == NULL, "memory_delete: Memory is null pointer.");
if (length <= 0) {
return;
}
for (i = 0; i != length; ++i) {
cast [i] = '\0';
}
}
int memory_compare (void * memory, void * source, int length) {
int i = 0;
char * cast_0 = (char *) memory;
char * cast_1 = (char *) source;
fatal_failure (memory == NULL, "memory_compare: Memory is null pointer.");
fatal_failure (source == NULL, "memory_compare: Source is null pointer.");
if (length <= 0) {
return (-1);
}
for (i = 0; (cast_0 [i] != '\0') && (cast_1 [i] != '\0'); ++i) {
if (cast_0 [i] != cast_1 [i]) {
return (0);
}
}
return (1);
}
void memory_copy (void * memory, void * source, int length) {
int i = 0;
char * cast_0 = (char *) memory;
char * cast_1 = (char *) source;
fatal_failure (memory == NULL, "memory_copy: Memory is null pointer.");
fatal_failure (source == NULL, "memory_copy: Source is null pointer.");
if (length <= 0) {
return;
}
for (i = 0; i != length; ++i) {
cast_0 [i] = cast_1 [i];
}
}
void terminal_clear (void) {
echo ("\033[2J\033[H");
}
void terminal_colour (int colour, int effect) {
char format [8] = "\033[ ;3 m";
format [2] = (char) (effect % EFFECT_COUNT) + '0';
format [5] = (char) (colour % COLOUR_COUNT) + '0';
echo (format);
}
void terminal_cancel (void) {
echo ("\033[0m");
}
void terminal_show_cursor (int show) {
if (show != 0) {
echo ("\033[?25h");
} else {
echo ("\033[?25l");
}
}
int encode_byte (char * byte) {
int encode = 0;
fatal_failure (character_is_hexadecimal (byte [0]) == 0, "encode_byte: Upper byte character is not hexadecimal digit.");
fatal_failure (character_is_hexadecimal (byte [1]) == 0, "encode_byte: Lower byte character is not hexadecimal digit.");
encode = ((byte [0] - (character_is_digit (byte [0]) ? ('0') : ('A' - 10))) << 4) | (byte [1] - (character_is_digit (byte [1]) ? ('0') : ('A' - 10)));
return (encode);
}
char * decode_byte (int byte) {
char * decode = " ";
fatal_failure ((byte <= -1) || (byte >= 256), "decode_byte: Byte is out of range.");
decode [0] = byte / 16;
decode [1] = byte % 16;
return (decode);
}
char * number_to_string (int number) {
int i, sign;
static char string [32];
string_delete (string, 32);
if (number == 0) {
string [0] = '0';
string [1] = '\0';
return (string);
}
if (number < 0) {
number *= -1;
sign = 1;
} else {
sign = 0;
}
for (i = (string [0] == '-'); number != 0; ++i) {
string [i] = (char) (number % 10) + '0';
number /= 10;
}
if (sign != 0) {
string [i] = '-';
++i;
}
string [i] = '\0';
string_reverse (string);
return (string);
}
#endif