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+8)&~7; 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+8)&~7; 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,cnt=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=DbgMode(ON), old_single=SingleUser(ON); if (!filename) filename=blkdev.tmp_filename; buf=FileRead(filename,&size); PUSHFD CLI text.raw_flags=text.raw_flags&~RWF_SCROLL|RWF_SHOW_DOLLAR; kbd.scan_code=0; QueInit(&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); QueIns(tmpl,head.last); cnt++; } if (src+1-buf<size) { bin_data=MAlloc(bin_size=size-(src-buf)); MemCpy(bin_data,src,bin_size); } Free(buf); res=TRUE; } cur_line=head.next; if (--num<0) res=FALSE; else { if (num<=cnt) 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=GetKey(&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; QueRem(tmpl); Free(tmpl); } } else StrCpy(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; QueIns(tmpl,cur_line); cur_line=tmpl; cur_col=0; break; case CH_BACKSPACE: if (cur_col) { StrCpy(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; QueRem(cur_line); Free(cur_line); cur_line=tmpl; } break; case CH_CTRLY: if (cur_line!=&head) { tmpl=cur_line; cur_line=cur_line->next; QueRem(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(""); QueIns(cur_line,head.last); } src=MAlloc(StrLen(cur_line->line)+2); MemCpy(src,cur_line->line,cur_col); src[cur_col]=ch; if (cur_col<StrLen(cur_line->line)) StrCpy(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); MemCpy(dst,tmpl->line,i); dst+=i; *dst++='\n'; tmpl=tmpl->next; } if (bin_data) MemCpy(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; QueRem(tmpl); Free(tmpl->line); Free(tmpl); tmpl=tmpl1; } Free(head.line); Free(bin_data); Raw(old_raw); DbgMode(old_debug); SingleUser(old_single); text.raw_flags=text.raw_flags&~RWF_SHOW_DOLLAR|old_raw_flags&RWF_SHOW_DOLLAR; POPFD return res; } U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum) {//"FI:D:/Dir/File.HC,123" to "D:/Dir/File.HC" and 123. U8 *st,*fl_file_line=StrNew(_fl_file_line); I64 linenum; StrFirstRem(fl_file_line,":"); st=StrNew(fl_file_line); StrLastRem(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(dbg.fix_file_line); dbg.fix_file_line=AStrNew(st); LBtr(&sys_semas[SEMA_FIX],0); } Bool Fix(I64 edf_dof_flags=0) {//Jump to last err src code to fix it. U8 *st; Bool res=FALSE; while (LBts(&sys_semas[SEMA_FIX],0)) Yield; st=StrNew(dbg.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; }