如何为 ARM 操作系统添加 ASCII 颜色识别?

问题描述 投票:0回答:1

我想创建自己的操作系统。在这个操作系统中,我有一个用于修改文件数据的编辑模式(目前仅在RAM中)。这是这个操作系统的完整代码:

#include "editor.h"
#include "uart.h"
#include "strings.h"

void edit_file(File *file){
    char c;
    int index = 0;
    uart_puts("\r\nEntering edit mode. Press Ctrl + Q to save and exit.\r\n");
    
    if (file -> content[0] != '\0'){
        uart_puts(file->content);
        index = my_strlen(file->content);
    }
    while(1){
        c = uart_getc();
        
        if(c == 17){ //Ctrl + Q
            file->content[index] = '\0';
            uart_puts("\r\nFile saved and exited edit mode.\r\n");
            break;
        }else if (c == '\b' || c == 127){
            if(index > 0){
                index--;
                uart_puts("\b \b");
            }
        }else if (c == '\r'){
            if(index < MAX_FILE_SIZE -1){
                file-> content[index++]='\n';
                uart_putc('\r');
                uart_putc('\n');
            }
        }else{
            if(index < MAX_FILE_SIZE -1){
                file->content[index++] = c;
                uart_putc(c);
            }
        }
    }
}

在系统内实现一个简单的文本编辑器。包括进入编辑模式和捕获用户输入的功能。支持编辑现有文件内容或创建新内容。处理特殊输入,例如:Ctrl + Q 保存并退出编辑模式。退格键和回车键。更新内存 (RAM) 中的文件内容。 这里编辑.h:

#ifndef EDITOR_H
#define EDITOR_H

#include "file_system.h"

void edit_file(File *file);

#endif

包括

edit_file(File *file)
的声明。 包括必要的标题:
file_system.h
。这里
file_system.c

#include "file_system.h"
#include "uart.h"
#include <stdint.h>
#include "editor.h"
#include "strings.h"

FileSystem fs;

void init_fs(){
    fs.file_count = 0;
}
int create_directory(const char *name){
    if(fs.file_count >= MAX_FILES){
        uart_puts("FileSystem is full, cannot create directory.\r\n");
        return -1;
    }
    for (int i = 0; i < fs.file_count; i++){
        if(my_strcmp(fs.files[i].name, name) == 0){
            uart_puts("Directory already exist.\r\n");
            return -1;
        }
    }
    my_strcpy(fs.files[fs.file_count].name, name);
    fs.files[fs.file_count].is_directory = 1;
    fs.file_count++;
    uart_puts("Directory created. \r\n");
    return 0;
}
int create_file(const char *name){
    if(fs.file_count >= MAX_FILES){
        uart_puts("FileSystem is full, cannot crete file. \r\n");
        return -1;
    }
    for (int i = 0; i < fs.file_count; i++){
        if(my_strcmp(fs.files[i].name, name) == 0){
            uart_puts("File already exist.\r\n");
            return -1;
        }
    }
    my_strcpy(fs.files[fs.file_count].name, name);
    fs.files[fs.file_count].is_directory = 0;
    fs.files[fs.file_count].content[0] = '\0';
    fs.file_count++;
    uart_puts("File created.\r\n");
    return 0;
}

void list_directory(){
    uart_puts("Directories:\r\n");
    if(fs.file_count == 0){
        uart_puts("No directories.\r\n");
    }else{
        for (int i = 0; i < fs.file_count; i++){
            if(fs.files[i].is_directory){
                uart_puts(fs.files[i].name);
                uart_putc('\r');
                uart_putc('\n');
            }
        }
    }
}

File *find_file(const char *name){
    for (int i = 0; i < fs.file_count; i++){
        if(!fs.files[i].is_directory && my_strcmp(fs.files[i].name, name) == 0){
            return &fs.files[i];
        }
    }
    return NULL;
}

