Browse Source

clean up, merged prototypes and anon's prototype rework

master
anon 9 months ago
parent
commit
452d55d012
11 changed files with 274 additions and 606 deletions
  1. +0
    -0
      LICENSE
  2. +18
    -6
      Makefile
  3. +21
    -0
      chad.mk
  4. +0
    -100
      hl_xolatile.c
  5. +0
    -8
      makefile_xolatile
  6. +34
    -0
      source/chad.h
  7. +106
    -0
      source/hl.h
  8. +95
    -0
      source/main.c
  9. +0
    -386
      src/main.c
  10. +0
    -61
      src2/Highlight.h
  11. +0
    -45
      src2/main.cpp

+ 0
- 0
LICENSE View File


+ 18
- 6
Makefile View File

@@ -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

+ 21
- 0
chad.mk View 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

+ 0
- 100
hl_xolatile.c View File

@@ -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;
}

+ 0
- 8
makefile_xolatile View File

@@ -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
- 0
source/chad.h View 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
- 0
source/hl.h View 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
- 0
source/main.c View 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;
}

+ 0
- 386
src/main.c View File

@@ -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);
}

+ 0
- 61
src2/Highlight.h View File

@@ -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;
}

+ 0
- 45
src2/main.cpp View File

@@ -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…
Cancel
Save