@@ -1,15 +1,27 @@ | |||
CFLAGS:=-std=c99 -O2 -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef | |||
include chad.mk | |||
DEBUG:=1 | |||
CFLAGS:=-std=c99 -O2 -Wvla -Wshadow -Wundef $(if ${DEBUG}, ${CHAD_DEBUG},'') | |||
CPPFLAGS:=-D_FORTIFY_SOURCE=2 | |||
SRC.dir:=src/ | |||
SRC.dir:=source/ | |||
SRC:=$(shell find ${SRC.dir} -iname '*.c') | |||
HDR:=$(shell find ${SRC.dir} -iname '*.h') | |||
OBJ:=$(subst .c,.o,${SRC}) | |||
OUT:=hl | |||
OUTARGS:=${OUT} < source/main.c | |||
main: ${OBJ} ${HDR} | |||
${LINK.c} ${OBJ} -o hl | |||
%.o: %.c | |||
${COMPILE.c} $< -o $@ | |||
hl: ${OBJ} | |||
${LINK.c} ${OBJ} -o $@ | |||
install: | |||
cp hl /usr/bin/hl | |||
clean: | |||
-rm ${OBJ} | |||
-rm ${OUT} | |||
new: | |||
g++ src2/main.cpp -o hl -ggdb | |||
test: chad_test |
@@ -0,0 +1,21 @@ | |||
# Make script for Chad projects | |||
# This script depends on the following variables | |||
# - OUT : output program name | |||
# - OUTARGS : default flags to fork ${OUT} with | |||
# | |||
CHAD_DEBUG:=-Og -ggdb -pg -fno-inline | |||
# Programs to check warnings for as defined by the Chad standard | |||
GCC:=gcc | |||
GCC.warnings:=-Wall -Wextra -Wpedantic | |||
CLANG:=clang | |||
CLANG.warnings:=-Weverything | |||
VALGRIND:=valgrind | |||
chad_test: | |||
${GCC} ${GCC.warnings} ${SRC} -o ${OUT} | |||
${CLANG} ${GCC.warnings} ${SRC} -o ${OUT} | |||
${VALGRIND} ${OUT} ${OUTARGS} | |||
.DEFAULT_GOAL:=main |
@@ -1,100 +0,0 @@ | |||
#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 (10UL) | |||
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 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_multiple_strings(char * string, | |||
const char * * strings, | |||
const int count) { | |||
int i = 0; | |||
do { | |||
if (!strcmp(string, strings[i])) { | |||
return 1; | |||
} | |||
} while (++i != count); | |||
return 0; | |||
} | |||
int main(int argc, | |||
char * * argv) { | |||
UNUSED(argc); | |||
UNUSED(argv); | |||
buffer = realloc(buffer, ALLOCATION_CHUNK); | |||
do { | |||
if (!((buffer_size + 1) % ALLOCATION_CHUNK)) { | |||
// Linear incremental reallocation (advanced)! | |||
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_colour(RED, BOLD); | |||
render_string(buffer); | |||
render_cancel(); | |||
free (buffer); | |||
return 0; | |||
} |
@@ -1,8 +0,0 @@ | |||
default: | |||
gcc -g -Wall -Wextra -Wpedantic -o hl hl_xolatile.c | |||
clang -g -Weverything -o hl hl_xolatile.c | |||
# 'This shit requires to be in /usr/bin currently...' | |||
# 'There are unused functions that will be used, ignore now.' | |||
# 'Next please do [$ sudo cp hl /usr/bin/hl].' | |||
# 'Then test it with example [$ echo ABCDEF | valgrind hl].' |
@@ -0,0 +1,34 @@ | |||
#ifndef CHAD_H | |||
#define CHAD_H | |||
#include <stdbool.h> | |||
#define UNUSED(x) ((void)x) | |||
// Terminal manipulation | |||
#define TERMINAL_RESET "\033[0m" | |||
#define TERMINAL_COLOR_FG_BLACK "\033[30m" | |||
#define TERMINAL_COLOR_FG_RED "\033[31m" | |||
#define TERMINAL_COLOR_FG_GREEN "\033[32m" | |||
#define TERMINAL_COLOR_FG_YELLOW "\033[33m" | |||
#define TERMINAL_COLOR_FG_BLUE "\033[34m" | |||
#define TERMINAL_COLOR_FG_MAGENTA "\033[35m" | |||
#define TERMINAL_COLOR_FG_CYAN "\033[36m" | |||
#define TERMINAL_COLOR_FG_WHITE "\033[37m" | |||
#define TERMINAL_COLOR_BG_BLACK "\033[40m" | |||
#define TERMINAL_COLOR_BG_RED "\033[41m" | |||
#define TERMINAL_COLOR_BG_GREEN "\033[42m" | |||
#define TERMINAL_COLOR_BG_YELLOW "\033[43m" | |||
#define TERMINAL_COLOR_BG_BLUE "\033[44m" | |||
#define TERMINAL_COLOR_BG_MAGENTA "\033[45m" | |||
#define TERMINAL_COLOR_BG_CYAN "\033[46m" | |||
#define TERMINAL_COLOR_BG_WHITE "\033[47m" | |||
#define TERMINAL_STYLE_BOLD "\033[1m" | |||
#define TERMINAL_STYLE_ITALICS "\033[3m" | |||
#define TERMINAL_STYLE_REVERSE "\033[7m" | |||
#endif |
@@ -0,0 +1,106 @@ | |||
#include <stdio.h> | |||
#include <uthash.h> | |||
#include <ctype.h> | |||
#include <string.h> | |||
#include "chad.h" | |||
typedef void (*attribute_callback_t)(const char * const string, | |||
const int length, | |||
void * const attributes); | |||
typedef struct { | |||
char * key; | |||
attribute_callback_t callback; | |||
UT_hash_handle hh; | |||
} display_t; | |||
display_t * display_table = NULL; | |||
typedef struct { | |||
void * attributes; | |||
struct hl_group_t * link; | |||
} hl_group_t; | |||
typedef enum { | |||
KEYWORD, | |||
MATCH, | |||
REGION | |||
} token_t; | |||
typedef struct { | |||
hl_group_t * hl; | |||
token_t t; | |||
char* syntax; | |||
} token; // XXX: this will have to be renamed | |||
/* Temp solution | |||
*/ | |||
token * token_table[1000]; | |||
int token_table_top = 0; | |||
token * new_token(const char * const syntax, | |||
const token_t t, | |||
const hl_group_t * const g) { | |||
token * mt = (token*)malloc(sizeof(token)); | |||
mt->hl = g; | |||
mt->t = t; | |||
mt->syntax = syntax; | |||
token_table[token_table_top++] = mt; | |||
return mt; | |||
} | |||
void new_keyword_tokens(const char * const * words, | |||
hl_group_t * const g) { | |||
while (*words) { | |||
new_token(*words, KEYWORD, g); | |||
words = words + 1; | |||
} | |||
} | |||
int token_fits(const char* const pattern, | |||
const char* const to) { | |||
if (pattern == NULL) { | |||
return true; | |||
} | |||
for (int i = 0;; i++) { | |||
if (pattern[i] == '\00') { | |||
return i; | |||
} | |||
if (to[i] == '\00' | |||
|| pattern[i] != to[i]) { | |||
return false; | |||
} | |||
} | |||
} | |||
bool is_word_separator(const char character) { | |||
if (( isascii(character)) | |||
&& (!isalnum(character)) | |||
&& ( character != '_')) { | |||
return 1; | |||
} else { | |||
return 0; | |||
} | |||
} | |||
void render_string(const char * const string, | |||
const char * const mode) { | |||
for (const char * s = string; *s != '\00';) { | |||
int f; | |||
int i = 0; | |||
for (; i < token_table_top; i++) { | |||
f = token_fits(token_table[i]->syntax, s); | |||
if(f){ break; }; | |||
} | |||
// | |||
display_t * display; | |||
HASH_FIND_STR(display_table, mode, display); | |||
// | |||
if(f){ | |||
display->callback(s, f, token_table[i]->hl->attributes); | |||
s += f; | |||
} else { | |||
display->callback(s, 0, NULL); | |||
++s; | |||
} | |||
} | |||
} |
@@ -0,0 +1,95 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <unistd.h> | |||
#include <fcntl.h> | |||
#include "hl.h" | |||
#define ALLOCATION_CHUNK (10UL) | |||
static char * buffer = NULL; | |||
static size_t buffer_size = 0; | |||
typedef struct { | |||
int attribute; | |||
int foreground_color; | |||
int background_color; | |||
} terminal_hl_t; | |||
void cterm_render_callback(const char * const string, | |||
const int length, | |||
void * const attributes) { | |||
if(!length){ | |||
putchar(*string); | |||
return; | |||
} | |||
UNUSED(attributes); | |||
fputs(TERMINAL_STYLE_BOLD, stdout); | |||
for (int i = 0; i < length; i++) { | |||
putchar(*(string+i)); | |||
} | |||
fputs(TERMINAL_RESET, stdout); | |||
} | |||
int main(int argc, | |||
char * * argv) { | |||
UNUSED(argc); | |||
UNUSED(argv); | |||
// Buffer init | |||
buffer = realloc(buffer, ALLOCATION_CHUNK); | |||
do { | |||
if (!((buffer_size + 1) % ALLOCATION_CHUNK)) { | |||
/* Linear incremental reallocation (advanced)! | |||
*/ | |||
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'; | |||
// Highlight init | |||
const char * c_keywords[] = { | |||
"register", "volatile", "auto", "const", "static", "extern", "if", "else", | |||
"do", "while", "for", "continue", "switch", "case", "default", "break", | |||
"enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof", | |||
"char", "short", "int", "long", "signed", "unsigned", "float", "double", | |||
NULL | |||
}; | |||
const char * preprocessor_keywords[] = { | |||
"#include", "#pragma", "#define", "#undef", "#ifdef", "#ifndef", "#elifdef", "#elifndef", | |||
"#if", "#elif", "#else", "#endif", "#embed", "#line", "#error", "#warning", | |||
NULL | |||
}; | |||
terminal_hl_t my_hl = (terminal_hl_t) { | |||
.attribute = 1 | |||
}; | |||
display_t * cterm = &(display_t) { | |||
.key = "cterm", | |||
.callback = cterm_render_callback | |||
}; | |||
hl_group_t mygroup = (hl_group_t) { | |||
.link = NULL | |||
}; | |||
HASH_ADD_STR(display_table, | |||
key, | |||
cterm); | |||
new_keyword_tokens(c_keywords, &mygroup); | |||
new_keyword_tokens(preprocessor_keywords, &mygroup); | |||
// | |||
render_string(buffer, "cterm"); | |||
putchar('\n'); | |||
free (buffer); | |||
return 0; | |||
} |
@@ -1,386 +0,0 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <fcntl.h> | |||
#define ALLOCATION_CHUNK (1024UL) | |||
#define ALLOCATION_LIMIT (1024UL * 1024UL) | |||
#ifndef PROGRAM_NAME | |||
# define PROGRAM_NAME "hl" | |||
#endif | |||
enum { NORMAL, BOLD, DARKNESS, ITALIC, UNDERLINE, BLINK, DUNNO_6, REVERSE, INVISIBLE }; | |||
enum { GREY, RED, GREEN, YELLOW, BLUE, PINK, CYAN, WHITE, CANCEL }; | |||
static int colour_short_comment = GREY; | |||
static int colour_long_comment = GREY; | |||
static int colour_short_string = PINK; | |||
static int colour_long_string = RED; | |||
static int colour_separator = BLUE; | |||
static int colour_number = CYAN; | |||
static int colour_keyword = YELLOW; | |||
static int colour_preprocessor = YELLOW; | |||
static int colour_default = WHITE; | |||
static int effect_short_comment = BOLD; | |||
static int effect_long_comment = BOLD; | |||
static int effect_short_string = BOLD; | |||
static int effect_long_string = BOLD; | |||
static int effect_separator = BOLD; | |||
static int effect_number = BOLD; | |||
static int effect_keyword = BOLD; | |||
static int effect_preprocessor = BOLD; | |||
static int effect_default = BOLD; | |||
static unsigned long int buffer_size = 0; | |||
static void render_character ( | |||
char character | |||
) { | |||
putchar (character); | |||
} | |||
static void render_string ( | |||
char * string | |||
) { | |||
while (* string) render_character (* string++); | |||
} | |||
static void render_colour ( | |||
int colour, | |||
int effect | |||
) { | |||
if (colour == CANCEL) { | |||
render_string ("\033[0m"); | |||
return; | |||
} | |||
render_string ("\033["); | |||
render_character ((char) (effect % 9) + '0'); | |||
render_string (";3"); | |||
render_character ((char) (colour % 8) + '0'); | |||
render_character ('m'); | |||
} | |||
static int is_space ( | |||
char character | |||
) { | |||
switch (character) | |||
{ | |||
case ' ': case '\t': case '\r': case '\n': | |||
return (1); | |||
default: | |||
return (0); | |||
} | |||
} | |||
static int is_separator ( | |||
char character | |||
) { | |||
switch (character) | |||
{ | |||
case ' ': case '\t': case '\r': case '\n': | |||
case '+': case '-': case '*': case '/': | |||
case '(': case ')': case '[': case ']': | |||
case '{': case '}': case '<': case '>': | |||
case ';': case ':': case ',': case '.': | |||
case '!': case '&': case '|': case '?': | |||
case '~': case '^': case '%': case '=': | |||
return (1); | |||
default: | |||
return (0); | |||
} | |||
} | |||
static int compare_multiple_strings ( | |||
char * string, | |||
const char ** strings, | |||
const int count | |||
) { | |||
int i = 0; | |||
do { | |||
if (strcmp (string, strings [i]) == 0) { | |||
return (1); | |||
} | |||
++i; | |||
} while (i != count); | |||
return (0); | |||
} | |||
static int render_short_comment ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
render_colour (colour_short_comment, effect_short_comment); | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} while ((buffer [data_offset] != '\n') && (buffer [data_offset] != '\0')); | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
return (data_offset); | |||
} | |||
static int render_long_comment ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
render_colour (colour_long_comment, effect_long_comment); | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} while (((buffer [data_offset] != '/') || | |||
(buffer [data_offset - 1] != '*')) && | |||
(buffer [data_offset] != '\0')); | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
return (data_offset); | |||
} | |||
static int render_short_string ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
render_colour (colour_short_string, effect_short_string); | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
if (buffer [data_offset - 1] == '\\') { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} | |||
} while ((buffer [data_offset] != '\'') && (buffer [data_offset] != '\0')); | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
return (data_offset); | |||
} | |||
static int render_long_string ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
render_colour (colour_long_string, effect_long_string); | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
if (buffer [data_offset - 1] == '\\') { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} | |||
} while ((buffer [data_offset] != '"') && (buffer [data_offset] != '\0')); | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
return (data_offset); | |||
} | |||
static int render_separator ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
if (is_space (buffer [data_offset]) != 0) { | |||
render_colour (WHITE, NORMAL); | |||
} else { | |||
render_colour (colour_separator, effect_separator); | |||
} | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
return (data_offset); | |||
} | |||
static int render_number ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
render_colour (colour_number, effect_number); | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} while ((is_separator (buffer [data_offset]) == 0) && (buffer [data_offset] != '\0')); | |||
return (data_offset); | |||
} | |||
static int render_word ( | |||
char * buffer, | |||
int data_offset | |||
) { | |||
const char * c_keywords [32] = { | |||
"register", "volatile", "auto", "const", "static", "extern", "if", "else", | |||
"do", "while", "for", "continue", "switch", "case", "default", "break", | |||
"enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof", | |||
"char", "short", "int", "long", "signed", "unsigned", "float", "double" | |||
}; | |||
const char * preprocessor_keywords [16] = { | |||
"#include", "#pragma", "#define", "#undef", "#ifdef", "#ifndef", "#elifdef", "#elifndef", | |||
"#if", "#elif", "#else", "#endif", "#embed", "#line", "#error", "#warning" | |||
}; | |||
char * word = NULL; | |||
int i = 0; | |||
do { | |||
word = realloc (word, sizeof (* word) * (unsigned long int) (i + 1)); | |||
word [i] = buffer [data_offset + i]; | |||
++i; | |||
} while ((is_separator (buffer [data_offset + i]) == 0) && (buffer [data_offset + i] != '\0')); | |||
word = realloc (word, sizeof (* word) * (unsigned long int) (i + 1)); | |||
word [i] = '\0'; | |||
if (compare_multiple_strings (word, c_keywords, 32) != 0) { | |||
render_colour (colour_keyword, effect_keyword); | |||
} else if (compare_multiple_strings (word, preprocessor_keywords, 16) != 0) { | |||
render_colour (colour_preprocessor, effect_preprocessor); | |||
} else { | |||
render_colour (colour_default, effect_default); | |||
} | |||
do { | |||
render_character (buffer [data_offset]); | |||
++data_offset; | |||
} while ((is_separator (buffer [data_offset]) == 0) && (buffer [data_offset] != '\0')); | |||
free (word); | |||
return (data_offset); | |||
} | |||
void | |||
handle_buffer( | |||
char * buffer | |||
) { | |||
int offset = 0; | |||
while (buffer [offset] != '\0') { | |||
if ((buffer [offset] == '/') && (buffer [offset + 1] == '/')) { | |||
offset = render_short_comment (buffer, offset); | |||
} else if ((buffer [offset] == '/') && (buffer [offset + 1] == '*')) { | |||
offset = render_long_comment (buffer, offset); | |||
} else if (buffer [offset] == '\'') { | |||
offset = render_short_string (buffer, offset); | |||
} else if (buffer [offset] == '"') { | |||
offset = render_long_string (buffer, offset); | |||
} else if (is_separator (buffer [offset]) != 0) { | |||
offset = render_separator (buffer, offset); | |||
} else if ((buffer [offset] >= '0') && (buffer [offset] <= '9')) { | |||
offset = render_number (buffer, offset); | |||
} else { | |||
offset = render_word (buffer, offset); | |||
} | |||
render_colour (CANCEL, NORMAL); | |||
} | |||
} | |||
static char * | |||
slurp(const char * fn) | |||
{ | |||
size_t len; | |||
char * b; | |||
FILE * fp = fopen(fn, "r"); | |||
if (fp) | |||
{ | |||
fseek(fp, 0, SEEK_END); | |||
len = ftell(fp); | |||
rewind(fp); | |||
b = malloc(len); | |||
if (b && | |||
len != fread(b, 1, len, fp)) | |||
{ perror(PROGRAM_NAME); } | |||
fclose(fp); | |||
return b; | |||
} | |||
else | |||
{ return NULL; } | |||
} | |||
/* "Short" */ | |||
#define SHORT_OPT(c,s) \ | |||
if ((c == argv[0][0] && argv[0][1] == '\0') || \ | |||
0 == strncmp(argv[0], s, strlen(s))) | |||
#define OPT(s) \ | |||
if (0 == strncmp(argv[0], s, strlen(s))) | |||
int main ( | |||
int argc, | |||
char ** argv | |||
) { | |||
char * buffer = NULL; | |||
if (argc != 1) { | |||
(void) argv; | |||
while (++argv, --argc) { | |||
if (argv[0][0] == '-') { | |||
argv[0]++; | |||
SHORT_OPT ('?',"help") { | |||
fprintf (stderr, PROGRAM_NAME ": hl [OPTIONS] FILES ...\n"); | |||
return (0); | |||
} | |||
OPT ("version") { | |||
fprintf(stderr, PROGRAM_NAME ": Version 9000\n"); | |||
return (0); | |||
} | |||
else { | |||
fprintf (stderr, PROGRAM_NAME ": Unrecognized option '%s'\n", argv [0]); | |||
return (1); | |||
} | |||
} else { | |||
if ((buffer = slurp (argv [0]))) { | |||
handle_buffer (buffer); | |||
free (buffer); | |||
} | |||
} | |||
} | |||
return (0); | |||
} | |||
buffer = realloc (buffer, ALLOCATION_CHUNK); | |||
#define MEMFAIL(v) if (v == NULL) { perror(PROGRAM_NAME); return (1); } | |||
MEMFAIL(buffer); | |||
do { | |||
if ((buffer_size + 1) % ALLOCATION_CHUNK == 0) { | |||
buffer = realloc (buffer, | |||
((buffer_size + 1) | |||
/ ALLOCATION_CHUNK + 1) | |||
* ALLOCATION_CHUNK); | |||
MEMFAIL(buffer); | |||
} | |||
buffer [buffer_size] = '\0'; /* Fixing Valgrind warnings... */ | |||
read (STDIN_FILENO, & buffer [buffer_size], sizeof (* buffer)); | |||
++buffer_size; | |||
} while ((buffer [buffer_size - 1] != '\0') /*|| | |||
(buffer_size != ALLOCATION_LIMIT)*/); | |||
buffer [buffer_size - 1] = '\0'; | |||
// Checking if short comments work... | |||
/* Checking if long comments work... */ | |||
handle_buffer(buffer); | |||
free (buffer); | |||
return (0); | |||
} |
@@ -1,61 +0,0 @@ | |||
#include <map> | |||
#include <vector> | |||
#include <stdio.h> | |||
typedef enum { | |||
BOLD, | |||
ITALICS, | |||
UNDERLINE, | |||
END | |||
} attr_t; | |||
typedef void (*attr_callback_t)(void); | |||
void bold_on(void){ | |||
fputs("\033[1m", stdout); | |||
} | |||
void bold_off(void){ | |||
fputs("\033[0m", stdout); | |||
} | |||
attr_callback_t attr_callbacks[END*2] = { | |||
(attr_callback_t)bold_on, | |||
(attr_callback_t)bold_off, | |||
}; | |||
typedef int color; | |||
struct hl_t { | |||
attr_t attrs; | |||
color fg_color; | |||
color bg_color; | |||
//? font; | |||
}; | |||
struct hl_group { | |||
char* name; | |||
std::map<char*, hl_t> o; | |||
hl_group* link; | |||
}; | |||
typedef enum { | |||
KEYWORD, | |||
MATCH, | |||
REGION | |||
} token_t; | |||
struct token{ | |||
hl_group* hl; | |||
token_t t; | |||
char* syntax; | |||
}; | |||
std::vector<token*> token_table; | |||
token* newtoken(char* syntax, token_t t, hl_group* g){ | |||
token* mt = new (token){ | |||
.hl = g, | |||
.t = t, | |||
.syntax = syntax | |||
}; | |||
token_table.push_back(mt); | |||
return mt; | |||
} |
@@ -1,45 +0,0 @@ | |||
#include "Highlight.h" | |||
const char *const test_string = "this (test) is my test string which im with testing in this test"; | |||
int fits(const char* const pattern, const char* const to){ | |||
if(pattern == NULL){ return true; } | |||
for(int i = 0;; i++){ | |||
if(pattern[i] == '\00'){ return i; } | |||
if(to[i] == '\00' or pattern[i] != to[i]){ return false; } | |||
} | |||
} | |||
void render_string(const char* const string, char* mode){ | |||
for(const char* s = string; *s != '\00';){ | |||
for(auto &i : token_table){ | |||
int f; | |||
f = fits(i->syntax, s); | |||
if(f){ | |||
int pos = i->hl->o.find(mode)->second.attrs; | |||
attr_callbacks[pos](); | |||
for(int h = 0; h < f; h++){ | |||
putchar(*(s+h)); | |||
} | |||
attr_callbacks[pos+1](); | |||
s += f; | |||
}else{ | |||
putchar(*s); | |||
++s; | |||
} | |||
} | |||
} | |||
} | |||
signed main(){ | |||
hl_group mygroup = (hl_group){ | |||
.name = "test", | |||
.link = NULL | |||
}; | |||
mygroup.o["cterm"] = (hl_t){ | |||
.attrs = BOLD | |||
}; | |||
token* mytoken = newtoken("test", KEYWORD, &mygroup); | |||
render_string(test_string, "cterm"); | |||
putchar('\n'); | |||
} |