void process_command(const char *cmd, int *debug_mode){
    uart_puts("\r\n");
    
    if(my_strcmp(cmd, "help") == 0){
        uart_puts("Avaible commands: help, echo <message>, debug on, debug off, mkdir <name>, ls, mkf <file> edit <file>. \r\n");
    }else if(my_strncmp(cmd, "echo ", 5) == 0){
        uart_puts(cmd + 5);
        uart_putc('\r');
        uart_putc('\n');
    }else if(my_strcmp(cmd, "debug on") == 0){
        *debug_mode = 1;
        uart_puts("Debug mode enabled. \r\n");
    }else if(my_strcmp(cmd, "debug off") == 0){
        *debug_mode = 0;
        uart_puts("Debug mode disable. \r\n");
    }else if(my_strncmp(cmd, "mkdir ", 6) == 0){
        create_directory(cmd + 6);
    }else if(my_strncmp(cmd, "edit ", 5) == 0){
        File *file = find_file(cmd + 5);
        if (file){
            edit_file(file);
        }else{
            uart_puts("File not found.\n\r");
        }
    }else if(my_strncmp(cmd, "mkf ", 4) == 0){
        create_file(cmd + 4);
    }else if (my_strcmp(cmd, "ls") == 0){
        list_directory();
    }else{
        uart_puts("Unknown command. \r\n");
    }
}

void print_command(const char *cmd, int debug_mode){
    if(debug_mode){
        uart_puts("\r\nReceived command: ");
        uart_puts(cmd);
        uart_putc('\r');
        uart_putc('\n');
    }
}

定义文件系统并使用 init_fs() 对其进行初始化。 功能:

  • 创建目录(create_directory)。
  • 创建文件(create_file)。
  • 列出目录 (list_directory)。
  • 查找文件(find_file)。
  • 处理来自用户的命令(process_command)。

命令处理支持 help、echo、debug on/off、mkdir、ls、mkf、edit 等命令。 通过 UART 提供反馈。

file_system.h

#ifndef FILE_SYSTEM_H
#define FILE_SYSTEM_H

#define MAX_FILES 16
#define MAX_NAME_LEGTH 32
#define MAX_FILE_SIZE 1024

#include <stddef.h>

typedef unsigned long size_t;

typedef struct{
    char name [MAX_NAME_LEGTH];
    int is_directory;
    char content[MAX_FILE_SIZE];
} File;

typedef struct{
    File files[MAX_FILES];
    int file_count;
} FileSystem;

void init_fs();
int create_directory(const char *name);
int create_file(const char *name);
void list_directory();
File *find_file(const char *name);
void process_command(const char *cmd, int *debug_mode);
void print_command(const char *cmd, int debug_mode);

#endif

file_system.c
的头文件,定义结构和函数原型。

详情:

常数:

  • MAX_FILES:文件/目录的最大数量。
  • MAX_NAME_LENGTH:文件/目录名称的最大长度。
  • MAX_FILE_SIZE:文件内容的最大大小。
  • 类型定义:
  • 文件:表示文件或目录,包含名称、类型和内容。
  • FileSystem:包含文件数组和文件计数。 函数声明:
  • 文件系统相关的初始化、创建、列出、查找、处理功能。

memmp - 它只是一个链接器:

ENTRY(_main)
SECTIONS
{
    . = 0x40000000;  /* Начальный адрес загрузки */

    .startup : { strap.o(.text) }  /* Секция для инициализации (например, strap.o) */

    .text : {
        *(.text)  /* Код программы */
    }

    .data : {
        *(.data)  /* Инициализированные данные */
    }

    .bss : {
        *(.bss COMMON)  /* Неиницилизированные данные */
    }

    /* Секция для хранения файловой системы */
    .fs_section (NOLOAD) : {
        *(.fs_section)  /* Секция для файловой системы */
    }

    . = ALIGN(8);  /* Выравнивание */
    . = . + 0x1000; /* 4kB памяти для стека */
    stack_top = .;  /* Указатель на верх стека */
}

这是主要文件:

#include "uart.h"
#include "file_system.h"
#include "strings.h"

#define COMMAND_HISTORY_SiZE 10 

