276 lines
9.3 KiB
C
276 lines
9.3 KiB
C
|
/*
|
||
|
* Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
|
||
|
*
|
||
|
* Xource is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
|
||
|
* And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
|
||
|
* It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
|
||
|
*/
|
||
|
|
||
|
#include <xolatile/xyntax.h>
|
||
|
#include <xolatile/xyntax.c>
|
||
|
#include <xolatile/xurses.h>
|
||
|
#include <xolatile/xurses.c>
|
||
|
|
||
|
extern int file_list_active;
|
||
|
extern int file_list_count;
|
||
|
extern int * file_list_mark;
|
||
|
extern int * file_list_size;
|
||
|
extern char * * file_list_name;
|
||
|
extern char * * file_list_data;
|
||
|
|
||
|
extern void file_list_import (char *);
|
||
|
extern void file_list_export (char *);
|
||
|
|
||
|
extern void append_character (char);
|
||
|
extern void remove_character (void);
|
||
|
|
||
|
extern void cursor_limits (void);
|
||
|
|
||
|
int file_list_active = 0;
|
||
|
int file_list_count = 0;
|
||
|
int * file_list_mark = NULL;
|
||
|
int * file_list_size = NULL;
|
||
|
char * * file_list_name = NULL;
|
||
|
char * * file_list_data = NULL;
|
||
|
|
||
|
void file_list_import (char * name) {
|
||
|
++file_list_count;
|
||
|
|
||
|
file_list_active = file_list_count - 1;
|
||
|
|
||
|
file_list_mark = reallocate (file_list_mark, (int) sizeof (* file_list_mark) * file_list_count);
|
||
|
file_list_size = reallocate (file_list_size, (int) sizeof (* file_list_size) * file_list_count);
|
||
|
file_list_name = reallocate (file_list_name, (int) sizeof (* file_list_name) * file_list_count);
|
||
|
file_list_data = reallocate (file_list_data, (int) sizeof (* file_list_data) * file_list_count);
|
||
|
|
||
|
file_list_mark [file_list_count - 1] = -1;
|
||
|
file_list_size [file_list_count - 1] = -1;
|
||
|
file_list_name [file_list_count - 1] = NULL;
|
||
|
file_list_data [file_list_count - 1] = NULL;
|
||
|
|
||
|
file_list_name [file_list_count - 1] = allocate (string_length (name) + 1);
|
||
|
|
||
|
(void) string_copy_limit (file_list_name [file_list_count - 1], name, string_length (name) + 1);
|
||
|
|
||
|
file_list_mark [file_list_count - 1] = open (name, O_RDONLY);
|
||
|
|
||
|
file_list_size [file_list_count - 1] = (int) lseek (file_list_mark [file_list_count - 1], 0, SEEK_END) + 1;
|
||
|
|
||
|
(void) lseek (file_list_mark [file_list_count - 1], 0, SEEK_SET);
|
||
|
|
||
|
file_list_data [file_list_count - 1] = allocate (file_list_size [file_list_count - 1]);
|
||
|
|
||
|
(void) read (file_list_mark [file_list_count - 1], file_list_data [file_list_count - 1], (unsigned long int) (file_list_size [file_list_count - 1] - 1));
|
||
|
|
||
|
close (file_list_mark [file_list_count - 1]);
|
||
|
|
||
|
file_list_data [file_list_count - 1] [file_list_size [file_list_count - 1] - 1] = '\0';
|
||
|
}
|
||
|
|
||
|
void file_list_export (char * name) {
|
||
|
file_list_mark [file_list_active] = open (name, O_WRONLY | O_CREAT | O_TRUNC);
|
||
|
|
||
|
(void) write (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) file_list_size [file_list_active]);
|
||
|
|
||
|
close (file_list_mark [file_list_active]);
|
||
|
}
|
||
|
|
||
|
void append_character (char character) {
|
||
|
int offset = 0;
|
||
|
|
||
|
++file_list_size [file_list_active];
|
||
|
|
||
|
file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]);
|
||
|
|
||
|
for (offset = file_list_size [file_list_active] - 1; offset != curses_cursor; --offset) {
|
||
|
file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset - 1];
|
||
|
}
|
||
|
|
||
|
file_list_data [file_list_active] [curses_cursor] = character;
|
||
|
|
||
|
++curses_cursor;
|
||
|
}
|
||
|
|
||
|
void remove_character (void) {
|
||
|
int offset = 0;
|
||
|
|
||
|
if (curses_cursor == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
--file_list_size [file_list_active];
|
||
|
|
||
|
for (offset = curses_cursor - 1; offset != file_list_size [file_list_active] - 1; ++offset) {
|
||
|
file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset + 1];
|
||
|
}
|
||
|
|
||
|
--curses_cursor;
|
||
|
}
|
||
|
|
||
|
void cursor_limits (void) {
|
||
|
if (curses_cursor <= -1) {
|
||
|
curses_cursor = 0;
|
||
|
}
|
||
|
|
||
|
if (curses_cursor >= file_list_size [file_list_active]) {
|
||
|
curses_cursor = file_list_size [file_list_active] - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main (int argc, char * * argv) {
|
||
|
int word = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
int preprocessor = 0;
|
||
|
int line_comment = 0;
|
||
|
int multiline_comment = 0;
|
||
|
int character = 0;
|
||
|
int string = 0;
|
||
|
int bracket = 0;
|
||
|
int operator = 0;
|
||
|
int keyword = 0;
|
||
|
int digit = 0;
|
||
|
int uppercase = 0;
|
||
|
int lowercase = 0;
|
||
|
int underscore = 0;
|
||
|
|
||
|
char separator [29] = ".,:;<=>+-*/%!&~^()[]{}'\" \t\r\n";
|
||
|
|
||
|
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"
|
||
|
};
|
||
|
|
||
|
char status_bar [36] = "Xource : C = Xolatile's text editor";
|
||
|
|
||
|
if (argc == 2) {
|
||
|
file_list_import (argv [1]);
|
||
|
} else {
|
||
|
out ("ARGUMENTS\n", 10);
|
||
|
return (-1);
|
||
|
}
|
||
|
|
||
|
curses_initialize ();
|
||
|
|
||
|
syntax_define (& preprocessor, 0, 0, "#", "\n", '\\', COLOUR_RED, EFFECT_BOLD);
|
||
|
syntax_define (& line_comment, 0, 0, "//", "\n", '\0', COLOUR_GREY, EFFECT_BOLD);
|
||
|
syntax_define (& multiline_comment, 0, 0, "/*", "*/", '\0', COLOUR_GREY, EFFECT_BOLD);
|
||
|
syntax_define (& character, 0, 0, "'", "'", '\\', COLOUR_PINK, EFFECT_BOLD);
|
||
|
syntax_define (& string, 0, 0, "\"", "\"", '\\', COLOUR_RED, EFFECT_BOLD);
|
||
|
syntax_define (& bracket, 1, 0, "()[]{}", "", '\0', COLOUR_GREEN, EFFECT_BOLD);
|
||
|
syntax_define (& operator, 1, 0, ".,:;<=>+-*/%!&~^?|", "", '\0', COLOUR_BLUE, EFFECT_BOLD);
|
||
|
|
||
|
for (word = 0; word != 32; ++word) {
|
||
|
syntax_define (& keyword, 0, 1, c_keywords [word], separator, '\0', COLOUR_YELLOW, EFFECT_BOLD);
|
||
|
}
|
||
|
|
||
|
syntax_define (& digit, 1, 1, "0123456789", separator, '\0', COLOUR_CYAN, EFFECT_BOLD);
|
||
|
syntax_define (& uppercase, 1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separator, '\0', COLOUR_PINK, EFFECT_ITALIC);
|
||
|
syntax_define (& lowercase, 1, 1, "abcdefghijklmnopqrstuvwxyz", separator, '\0', COLOUR_WHITE, EFFECT_ITALIC);
|
||
|
syntax_define (& underscore, 0, 1, "_", separator, '\0', COLOUR_YELLOW, EFFECT_ITALIC);
|
||
|
|
||
|
do {
|
||
|
int offset = 0;
|
||
|
int index = 0;
|
||
|
int length = 0;
|
||
|
int line = 0;
|
||
|
|
||
|
curses_append_string (status_bar, EFFECT_REVERSE, COLOUR_WHITE, string_length (status_bar));
|
||
|
|
||
|
for (offset = 0; offset != curses_screen_width - string_length (status_bar); ++offset) {
|
||
|
curses_append_string (" ", EFFECT_REVERSE, COLOUR_WHITE, 1);
|
||
|
}
|
||
|
|
||
|
curses_append_string ("\r\n", EFFECT_NORMAL, COLOUR_WHITE, 2);
|
||
|
|
||
|
for (offset = 0; file_list_data [file_list_active] [offset] != '\0'; offset += length) {
|
||
|
if (line <= curses_screen_height - 1) {
|
||
|
break;
|
||
|
}
|
||
|
syntax_select (& file_list_data [file_list_active] [offset], & index, & length);
|
||
|
if (file_list_data [file_list_active] [offset] == '\n') {
|
||
|
curses_append_string ("\r\n", EFFECT_NORMAL, COLOUR_WHITE, 2);
|
||
|
++line;
|
||
|
} else {
|
||
|
if (index >= syntax_count) {
|
||
|
curses_append_string (& file_list_data [file_list_active] [offset], EFFECT_NORMAL, COLOUR_WHITE, length);
|
||
|
} else {
|
||
|
curses_append_string (& file_list_data [file_list_active] [offset], syntax_effect [index], syntax_colour [index], length);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (line <= curses_screen_height - 2) {
|
||
|
for (offset = 0; offset != curses_screen_height - 2 - line; ++offset) {
|
||
|
curses_append_string ("~\r\n", EFFECT_REVERSE, COLOUR_WHITE, 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
curses_append_cursor (5, 3);
|
||
|
|
||
|
curses_synchronize ();
|
||
|
|
||
|
if (curses_signal == ('Q' & 0X1F)) {
|
||
|
curses_active = 0;
|
||
|
} else if (curses_signal == '\r') {
|
||
|
append_character ('\n');
|
||
|
} else if (curses_signal == ('S' & 0X1F)) {
|
||
|
file_list_export (file_list_name [file_list_active]);
|
||
|
} else if (curses_signal == (char) 127) {
|
||
|
remove_character ();
|
||
|
} else if (curses_signal == '\033') {
|
||
|
in (& curses_signal, 1);
|
||
|
if (curses_signal == '[') {
|
||
|
in (& curses_signal, 1);
|
||
|
if (curses_signal == 'A') {
|
||
|
do {
|
||
|
--curses_cursor;
|
||
|
} while (
|
||
|
(curses_cursor >= 0) &&
|
||
|
(file_list_data [file_list_active] [curses_cursor] != '\n') &&
|
||
|
(file_list_data [file_list_active] [curses_cursor] != '\0')
|
||
|
);
|
||
|
--curses_cursor;
|
||
|
} else if (curses_signal == 'B') {
|
||
|
do {
|
||
|
++curses_cursor;
|
||
|
} while (
|
||
|
(curses_cursor <= file_list_size [file_list_active] - 1) &&
|
||
|
(file_list_data [file_list_active] [curses_cursor] != '\n') &&
|
||
|
(file_list_data [file_list_active] [curses_cursor] != '\0')
|
||
|
);
|
||
|
++curses_cursor;
|
||
|
} else if (curses_signal == 'C') {
|
||
|
++curses_cursor;
|
||
|
} else if (curses_signal == 'D') {
|
||
|
--curses_cursor;
|
||
|
}
|
||
|
cursor_limits ();
|
||
|
}
|
||
|
} else if ((curses_signal >= ' ') && (curses_signal <= '~')) {
|
||
|
append_character (curses_signal);
|
||
|
cursor_limits ();
|
||
|
} else {
|
||
|
continue;
|
||
|
}
|
||
|
} while (curses_active != 0);
|
||
|
|
||
|
syntax_delete ();
|
||
|
|
||
|
curses_deinitialize ();
|
||
|
|
||
|
for (i = 0; i != file_list_count; ++i) {
|
||
|
file_list_name [i] = deallocate (file_list_name [i]);
|
||
|
file_list_data [i] = deallocate (file_list_data [i]);
|
||
|
}
|
||
|
|
||
|
file_list_mark = deallocate (file_list_mark);
|
||
|
file_list_size = deallocate (file_list_size);
|
||
|
file_list_name = deallocate (file_list_name);
|
||
|
file_list_data = deallocate (file_list_data);
|
||
|
|
||
|
return (EXIT_SUCCESS);
|
||
|
}
|