clean up, merged prototypes and anon's prototype rework
This commit is contained in:
parent
f2cca50f97
commit
452d55d012
24
Makefile
24
Makefile
@ -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
|
||||
|
||||
new:
|
||||
g++ src2/main.cpp -o hl -ggdb
|
||||
clean:
|
||||
-rm ${OBJ}
|
||||
-rm ${OUT}
|
||||
|
||||
test: chad_test
|
||||
|
21
chad.mk
Normal file
21
chad.mk
Normal file
@ -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
|
100
hl_xolatile.c
100
hl_xolatile.c
@ -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].'
|
34
source/chad.h
Normal file
34
source/chad.h
Normal file
@ -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
|
106
source/hl.h
Normal file
106
source/hl.h
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
95
source/main.c
Normal file
95
source/main.c
Normal file
@ -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;
|
||||
}
|
386
src/main.c
386
src/main.c
@ -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');
|
||||
}
|
Loading…
Reference in New Issue
Block a user