Removed division from get_stdin, and made it fail properly on failed allocation Fixed the retard brain #include syntax/c.h shit (god I hope I didn't break highlightlighting I'm not - I checked and it outputs the same under the last commit, it's probably fine anon'll fix it what a cuck) Much better input handling, properly using perror and handling multible files even under a noexist condition, probably fixed a seggy on noexist conditionmaster
@@ -1,23 +1,27 @@ | |||
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 | |||
}; | |||
void | |||
highlight_c(void) | |||
{ | |||
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 | |||
}; | |||
const char * preprocessor_keywords[] = { | |||
"#include", "#pragma", "#define", "#undef", "#ifdef", "#ifndef", "#elifdef", "#elifndef", | |||
"#if", "#elif", "#else", "#endif", "#embed", "#line", "#error", "#warning", | |||
NULL | |||
}; | |||
new_char_tokens("+-&|.()[]{}", operator_hl); | |||
new_keyword_tokens(c_keywords, control_hl); | |||
new_keyword_tokens(preprocessor_keywords, special_hl); | |||
new_region_token("/\\*", "\\*/", comment_hl); | |||
new_region_token("//", "\\n", comment_hl); | |||
new_region_token("\"", "\"", string_literal_hl); | |||
new_region_token("<", ">", string_literal_hl); | |||
new_keyword_token("keyword", special_hl); | |||
new_keyword_token("while", operator_hl); | |||
new_char_tokens("+-&|.()[]{}", operator_hl); | |||
new_keyword_tokens(c_keywords, control_hl); | |||
new_keyword_tokens(preprocessor_keywords, special_hl); | |||
new_region_token("/\\*", "\\*/", comment_hl); | |||
new_region_token("//", "\\n", comment_hl); | |||
new_region_token("\"", "\"", string_literal_hl); | |||
new_region_token("<", ">", string_literal_hl); | |||
new_keyword_token("keyword", special_hl); | |||
new_keyword_token("while", operator_hl); | |||
} |
@@ -0,0 +1,6 @@ | |||
#ifndef SYNTAX_H_ | |||
#include "c.h" | |||
#define SYNTAX_H_ | |||
#endif |
@@ -9,13 +9,14 @@ | |||
#include <fcntl.h> | |||
#include "terminal.h" | |||
#include "syntax/syntax.h" | |||
#define ALLOCATION_CHUNK (128UL) | |||
static const char * argv0; | |||
static char * | |||
slurp(const char * fn) | |||
read_entire_file(const char * fn) | |||
{ | |||
FILE * fp = fopen(fn, "r"); | |||
if (fp) | |||
@@ -26,8 +27,7 @@ slurp(const char * fn) | |||
len = ftell(fp); | |||
rewind(fp); | |||
b = malloc(len + 1); | |||
if (b && fread(b, 1, len, fp)) | |||
{ | |||
if (b && fread(b, 1, len, fp)) { | |||
b[len] = '\0'; | |||
} | |||
fclose(fp); | |||
@@ -41,88 +41,69 @@ static char * | |||
get_stdin(void) | |||
{ | |||
size_t buffer_size = 0; | |||
size_t n = 1; | |||
char * buffer = malloc(ALLOCATION_CHUNK); | |||
if (!buffer) | |||
{ return NULL; } | |||
do { | |||
if (!((buffer_size + 1) % ALLOCATION_CHUNK)) { | |||
buffer = realloc(buffer, (((buffer_size + 1) / ALLOCATION_CHUNK) + 1) * ALLOCATION_CHUNK); | |||
if (buffer_size + 1 >= (ALLOCATION_CHUNK * n)) { | |||
buffer = realloc(buffer, ALLOCATION_CHUNK * ++n + 1); | |||
if (!buffer) | |||
{ return NULL; } | |||
buffer[ALLOCATION_CHUNK * n] = '\0'; | |||
} | |||
buffer[buffer_size] = '\0'; | |||
if (read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer)) == -1) | |||
{ | |||
free(buffer); | |||
fprintf(stderr, "%s: Failed to read from STDIN\n", argv0); | |||
fprintf(stderr, "%s: Failed to read from stdin\n", argv0); | |||
return NULL; | |||
} | |||
++buffer_size; | |||
} while (buffer[buffer_size - 1]); | |||
} while (buffer[buffer_size++]); | |||
buffer[buffer_size - 1] = '\0'; | |||
return buffer; | |||
} | |||
/* TODO: fix the shit going on with syntax/c.h , replace with a function, | |||
* and ideally how make it hotswappable. */ | |||
int | |||
main(int argc, | |||
char ** argv) { | |||
int arg = 0; | |||
int syn = 0; | |||
int ret = 0; | |||
char * buffer = NULL; | |||
argv0 = argv[0]; | |||
terminal_hl_init(); | |||
highlight_c(); /* this mustn't break overrides (but definitely does) */ | |||
while (++argv, | |||
--argc) | |||
{ | |||
if (**argv == '-') | |||
{ | |||
syn = 1; | |||
/* fprintf(stderr, "handle '%s'\n", *argv+1); */ | |||
/* lazy as hell, TODO use uthash */ | |||
if (strcmp(*argv+1, "c") == 0) | |||
{ | |||
#include "syntax/c.h" | |||
--argc) { | |||
if (**argv == '-') { | |||
/* TODO use uthash */ | |||
if (strcmp(*argv+1, "c") == 0) { | |||
highlight_c(); | |||
} | |||
else | |||
{ | |||
else { | |||
fprintf(stderr, "%s: Unimplemented syntax '%s'\n", argv0, *argv+1); | |||
return 1; | |||
} | |||
} | |||
else | |||
{ | |||
if (!syn) | |||
{ | |||
#include "syntax/c.h" | |||
} | |||
else { | |||
free(buffer); | |||
arg = 1; | |||
buffer = slurp(*argv); | |||
render_string(buffer, "cterm"); | |||
if (!buffer) | |||
{ | |||
perror(argv0); | |||
return 1; | |||
buffer = read_entire_file(*argv); | |||
if (!buffer) { | |||
fprintf(stderr,"%s: cannot access '%s': ", argv0, *argv); | |||
perror(NULL); | |||
ret = 2; | |||
} | |||
else | |||
{ render_string(buffer, "cterm"); } | |||
} | |||
} | |||
if (!arg) | |||
{ | |||
if (!syn) | |||
{ | |||
#include "syntax/c.h" | |||
} | |||
if (!arg) { | |||
buffer = get_stdin(); | |||
render_string(buffer, "cterm"); | |||
} | |||
fflush(stdout); | |||
hl_deinit(); | |||
free(buffer); | |||
//terminal_hl_deinit(); | |||
return 0; | |||
return ret; | |||
} |