|
|
@@ -0,0 +1,246 @@ |
|
|
|
// Listen, this is still prototype, it's not code-merged with other stuff... |
|
|
|
// Once I prototype out more stuff, this will use chad.h and hl.h... |
|
|
|
// So, this file can run on its' own when compiled, gonna rewrite later. |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <fcntl.h> |
|
|
|
#include <ctype.h> |
|
|
|
|
|
|
|
#define UNUSED(x) ((void) (x)) |
|
|
|
|
|
|
|
#define ALLOCATION_CHUNK (1024UL) |
|
|
|
|
|
|
|
enum { |
|
|
|
NORMAL, BOLD, DARKNESS, ITALIC, |
|
|
|
UNDERLINE, BLINK, DUNNO_6, REVERSE, |
|
|
|
INVISIBLE |
|
|
|
}; |
|
|
|
|
|
|
|
enum { |
|
|
|
GREY, RED, GREEN, YELLOW, |
|
|
|
BLUE, PINK, CYAN, WHITE, |
|
|
|
CANCEL |
|
|
|
}; |
|
|
|
|
|
|
|
static char * buffer = NULL; |
|
|
|
static size_t buffer_size = 0; |
|
|
|
|
|
|
|
static int match_count = 0; |
|
|
|
static char match_character[80] = ""; |
|
|
|
static int match_colour[80] = { 0 }; |
|
|
|
static int match_effect[80] = { 0 }; |
|
|
|
|
|
|
|
static int range_count = 0; |
|
|
|
static char range_begin[80] = ""; |
|
|
|
static char range_end[80] = ""; |
|
|
|
static char range_except[80] = ""; |
|
|
|
static int range_colour[80] = { 0 }; |
|
|
|
static int range_effect[80] = { 0 }; |
|
|
|
|
|
|
|
static int drange_count = 0; |
|
|
|
static char **drange_begin = NULL; |
|
|
|
static char **drange_end = NULL; |
|
|
|
static int drange_colour[80] = { 0 }; |
|
|
|
static int drange_effect[80] = { 0 }; |
|
|
|
|
|
|
|
static void render_character(char * character) { |
|
|
|
write(STDOUT_FILENO, character, sizeof (*character)); |
|
|
|
} |
|
|
|
|
|
|
|
static void render_string(char * string) { |
|
|
|
write(STDOUT_FILENO, string, strlen(string)); |
|
|
|
} |
|
|
|
|
|
|
|
static void render_colour(int colour, |
|
|
|
int effect) { |
|
|
|
char format[8] = "\033[ ;3 m"; |
|
|
|
|
|
|
|
format[2] = (char) (effect % 9) + '0'; |
|
|
|
format[5] = (char) (colour % 8) + '0'; |
|
|
|
|
|
|
|
render_string(format); |
|
|
|
} |
|
|
|
|
|
|
|
static void render_cancel(void) { |
|
|
|
render_string("\033[0m"); |
|
|
|
} |
|
|
|
|
|
|
|
static int is_separator(char character) { |
|
|
|
if (( isascii(character)) |
|
|
|
&& (!isalnum(character)) |
|
|
|
&& (character != '_')) { |
|
|
|
return 1; |
|
|
|
} else { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static int compare_characters(char character, |
|
|
|
const char * characters, |
|
|
|
const int count) { |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
do { |
|
|
|
if (character == characters[i]) { |
|
|
|
return i; |
|
|
|
} |
|
|
|
} while (++i != count); |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
static int compare_strings(char * string, |
|
|
|
char * * strings, |
|
|
|
int count) { |
|
|
|
int i = 0; |
|
|
|
//~if ((match = compare_strings(&buffer[i], drange_begin, drange_count)) != -1) { |
|
|
|
do { |
|
|
|
if (!strncmp(string, strings[i], strlen(strings[i]))) { |
|
|
|
return i; |
|
|
|
} |
|
|
|
} while (++i != count); |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
static void syntax_character(char character, |
|
|
|
int colour, |
|
|
|
int effect) { |
|
|
|
match_character[match_count] = character; |
|
|
|
match_colour[match_count] = colour; |
|
|
|
match_effect[match_count] = effect; |
|
|
|
|
|
|
|
++match_count; |
|
|
|
} |
|
|
|
|
|
|
|
static void syntax_simple_range(char begin, |
|
|
|
char end, |
|
|
|
char except, |
|
|
|
int colour, |
|
|
|
int effect) { |
|
|
|
range_begin[range_count] = begin; |
|
|
|
range_end[range_count] = end; |
|
|
|
range_except[range_count] = except; |
|
|
|
range_colour[range_count] = colour; |
|
|
|
range_effect[range_count] = effect; |
|
|
|
|
|
|
|
++range_count; |
|
|
|
} |
|
|
|
|
|
|
|
static void syntax_double_range(char * begin, |
|
|
|
char * end, |
|
|
|
int colour, |
|
|
|
int effect) { |
|
|
|
if ((strlen(begin) > 3) && (strlen(end) > 3)) { |
|
|
|
exit(3); |
|
|
|
} |
|
|
|
strcpy(&drange_begin[drange_count][0], begin); |
|
|
|
strcpy(&drange_end[drange_count][0], end); |
|
|
|
|
|
|
|
drange_colour[drange_count] = colour; |
|
|
|
drange_effect[drange_count] = effect; |
|
|
|
|
|
|
|
++drange_count; |
|
|
|
} |
|
|
|
|
|
|
|
static void syntax_character_array(char * string, |
|
|
|
int colour, |
|
|
|
int effect) { |
|
|
|
for (size_t i = 0; i != strlen(string); ++i) { |
|
|
|
syntax_character(string[i], colour, effect); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void render_buffer(void) { |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
render_colour(WHITE, BOLD); |
|
|
|
|
|
|
|
do { |
|
|
|
int match = -1; |
|
|
|
if ((match = compare_strings(&buffer[i], drange_begin, drange_count)) != -1) { |
|
|
|
render_colour(drange_colour[match], drange_effect[match]); |
|
|
|
do { |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
} while ((buffer[i]) |
|
|
|
&& (strncmp(&buffer[i - 1], drange_end[match], strlen(drange_end[match])))); |
|
|
|
//~&& (buffer[i] != drange_end[match][0])); |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
render_colour(WHITE, BOLD); |
|
|
|
} else if ((match = compare_characters(buffer[i], range_begin, range_count)) != -1) { |
|
|
|
render_colour(range_colour[match], range_effect[match]); |
|
|
|
do { |
|
|
|
if (buffer[i] == range_except[match]) { |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
} |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
} while ((buffer[i]) |
|
|
|
&& (buffer[i] != range_end[match])); |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
render_colour(WHITE, BOLD); |
|
|
|
} else if ((match = compare_characters(buffer[i], match_character, match_count)) != -1) { |
|
|
|
render_colour(match_colour[match], match_effect[match]); |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
} else { |
|
|
|
render_colour(WHITE, BOLD); |
|
|
|
render_character(&buffer[i]); |
|
|
|
++i; |
|
|
|
} |
|
|
|
} while (buffer[i]); |
|
|
|
|
|
|
|
render_cancel(); |
|
|
|
} |
|
|
|
|
|
|
|
int main(int argc, |
|
|
|
char * * argv) { |
|
|
|
UNUSED(argc); |
|
|
|
UNUSED(argv); |
|
|
|
|
|
|
|
buffer = realloc(buffer, ALLOCATION_CHUNK); |
|
|
|
|
|
|
|
drange_begin = calloc(80UL, sizeof(*drange_begin)); |
|
|
|
drange_end = calloc(80UL, sizeof(*drange_begin)); |
|
|
|
for (int i = 0; i != 80; ++i) drange_begin[i] = calloc(4UL, 1UL); |
|
|
|
for (int i = 0; i != 80; ++i) drange_end[i] = calloc(4UL, 1UL); |
|
|
|
|
|
|
|
syntax_character_array(".,:;<=>+-*/%!&~^", BLUE, BOLD); |
|
|
|
syntax_character_array("()[]{}", GREEN, BOLD); |
|
|
|
syntax_simple_range('\'', '\'', '\\', RED, BOLD); |
|
|
|
syntax_simple_range('"', '"', '\\', RED, BOLD); |
|
|
|
syntax_double_range("//", "\n", GREY, BOLD); |
|
|
|
syntax_double_range("/*", "*/", GREY, BOLD); |
|
|
|
|
|
|
|
do { |
|
|
|
if (!((buffer_size + 1) % ALLOCATION_CHUNK)) { |
|
|
|
// Linear incremental reallocation (advanced)! |
|
|
|
/* Test... */ |
|
|
|
size_t chunks = (buffer_size + 1) / ALLOCATION_CHUNK; |
|
|
|
buffer = realloc(buffer, ++chunks * ALLOCATION_CHUNK); |
|
|
|
} |
|
|
|
buffer[buffer_size] = '\0'; |
|
|
|
read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer)); |
|
|
|
++buffer_size; |
|
|
|
} while (buffer[buffer_size - 1]); |
|
|
|
|
|
|
|
buffer[buffer_size - 1] = '\0'; |
|
|
|
|
|
|
|
render_buffer(); |
|
|
|
|
|
|
|
for (int i = 0; i != 80; ++i) free(drange_begin[i]); |
|
|
|
for (int i = 0; i != 80; ++i) free(drange_end[i]); |
|
|
|
free(drange_begin); |
|
|
|
free(drange_end); |
|
|
|
|
|
|
|
free(buffer); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |