overflow errors
This commit is contained in:
@@ -7,6 +7,6 @@
|
||||
|
||||
void abAppend(struct abuf *ab, const char *s, int len);
|
||||
|
||||
void abFree(const struct abuf *ab);
|
||||
void abFree(struct abuf *ab);
|
||||
|
||||
#endif // APPEND_BUFFER_H_
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#define TAB "\t"
|
||||
#define SPACE "\x20"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
/* Uncomment to see debug logs on stderr */
|
||||
#define APP_DEBUG
|
||||
|
||||
|
||||
@@ -28,42 +28,39 @@
|
||||
struct editorConfig E;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Get HOME with NULL check
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
fprintf(stderr, "Error: HOME environment variable not set\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char * splash_screen = strdup(getenv("HOME"));
|
||||
int home_path_len = (int) strlen(splash_screen);
|
||||
char * splash_screen_relative_path = strdup("/.beluga/assets/beluga.txt");
|
||||
int splash_screen_relative_path_len = (int) strlen(splash_screen_relative_path);
|
||||
|
||||
signal(SIGPIPE, SIG_IGN); // don't die on broken pipe, just get EPIPE from write()
|
||||
// Allocate and build splash screen path safely
|
||||
char *splash_screen;
|
||||
if (asprintf(&splash_screen, "%s/.beluga/assets/beluga.txt", home) == -1) {
|
||||
fprintf(stderr, "Error: Failed to allocate splash screen path\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
enableRawMode();
|
||||
initEditor();
|
||||
|
||||
EditorPane *active = splitScreenGetActivePane();
|
||||
struct buffer_t *buf;
|
||||
|
||||
splash_screen = realloc(splash_screen, sizeof(char) * (home_path_len + splash_screen_relative_path_len + 1));
|
||||
strcat(splash_screen, "/.beluga/assets/beluga.txt");
|
||||
free(splash_screen_relative_path);
|
||||
|
||||
appDebug("splash : %s\n", splash_screen);
|
||||
active->buffer_id = bufferCreate(splash_screen, READ_ONLY);
|
||||
|
||||
if (argc >= 2) {
|
||||
if (E.constantes.LSP) {
|
||||
|
||||
}
|
||||
active->buffer_id = bufferCreate(argv[1], READ_AND_WRITE);
|
||||
|
||||
buf = &E.buffers[active->buffer_id];
|
||||
|
||||
appDebug("peoject root : %s\n", dirname(buf->fullname));
|
||||
|
||||
|
||||
appDebug("project root : %s\n", dirname(buf->fullname));
|
||||
}
|
||||
free(splash_screen);
|
||||
|
||||
free(splash_screen); // Now guaranteed safe
|
||||
|
||||
editorSetStatusMessage("HELP: Ctrl-x Ctrl-s = save | Ctrl-x Ctrl-c = quit");
|
||||
|
||||
while (1) {
|
||||
editorRefreshScreen();
|
||||
editorProcessKeypress();
|
||||
|
||||
+5
-1
@@ -11,4 +11,8 @@ void abAppend(struct abuf *ab, const char *s, int len) {
|
||||
ab->len += len;
|
||||
}
|
||||
|
||||
void abFree(const struct abuf *ab) { free(ab->b); }
|
||||
void abFree(struct abuf *ab) {
|
||||
free(ab->b);
|
||||
ab->b = NULL;
|
||||
ab->len = 0;
|
||||
}
|
||||
|
||||
+55
-23
@@ -63,7 +63,7 @@ struct buffer_t* bufferFindById(int buffer_id)
|
||||
int bufferCreate(const char* path, enum bufferStatus_e state)
|
||||
{
|
||||
appDebug("Creating new buffer");
|
||||
char *filename = basename((char *) path);
|
||||
char* filename = basename((char*)path);
|
||||
// Check if file is already open
|
||||
const int existing_id = bufferFindByFilename(path);
|
||||
if (existing_id != -1)
|
||||
@@ -81,7 +81,16 @@ int bufferCreate(const char* path, enum bufferStatus_e state)
|
||||
struct buffer_t* new_buf = &E.buffers[E.number_of_buffer];
|
||||
new_buf->buffer_id = E.number_of_buffer;
|
||||
new_buf->filename = strdup(filename);
|
||||
if (!new_buf->filename)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
new_buf->fullname = malloc(1024 * sizeof(char));
|
||||
if (!new_buf->fullname)
|
||||
{
|
||||
free(new_buf->filename);
|
||||
return -1;
|
||||
}
|
||||
realpath(path, new_buf->fullname);
|
||||
new_buf->path = dirname(new_buf->fullname);
|
||||
new_buf->type = FILE_BUFF;
|
||||
@@ -98,8 +107,7 @@ int bufferCreate(const char* path, enum bufferStatus_e state)
|
||||
{
|
||||
if (E.lsp_client->state == LSP_SHUTDOWN)
|
||||
lspStart(E.lsp_client, dirname(new_buf->path));
|
||||
while (E.lsp_client->state != LSP_READY)
|
||||
;
|
||||
while (E.lsp_client->state != LSP_READY);
|
||||
lspDidOpen(E.lsp_client, new_buf);
|
||||
}
|
||||
|
||||
@@ -301,7 +309,7 @@ void bufferFind(struct buffer_t* buf)
|
||||
if (query == NULL)
|
||||
return;
|
||||
int i;
|
||||
for (i = buf->y+1; i < buf->numrows; i++)
|
||||
for (i = buf->y + 1; i < buf->numrows; i++)
|
||||
{
|
||||
row_t* row = &buf->row[i];
|
||||
char* match = strstr(row->chars, query);
|
||||
@@ -337,23 +345,25 @@ void bufferFindReverse(struct buffer_t* buf)
|
||||
free(query);
|
||||
}
|
||||
|
||||
void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) {
|
||||
void bufferInsertRow(struct buffer_t* buffer, int at, char* s, size_t len)
|
||||
{
|
||||
if (at < 0 || at > buffer->numrows)
|
||||
return;
|
||||
|
||||
row_t *tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1));
|
||||
row_t* tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1));
|
||||
if (!tmp)
|
||||
return;
|
||||
buffer->row = tmp;
|
||||
|
||||
/* Shift existing rows to make room at 'at' — no at++ */
|
||||
if (at < buffer->numrows) {
|
||||
if (at < buffer->numrows)
|
||||
{
|
||||
memmove(&buffer->row[at + 1], &buffer->row[at],
|
||||
sizeof(row_t) * (buffer->numrows - at)); /* not -at+1 */
|
||||
}
|
||||
|
||||
buffer->row[at].size = (int) len;
|
||||
buffer->row[at].cap = (int) len + 1;
|
||||
buffer->row[at].size = (int)len;
|
||||
buffer->row[at].cap = (int)len + 1;
|
||||
buffer->row[at].chars = malloc(len + 1);
|
||||
if (!buffer->row[at].chars)
|
||||
return;
|
||||
@@ -364,24 +374,41 @@ void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) {
|
||||
buffer->dirty++;
|
||||
}
|
||||
|
||||
void bufferFreeRow(row_t *row) { free(row->chars); }
|
||||
void bufferFreeRow(row_t* row) { free(row->chars); }
|
||||
|
||||
/**
|
||||
* \fn editorRowInsertChar(erow *row, int at, int c)
|
||||
* \param at Index of where we want to insert the char */
|
||||
|
||||
void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at,
|
||||
const char *src, int n) {
|
||||
void bufferRowInsertBytes(struct buffer_t* buffer, row_t* row, int at,
|
||||
const char* src, int n)
|
||||
{
|
||||
if (buffer->state == READ_ONLY)
|
||||
return;
|
||||
if (row->size + n + 1 > row->cap) {
|
||||
row->cap = (row->size + n + 1) * 2;
|
||||
row->chars = realloc(row->chars, row->cap);
|
||||
if (at < 0 || at > row->size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (row->size + n + 1 > row->cap)
|
||||
{
|
||||
size_t new_cap = row->cap == 0 ? 128 : row->cap * 2;
|
||||
while (new_cap < row->size + n + 1) {
|
||||
new_cap *= 2;
|
||||
}
|
||||
char *new_chars = realloc(row->chars, new_cap);
|
||||
if (!new_chars) {
|
||||
return; // Allocation failed
|
||||
}
|
||||
row->chars = new_chars;
|
||||
row->cap = (int) new_cap;
|
||||
}
|
||||
memmove(row->chars + at + n, row->chars + at, row->size - at);
|
||||
|
||||
// Copy new bytes
|
||||
memcpy(row->chars + at, src, n);
|
||||
row->size += n;
|
||||
row->chars = realloc(row->chars, row->size + 2);
|
||||
|
||||
row->chars[row->size] = '\0';
|
||||
++buffer->dirty;
|
||||
}
|
||||
|
||||
@@ -390,7 +417,8 @@ void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at,
|
||||
* \brief Delete the a char at the chosen position on the given row
|
||||
* \param at Index of the char to delete
|
||||
* \param row Row on operation is made */
|
||||
void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n) {
|
||||
void bufferRowDelByte(struct buffer_t* buffer, row_t* row, int at, int n)
|
||||
{
|
||||
if (buffer->state == READ_ONLY)
|
||||
return;
|
||||
if (at < 0 || at >= row->size)
|
||||
@@ -461,18 +489,22 @@ void bufferDelBytes(void)
|
||||
}
|
||||
}
|
||||
|
||||
void bufferInsertNewLine(void) {
|
||||
void bufferInsertNewLine(void)
|
||||
{
|
||||
appDebug("Inserting new line\n");
|
||||
EditorPane *active = splitScreenGetActivePane();
|
||||
struct buffer_t *buf = bufferFindById(active->buffer_id);
|
||||
EditorPane* active = splitScreenGetActivePane();
|
||||
struct buffer_t* buf = bufferFindById(active->buffer_id);
|
||||
|
||||
appDebug("buf x %d\n", buf->x);
|
||||
|
||||
if (buf->y >= buf->numrows) {
|
||||
if (buf->y >= buf->numrows)
|
||||
{
|
||||
/* Cursor is past the last row: just append a blank line */
|
||||
bufferInsertRow(buf, buf->numrows, "", 0);
|
||||
} else {
|
||||
row_t *row = &buf->row[buf->y];
|
||||
}
|
||||
else
|
||||
{
|
||||
row_t* row = &buf->row[buf->y];
|
||||
|
||||
/* Insert the tail (from cursor to end) as a new row below */
|
||||
bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x);
|
||||
|
||||
+30
-20
@@ -137,24 +137,27 @@ void bFree_structs(void)
|
||||
{
|
||||
int i, j;
|
||||
free(E.prefix);
|
||||
for (i = 0; i < E.number_of_keybinds; ++i)
|
||||
{
|
||||
for (i = 0; i < E.number_of_keybinds; ++i) {
|
||||
free(E.key_binds[i].key_sequence);
|
||||
E.key_binds[i].key_sequence = NULL;
|
||||
}
|
||||
free(E.key_binds);
|
||||
// bFree layout
|
||||
free(E.layout.panes);
|
||||
E.key_binds = NULL;
|
||||
E.number_of_keybinds = 0;
|
||||
|
||||
// bFree buffers
|
||||
for (i = 0; i < E.number_of_buffer; ++i)
|
||||
{
|
||||
// Similar fix for buffers
|
||||
for (i = 0; i < E.number_of_buffer; ++i) {
|
||||
free(E.buffers[i].filename);
|
||||
for (j = 0; j < E.buffers[i].numrows; ++j)
|
||||
{
|
||||
E.buffers[i].filename = NULL;
|
||||
for (j = 0; j < E.buffers[i].numrows; ++j) {
|
||||
free(E.buffers[i].row[j].chars);
|
||||
E.buffers[i].row[j].chars = NULL;
|
||||
}
|
||||
free(E.buffers[i].row);
|
||||
E.buffers[i].row = NULL;
|
||||
}
|
||||
// bFree layout
|
||||
free(E.layout.panes);
|
||||
|
||||
free(E.init_file_path);
|
||||
fclose(E.fd_init_file);
|
||||
@@ -187,7 +190,7 @@ Lisp editorQuit(Lisp args, LispError* e, LispContext ctx)
|
||||
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
|
||||
lspShutdown(E.lsp_client);
|
||||
lisp_shutdown(E.ctx);
|
||||
deInitEditor();
|
||||
// deInitEditor();
|
||||
disableRawMode();
|
||||
exit(0);
|
||||
}
|
||||
@@ -414,16 +417,23 @@ Lisp addPackage(Lisp args, LispError* e, LispContext ctx)
|
||||
{
|
||||
const char* package_name = lisp_string(lisp_car(args));
|
||||
appDebug("%s\n", package_name);
|
||||
char* package_dir = calloc(256, sizeof(char));
|
||||
FILE* fd_package = NULL;
|
||||
strcat(package_dir, getenv("HOME"));
|
||||
strcat(package_dir, "/.beluga/packages/");
|
||||
strcat(package_dir, package_name);
|
||||
strcat(package_dir, "/init.lisp");
|
||||
appDebug("%s\n", package_dir);
|
||||
fd_package = fopen(package_dir, "r");
|
||||
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error,
|
||||
E.ctx);
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
return lisp_null();
|
||||
}
|
||||
|
||||
char *package_dir;
|
||||
if (asprintf(&package_dir, "%s/.beluga/packages/%s/init.lisp", home, package_name) == -1) {
|
||||
return lisp_null();
|
||||
}
|
||||
|
||||
FILE* fd_package = fopen(package_dir, "r");
|
||||
if (!fd_package) {
|
||||
free(package_dir);
|
||||
return lisp_null();
|
||||
}
|
||||
|
||||
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error, E.ctx);
|
||||
fclose(fd_package);
|
||||
free(package_dir);
|
||||
|
||||
|
||||
+14
-4
@@ -49,13 +49,13 @@ int editorMoveCursor(int key) {
|
||||
if (row && buf->x < row->size) {
|
||||
int len = utf8Seqlen(row->chars[buf->x]);
|
||||
buf->x += len;
|
||||
} else if (row && buf->y < buf->numrows) {
|
||||
} else if (row && buf->y < buf->numrows - 1) {
|
||||
buf->y++;
|
||||
buf->x = 0;
|
||||
}
|
||||
break;
|
||||
case ARROW_DOWN:
|
||||
if (buf->y < buf->numrows) {
|
||||
if (buf->y < buf->numrows - 1) {
|
||||
|
||||
buf->y++;
|
||||
}
|
||||
@@ -86,18 +86,28 @@ char *editorGetClipboard(void) {
|
||||
size_t cap = 4096;
|
||||
size_t len = 0;
|
||||
char *buf = malloc(cap);
|
||||
if (!buf) {
|
||||
pclose(pipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int c;
|
||||
while ((c = fgetc(pipe)) != EOF) {
|
||||
if (len + 1 >= cap) {
|
||||
cap *= 2;
|
||||
buf = realloc(buf, cap);
|
||||
char *new_buf = realloc(buf, cap);
|
||||
if (!new_buf) {
|
||||
free(buf);
|
||||
pclose(pipe);
|
||||
return NULL;
|
||||
}
|
||||
buf = new_buf;
|
||||
}
|
||||
buf[len++] = (char)c;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
pclose(pipe);
|
||||
return buf; // caller must free
|
||||
return buf;
|
||||
}
|
||||
|
||||
void editorSetClipboard(const char *text, int len) {
|
||||
|
||||
+4
-12
@@ -60,19 +60,12 @@ void editorCloseFile(void) {
|
||||
*/
|
||||
void editorOpen(struct buffer_t* buffer) {
|
||||
FILE *fp;
|
||||
char full_name[1024];
|
||||
strcpy(full_name, buffer->path);
|
||||
strcat(full_name, "/");
|
||||
strcat(full_name, buffer->filename);
|
||||
strcat(full_name, "\0");
|
||||
appDebug("full name : %s", full_name);
|
||||
|
||||
fp = fopen(full_name, "a+");
|
||||
fp = fopen(buffer->fullname, "a+");
|
||||
if (!fp)
|
||||
die("fopen");
|
||||
|
||||
char *line = NULL;
|
||||
size_t line_cap;
|
||||
size_t line_cap = 0;
|
||||
ssize_t line_len;
|
||||
|
||||
rewind(fp);
|
||||
@@ -82,12 +75,11 @@ void editorOpen(struct buffer_t* buffer) {
|
||||
(line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) {
|
||||
--line_len;
|
||||
}
|
||||
appDebug("line %s\n", line);
|
||||
bufferInsertRow(buffer, buffer->numrows, line, line_len);
|
||||
free(line);
|
||||
line = NULL;
|
||||
line_cap = 0; // Reset for next iteration
|
||||
}
|
||||
free(line);
|
||||
fclose(fp);
|
||||
E.dirty = 0;
|
||||
}
|
||||
@@ -114,7 +106,7 @@ void editorSave() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fd = open(buffer->fullname, O_RDWR | O_CREAT, 0644);
|
||||
fd = open(buffer->fullname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd != -1) {
|
||||
for (int i = 0; i < buffer->numrows; ++i)
|
||||
{
|
||||
|
||||
+28
-8
@@ -57,7 +57,7 @@ void initBuiltins() {
|
||||
void initConfig() {
|
||||
|
||||
E.ctx = lisp_init();
|
||||
E.ctx.p->err_port = fopen("log.err", "w");
|
||||
E.ctx.p->err_port = fopen("lisp_log.err", "w");
|
||||
E.env = lisp_env(E.ctx);
|
||||
lisp_lib_load(E.ctx);
|
||||
// Init builtins lisp functions
|
||||
@@ -117,14 +117,26 @@ void initEditor() {
|
||||
active->width = E.screencols;
|
||||
active->height = E.screenrows;
|
||||
|
||||
E.init_file_path = (char *)calloc(256, sizeof(char));
|
||||
strcat(E.init_file_path, getenv("HOME"));
|
||||
strcat(E.init_file_path, "/.beluga/config/init.lisp");
|
||||
appDebug("%s\n", E.init_file_path);
|
||||
E.fd_init_file = fopen(E.init_file_path, "r");
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
die("HOME environment variable not set");
|
||||
}
|
||||
|
||||
// Status bar
|
||||
E.status_msg = (char *)calloc(E.screencols, sizeof(char));
|
||||
if (asprintf(&E.init_file_path, "%s/.beluga/config/init.lisp", home) == -1) {
|
||||
die("asprintf failed");
|
||||
}
|
||||
|
||||
E.fd_init_file = fopen(E.init_file_path, "r");
|
||||
if (!E.fd_init_file) {
|
||||
// File might not exist, that's okay for some cases
|
||||
// Handle accordingly
|
||||
}
|
||||
|
||||
E.status_msg = calloc(E.screencols, sizeof(char));
|
||||
if (!E.status_msg) {
|
||||
die("malloc failed");
|
||||
}
|
||||
E.status_msg[0] = '\0';
|
||||
E.status_msg[0] = '\0';
|
||||
E.status_msg_time = 0;
|
||||
|
||||
@@ -168,5 +180,13 @@ void deInitEditor()
|
||||
{
|
||||
free(E.key_binds[i].key_sequence);
|
||||
}
|
||||
for (int i = 0; i < E.number_of_buffer; ++i)
|
||||
{
|
||||
free(E.buffers[i].filename);
|
||||
free(E.buffers[i].path);
|
||||
free(E.buffers[i].fullname);
|
||||
free(E.buffers[i].row->chars);
|
||||
free(E.buffers[i].row);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-3
@@ -158,10 +158,13 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
} else if (!iscntrl(c) && c < 256) {
|
||||
if (buf_len == buf_size - 1) {
|
||||
buf_size *= 2;
|
||||
buf = realloc(buf, buf_size);
|
||||
char *new_buf = realloc(buf, buf_size);
|
||||
if (!new_buf) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf = new_buf;
|
||||
}
|
||||
buf[buf_len++] = (char)c;
|
||||
buf[buf_len] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-3
@@ -20,7 +20,12 @@ void splitScreenInit(void) {
|
||||
E.layout.num_panes = 1;
|
||||
E.layout.active_pane = 0;
|
||||
|
||||
E.layout.panes = malloc(sizeof(EditorPane) * 2);
|
||||
EditorPane *new_panes = realloc(E.layout.panes, sizeof(EditorPane) * 2);
|
||||
if (!new_panes) {
|
||||
editorSetStatusMessage("Error: realloc failed");
|
||||
return;
|
||||
}
|
||||
E.layout.panes = new_panes;
|
||||
|
||||
// Initialize single fullscreen pane
|
||||
E.layout.panes[0].buffer_id = -1; // No buffer for now
|
||||
@@ -218,9 +223,11 @@ EditorPane *splitScreenGetActivePane(void) {
|
||||
return &E.layout.panes[E.layout.active_pane];
|
||||
}
|
||||
|
||||
void freeScreenLayout(ScreenLayout *layout)
|
||||
{
|
||||
void freeScreenLayout(ScreenLayout *layout) {
|
||||
if (layout) {
|
||||
free(layout->panes);
|
||||
layout->panes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void freePane(EditorPane *pane)
|
||||
|
||||
+20
-16
@@ -110,9 +110,13 @@ int comment_section = 0;
|
||||
char *highlight_line(const char *line, int *length) {
|
||||
// Each byte can expand to at most (color_prefix + 4 bytes + color_reset).
|
||||
// Allocate generously based on line length to avoid overflow.
|
||||
int line_len = strlen(line);
|
||||
int line_len = (int) strlen(line);
|
||||
int buf_size = line_len * 32 + 256;
|
||||
char *result = malloc(buf_size);
|
||||
if (!result) {
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
int result_pos = 0;
|
||||
int i = 0;
|
||||
|
||||
@@ -125,31 +129,31 @@ char *highlight_line(const char *line, int *length) {
|
||||
}
|
||||
|
||||
if (comment_section) {
|
||||
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
|
||||
while (line[i] != '\0' && line[i] != '\n') {
|
||||
if (line[i] == '*' && line[i + 1] == '/') {
|
||||
comment_section = 0;
|
||||
}
|
||||
copy_utf8_char(result, &result_pos, line, &i);
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle line comments
|
||||
if (line[i] == '/' && line[i + 1] == '/') {
|
||||
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
|
||||
while (line[i] != '\0' && line[i] != '\n') {
|
||||
copy_utf8_char(result, &result_pos, line, &i);
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle block comments
|
||||
if (line[i] == '/' && line[i + 1] == '*') {
|
||||
comment_section = 1;
|
||||
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
|
||||
result[result_pos++] = line[i++];
|
||||
result[result_pos++] = line[i++];
|
||||
while (line[i] != '\0') {
|
||||
@@ -161,13 +165,13 @@ char *highlight_line(const char *line, int *length) {
|
||||
}
|
||||
copy_utf8_char(result, &result_pos, line, &i);
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (line[i] == '"') {
|
||||
result_pos += sprintf(&result[result_pos], "%s\"", E.theme.COLOR_STRING);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s\"", E.theme.COLOR_STRING);
|
||||
i++;
|
||||
while (line[i] != '\0' && line[i] != '"') {
|
||||
if (line[i] == '\\') {
|
||||
@@ -179,13 +183,13 @@ char *highlight_line(const char *line, int *length) {
|
||||
}
|
||||
if (line[i] == '"')
|
||||
result[result_pos++] = line[i++];
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle character literals
|
||||
if (line[i] == '\'') {
|
||||
result_pos += sprintf(&result[result_pos], "%s'", E.theme.COLOR_STRING);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s'", E.theme.COLOR_STRING);
|
||||
i++;
|
||||
while (line[i] != '\0' && line[i] != '\'') {
|
||||
if (line[i] == '\\') {
|
||||
@@ -197,17 +201,17 @@ char *highlight_line(const char *line, int *length) {
|
||||
}
|
||||
if (line[i] == '\'')
|
||||
result[result_pos++] = line[i++];
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle numbers
|
||||
if (line[i] >= '0' && line[i] <= '9') {
|
||||
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_NUMBER);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_NUMBER);
|
||||
while (is_word_char(&line[i]) || line[i] == '.') {
|
||||
copy_utf8_char(result, &result_pos, line, &i);
|
||||
}
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -231,15 +235,15 @@ char *highlight_line(const char *line, int *length) {
|
||||
else if (is_type(word))
|
||||
type = TOKEN_TYPE;
|
||||
|
||||
result_pos += sprintf(&result[result_pos], "%s%s%s", get_color(type),
|
||||
result_pos += snprintf(&result[result_pos], 100, "%s%s%s", get_color(type),
|
||||
word, COLOR_RESET);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle operators and other characters (including non-ASCII multi-byte)
|
||||
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_DEFAULT);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_DEFAULT);
|
||||
copy_utf8_char(result, &result_pos, line, &i);
|
||||
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET);
|
||||
result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
|
||||
}
|
||||
|
||||
result[result_pos] = '\0';
|
||||
|
||||
Reference in New Issue
Block a user