mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-03-13 11:38:16 +00:00
409 lines
8.3 KiB
HolyC
Executable file
409 lines
8.3 KiB
HolyC
Executable file
class CLine
|
|
{
|
|
CLine *next, *last;
|
|
U8 *line;
|
|
};
|
|
|
|
U0 EdLiteUpdate(CLine *head, CLine *cur_line, I64 cur_col, I64 line_start_col)
|
|
{
|
|
I64 ch, i, j, k, k2, cursor_col, cursor_row = -1;
|
|
U8 *st;
|
|
CLine *tmpl = cur_line;
|
|
Bool done_eof = FALSE;
|
|
|
|
text.raw_col = 0;
|
|
for (i = 0; i < text.rows / 2; i++)
|
|
if (tmpl->last != head)
|
|
tmpl = tmpl->last;
|
|
for (i = 0; i < text.rows; i++)
|
|
{
|
|
if (cursor_row < 0 && tmpl == cur_line)
|
|
{
|
|
k = 0;
|
|
for (j = 0; j < cur_col; j++)
|
|
if (tmpl->line[j] == '\t')
|
|
k = (k + 4) & ~3;
|
|
else
|
|
k++;
|
|
cursor_col = k;
|
|
cursor_row = i;
|
|
}
|
|
if (tmpl != head)
|
|
{
|
|
st = tmpl->line;
|
|
k = 0;
|
|
j= 0 ;
|
|
while (ch = *st++)
|
|
{
|
|
if (ch == '\t')
|
|
k2 = (k + 4) & ~3;
|
|
else
|
|
k2 = k + 1;
|
|
if (line_start_col <= k < line_start_col + text.cols)
|
|
{
|
|
'' ch;
|
|
j = k2 - line_start_col;
|
|
}
|
|
k = k2;
|
|
}
|
|
if (j < text.cols)
|
|
'\n';
|
|
tmpl = tmpl->next;
|
|
}
|
|
else
|
|
{
|
|
if (!done_eof)
|
|
{
|
|
'<EOF>';
|
|
done_eof = TRUE;
|
|
}
|
|
'\n';
|
|
}
|
|
}
|
|
text.raw_col = text.cols * cursor_row + cursor_col - line_start_col;
|
|
RawPutChar(0x7F);
|
|
}
|
|
|
|
Bool EdLite(U8 *filename, I64 num=1, I64 edf_dof_flags=0)
|
|
{//Light weight text editor for debugging.
|
|
U8 *src, *src2, *src3, *dst, *buf, *bin_data = NULL;
|
|
I64 i, count = 0, ch, sc, size, bin_size = 0, line_start_col = 0, cur_col = 0, old_raw_flags = text.raw_flags;
|
|
CLine head, *tmpl, *tmpl1, *cur_line;
|
|
Bool res = FALSE,
|
|
old_raw = Raw(ON),
|
|
old_debug = DebugMode(ON),
|
|
old_single = SingleUser(ON);
|
|
|
|
if (!filename)
|
|
filename = blkdev.tmp_filename;
|
|
buf = FileRead(filename, &size);
|
|
|
|
PUSHFD
|
|
CLI
|
|
text.raw_flags = text.raw_flags & ~RAWF_SCROLL | RAWF_SHOW_DOLLAR;
|
|
kbd.scan_code = 0;
|
|
QueueInit(&head);
|
|
head.line = StrNew("");
|
|
|
|
if (buf)
|
|
{
|
|
src = buf;
|
|
while (*src)
|
|
{
|
|
src2 = src;
|
|
while ((ch = *src++) && ch != '\r' && ch != '\n');
|
|
src--;
|
|
*src++ = 0;
|
|
if (!ch)
|
|
src--;
|
|
while (ch == '\r' && *src == '\n' || *src == CH_CURSOR)
|
|
src++;
|
|
dst = src3 = src2;
|
|
while (ch = *src3++)
|
|
if (ch != '\n' && ch != CH_CURSOR)
|
|
*dst++ = ch;
|
|
*dst = 0;
|
|
|
|
tmpl = MAlloc(sizeof(CLine));
|
|
tmpl->line = StrNew(src2);
|
|
QueueInsert(tmpl, head.last);
|
|
count++;
|
|
}
|
|
|
|
if (src + 1 - buf<size)
|
|
{
|
|
bin_data = MAlloc(bin_size = size - (src - buf));
|
|
MemCopy(bin_data, src, bin_size);
|
|
}
|
|
Free(buf);
|
|
res = TRUE;
|
|
}
|
|
|
|
cur_line = head.next;
|
|
if (--num < 0)
|
|
res = FALSE;
|
|
else
|
|
{
|
|
if (num <= count)
|
|
while (num--)
|
|
cur_line = cur_line->next;
|
|
else
|
|
{
|
|
cur_line = &head;
|
|
res = FALSE;
|
|
}
|
|
}
|
|
do
|
|
{
|
|
if (cur_line == &head)
|
|
cur_col = 0;
|
|
while (cur_col - line_start_col < 0)
|
|
line_start_col -= 8;
|
|
while (cur_col - line_start_col >= text.cols)
|
|
line_start_col += 8;
|
|
EdLiteUpdate(&head, cur_line, cur_col, line_start_col);
|
|
switch (ch = KeyGet(&sc, FALSE, TRUE))
|
|
{
|
|
case 0:
|
|
switch (sc.u8[0])
|
|
{
|
|
case SC_CURSOR_UP:
|
|
if (cur_line->last != &head)
|
|
cur_line = cur_line->last;
|
|
if (cur_col > StrLen(cur_line->line))
|
|
cur_col = StrLen(cur_line->line);
|
|
break;
|
|
|
|
case SC_CURSOR_DOWN:
|
|
if (cur_line != &head)
|
|
cur_line = cur_line->next;
|
|
if (cur_col > StrLen(cur_line->line))
|
|
cur_col = StrLen(cur_line->line);
|
|
break;
|
|
|
|
case SC_CURSOR_RIGHT:
|
|
cur_col++;
|
|
if (cur_col > StrLen(cur_line->line))
|
|
{
|
|
tmpl = cur_line->next;
|
|
if (tmpl != &head)
|
|
{
|
|
cur_col = 0;
|
|
cur_line = tmpl;
|
|
}
|
|
else
|
|
cur_col = StrLen(cur_line->line);
|
|
}
|
|
break;
|
|
|
|
case SC_CURSOR_LEFT:
|
|
if (cur_col)
|
|
cur_col--;
|
|
else
|
|
{
|
|
tmpl = cur_line->last;
|
|
if (tmpl != &head)
|
|
{
|
|
cur_line = tmpl;
|
|
cur_col = StrLen(tmpl->line);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SC_PAGE_UP:
|
|
for (i = 1; i < text.rows; i++)
|
|
{
|
|
if (cur_line->last != &head)
|
|
cur_line = cur_line->last;
|
|
if (cur_col > StrLen(cur_line->line))
|
|
cur_col = StrLen(cur_line->line);
|
|
}
|
|
break;
|
|
|
|
case SC_PAGE_DOWN:
|
|
for (i = 1; i < text.rows; i++)
|
|
{
|
|
if (cur_line != &head)
|
|
cur_line = cur_line->next;
|
|
if (cur_col > StrLen(cur_line->line))
|
|
cur_col = StrLen(cur_line->line);
|
|
}
|
|
break;
|
|
|
|
case SC_DELETE:
|
|
if (cur_col == StrLen(cur_line->line))
|
|
{
|
|
tmpl = cur_line->next;
|
|
if (cur_line != &head && tmpl != &head) {
|
|
src = MStrPrint("%s%s", cur_line->line, tmpl->line);
|
|
Free(cur_line->line);
|
|
Free(tmpl->line);
|
|
cur_line->line = src;
|
|
QueueRemove(tmpl);
|
|
Free(tmpl);
|
|
}
|
|
}
|
|
else
|
|
StrCopy(cur_line->line + cur_col, cur_line->line + cur_col + 1);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case '\n':
|
|
case '\r':
|
|
tmpl = MAlloc(sizeof(CLine));
|
|
tmpl->line = StrNew(cur_line->line + cur_col);
|
|
cur_line->line[cur_col] = 0;
|
|
QueueInsert(tmpl, cur_line);
|
|
cur_line = tmpl;
|
|
cur_col = 0;
|
|
break;
|
|
|
|
case CH_BACKSPACE:
|
|
if (cur_col) {
|
|
StrCopy(cur_line->line + cur_col - 1, cur_line->line + cur_col);
|
|
cur_col--;
|
|
}
|
|
else if (cur_line!=&head && cur_line->last!=&head)
|
|
{
|
|
tmpl = cur_line->last;
|
|
src = MStrPrint("%s%s", tmpl->line, cur_line->line);
|
|
cur_col = StrLen(tmpl->line);
|
|
Free(cur_line->line);
|
|
Free(tmpl->line);
|
|
tmpl->line = src;
|
|
QueueRemove(cur_line);
|
|
Free(cur_line);
|
|
cur_line = tmpl;
|
|
}
|
|
break;
|
|
|
|
case CH_CTRLY:
|
|
if (cur_line != &head)
|
|
{
|
|
tmpl = cur_line;
|
|
cur_line = cur_line->next;
|
|
QueueRemove(tmpl);
|
|
Free(tmpl->line);
|
|
Free(tmpl);
|
|
cur_col = 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (Bt(char_bmp_printable, ch))
|
|
{
|
|
if (cur_line == &head) {
|
|
cur_line = MAlloc(sizeof(CLine));
|
|
cur_line->line = StrNew("");
|
|
QueueInsert(cur_line, head.last);
|
|
}
|
|
src = MAlloc(StrLen(cur_line->line) + 2);
|
|
MemCopy(src, cur_line->line, cur_col);
|
|
src[cur_col] = ch;
|
|
if (cur_col < StrLen(cur_line->line))
|
|
StrCopy(src + cur_col + 1, cur_line->line + cur_col);
|
|
else
|
|
src[cur_col + 1] = 0;
|
|
Free(cur_line->line);
|
|
cur_line->line = src;
|
|
cur_col++;
|
|
}
|
|
}
|
|
}
|
|
while (ch != CH_SHIFT_ESC && ch != CH_ESC);
|
|
|
|
if (ch != CH_ESC)
|
|
{
|
|
if (edf_dof_flags & EDF_WAS_WRITE)
|
|
res = FALSE;
|
|
}
|
|
else
|
|
{
|
|
size = bin_size;
|
|
|
|
tmpl = head.next;
|
|
while (tmpl != &head)
|
|
{
|
|
size += StrLen(tmpl->line) + 1;
|
|
tmpl = tmpl->next;
|
|
}
|
|
|
|
buf = dst = MAlloc(size);
|
|
tmpl = head.next;
|
|
while (tmpl != &head)
|
|
{
|
|
i = StrLen(tmpl->line);
|
|
MemCopy(dst, tmpl->line, i);
|
|
dst += i;
|
|
*dst++ = '\n';
|
|
tmpl = tmpl->next;
|
|
}
|
|
if (bin_data)
|
|
MemCopy(dst, bin_data, bin_size);
|
|
FileWrite(filename, buf, size);
|
|
Free(buf);
|
|
|
|
if (edf_dof_flags & EDF_WAS_WRITE)
|
|
res = TRUE;
|
|
}
|
|
|
|
tmpl = head.next;
|
|
while (tmpl != &head)
|
|
{
|
|
tmpl1 = tmpl->next;
|
|
QueueRemove(tmpl);
|
|
Free(tmpl->line);
|
|
Free(tmpl);
|
|
tmpl = tmpl1;
|
|
}
|
|
Free(head.line);
|
|
Free(bin_data);
|
|
Raw(old_raw);
|
|
DebugMode(old_debug);
|
|
SingleUser(old_single);
|
|
text.raw_flags = text.raw_flags & ~RAWF_SHOW_DOLLAR | old_raw_flags & (RAWF_SHOW_DOLLAR | RAWF_SCROLL);
|
|
POPFD
|
|
|
|
return res;
|
|
}
|
|
|
|
U0 ToFileLine(U8 *_fl_file_line, U8 **_filename, I64 *_linenum)
|
|
{//"FI:D:/Dir/File.ZC,123" to "D:/Dir/File.ZC" and 123.
|
|
U8 *st, *fl_file_line = StrNew(_fl_file_line);
|
|
I64 linenum;
|
|
|
|
StrFirstRemove(fl_file_line, ":");
|
|
st = StrNew(fl_file_line);
|
|
StrLastRemove(fl_file_line, ",", st);
|
|
linenum = Str2I64(st);
|
|
Free(st);
|
|
*_filename = fl_file_line;
|
|
*_linenum = linenum;
|
|
}
|
|
|
|
Bool EdLiteFileLine(U8 *fl_file_line, I64 edf_dof_flags=0)
|
|
{
|
|
Bool res;
|
|
U8 *filename;
|
|
I64 linenum;
|
|
|
|
ToFileLine(fl_file_line, &filename, &linenum);
|
|
res = EdLite(filename, linenum, edf_dof_flags);
|
|
Free(filename);
|
|
|
|
return res;
|
|
}
|
|
|
|
U0 FixSet(U8 *filename, I64 line)
|
|
{//Compiler calls this to set file line for Fix
|
|
U8 *st = MStrPrint("FL:%s,%d", filename, line);
|
|
|
|
while (LBts(&sys_semas[SEMA_FIX], 0))
|
|
Yield;
|
|
Free(debug.fix_file_line);
|
|
debug.fix_file_line = SysStrNew(st);
|
|
LBtr(&sys_semas[SEMA_FIX], 0);
|
|
}
|
|
|
|
Bool Fix(I64 edf_dof_flags=0)
|
|
{//Jump to last error src code to fix it.
|
|
U8 *st;
|
|
Bool res = FALSE;
|
|
|
|
while (LBts(&sys_semas[SEMA_FIX], 0))
|
|
Yield;
|
|
st = StrNew(debug.fix_file_line);
|
|
LBtr(&sys_semas[SEMA_FIX], 0);
|
|
|
|
if (st)
|
|
{
|
|
if (IsRaw)
|
|
res = EdLiteFileLine(st, edf_dof_flags);
|
|
else
|
|
res = Ed(st, edf_dof_flags);
|
|
}
|
|
Free(st);
|
|
|
|
return res;
|
|
}
|