void notmain(void){
    char c;
    char command[100];
    int index = 0;
    int debug_mode = 0;//0 - debug off, 1 - on
    
    char command_history[COMMAND_HISTORY_SiZE][100];
    int command_history_count = 0;
    int command_history_pos = -1;
    uart_puts("UART test... \n");
    init_fs();
    while(1){
        c = uart_getc();
        if(c == '\r'){
            command[index] = '\0';
            if(command[0] != '\0'){
                if(command_history_count < COMMAND_HISTORY_SiZE){
                    my_strcpy(command_history[command_history_count++], command);
                }else{
                    for (int i = 0; i < COMMAND_HISTORY_SiZE; i++){
                        my_strcpy(command_history[i-1], command_history[i]);
                    }
                    my_strcpy(command_history[COMMAND_HISTORY_SiZE - 1], command);
                }
            }
            command_history_pos = command_history_count;
            print_command(command, debug_mode);
            process_command(command, &debug_mode);
            index = 0;
        } else if (c == '\b' || c == 127){
            if(index > 0){
                index--;
                uart_puts("\b \b");
            }
        } else if(c == 27){
            char seq[2];
            seq[0] = uart_getc();
            seq[1] = uart_getc();
            if(seq[0] == '['){
                if(seq[1]=='A'){
                    if(command_history_pos > 0){
                        command_history_pos--;
                        while(index > 0){
                            uart_puts("\b \b");
                            index--;
                        }
                        my_strcpy(command, command_history[command_history_pos]);
                        index = my_strlen(command);
                        uart_puts(command);
                    }
                }else if(seq[1] == 'B'){
                    if(command_history_pos < command_history_count - 1){
                        command_history_pos++;
                        while(index > 0){
                            uart_puts("\b \b");
                            index--;
                        }
                        my_strcpy(command, command_history[command_history_pos]);
                        index = my_strlen(command);
                        uart_puts(command);
                    }else if(command_history_pos == command_history_count - 1){
                        while(index > 0){
                            uart_puts("\b \b");
                            index--;
                        }
                        command[0] = '\0';
                    }
                }
            }   
        }else{
            if(index < sizeof(command)-1){
                command[index++] = c;
                uart_putc(c);
            }
        }
    }
}

功能:

  • 初始化 UART 通信和文件系统。
  • 实现命令行界面 (CLI):
  • 通过 UART 读取用户输入。
  • 维护命令历史记录(支持使用向上/向下箭头导航)。
  • 使用 process_command 处理命令。
  • 处理特殊字符和按键序列(例如退格键、箭头键)。
  • 支持调试模式打印接收到的命令。

这里是汇编代码(strap.s):

.global _main
_main:
    ldr x30, =stack_top
    mov sp, x30
    bl notmain
    b .
    

功能:

  • 全局标签_main作为入口点。
  • 使用链接描述文件中的 stack_top 设置堆栈指针 (sp)。
  • 调用notmain启动主程序。
  • notmain返回后进入无限循环。

我还写了自己的strings.s文件:

#include "strings.h"


int my_strlen(const char *str){
    int len = 0;
    while(*str++){
        len++;
    }
    return len;
}

int my_strcmp(const char *s1, const char *s2){
    while (*s1 && (*s1 == *s2)){
        s1++;
        s2++;
    }
    return (unsigned char)*s1 - (unsigned char)*s2;
}
int my_strncmp(const char *s1, const char *s2, size_t n){
    while (n > 0){
        if(*s1 != *s2){
            return (unsigned char)*s1 - (unsigned char)*s2;
        }
        if (*s1 == '\0'){
            return 0;
        }
        s1++;
        s2++;
        n--;
    }
    return 0;
}
void my_strcpy(char *dest, const char *src){
    while(*src){
        *dest++ = *src++;
    }
    *dest = '\0';
}

包括strcpy、strncmp、strcmp、strlen。 我还有头文件:

#ifndef STRINGS_H
#define STRINGS_H

#include <stddef.h>

int my_strlen(const char *str);
int my_strcmp(const char *s1, const char *s2);
int my_strncmp(const char *s1, const char *s2, size_t n);
void my_strcpy(char *dest, const char *src);

#endif

我还有

uart.c
用于 I/O 识别的文件:

#include "uart.h"
#include <stdint.h>

void uart_putc(char c){
    volatile uint32_t *UARTFR = (uint32_t *)UART0_FR;
    volatile uint32_t *UARTDR = (uint32_t *)UART0_DR;
    
    while(*UARTFR & (1<<5)){
        
    }
    *UARTDR = c;
}
char uart_getc(){
    volatile uint32_t *UARTFR = (uint32_t *)UART0_FR;
    volatile uint32_t *UARTDR = (uint32_t *)UART0_DR;
    
    while(*UARTFR & (1<<4)){
            
    }
    return *UARTDR & 0xFF;
}
void uart_puts(const char *str){
    while (*str){
        uart_putc(*str++);
    }
}

该文件的功能:

  • 发送单个字符(uart_putc)。
  • 接收单个字符(uart_getc)。
  • 发送字符串(uart_puts)。
  • 使用内存映射 I/O 与 UART 硬件寄存器交互。在发送或接收数据之前等待 UART 缓冲区准备就绪。

