erythros/System/Libraries/Stdio.HC

155 lines
No EOL
3.6 KiB
HolyC

class @stdio
{
U0 (*ReadLine)(@shell* sh, U8* str);
U0 (*WriteLine)(@shell* sh, U8* fmt, ...);
};
U0 @stdio_write_line(@shell* sh, U8* fmt, ...)
{
if (!sh)
return;
if (!fmt || !sh->output)
return;
U8* buf;
if (argc) {
buf = StrPrintJoin(NULL, fmt, argc, argv);
} else {
buf = StrNew(fmt, erythros_mem_task);
}
I64 i;
for (i = 0; i < StrLen(buf); i++)
FifoU8Ins(sh->output, buf[i]);
Free(buf);
}
I64 @stdio_handle_control_chars(@shell* sh)
{
if (!FifoU8Cnt(sh->input))
return 0;
U8 char;
FifoU8Rem(sh->input, &char);
switch (char) {
case '[':
if (!FifoU8Cnt(sh->input))
return 0;
FifoU8Rem(sh->input, &char);
switch (char) {
case 'A':
return SC_CURSOR_UP;
break;
case 'B':
return SC_CURSOR_DOWN;
break;
case 'D':
return SC_CURSOR_LEFT;
break;
case 'C':
return SC_CURSOR_RIGHT;
break;
default:
return 0;
break;
}
break;
default:
return 0;
break;
}
}
U0 @stdio_read_line_history_back(@shell* sh, I64 pos)
{
if (sh->history.index < 0)
sh->history.index = 0;
while (pos > 0) {
FifoU8Ins(sh->input, '\x8');
pos--;
}
U8* char = sh->history.entries[sh->history.index];
while (*char)
FifoU8Ins(sh->input, *char ++);
if (sh->history.index > -1) {
sh->history.index--;
}
}
U0 @stdio_read_line_history_fwd(@shell* sh, I64 pos)
{
if (sh->history.index < sh->history.pos) {
sh->history.index++;
}
if (sh->history.index > sh->history.pos)
sh->history.index = sh->history.pos;
while (pos > 0) {
FifoU8Ins(sh->input, '\x8');
pos--;
}
U8* char = sh->history.entries[sh->history.index];
while (*char)
FifoU8Ins(sh->input, *char ++);
}
U0 @stdio_read_line(@shell* sh, U8* str)
{
U8 char = NULL;
U8 line[4096];
I64 pos = 0;
if (!str || !sh)
return;
sh->history.index = sh->history.pos - 1;
while (char != '\x3' && char != '\n') {
while (FifoU8Cnt(sh->input)) {
FifoU8Rem(sh->input, &char);
switch (char) {
case 3:
@stdio_write_line(sh, "^C");
break;
case 8:
if (pos > 0) {
line[StrLen(line) - 1] = NULL;
FifoU8Ins(sh->output, '\x8');
pos--;
} else
FifoU8Ins(sh->output, '\x7');
break;
case 13:
break;
case 27:
switch (@stdio_handle_control_chars(sh)) {
case SC_CURSOR_UP:
@stdio_read_line_history_back(sh, pos);
break;
case SC_CURSOR_DOWN:
@stdio_read_line_history_fwd(sh, pos);
break;
default:
break;
}
break;
case 32...127:
line[pos] = char;
FifoU8Ins(sh->output, char);
pos++;
break;
};
}
Sleep(1);
}
line[pos] = NULL;
switch (char) {
case '\x3':
StrCpy(str, "");
break;
case '\n':
StrCpy(str, &line);
break;
};
FifoU8Ins(sh->output, '\n');
}
@stdio Stdio;
Stdio.ReadLine = &@stdio_read_line;
Stdio.WriteLine = &@stdio_write_line;
"stdio ";