// @COMPILECMD gcc $@ -o hl #include #include #include #include #include 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 char * buffer = NULL; 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 ) { if ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n')) { return (1); } else { return (0); } } static int is_separator ( 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); } } 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( 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')); return (data_offset); } int main ( int argc, char * * argv ) { int offset = 0; if (argc != 1) { (void) argv; puts ("ARGUMENTS \"Heyo world!\""); return (-1); } do { ++buffer_size; buffer = realloc (buffer, buffer_size); read (STDIN_FILENO, & buffer [buffer_size - 1], sizeof (* buffer)); } while ((buffer [buffer_size] != '\0') || (buffer_size != 10000)); ++buffer_size; buffer = realloc (buffer, buffer_size); buffer [buffer_size] = '\0'; /* Checking if long comments work... */ // Checking if long 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); }