我正在尝试更新我的编辑器,以突出显示 C/C++ 关键字、数字和分号。我试着用

editor.c
来做到这一点:

#include "editor.h"
#include "uart.h"
#include "strings.h"

// ANSI color codes
#define COLOR_RESET "\033[0m"
#define COLOR_KEYWORD "\033[31m"  // Red color for keywords and semicolons
#define COLOR_NUMBER "\033[32m"   // Green color for numbers
// You can adjust the colors as needed

int is_c_or_cpp_file(const char *filename){
    int len = my_strlen(filename);
    if(len >= 2 && my_strcmp(filename + len - 2, ".c") == 0){
        return 1;
    }
    if(len >= 4 && my_strcmp(filename + len - 4, ".cpp") == 0){
        return 1;
    }
    return 0;
}

const char* keywords[] = {
    "int", "char", "if", "else", "for", "while", "return", "void", "include",
    "define", "struct", "typedef", "enum", "static", "const", "unsigned",
    "signed", "long", "short", "float", "double", "do", "switch", "case",
    "break", "continue", "default", "goto", "sizeof", "volatile", "register",
    "extern", "auto", "union", "inline"
};
#define NUM_KEYWORDS (sizeof(keywords)/sizeof(keywords[0]))

int is_keyword(const char *word){
    for(int i = 0; i < NUM_KEYWORDS; i++){
        if(my_strcmp(word, keywords[i]) == 0){
            return 1;
        }
    }
    return 0;
}

int is_number(const char *word){
    int i = 0;
    if(word[0] == '-' || word[0] == '+') i++;  // handle sign
    int has_digits = 0;
    for(; word[i]; i++){
        if(word[i] >= '0' && word[i] <= '9'){
            has_digits = 1;
        } else {
            return 0;
        }
    }
    return has_digits;
}

void move_cursor_back(int n){
    for(int i = 0; i < n; i++){
        uart_puts("\b \b");
    }
}

void output_with_syntax_highlighting(const char *content){
    int i = 0;
    char word[50];
    int word_index = 0;
    char c;
    while((c = content[i]) != '\0'){
        if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9')){
            if(word_index < sizeof(word) - 1){
                word[word_index++] = c;
            }
            // We don't output yet
        }else{
            word[word_index] = '\0';

            if(is_keyword(word)){
                uart_puts(COLOR_KEYWORD);
                uart_puts(word);
                uart_puts(COLOR_RESET);
            }else if(is_number(word)){
                uart_puts(COLOR_NUMBER);
                uart_puts(word);
                uart_puts(COLOR_RESET);
            }else{
                uart_puts(word);
            }
            word_index = 0;

            if(c == ';'){
                uart_puts(COLOR_KEYWORD);
                uart_putc(c);
                uart_puts(COLOR_RESET);
            }else{
                uart_putc(c);
            }
        }
        i++;
    }
    // Output any remaining word
    if(word_index > 0){
        word[word_index] = '\0';
        if(is_keyword(word)){
            uart_puts(COLOR_KEYWORD);
            uart_puts(word);
            uart_puts(COLOR_RESET);
        }else if(is_number(word)){
            uart_puts(COLOR_NUMBER);
            uart_puts(word);
            uart_puts(COLOR_RESET);
        }else{
            uart_puts(word);
        }
    }
}

