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