소스 검색

Improved CLI

master
Emil 9 달 전
부모
커밋
99327046d4
No known key found for this signature in database GPG 키 ID: 5432DB986FDBCF8A
3개의 변경된 파일283개의 추가작업 그리고 199개의 파일을 삭제
  1. +278
    -199
      src/main.c
  2. +4
    -0
      tests/extra.c
  3. +1
    -0
      tests/main.c

+ 278
- 199
src/main.c 파일 보기

@@ -7,6 +7,10 @@
#define ALLOCATION_CHUNK (1024UL)
#define ALLOCATION_LIMIT (1024UL * 1024UL)

#ifndef PROGN
# define PROGN "hl"
#endif

enum { NORMAL, BOLD, DARKNESS, ITALIC, UNDERLINE, BLINK, DUNNO_6, REVERSE, INVISIBLE };
enum { GREY, RED, GREEN, YELLOW, BLUE, PINK, CYAN, WHITE, CANCEL };

@@ -30,281 +34,356 @@ static int effect_keyword = BOLD;
static int effect_preprocessor = BOLD;
static int effect_default = BOLD;

static char * buffer = NULL;

static unsigned long int buffer_size = 0;

static void render_character (
char character
char character
) {
putchar (character);
putchar (character);
}

static void render_string (
char * string
char * string
) {
while (* string) render_character (* string++);
while (* string) render_character (* string++);
}

static void render_colour (
int colour,
int effect
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');
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
char character
) {
if ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n')) {
return (1);
} else {
return (0);
}
switch (character)
{
case ' ': case '\t': case '\r': case '\n':
return (1);
default:
return (0);
}
}

static int is_separator (
char character
char character
) {
if ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n') ||
(character == '+') || (character == '-') || (character == '*') || (character == '/') ||
(character == '(') || (character == ')') || (character == '[') || (character == ']') ||
(character == '{') || (character == '}') || (character == '<') || (character == '>') ||
(character == ';') || (character == ':') || (character == ',') || (character == '.') ||
(character == '!') || (character == '&') || (character == '|') || (character == '?') ||
(character == '~') || (character == '^') || (character == '%') || (character == '=')) {
return (1);
} else {
return (0);
}
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
char * string,
const char ** strings,
const int count
) {
int i = 0;
int i = 0;

do {
if (strcmp (string, strings [i]) == 0) {
return (1);
}
++i;
} while (i != count);
do {
if (strcmp (string, strings [i]) == 0) {
return (1);
}
++i;
} while (i != count);

return (0);
return (0);
}

static int render_short_comment (
int data_offset
char * buffer,
int data_offset
) {
render_colour (colour_short_comment, effect_short_comment);
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'));
do {
render_character (buffer [data_offset]);
++data_offset;
} while ((buffer [data_offset] != '\n') && (buffer [data_offset] != '\0'));

render_character (buffer [data_offset]);
++data_offset;
render_character (buffer [data_offset]);
++data_offset;

return (data_offset);
return (data_offset);
}

static int render_long_comment (
int data_offset
char * buffer,
int data_offset
) {
render_colour (colour_long_comment, effect_long_comment);
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'));
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;
render_character (buffer [data_offset]);
++data_offset;

return (data_offset);
return (data_offset);
}

static int render_short_string (
int data_offset
char * buffer,
int data_offset
) {
render_colour (colour_short_string, effect_short_string);
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'));
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;
render_character (buffer [data_offset]);
++data_offset;

return (data_offset);
return (data_offset);
}

static int render_long_string (
int data_offset
char * buffer,
int data_offset
) {
render_colour (colour_long_string, effect_long_string);
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'));
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;
render_character (buffer [data_offset]);
++data_offset;

return (data_offset);
return (data_offset);
}

static int render_separator (
int data_offset
char * buffer,
int data_offset
) {
if (is_space (buffer [data_offset]) != 0) {
render_colour (WHITE, NORMAL);
} else {
render_colour (colour_separator, effect_separator);
}
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;
render_character (buffer [data_offset]);
++data_offset;

return (data_offset);
return (data_offset);
}

static int render_number (
int data_offset
char * buffer,
int data_offset
) {
render_colour (colour_number, effect_number);
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'));
do {
render_character (buffer [data_offset]);
++data_offset;
} while ((is_separator (buffer [data_offset]) == 0) && (buffer [data_offset] != '\0'));

return (data_offset);
return (data_offset);
}

static int render_word (
int data_offset
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
) {
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);
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(PROGN); }
fclose(fp);
return b;
}
else
{ return NULL; }
}

#define OPT(c,s) \
if ((c == argv[0][0] && argv[0][1] == '\0') || \
0 == strncmp(argv[0], s, strlen(s)))

#define SOPT(s) \
if (0 == strncmp(argv[0], s, strlen(s)))

/*
Valgrind: Depends on uninitialized value (buffer [0])...?
280 : } while ((buffer [buffer_size - 1] != '\0') || (buffer_size != ALLOCATION_LIMIT));
285 : while (buffer [offset] != '\0') {
*/
int main (
int argc,
char * * argv
int argc,
char ** argv
) {
int offset = 0;

if (argc != 1) {
(void) argv;
puts ("ARGUMENTS \"Heyo world!\"");
return (-1);
}

buffer = realloc (buffer, ALLOCATION_CHUNK);

do {
if ((buffer_size + 1) % ALLOCATION_CHUNK == 0) {
buffer = realloc (buffer, ((buffer_size + 1) / ALLOCATION_CHUNK + 1) * ALLOCATION_CHUNK);
}
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 long comments work... */
// Checking if short comments work...

while (buffer [offset] != '\0') {
if ((buffer [offset] == '/') && (buffer [offset + 1] == '/')) {
offset = render_short_comment (offset);
} else if ((buffer [offset] == '/') && (buffer [offset + 1] == '*')) {
offset = render_long_comment (offset);
} else if (buffer [offset] == '\'') {
offset = render_short_string (offset);
} else if (buffer [offset] == '"') {
offset = render_long_string (offset);
} else if (is_separator (buffer [offset]) != 0) {
offset = render_separator (offset);
} else if ((buffer [offset] >= '0') && (buffer [offset] <= '9')) {
offset = render_number (offset);
} else {
offset = render_word (offset);
}
render_colour (CANCEL, NORMAL);
}

free (buffer);

return (0);
char * buffer = NULL;

if (argc != 1) {
(void) argv;
while (++argv, --argc) {
if (argv[0][0] == '-') {
argv[0]++;
OPT ('?',"help") {
fprintf (stderr, PROGN ": ... | hl [OPTIONS] FILES ...\n");
return (0);
}
SOPT ("version") {
fprintf(stderr, PROGN ": Version 9000\n");
return (0);
}
else {
fprintf (stderr, PROGN ": Unrecognized option '%s'\n", argv [0]);
return (1);
}
} else {
if ((buffer = slurp (argv [0]))) {
handle_buffer (buffer);
free (buffer);
}
}
}
}

buffer = realloc (buffer, ALLOCATION_CHUNK);

#define MEMFAIL(v) if (v == NULL) { perror(PROGN); 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);
}

+ 4
- 0
tests/extra.c 파일 보기

@@ -0,0 +1,4 @@
int
main(void)

{nothing.}

+ 1
- 0
tests/main.c 파일 보기

@@ -319,3 +319,4 @@ signed main(){

return 0;
}

불러오는 중...
취소
저장