void edit_file(File *file){
    char c;
    int index = 0;
    uart_puts("\r\nEntering edit mode. Press Ctrl + Q to save and exit.\r\n");
    
    int syntax_highlighting = 0;
    if(is_c_or_cpp_file(file->name)){
        syntax_highlighting = 1;
    }

    if (file->content[0] != '\0'){
        if(syntax_highlighting){
            output_with_syntax_highlighting(file->content);
        }else{
            uart_puts(file->content);
        }
        index = my_strlen(file->content);
    }
    
    char word[50];
    int word_index = 0;

    while(1){
        c = uart_getc();
        
        if(c == 17){ //Ctrl + Q
            file->content[index] = '\0';
            uart_puts("\r\nFile saved and exited edit mode.\r\n");
            break;
        }else if (c == '\b' || c == 127){
            if(index > 0){
                index--;
                uart_puts("\b \b");

                // Handle word buffer
                if(word_index > 0){
                    word_index--;
                }
            }
        }else if (c == '\r'){
            if(index < MAX_FILE_SIZE -1){
                file->content[index++]='\n';
                uart_putc('\r');
                uart_putc('\n');
                word[word_index] = '\0';

                // Process the word at end of line
                if(syntax_highlighting && word_index > 0){
                    if(is_keyword(word)){
                        move_cursor_back(word_index);
                        uart_puts(COLOR_KEYWORD);
                        uart_puts(word);
                        uart_puts(COLOR_RESET);
                    }else if(is_number(word)){
                        move_cursor_back(word_index);
                        uart_puts(COLOR_NUMBER);
                        uart_puts(word);
                        uart_puts(COLOR_RESET);
                    }
                    word_index = 0;
                }else{
                    word_index = 0;
                }
            }
        }else{
            if(index < MAX_FILE_SIZE -1){
                file->content[index++] = c;
                
                if(syntax_highlighting){
                    if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9')){
                        if(word_index < sizeof(word) - 1){
                            word[word_index++] = c;
                        }
                        uart_putc(c);  // Temporarily output the character
                    }else{
                        // Non-alphanumeric character
                        word[word_index] = '\0';

                        // Check for keyword or number
                        if(is_keyword(word)){
                            move_cursor_back(word_index);
                            uart_puts(COLOR_KEYWORD);
                            uart_puts(word);
                            uart_puts(COLOR_RESET);
                        }else if(is_number(word)){
                            move_cursor_back(word_index);
                            uart_puts(COLOR_NUMBER);
                            uart_puts(word);
                            uart_puts(COLOR_RESET);
                        }
                        word_index = 0;

                        // Handle semicolons
                        if(c == ';'){
                            uart_puts(COLOR_KEYWORD);
                            uart_putc(c);
                            uart_puts(COLOR_RESET);
                        }else{
                            uart_putc(c);
                        }
                    }
                }else{
                    uart_putc(c);
                }
            }
        }
    }
}   

和头文件:

#ifndef EDITOR_H
#define EDITOR_H

#include "file_system.h"

// Визначення ANSI-кодів кольорів
#define ANSI_COLOR_RED     "\033[31m"
#define ANSI_COLOR_GREEN   "\033[32m"
#define ANSI_COLOR_YELLOW  "\033[33m"
#define ANSI_COLOR_BLUE    "\033[34m"
#define ANSI_COLOR_MAGENTA "\033[35m"
#define ANSI_COLOR_CYAN    "\033[36m"
#define ANSI_COLOR_RESET   "\033[0m"

void edit_file(File *file);
// Прототипи функцій
void display_with_syntax_highlighting(const char *content);
void re_render_current_line(const char *content, int length);
int is_letter_or_digit(char c);
int is_keyword(const char *word);
#endif

我还添加了notmain.c用于测试颜色的小功能:

void test_ansi_colors() {
    uart_puts("\033[31mЦей текст повинен бути червоним\033[0m\r\n");
    uart_puts("\033[32mЦей текст повинен бути зеленим\033[0m\r\n");
    uart_puts("\033[34mЦей текст повинен бути синім\033[0m\r\n");
}

我正在使用 qemu 命令进行测试:

qemu-system-aarch64 -nographic -M virt -cpu cortex-a53 -m 128 -serial mon:stdio -kernel os.bin

当我启动它时,它是彩色的:

enter image description here

但是,当我创建文件并尝试编辑它时,我遇到了一个小问题:

enter image description here

为什么关键词没有突出显示?

所以,总而言之,我需要什么:

为 .c/.cpp 文件和 .java 文件添加关键字突出显示(只需 else if 语句)。它还必须以绿色文本突出显示,其中

" "
(双引号)和数字 (4, 4412, 2_000_000, 2E+1)

c operating-system arm syntax-highlighting text-editor
1个回答
0
投票
// #include "editor.h"
// #include "uart.h"
// #include "strings.h"

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#ifdef __linux__
#include <termios.h> //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>  //STDIN_FILENO
#endif // #ifdef __linux__
#include <stdio.h>

int my_strncmp(const char *s1, const char *s2, size_t n)
{
    while (n > 0 && *s1 && (*s1 == *s2))
    {
        s1++;
        s2++;
        n--;
    }
    return (unsigned char)*s1 - (unsigned char)*s2;
}
void my_strcpy(char *dest, const char *src)
{
    while (*src)
        *dest++ = *src++;
    *dest = '\0';
}

