Syntax highlighting and comment
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
#include "../include/syntax_highlighter.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const char *c_keywords[] = {
|
||||
"if", "else", "while", "for", "do", "switch", "case", "break",
|
||||
"continue", "return", "goto", "struct", "union", "enum",
|
||||
"typedef", "static", "extern", "const", "volatile", "sizeof",
|
||||
"auto", "register", "inline", "restrict", NULL
|
||||
};
|
||||
|
||||
// C types
|
||||
const char *c_types[] = {
|
||||
"int", "char", "float", "double", "void", "long", "short",
|
||||
"unsigned", "signed", "bool", NULL
|
||||
};
|
||||
|
||||
// Check if character is alphanumeric or underscore
|
||||
int is_word_char(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') || c == '_';
|
||||
}
|
||||
|
||||
// Check if string is a keyword
|
||||
int is_keyword(const char *word) {
|
||||
for (int i = 0; c_keywords[i] != NULL; i++) {
|
||||
if (strcmp(word, c_keywords[i]) == 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if string is a type
|
||||
int is_type(const char *word) {
|
||||
for (int i = 0; c_types[i] != NULL; i++) {
|
||||
if (strcmp(word, c_types[i]) == 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get color code for token type
|
||||
const char *get_color(TokenType type) {
|
||||
switch (type) {
|
||||
case TOKEN_KEYWORD: return COLOR_KEYWORD;
|
||||
case TOKEN_TYPE: return COLOR_TYPE;
|
||||
case TOKEN_STRING: return COLOR_STRING;
|
||||
case TOKEN_COMMENT: return COLOR_COMMENT;
|
||||
case TOKEN_NUMBER: return COLOR_NUMBER;
|
||||
default: return COLOR_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
// Highlight a line of C code and return the highlighted string
|
||||
// Returns a newly allocated string that must be freed by the caller
|
||||
char *highlight_line(const char *line, int *length) {
|
||||
char *result = malloc(1024); // Allocate space for result
|
||||
int result_pos = 0;
|
||||
int i = 0;
|
||||
|
||||
while (line[i] != '\0' && line[i] != '\n') {
|
||||
// Skip whitespace
|
||||
if (line[i] == ' ' || line[i] == '\t') {
|
||||
result[result_pos++] = line[i++];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle line comments
|
||||
if (line[i] == '/' && line[i + 1] == '/') {
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_COMMENT);
|
||||
while (line[i] != '\0' && line[i] != '\n') {
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle block comments
|
||||
if (line[i] == '/' && line[i + 1] == '*') {
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_COMMENT);
|
||||
result[result_pos++] = line[i++];
|
||||
result[result_pos++] = line[i++];
|
||||
while (line[i] != '\0') {
|
||||
if (line[i] == '*' && line[i + 1] == '/') {
|
||||
result[result_pos++] = line[i++];
|
||||
result[result_pos++] = line[i++];
|
||||
break;
|
||||
}
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (line[i] == '"') {
|
||||
result_pos += sprintf(&result[result_pos], "%s\"", COLOR_STRING);
|
||||
i++;
|
||||
while (line[i] != '\0' && line[i] != '"') {
|
||||
if (line[i] == '\\') {
|
||||
result[result_pos++] = line[i++];
|
||||
result[result_pos++] = line[i++];
|
||||
} else {
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
}
|
||||
if (line[i] == '"') result[result_pos++] = line[i++];
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle character literals
|
||||
if (line[i] == '\'') {
|
||||
result_pos += sprintf(&result[result_pos], "%s'", COLOR_STRING);
|
||||
i++;
|
||||
while (line[i] != '\0' && line[i] != '\'') {
|
||||
if (line[i] == '\\') {
|
||||
result[result_pos++] = line[i++];
|
||||
result[result_pos++] = line[i++];
|
||||
} else {
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
}
|
||||
if (line[i] == '\'') result[result_pos++] = line[i++];
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle numbers
|
||||
if (line[i] >= '0' && line[i] <= '9') {
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_NUMBER);
|
||||
while (is_word_char(line[i]) || line[i] == '.') {
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle identifiers and keywords
|
||||
if (is_word_char(line[i])) {
|
||||
int start = i;
|
||||
while (is_word_char(line[i])) i++;
|
||||
|
||||
char word[256];
|
||||
strncpy(word, &line[start], i - start);
|
||||
word[i - start] = '\0';
|
||||
|
||||
TokenType type = TOKEN_DEFAULT;
|
||||
if (is_keyword(word)) type = TOKEN_KEYWORD;
|
||||
else if (is_type(word)) type = TOKEN_TYPE;
|
||||
|
||||
result_pos += sprintf(&result[result_pos], "%s%s%s",
|
||||
get_color(type), word, COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle operators and other characters
|
||||
result[result_pos++] = line[i++];
|
||||
}
|
||||
|
||||
result[result_pos] = '\0';
|
||||
*length = result_pos + 1;
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user