54,13 → 54,11 |
}; |
|
struct file { |
int fd; |
struct line far *cursor; |
unsigned short xoffset; |
unsigned char cursorposx; |
unsigned char cursorposy; |
char lfonly; /* set if line endings are LF (CR/LF otherwise) */ |
char fname[1]; /* dynamically sized */ |
}; |
|
|
110,7 → 108,7 |
} |
|
|
static void ui_basic(unsigned char screenw, unsigned char screenh, const struct file *db) { |
static void ui_basic(unsigned char screenw, unsigned char screenh, const char *fname, const struct file *db) { |
unsigned char i; |
const char *s = svarlang_strid(0); /* HELP */ |
unsigned char helpcol = screenw - (strlen(s) + 4); |
119,7 → 117,7 |
mdr_cout_char_rep(screenh - 1, 0, ' ', scheme[COL_STATUSBAR1], screenw); |
|
/* filename */ |
mdr_cout_str(screenh - 1, 0, db->fname, scheme[COL_STATUSBAR1], screenw); |
mdr_cout_str(screenh - 1, 0, fname, scheme[COL_STATUSBAR1], screenw); |
|
/* eol type */ |
if (db->lfonly) { |
389,26 → 387,18 |
} |
|
|
static struct file *loadfile(const char *fname) { |
static int loadfile(struct file *db, const char *fname) { |
char buff[1024]; |
unsigned int prevlen = 0, len, llen; |
int fd; |
struct file *db; |
int r = 0; |
|
if (_dos_open(fname, O_RDONLY, &fd) != 0) { |
mdr_coutraw_puts("Failed to open file:"); |
mdr_coutraw_puts(fname); |
return(NULL); |
return(-1); |
} |
|
len = strlen(fname) + 1; |
db = calloc(1, sizeof(struct file) + len); |
if (db == NULL) { |
_dos_close(fd); |
return(NULL); |
} |
memcpy(db->fname, fname, len); |
|
db->lfonly = 1; |
|
do { |
420,9 → 410,7 |
|
/* look for nearest \n and replace with 0*/ |
for (llen = 0; buff[llen] != '\n'; llen++) { |
if (llen == sizeof(buff)) { /* TODO line too long: handle it in some classy way */ |
break; |
} |
if (llen == sizeof(buff)) break; |
} |
buff[llen] = 0; |
if ((llen > 0) && (buff[llen - 1] == '\r')) { |
431,8 → 419,7 |
} |
if (line_add(db, buff) != 0) { |
mdr_coutraw_puts("out of memory"); |
free(db); |
db = NULL; |
r = -1; |
break; |
} |
|
443,17 → 430,11 |
|
_dos_close(fd); |
|
/* add an empty line at end if not present already, also rewind cursor to top of file */ |
if (db != NULL) { |
if (db->cursor->len != 0) line_add(db, ""); |
db_rewind(db); |
} |
|
return(db); |
return(r); |
} |
|
|
static int savefile(const struct file *db) { |
static int savefile(const struct file *db, const char *fname) { |
int fd; |
const struct line far *l; |
unsigned bytes; |
460,7 → 441,7 |
unsigned char eollen; |
unsigned char eolbuf[2]; |
|
if (_dos_open(db->fname, O_WRONLY, &fd) != 0) { |
if (_dos_open(fname, O_WRONLY, &fd) != 0) { |
return(-1); |
} |
|
511,10 → 492,12 |
|
int main(void) { |
const char *fname; |
struct file *db; |
struct file db; |
unsigned char screenw = 0, screenh = 0; |
unsigned char uidirtyfrom = 0, uidirtyto = 0xff; /* make sure to redraw entire UI at first run */ |
|
bzero(&db, sizeof(db)); |
|
{ |
char nlspath[128], lang[8]; |
svarlang_autoload_pathlist("sved", mdr_dos_getenv(nlspath, "NLSPATH", sizeof(nlspath)), mdr_dos_getenv(lang, "LANG", sizeof(lang))); |
528,20 → 511,24 |
} |
|
/* load file */ |
db = loadfile(fname); |
if (db == NULL) return(1); |
if (loadfile(&db, fname) != 0) return(1); |
|
/* add an empty line at end if not present already */ |
if (db.cursor->len != 0) line_add(&db, ""); |
|
if (mdr_cout_init(&screenw, &screenh)) load_colorscheme(); |
ui_basic(screenw, screenh, db); |
ui_basic(screenw, screenh, fname, &db); |
|
db_rewind(&db); |
|
for (;;) { |
int k; |
|
check_cursor_not_after_eol(db, &uidirtyfrom, &uidirtyto); |
mdr_cout_locate(db->cursorposy, db->cursorposx); |
check_cursor_not_after_eol(&db, &uidirtyfrom, &uidirtyto); |
mdr_cout_locate(db.cursorposy, db.cursorposx); |
|
if (uidirtyfrom != 0xff) { |
ui_refresh(db, screenw, screenh, uidirtyfrom, uidirtyto); |
ui_refresh(&db, screenw, screenh, uidirtyfrom, uidirtyto); |
uidirtyfrom = 0xff; |
} |
|
548,16 → 535,16 |
k = keyb_getkey(); |
|
if (k == 0x150) { /* down */ |
cursor_down(db, screenh, &uidirtyfrom, &uidirtyto); |
cursor_down(&db, screenh, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x148) { /* up */ |
cursor_up(db, &uidirtyfrom, &uidirtyto); |
cursor_up(&db, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x14D) { /* right */ |
cursor_right(db, screenw, screenh, &uidirtyfrom, &uidirtyto); |
cursor_right(&db, screenw, screenh, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x14B) { /* left */ |
cursor_left(db, screenw, &uidirtyfrom, &uidirtyto); |
cursor_left(&db, screenw, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x149) { /* pgup */ |
// TODO |
566,10 → 553,10 |
// TODO |
|
} else if (k == 0x147) { /* home */ |
cursor_home(db, &uidirtyfrom, &uidirtyto); |
cursor_home(&db, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x14F) { /* end */ |
cursor_eol(db, screenw, &uidirtyfrom, &uidirtyto); |
cursor_eol(&db, screenw, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x1B) { /* ESC */ |
break; |
576,15 → 563,15 |
|
} else if (k == 0x0D) { /* ENTER */ |
/* add a new line */ |
if (line_add(db, db->cursor->payload + db->xoffset + db->cursorposx) == 0) { |
if (line_add(&db, db.cursor->payload + db.xoffset + db.cursorposx) == 0) { |
/* trim the line above */ |
db->cursor->prev->len = db->xoffset + db->cursorposx; |
db->cursor->prev->payload[db->cursor->prev->len] = 0; |
db.cursor->prev->len = db.xoffset + db.cursorposx; |
db.cursor->prev->payload[db.cursor->prev->len] = 0; |
/* move cursor to the (new) line below */ |
db->cursorposx = 0; |
if (db->cursorposy < screenh - 2) { |
uidirtyfrom = db->cursorposy; |
db->cursorposy++; |
db.cursorposx = 0; |
if (db.cursorposy < screenh - 2) { |
uidirtyfrom = db.cursorposy; |
db.cursorposy++; |
} else { |
uidirtyfrom = 0; |
} |
594,18 → 581,18 |
} |
|
} else if (k == 0x153) { /* DEL */ |
del(db, &uidirtyfrom, &uidirtyto); |
del(&db, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x008) { /* BKSPC */ |
bkspc(db, screenw, &uidirtyfrom, &uidirtyto); |
bkspc(&db, screenw, &uidirtyfrom, &uidirtyto); |
|
} else if ((k >= 0x20) && (k <= 0xff)) { /* "normal" character */ |
char c = k; |
insert_in_line(db, &c, 1, screenw, screenh, &uidirtyfrom, &uidirtyto); |
insert_in_line(&db, &c, 1, screenw, screenh, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x009) { /* TAB */ |
const char *tab = " "; |
insert_in_line(db, tab, 8, screenw, screenh, &uidirtyfrom, &uidirtyto); |
insert_in_line(&db, tab, 8, screenw, screenh, &uidirtyfrom, &uidirtyto); |
|
} else if (k == 0x13b) { /* F1 */ |
ui_help(screenw); |
615,13 → 602,13 |
} else if (k == 0x13f) { /* F5 */ |
const char *m[] = {"SAVED", "SAVING FILE FAILED"}; |
int i; |
i = !!savefile(db); |
i = !!savefile(&db, fname); |
ui_msg(m[i], screenw, screenh, &uidirtyfrom, &uidirtyto); |
mdr_bios_tickswait(11); /* 11 ticks is about 600 ms */ |
|
} else if (k == 0x144) { /* F10 */ |
db->lfonly ^= 1; |
ui_basic(screenw, screenh, db); |
db.lfonly ^= 1; |
ui_basic(screenw, screenh, fname, &db); |
|
} else { /* UNHANDLED KEY - TODO IGNORE THIS IN PRODUCTION RELEASE */ |
char buff[4]; |
638,7 → 625,7 |
|
mdr_cout_close(); |
|
/* no need to free memory, DOS will do it for me */ |
/* TODO free memory */ |
|
return(0); |
} |