// ANSI color codes
#define COLOR_RESET "\033[0m"
#define COLOR_KEYWORD "\033[35m" // Red color for keywords and semicolons
#define COLOR_NUMBER "\033[36m"  // Green color for numbers
// You can adjust the colors as needed

bool is_c_or_cpp_file(const char *filename)
{
    int len = my_strlen(filename);
    return (len >= 2 && my_strcmp(filename + len - 2, ".c") == 0) || (len >= 4 && my_strcmp(filename + len - 4, ".cpp") == 0);
}

static const char *keywords[] = {
    "int", "char", "if", "else", "for", "while", "return", "void", "include",
    "define", "struct", "typedef", "enum", "static", "const", "unsigned",
    "signed", "long", "short", "float", "double", "do", "switch", "case",
    "break", "continue", "default", "goto", "sizeof", "volatile", "register",
    "extern", "auto", "union", "inline"};
#define NUM_KEYWORDS (sizeof(keywords) / sizeof(keywords[0]))

void move_cursor_back(int n)
{
    for (int i = 0; i < n; i++)
        uart_puts("\b \b");
}

void highlight(const char *s, const int l, const char *colour)
{
    move_cursor_back(l);
    uart_puts(colour);
    uart_puts(s);
    uart_puts(COLOR_RESET);
}

void edit_file(File *file)
{
    int c;
    int index = 0;
    uart_puts("\r\nEntering edit mode. Press Ctrl + Q to save and exit.\r\n");

    int syntax_highlighting = 0;
    if (is_c_or_cpp_file(file->name))
    {
        syntax_highlighting = 1;
    }

    if (file->content[0] != '\0')
    {
        if (syntax_highlighting)
            output_with_syntax_highlighting(file->content);
        else
            uart_puts(file->content);
        index = my_strlen(file->content);
    }

    char word[2048];
    int word_index = 0;

#ifdef __linux__
    static struct termios oldt, newt;

    /*tcgetattr gets the parameters of the current terminal
    STDIN_FILENO will tell tcgetattr that it should write the settings
    of stdin to oldt*/
    tcgetattr(STDIN_FILENO, &oldt);
    /*now the settings will be copied*/
    newt = oldt;

    /*ICANON normally takes care that one line at a time will be processed
    that means it will return if it sees a "\n" or an EOF or an EOL*/
    newt.c_lflag &= ~(ICANON);

    /*Those new settings will be set to STDIN
    TCSANOW tells tcsetattr to change attributes immediately. */
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
#endif // __linux__
    while (1)
    {
        c = uart_getc();

        switch (c)
        {
        case '\b':
        case 0x7f:
            if (index > 0)
            {
                index--;
                uart_puts("\b\b\b   \b\b\b");

                // Handle word buffer
                if (word_index > 0)
                {
                    word_index--;
                }
            }
            break;
        case '\r':
            if (index < 255 - 1 && word_index > 0)
                file->content[++index] = '\n';
            break;
        default:
            if (index < MAX_FILE_SIZE - 1)
            {
                file->content[index++] = c;
                // break;

                if (syntax_highlighting)
                {
                    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
                    {
                        if (word_index < sizeof(word) - 1)
                            word[word_index++] = c;
                    }
                    else
                    {
                        // Non-alphanumeric character
                        word[word_index++] = '\0';

                        // Check for keyword or number
                        bool highlighted = false;

                        if ((highlighted = is_keyword(word)))
                            highlight(word, word_index, COLOR_KEYWORD);
                        else if ((highlighted = is_number(word)))
                            highlight(word, word_index, COLOR_NUMBER);
                        if (c == ';')
                            highlight((char *)&c, 0, COLOR_KEYWORD);
                        else if (c != '\n' && highlighted)
                            uart_putc(c);

                        word_index = 0;
                    }
                }
            }
            break;
        }
    }
#ifdef __linux__
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#endif // __linux__
}

我改变了什么:

  1. 将设置更改为标准输入,以便它立即捕获字符。 受到这个答案的启发
  2. DEL
    (0x7f) 需要 3
    \b
    ,因为它被视为
    ^?\x7f
  3. keywords
    定义为
    static const char *

为了更好的可读性:

  1. bool
    而不是
    int
  2. 新的
    highlight
    功能和
    is_c_or_cpp_file
    缩短了
  3. switch
    案例而不是连锁的
    if
    陈述

让我知道它是否也适合您,也许您的模拟器上的行为有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.