Add C support
This commit is contained in:
parent
384c8130f9
commit
0f722e126b
1 changed files with 276 additions and 39 deletions
259
nsh.c
259
nsh.c
|
@ -1,23 +1,259 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#define COLOR_RESET "\033[0m"
|
#define COLOR_RESET "\033[0m"
|
||||||
#define COLOR_TEAL "\033[38;2;148;226;213m"
|
|
||||||
#define COLOR_GREEN "\033[38;2;166;227;161m"
|
|
||||||
#define COLOR_RED "\033[38;2;243;139;168m"
|
|
||||||
#define COLOR_BLUE "\033[38;2;137;180;250m"
|
#define COLOR_BLUE "\033[38;2;137;180;250m"
|
||||||
#define COLOR_PEACH "\033[38;2;250;179;135m"
|
#define COLOR_GREEN "\033[38;2;166;227;161m"
|
||||||
#define COLOR_YELLOW "\033[38;2;249;226;175m"
|
#define COLOR_ORANGE "\033[38;2;250;179;135m"
|
||||||
#define COLOR_OVERLAY0 "\033[38;2;108;112;134m"
|
#define COLOR_OVERLAY0 "\033[38;2;108;112;134m"
|
||||||
|
#define COLOR_TEAL "\033[38;2;148;226;213m"
|
||||||
|
#define COLOR_MAUVE "\033[38;2;203;166;247m"
|
||||||
|
#define COLOR_YELLOW "\033[38;2;249;226;175m"
|
||||||
|
#define COLOR_SKY "\033[38;2;137;220;235m"
|
||||||
|
#define COLOR_RED "\033[38;2;243;139;168m"
|
||||||
|
#define COLOR_PEACH "\033[38;2;250;179;135m"
|
||||||
|
|
||||||
#define MAX_LINE_LENGTH 1024
|
const char *keywords[] = {
|
||||||
|
"if", "else", "while", "for", "return", "switch", "case", "default", "break", "continue", "const", "#define", "#include", NULL
|
||||||
|
};
|
||||||
|
|
||||||
int main()
|
const char *types[] = {
|
||||||
|
"void", "int", "char", "float", "double", "long", "short", "unsigned", "signed", "struct", "enum", "union", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function declarations for different token handling */
|
||||||
|
void highlight_keyword(const char *word);
|
||||||
|
void highlight_type(const char *word);
|
||||||
|
void highlight_function(const char *word);
|
||||||
|
void highlight_string(const char *line, int *i);
|
||||||
|
void highlight_char(const char *line, int *i);
|
||||||
|
void highlight_single_comment(const char *line, int *i);
|
||||||
|
void highlight_multi_comment(const char *line, int *i);
|
||||||
|
|
||||||
|
/* Check if a word is a keyword */
|
||||||
|
int is_keyword(const char *word)
|
||||||
{
|
{
|
||||||
char buffer[MAX_LINE_LENGTH];
|
for (int i = 0; keywords[i] != NULL; i++) {
|
||||||
|
if (strcmp(word, keywords[i]) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
|
/* Check if a word is a type */
|
||||||
|
int is_type(const char *word)
|
||||||
|
{
|
||||||
|
for (int i = 0; types[i] != NULL; i++) {
|
||||||
|
if (strcmp(word, types[i]) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight keywords */
|
||||||
|
void highlight_keyword(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_MAUVE "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight types */
|
||||||
|
void highlight_type(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_YELLOW "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight function names */
|
||||||
|
void highlight_function(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_BLUE "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlight_symbol(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_SKY "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlight_number(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_ORANGE "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlight_normal(const char *word)
|
||||||
|
{
|
||||||
|
int is_constant = 1;
|
||||||
|
for (int i = 0; i < strlen(word); i++) {
|
||||||
|
if (word[i] == '_') continue;
|
||||||
|
if (word[i] > 'a' && word[i] < 'z') {
|
||||||
|
is_constant = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (is_constant) {
|
||||||
|
printf(COLOR_ORANGE "%s" COLOR_RESET, word);
|
||||||
|
} else {
|
||||||
|
printf("%s", word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlight_brackets(const char *word)
|
||||||
|
{
|
||||||
|
printf(COLOR_RED "%s" COLOR_RESET, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight single-line comments */
|
||||||
|
void highlight_single_comment(const char *line, int *i)
|
||||||
|
{
|
||||||
|
printf(COLOR_OVERLAY0 "//");
|
||||||
|
(*i) += 2;
|
||||||
|
while (line[*i] != '\0') {
|
||||||
|
printf("%c", line[*i]);
|
||||||
|
(*i)++;
|
||||||
|
}
|
||||||
|
printf(COLOR_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight multi-line comments */
|
||||||
|
void highlight_multi_comment(const char *line, int *i)
|
||||||
|
{
|
||||||
|
printf(COLOR_OVERLAY0 "/*");
|
||||||
|
(*i) += 2;
|
||||||
|
while (!(line[*i] == '*' && line[*i + 1] == '/') && line[*i] != '\0') {
|
||||||
|
printf("%c", line[*i]);
|
||||||
|
(*i)++;
|
||||||
|
}
|
||||||
|
if (line[*i] == '*' && line[*i + 1] == '/') {
|
||||||
|
printf("*/" COLOR_RESET);
|
||||||
|
(*i) += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight character literals */
|
||||||
|
void highlight_char(const char *line, int *i)
|
||||||
|
{
|
||||||
|
printf(COLOR_TEAL "'");
|
||||||
|
(*i)++;
|
||||||
|
while (line[*i] != '\'' && line[*i] != '\0') {
|
||||||
|
if (line[*i] == '\\' && (line[*i + 1] == '\'' || line[*i + 1] == '\\')) {
|
||||||
|
printf("%c%c", line[*i], line[*i + 1]); // Handle escape sequences
|
||||||
|
(*i) += 2;
|
||||||
|
} else {
|
||||||
|
printf("%c", line[*i]);
|
||||||
|
(*i)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line[*i] == '\'') {
|
||||||
|
printf("'" COLOR_RESET); // Print closing single quote and reset color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to handle and highlight string literals */
|
||||||
|
void highlight_string(const char *line, int *i)
|
||||||
|
{
|
||||||
|
printf(COLOR_GREEN "\""); // Print opening quote in green
|
||||||
|
(*i)++;
|
||||||
|
while (line[*i] != '"' && line[*i] != '\0') {
|
||||||
|
if (line[*i] == '\\' && (line[*i + 1] == '"' || line[*i + 1] == '\\')) {
|
||||||
|
printf("%c%c", line[*i], line[*i + 1]); // Print the escape character and the next character
|
||||||
|
(*i) += 2; // Move past the escape character and the next character
|
||||||
|
} else {
|
||||||
|
printf("%c", line[*i]);
|
||||||
|
(*i)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line[*i] == '"') {
|
||||||
|
printf("\"" COLOR_RESET); // Print the closing quote and reset color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main function to process input */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "nsh <file> <file2> ...\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
FILE *f = fopen(argv[i], "r");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Unable to open file: %s\n", argv[i]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* handle file without extension
|
||||||
|
* ext is the extension if . exist in filename, otherwise nothing */
|
||||||
|
char *ext = strrchr(argv[i], '.');
|
||||||
|
if (ext != NULL) {
|
||||||
|
/* how to identify file type if there isn't extension? */
|
||||||
|
ext++;
|
||||||
|
}
|
||||||
|
char buffer[1024];
|
||||||
|
char word[256];
|
||||||
|
int word_len = 0;
|
||||||
|
|
||||||
|
while (fgets(buffer, sizeof(buffer), f) != NULL) {
|
||||||
|
if (ext && strcmp(ext, "c") == 0) {
|
||||||
|
for (int i = 0; buffer[i] != '\0'; i++) {
|
||||||
|
if (buffer[i] == '\'') {
|
||||||
|
highlight_char(buffer, &i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buffer[i] == '"') {
|
||||||
|
highlight_string(buffer, &i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buffer[i] == '/' && buffer[i+1] == '/') {
|
||||||
|
highlight_single_comment(buffer, &i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buffer[i] == '/' && buffer[i+1] == '*') {
|
||||||
|
highlight_multi_comment(buffer, &i);
|
||||||
|
}
|
||||||
|
if (isspace(buffer[i]) || (ispunct(buffer[i]) && buffer[i] != '_' && buffer[i] != '#')) {
|
||||||
|
if (word_len > 0 && buffer[i] != '*' && buffer[i] != '&' && buffer[i] != '=' && buffer[i] != '+' && buffer[i] != '|') {
|
||||||
|
word[word_len] = '\0';
|
||||||
|
if (buffer[i] == '(' && !is_keyword(word) && !is_type(word)) {
|
||||||
|
highlight_function(word); // Highlight function if it’s not a keyword or type
|
||||||
|
} else if (is_type(word)) {
|
||||||
|
highlight_type(word); // Highlight types correctly
|
||||||
|
} else if (is_keyword(word)) {
|
||||||
|
highlight_keyword(word); // Highlight keywords or other words
|
||||||
|
} else {
|
||||||
|
highlight_normal(word);
|
||||||
|
}
|
||||||
|
word_len = 0;
|
||||||
|
}
|
||||||
|
if (buffer[i] == '[' || buffer[i] == ']' || buffer[i] == '(' || buffer[i] == ')' || buffer[i] == '{' || buffer[i] == '}') {
|
||||||
|
word[word_len++] = buffer[i];
|
||||||
|
word[word_len] = '\0';
|
||||||
|
highlight_brackets(word);
|
||||||
|
word_len = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buffer[i] == '*' || buffer[i] == '&' || buffer[i] == '=' || buffer[i] == '+' || buffer[i] == '|') {
|
||||||
|
word[word_len++] = buffer[i];
|
||||||
|
if (buffer[i+1] != '*' && buffer[i+1] != '&' && buffer[i+1] != '=' && buffer[i+1] != '+' && buffer[i+1] != '|') {
|
||||||
|
word[word_len] = '\0';
|
||||||
|
highlight_symbol(word);
|
||||||
|
word_len = 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("%c", buffer[i]);
|
||||||
|
} else if (isdigit(buffer[i]) ) {
|
||||||
|
word[word_len++] = buffer[i];
|
||||||
|
if (isdigit(buffer[i+1]) == 0) {
|
||||||
|
word[word_len] = '\0';
|
||||||
|
highlight_number(word);
|
||||||
|
word_len = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
word[word_len++] = buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
/* Remove newline from buffer, if present */
|
/* Remove newline from buffer, if present */
|
||||||
size_t len = strlen(buffer);
|
size_t len = strlen(buffer);
|
||||||
if (len > 0 && buffer[len - 1] == '\n') {
|
if (len > 0 && buffer[len - 1] == '\n') {
|
||||||
|
@ -42,6 +278,7 @@ int main()
|
||||||
printf("%s\n", buffer);
|
printf("%s\n", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue