From 759e2688de32d375e5593e4bab19f4b7505775e2 Mon Sep 17 00:00:00 2001 From: Anton Krotov Date: Fri, 24 Feb 2023 15:02:24 +0000 Subject: [PATCH] CEdit: reduced memory usage, small improvements git-svn-id: svn://kolibrios.org@9903 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/cedit/CEDIT | Bin 33005 -> 33255 bytes programs/develop/cedit/SRC/API.ob07 | 290 ------------ programs/develop/cedit/SRC/CEdit.ob07 | 8 +- programs/develop/cedit/SRC/ChangeLog.ob07 | 344 ++++++++------ programs/develop/cedit/SRC/Languages.ob07 | 33 +- programs/develop/cedit/SRC/RTL.ob07 | 543 ---------------------- programs/develop/cedit/SRC/Search.ob07 | 174 ++++--- programs/develop/cedit/SRC/Tabs.ob07 | 36 +- programs/develop/cedit/SRC/Text.ob07 | 109 +++-- programs/develop/cedit/SRC/Utils.ob07 | 102 ++-- 10 files changed, 431 insertions(+), 1208 deletions(-) delete mode 100644 programs/develop/cedit/SRC/API.ob07 delete mode 100644 programs/develop/cedit/SRC/RTL.ob07 diff --git a/programs/develop/cedit/CEDIT b/programs/develop/cedit/CEDIT index 702a5192238f3fa423b80761b02c68d72992f3b0..b90539dc6efa1d6697febc12ae071691c86f3637 100644 GIT binary patch literal 33255 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 gT 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 F00+`zFlGP% diff --git a/programs/develop/cedit/SRC/API.ob07 b/programs/develop/cedit/SRC/API.ob07 deleted file mode 100644 index 4151eb2368..0000000000 --- a/programs/develop/cedit/SRC/API.ob07 +++ /dev/null @@ -1,290 +0,0 @@ -(* - BSD 2-Clause License - - Copyright (c) 2018, 2020-2022, Anton Krotov - All rights reserved. -*) - -MODULE API; - -IMPORT SYSTEM, K := KOSAPI; - - -CONST - - eol* = 0DX + 0AX; - BIT_DEPTH* = 32; - - MAX_SIZE = 16 * 400H; - HEAP_SIZE = 1 * 100000H; - - _new = 1; - _dispose = 2; - - SizeOfHeader = 36; - - -TYPE - - CRITICAL_SECTION = ARRAY 2 OF INTEGER; - - -VAR - - heap, endheap: INTEGER; - pockets: ARRAY MAX_SIZE DIV 32 + 1 OF INTEGER; - - CriticalSection: CRITICAL_SECTION; - - multi: BOOLEAN; - - base*: INTEGER; - - -PROCEDURE [stdcall] zeromem* (dwords: INTEGER; adr: INTEGER); -BEGIN - SYSTEM.CODE( - 0FCH, (* cld *) - 031H, 0C0H, (* xor eax, eax *) - 057H, (* push edi *) - 08BH, 07DH, 00CH, (* mov edi, dword [ebp + 12] *) - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) - 0F3H, 0ABH, (* rep stosd *) - 05FH (* pop edi *) - ) -END zeromem; - - -PROCEDURE mem_commit* (adr, size: INTEGER); -VAR - tmp: INTEGER; -BEGIN - FOR tmp := adr TO adr + size - 1 BY 4096 DO - SYSTEM.PUT(tmp, 0) - END -END mem_commit; - - -PROCEDURE switch_task; -BEGIN - K.sysfunc2(68, 1) -END switch_task; - - -PROCEDURE futex_create (ptr: INTEGER): INTEGER; - RETURN K.sysfunc3(77, 0, ptr) -END futex_create; - - -PROCEDURE futex_wait (futex, value, timeout: INTEGER); -BEGIN - K.sysfunc5(77, 2, futex, value, timeout) -END futex_wait; - - -PROCEDURE futex_wake (futex, number: INTEGER); -BEGIN - K.sysfunc4(77, 3, futex, number) -END futex_wake; - - -PROCEDURE EnterCriticalSection* (VAR CriticalSection: CRITICAL_SECTION); -BEGIN - switch_task; - futex_wait(CriticalSection[0], 1, 10000); - CriticalSection[1] := 1 -END EnterCriticalSection; - - -PROCEDURE LeaveCriticalSection* (VAR CriticalSection: CRITICAL_SECTION); -BEGIN - CriticalSection[1] := 0; - futex_wake(CriticalSection[0], 1) -END LeaveCriticalSection; - - -PROCEDURE InitializeCriticalSection* (VAR CriticalSection: CRITICAL_SECTION); -BEGIN - CriticalSection[0] := futex_create(SYSTEM.ADR(CriticalSection[1])); - CriticalSection[1] := 0 -END InitializeCriticalSection; - - -PROCEDURE __NEW (size: INTEGER): INTEGER; -VAR - res, idx, temp: INTEGER; -BEGIN - IF size <= MAX_SIZE THEN - idx := ASR(size, 5); - res := pockets[idx]; - IF res # 0 THEN - SYSTEM.GET(res, pockets[idx]); - SYSTEM.PUT(res, size); - INC(res, 4) - ELSE - temp := 0; - IF heap + size >= endheap THEN - IF K.sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN - temp := K.sysfunc3(68, 12, HEAP_SIZE) - ELSE - temp := 0 - END; - IF temp # 0 THEN - mem_commit(temp, HEAP_SIZE); - heap := temp; - endheap := heap + HEAP_SIZE - ELSE - temp := -1 - END - END; - IF (heap # 0) & (temp # -1) THEN - SYSTEM.PUT(heap, size); - res := heap + 4; - heap := heap + size - ELSE - res := 0 - END - END - ELSE - IF K.sysfunc2(18, 16) > ASR(size, 10) THEN - res := K.sysfunc3(68, 12, size); - IF res # 0 THEN - mem_commit(res, size); - SYSTEM.PUT(res, size); - INC(res, 4) - END - ELSE - res := 0 - END - END; - IF (res # 0) & (size <= MAX_SIZE) THEN - zeromem(ASR(size, 2) - 1, res) - END - RETURN res -END __NEW; - - -PROCEDURE __DISPOSE (ptr: INTEGER): INTEGER; -VAR - size, idx: INTEGER; -BEGIN - DEC(ptr, 4); - SYSTEM.GET(ptr, size); - IF size <= MAX_SIZE THEN - idx := ASR(size, 5); - SYSTEM.PUT(ptr, pockets[idx]); - pockets[idx] := ptr - ELSE - size := K.sysfunc3(68, 13, ptr) - END - RETURN 0 -END __DISPOSE; - - -PROCEDURE NEW_DISPOSE (func, arg: INTEGER): INTEGER; -VAR - res: INTEGER; - -BEGIN - IF multi THEN - EnterCriticalSection(CriticalSection) - END; - - IF func = _new THEN - res := __NEW(arg) - ELSIF func = _dispose THEN - res := __DISPOSE(arg) - END; - - IF multi THEN - LeaveCriticalSection(CriticalSection) - END - - RETURN res -END NEW_DISPOSE; - - -PROCEDURE _NEW* (size: INTEGER): INTEGER; - RETURN NEW_DISPOSE(_new, size) -END _NEW; - - -PROCEDURE _DISPOSE* (ptr: INTEGER): INTEGER; - RETURN NEW_DISPOSE(_dispose, ptr) -END _DISPOSE; - - -PROCEDURE exit* (p1: INTEGER); -BEGIN - K.sysfunc1(-1) -END exit; - - -PROCEDURE exit_thread* (p1: INTEGER); -BEGIN - K.sysfunc1(-1) -END exit_thread; - - -PROCEDURE OutStr (pchar: INTEGER); -VAR - c: CHAR; -BEGIN - IF pchar # 0 THEN - REPEAT - SYSTEM.GET(pchar, c); - IF c # 0X THEN - K.OutChar(c) - END; - INC(pchar) - UNTIL c = 0X - END -END OutStr; - - -PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER); -BEGIN - IF lpCaption # 0 THEN - K.OutLn; - OutStr(lpCaption); - K.OutChar(":"); - K.OutLn - END; - OutStr(lpText); - IF lpCaption # 0 THEN - K.OutLn - END -END DebugMsg; - - -PROCEDURE init* (import_, code: INTEGER); -BEGIN - multi := FALSE; - base := code - SizeOfHeader; - K.sysfunc2(68, 11); - InitializeCriticalSection(CriticalSection); - K._init(import_) -END init; - - -PROCEDURE SetMultiThr* (value: BOOLEAN); -BEGIN - multi := value -END SetMultiThr; - - -PROCEDURE GetTickCount* (): INTEGER; - RETURN K.sysfunc2(26, 9) * 10 -END GetTickCount; - - -PROCEDURE dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER; - RETURN 0 -END dllentry; - - -PROCEDURE sofinit*; -END sofinit; - - -END API. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/CEdit.ob07 b/programs/develop/cedit/SRC/CEdit.ob07 index 05d5ef7b2c..cceac61cbb 100644 --- a/programs/develop/cedit/SRC/CEdit.ob07 +++ b/programs/develop/cedit/SRC/CEdit.ob07 @@ -28,10 +28,10 @@ IMPORT RW, Ini, EB := EditBox, Tabs, Toolbar, SB := StatusBar; CONST - HEADER = "CEdit (22-feb-2023)"; + HEADER = "CEdit (24-feb-2023)"; ShellFilter = ""; - EditFilter = "SH|INC|TXT|ASM|OB07|C|CPP|H|PAS|PP|LUA|INI|JSON"; + EditFilter = "sh|inc|txt|asm|ob07|c|cpp|h|pas|pp|lua|ini|json"; fontWidth = K.fontWidth; fontHeight = K.fontHeight; @@ -745,8 +745,8 @@ VAR BEGIN n1 := name1; n2 := name2; - U.upcase(n1); - U.upcase(n2) + U.lowcase8(n1); + U.lowcase8(n2) RETURN n1 = n2 END nameEq; diff --git a/programs/develop/cedit/SRC/ChangeLog.ob07 b/programs/develop/cedit/SRC/ChangeLog.ob07 index 7aef4f8c28..3184438818 100644 --- a/programs/develop/cedit/SRC/ChangeLog.ob07 +++ b/programs/develop/cedit/SRC/ChangeLog.ob07 @@ -21,58 +21,66 @@ MODULE ChangeLog; IMPORT List, Lines, API, SYSTEM; +CONST + boolItemSize = 8; + fillMap = {0..boolItemSize-1}; + TYPE - tIntItem = POINTER TO RECORD (List.tItem) - cnt: INTEGER; - adr, val: ARRAY 8 OF INTEGER - END; + tIntItem = POINTER TO RECORD (List.tItem) + cnt: INTEGER; + adr, val: ARRAY 8 OF INTEGER + END; - tBoolItem = POINTER TO RECORD (List.tItem) - line: Lines.tLine; - adr: INTEGER; - val, save: BOOLEAN - END; + tBoolItem = POINTER TO RECORD (List.tItem) + map: SET; + data: ARRAY boolItemSize OF + RECORD + line: Lines.tLine; + adr: INTEGER; + val, save: BOOLEAN + END + END; - tUntypedPtr = POINTER TO RECORD (List.tItem) - cnt: INTEGER; - p: ARRAY 64 OF INTEGER - END; + tUntypedPtr = POINTER TO RECORD (List.tItem) + cnt: INTEGER; + p: ARRAY 64 OF INTEGER + END; - tTypedPtr = POINTER TO RECORD (List.tItem) - cnt: INTEGER; - p: ARRAY 64 OF List.tItem - END; + tTypedPtr = POINTER TO RECORD (List.tItem) + cnt: INTEGER; + p: ARRAY 64 OF List.tItem + END; - tGuard* = POINTER TO RECORD (List.tItem) - saved*: BOOLEAN - END; + tGuard* = POINTER TO RECORD (List.tItem) + saved*: BOOLEAN + END; - tLog* = POINTER TO RECORD - Log*, TPointers, UPointers: List.tList; - guard, first: tGuard; - isLast: BOOLEAN - END; + tLog* = POINTER TO RECORD + Log*, TPointers, UPointers: List.tList; + guard, first: tGuard; + isLast: BOOLEAN + END; VAR - CL*: tLog; + CL*: tLog; PROCEDURE isLastGuard* (guard: tGuard): BOOLEAN; VAR - item: List.tItem; - res: BOOLEAN; + item: List.tItem; + res: BOOLEAN; BEGIN - IF guard # NIL THEN - item := CL.Log.last; - WHILE ~(item IS tGuard) DO - item := item.prev - END; - res := guard = item - ELSE - res := TRUE - END - RETURN res + IF guard # NIL THEN + item := CL.Log.last; + WHILE ~(item IS tGuard) DO + item := item.prev + END; + res := guard = item + ELSE + res := TRUE + END + RETURN res END isLastGuard; @@ -100,8 +108,8 @@ END isFirstGuard; PROCEDURE setGuard* (_guard: tGuard); BEGIN - CL.guard := _guard; - CL.isLast := isLastGuard(_guard) + CL.guard := _guard; + CL.isLast := isLastGuard(_guard) END setGuard; @@ -114,23 +122,27 @@ BEGIN SYSTEM.PUT(item(tIntItem).adr[i], item(tIntItem).val[i]) END ELSIF item IS tBoolItem THEN - SYSTEM.PUT(item(tBoolItem).adr, item(tBoolItem).val) + FOR i := 0 TO boolItemSize - 1 DO + IF i IN item(tBoolItem).map THEN + SYSTEM.PUT(item(tBoolItem).data[i].adr, item(tBoolItem).data[i].val) + END + END END END redo; PROCEDURE clear (guard: tGuard); VAR - item: List.tItem; + item: List.tItem; BEGIN - CL.isLast := TRUE; - REPEAT - item := List.pop(CL.Log); - IF item # guard THEN - DISPOSE(item) - END - UNTIL item = guard; - List.append(CL.Log, item) + CL.isLast := TRUE; + REPEAT + item := List.pop(CL.Log); + IF item # guard THEN + DISPOSE(item) + END + UNTIL item = guard; + List.append(CL.Log, item) END clear; @@ -139,31 +151,34 @@ VAR item: List.tItem; boolItem: tBoolItem; cur: List.tItem; - del: BOOLEAN; + i: INTEGER; BEGIN - item := CL.Log.first; - WHILE item # NIL DO - IF item IS tGuard THEN - item(tGuard).saved := FALSE - END; - item := item.next - END; - guard.saved := TRUE; + item := CL.Log.first; + WHILE item # NIL DO + IF item IS tGuard THEN + item(tGuard).saved := FALSE + END; + item := item.next + END; + guard.saved := TRUE; - cur := CL.guard.prev; - WHILE cur # NIL DO - IF cur IS tBoolItem THEN - boolItem := cur(tBoolItem); - del := boolItem.save & boolItem.line.modified - ELSE - del := FALSE - END; - cur := cur.prev; - IF del THEN - List.delete(CL.Log, boolItem); - DISPOSE(boolItem) - END - END + cur := CL.guard.prev; + WHILE cur # NIL DO + IF cur IS tBoolItem THEN + boolItem := cur(tBoolItem); + FOR i := 0 TO boolItemSize - 1 DO + IF (i IN boolItem.map) & boolItem.data[i].save & + boolItem.data[i].line.modified THEN + EXCL(boolItem.map, i) + END + END + END; + cur := cur.prev; + IF boolItem.map = {} THEN + List.delete(CL.Log, boolItem); + DISPOSE(boolItem) + END + END END save; @@ -192,91 +207,124 @@ BEGIN END changeWord; -PROCEDURE changeBool (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN); -VAR - item: tBoolItem; -BEGIN - NEW(item); - item.line := line; - item.adr := SYSTEM.ADR(v); - item.val := x; - item.save := FALSE; - IF ~CL.isLast THEN - clear(CL.guard) - END; - List.append(CL.Log, item) -END changeBool; - - PROCEDURE delSaved*; VAR - boolItem: tBoolItem; - cur: List.tItem; - del: BOOLEAN; + boolItem: tBoolItem; + cur: List.tItem; + i: INTEGER; BEGIN - cur := CL.guard.next; - WHILE cur # NIL DO - IF cur IS tBoolItem THEN - boolItem := cur(tBoolItem); - del := boolItem.save - ELSE - del := FALSE - END; - cur := cur.next; - IF del THEN - List.delete(CL.Log, boolItem); - DISPOSE(boolItem) - END - END + cur := CL.guard.next; + WHILE cur # NIL DO + IF cur IS tBoolItem THEN + boolItem := cur(tBoolItem); + FOR i := 0 TO boolItemSize - 1 DO + IF (i IN boolItem.map) & boolItem.data[i].save THEN + EXCL(boolItem.map, i) + END + END + END; + cur := cur.next; + IF boolItem.map = {} THEN + List.delete(CL.Log, boolItem); + DISPOSE(boolItem) + END + END END delSaved; PROCEDURE delCurSaved*; VAR - boolItem: tBoolItem; - cur: List.tItem; - del: BOOLEAN; + boolItem: tBoolItem; + cur: List.tItem; + i: INTEGER; BEGIN - cur := CL.guard.prev; - WHILE (cur # NIL) & ~(cur IS tGuard) DO - IF cur IS tBoolItem THEN - boolItem := cur(tBoolItem); - del := boolItem.save - ELSE - del := FALSE - END; - cur := cur.prev; - IF del THEN - SYSTEM.PUT(boolItem.adr, ~boolItem.val); - List.delete(CL.Log, boolItem); - DISPOSE(boolItem) - END - END + cur := CL.guard.prev; + WHILE (cur # NIL) & ~(cur IS tGuard) DO + IF cur IS tBoolItem THEN + boolItem := cur(tBoolItem); + FOR i := 0 TO boolItemSize - 1 DO + IF (i IN boolItem.map) & boolItem.data[i].save THEN + SYSTEM.PUT(boolItem.data[i].adr, ~boolItem.data[i].val); + EXCL(boolItem.map, i) + END + END + END; + cur := cur.prev; + IF boolItem.map = {} THEN + List.delete(CL.Log, boolItem); + DISPOSE(boolItem) + END + END END delCurSaved; -PROCEDURE changeBool2 (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN); +PROCEDURE _changeBool (fn2: BOOLEAN; line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN); VAR - item: tBoolItem; + item: tBoolItem; + cur: List.tItem; + i: INTEGER; BEGIN - NEW(item); - item.line := line; - item.adr := SYSTEM.ADR(v); - item.val := x; - item.save := TRUE; - List.insert(CL.Log, CL.guard.prev, item) + IF fn2 THEN + cur := CL.guard.prev + ELSE + IF ~CL.isLast THEN + clear(CL.guard) + END; + cur := CL.Log.last + END; + + WHILE (cur # NIL) & ~(cur IS tGuard) & + (~(cur IS tBoolItem) OR (cur(tBoolItem).map = fillMap)) DO + cur := cur.prev + END; + IF (cur IS tBoolItem) & (cur(tBoolItem).map # fillMap) THEN + item := cur(tBoolItem) + ELSE + NEW(item); + item.map := {}; + IF fn2 THEN + List.insert(CL.Log, CL.guard.prev, item) + ELSE + List.append(CL.Log, item) + END + END; + + i := 0; + WHILE i < boolItemSize DO + IF ~(i IN item.map) THEN + item.data[i].line := line; + item.data[i].adr := SYSTEM.ADR(v); + item.data[i].val := x; + item.data[i].save := fn2; + INCL(item.map, i); + i := boolItemSize + END; + INC(i) + END +END _changeBool; + + +PROCEDURE changeBool (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN); +BEGIN + _changeBool(FALSE, line, v, x) +END changeBool; + + +PROCEDURE changeBool2 (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN); +BEGIN + _changeBool(TRUE, line, v, x) END changeBool2; PROCEDURE changeInt* (VAR v: INTEGER; x: INTEGER); BEGIN - changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x)) + changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x)) END changeInt; PROCEDURE changePtr (VAR v: List.tItem; x: List.tItem); BEGIN - changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x)) + changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x)) END changePtr; @@ -312,24 +360,24 @@ END untypedPtr; PROCEDURE setLog* (_CL: tLog); BEGIN - CL := _CL + CL := _CL END setLog; PROCEDURE create* (VAR maxLength: INTEGER): tLog; VAR - newLog: tLog; + newLog: tLog; BEGIN - NEW(newLog); - newLog.guard := NIL; - newLog.first := NIL; - newLog.isLast := TRUE; - newLog.Log := List.create(NIL); - newLog.TPointers := List.create(NIL); - newLog.UPointers := List.create(NIL); - CL := newLog; - Lines.setMaxLength(maxLength) - RETURN newLog + NEW(newLog); + newLog.guard := NIL; + newLog.first := NIL; + newLog.isLast := TRUE; + newLog.Log := List.create(NIL); + newLog.TPointers := List.create(NIL); + newLog.UPointers := List.create(NIL); + CL := newLog; + Lines.setMaxLength(maxLength) + RETURN newLog END create; @@ -372,6 +420,6 @@ END destroy; BEGIN - List.init(changeInt, changePtr); - Lines.init(changeInt, changePtr, changeBool, changeBool2, typedPtr, untypedPtr) + List.init(changeInt, changePtr); + Lines.init(changeInt, changePtr, changeBool, changeBool2, typedPtr, untypedPtr) END ChangeLog. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/Languages.ob07 b/programs/develop/cedit/SRC/Languages.ob07 index ecde03a3ec..801995aa4d 100644 --- a/programs/develop/cedit/SRC/Languages.ob07 +++ b/programs/develop/cedit/SRC/Languages.ob07 @@ -141,7 +141,7 @@ BEGIN REPEAT INC(pos); c := Lines.getChar(line, pos); - IF Utils.cap(c) THEN END; + IF Utils.upper(c) THEN END; IF Utils.isHex(c) THEN INC(k) ELSE @@ -166,7 +166,7 @@ BEGIN REPEAT INC(pos); c := Lines.getChar(line, pos); - IF Utils.cap(c) THEN END; + IF Utils.upper(c) THEN END; IF Utils.isHex(c) THEN INC(k) ELSE @@ -457,7 +457,7 @@ BEGIN key[2] := CHR(ORD("1") + i); getStr(lang_name, key, s); IF ~(lang IN csLang) THEN - Utils.upcase(s) + Utils.lowcase8(s) END; IF lang = langOberon THEN k := LENGTH(s); @@ -465,7 +465,7 @@ BEGIN FOR j := 0 TO k - 1 DO s[j + k + 1] := s[j]; w := WCHR(ORD(s[j])); - IF Utils.low(w) THEN + IF Utils.lower(w) THEN s[j + k + 1] := CHR(ORD(w) MOD 256) END END; @@ -508,8 +508,7 @@ BEGIN WHILE fileExt[i].lang # lang DO INC(i) END; - COPY(fileExt[i].ext, ext); - Utils.lowcase(ext) + COPY(fileExt[i].ext, ext) END getExt; @@ -525,17 +524,17 @@ BEGIN loadKW(langFasm, KW[langFasm], Delim[langFasm], getStr, "lang_Fasm"); loadKW(langJSON, KW[langJSON], Delim[langJSON], getStr, "lang_JSON"); - fileExt[ 0].ext := "OB07"; fileExt[ 0].lang := langOberon; - fileExt[ 1].ext := "C"; fileExt[ 1].lang := langC; - fileExt[ 2].ext := "H"; fileExt[ 2].lang := langC; - fileExt[ 3].ext := "CPP"; fileExt[ 3].lang := langC; - fileExt[ 4].ext := "PAS"; fileExt[ 4].lang := langPascal; - fileExt[ 5].ext := "PP"; fileExt[ 5].lang := langPascal; - fileExt[ 6].ext := "ASM"; fileExt[ 6].lang := langFasm; - fileExt[ 7].ext := "LUA"; fileExt[ 7].lang := langLua; - fileExt[ 8].ext := "INI"; fileExt[ 8].lang := langIni; - fileExt[ 9].ext := "JSON"; fileExt[ 9].lang := langJSON; - fileExt[10].ext := "TXT"; fileExt[10].lang := langText; + fileExt[ 0].ext := "ob07"; fileExt[ 0].lang := langOberon; + fileExt[ 1].ext := "c"; fileExt[ 1].lang := langC; + fileExt[ 2].ext := "h"; fileExt[ 2].lang := langC; + fileExt[ 3].ext := "cpp"; fileExt[ 3].lang := langC; + fileExt[ 4].ext := "pas"; fileExt[ 4].lang := langPascal; + fileExt[ 5].ext := "pp"; fileExt[ 5].lang := langPascal; + fileExt[ 6].ext := "asm"; fileExt[ 6].lang := langFasm; + fileExt[ 7].ext := "lua"; fileExt[ 7].lang := langLua; + fileExt[ 8].ext := "ini"; fileExt[ 8].lang := langIni; + fileExt[ 9].ext := "json"; fileExt[ 9].lang := langJSON; + fileExt[10].ext := "txt"; fileExt[10].lang := langText; END init; diff --git a/programs/develop/cedit/SRC/RTL.ob07 b/programs/develop/cedit/SRC/RTL.ob07 deleted file mode 100644 index 0818bca97d..0000000000 --- a/programs/develop/cedit/SRC/RTL.ob07 +++ /dev/null @@ -1,543 +0,0 @@ -(* - BSD 2-Clause License - - Copyright (c) 2018-2021, Anton Krotov - All rights reserved. -*) - -MODULE RTL; - -IMPORT SYSTEM, API; - - -CONST - - minint = ROR(1, 1); - - WORD = API.BIT_DEPTH DIV 8; - - -VAR - - name: INTEGER; - types: INTEGER; - - -PROCEDURE [stdcall] _move* (bytes, dest, source: INTEGER); -BEGIN - SYSTEM.CODE( - 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *) - 085H, 0C0H, (* test eax, eax *) - 07EH, 019H, (* jle L *) - 0FCH, (* cld *) - 057H, (* push edi *) - 056H, (* push esi *) - 08BH, 075H, 010H, (* mov esi, dword [ebp + 16] *) - 08BH, 07DH, 00CH, (* mov edi, dword [ebp + 12] *) - 089H, 0C1H, (* mov ecx, eax *) - 0C1H, 0E9H, 002H, (* shr ecx, 2 *) - 0F3H, 0A5H, (* rep movsd *) - 089H, 0C1H, (* mov ecx, eax *) - 083H, 0E1H, 003H, (* and ecx, 3 *) - 0F3H, 0A4H, (* rep movsb *) - 05EH, (* pop esi *) - 05FH (* pop edi *) - (* L: *) - ) -END _move; - - -PROCEDURE [stdcall] _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN; -VAR - res: BOOLEAN; - -BEGIN - IF len_src > len_dst THEN - res := FALSE - ELSE - _move(len_src * base_size, dst, src); - res := TRUE - END - - RETURN res -END _arrcpy; - - -PROCEDURE [stdcall] _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER); -BEGIN - _move(MIN(len_dst, len_src) * chr_size, dst, src) -END _strcpy; - - -PROCEDURE [stdcall] _rot* (Len, Ptr: INTEGER); -BEGIN - SYSTEM.CODE( - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) (* ecx <- Len *) - 08BH, 045H, 00CH, (* mov eax, dword [ebp + 12] *) (* eax <- Ptr *) - 049H, (* dec ecx *) - 053H, (* push ebx *) - 08BH, 018H, (* mov ebx, dword [eax] *) - (* L: *) - 08BH, 050H, 004H, (* mov edx, dword [eax + 4] *) - 089H, 010H, (* mov dword [eax], edx *) - 083H, 0C0H, 004H, (* add eax, 4 *) - 049H, (* dec ecx *) - 075H, 0F5H, (* jnz L *) - 089H, 018H, (* mov dword [eax], ebx *) - 05BH, (* pop ebx *) - 05DH, (* pop ebp *) - 0C2H, 008H, 000H (* ret 8 *) - ) -END _rot; - - -PROCEDURE [stdcall] _set* (b, a: INTEGER); (* {a..b} -> eax *) -BEGIN - SYSTEM.CODE( - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) (* ecx <- b *) - 08BH, 045H, 00CH, (* mov eax, dword [ebp + 12] *) (* eax <- a *) - 039H, 0C8H, (* cmp eax, ecx *) - 07FH, 033H, (* jg L1 *) - 083H, 0F8H, 01FH, (* cmp eax, 31 *) - 07FH, 02EH, (* jg L1 *) - 085H, 0C9H, (* test ecx, ecx *) - 07CH, 02AH, (* jl L1 *) - 083H, 0F9H, 01FH, (* cmp ecx, 31 *) - 07EH, 005H, (* jle L3 *) - 0B9H, 01FH, 000H, 000H, 000H, (* mov ecx, 31 *) - (* L3: *) - 085H, 0C0H, (* test eax, eax *) - 07DH, 002H, (* jge L2 *) - 031H, 0C0H, (* xor eax, eax *) - (* L2: *) - 089H, 0CAH, (* mov edx, ecx *) - 029H, 0C2H, (* sub edx, eax *) - 0B8H, 000H, 000H, 000H, 080H, (* mov eax, 0x80000000 *) - 087H, 0CAH, (* xchg edx, ecx *) - 0D3H, 0F8H, (* sar eax, cl *) - 087H, 0CAH, (* xchg edx, ecx *) - 083H, 0E9H, 01FH, (* sub ecx, 31 *) - 0F7H, 0D9H, (* neg ecx *) - 0D3H, 0E8H, (* shr eax, cl *) - 05DH, (* pop ebp *) - 0C2H, 008H, 000H, (* ret 8 *) - (* L1: *) - 031H, 0C0H, (* xor eax, eax *) - 05DH, (* pop ebp *) - 0C2H, 008H, 000H (* ret 8 *) - ) -END _set; - - -PROCEDURE [stdcall] _set1* (a: INTEGER); (* {a} -> eax *) -BEGIN - SYSTEM.CODE( - 031H, 0C0H, (* xor eax, eax *) - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) (* ecx <- a *) - 083H, 0F9H, 01FH, (* cmp ecx, 31 *) - 077H, 003H, (* ja L *) - 00FH, 0ABH, 0C8H (* bts eax, ecx *) - (* L: *) - ) -END _set1; - - -PROCEDURE [stdcall] _divmod* (y, x: INTEGER); (* (x div y) -> eax; (x mod y) -> edx *) -BEGIN - SYSTEM.CODE( - 053H, (* push ebx *) - 08BH, 045H, 00CH, (* mov eax, dword [ebp + 12] *) (* eax <- x *) - 031H, 0D2H, (* xor edx, edx *) - 085H, 0C0H, (* test eax, eax *) - 074H, 018H, (* je L2 *) - 07FH, 002H, (* jg L1 *) - 0F7H, 0D2H, (* not edx *) - (* L1: *) - 089H, 0C3H, (* mov ebx, eax *) - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 8] *) (* ecx <- y *) - 0F7H, 0F9H, (* idiv ecx *) - 085H, 0D2H, (* test edx, edx *) - 074H, 009H, (* je L2 *) - 031H, 0CBH, (* xor ebx, ecx *) - 085H, 0DBH, (* test ebx, ebx *) - 07DH, 003H, (* jge L2 *) - 048H, (* dec eax *) - 001H, 0CAH, (* add edx, ecx *) - (* L2: *) - 05BH (* pop ebx *) - ) -END _divmod; - - -PROCEDURE [stdcall] _new* (t, size: INTEGER; VAR ptr: INTEGER); -BEGIN - ptr := API._NEW(size); - IF ptr # 0 THEN - SYSTEM.PUT(ptr, t); - INC(ptr, WORD) - END -END _new; - - -PROCEDURE [stdcall] _dispose* (VAR ptr: INTEGER); -BEGIN - IF ptr # 0 THEN - ptr := API._DISPOSE(ptr - WORD) - END -END _dispose; - - -PROCEDURE [stdcall] _length* (len, str: INTEGER); -BEGIN - SYSTEM.CODE( - 08BH, 045H, 00CH, (* mov eax, dword [ebp + 0Ch] *) - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 08h] *) - 048H, (* dec eax *) - (* L1: *) - 040H, (* inc eax *) - 080H, 038H, 000H, (* cmp byte [eax], 0 *) - 074H, 003H, (* jz L2 *) - 0E2H, 0F8H, (* loop L1 *) - 040H, (* inc eax *) - (* L2: *) - 02BH, 045H, 00CH (* sub eax, dword [ebp + 0Ch] *) - ) -END _length; - - -PROCEDURE [stdcall] _lengthw* (len, str: INTEGER); -BEGIN - SYSTEM.CODE( - 08BH, 045H, 00CH, (* mov eax, dword [ebp + 0Ch] *) - 08BH, 04DH, 008H, (* mov ecx, dword [ebp + 08h] *) - 048H, (* dec eax *) - 048H, (* dec eax *) - (* L1: *) - 040H, (* inc eax *) - 040H, (* inc eax *) - 066H, 083H, 038H, 000H, (* cmp word [eax], 0 *) - 074H, 004H, (* jz L2 *) - 0E2H, 0F6H, (* loop L1 *) - 040H, (* inc eax *) - 040H, (* inc eax *) - (* L2: *) - 02BH, 045H, 00CH, (* sub eax, dword [ebp + 0Ch] *) - 0D1H, 0E8H (* shr eax, 1 *) - ) -END _lengthw; - - -PROCEDURE [stdcall] strncmp (a, b, n: INTEGER): INTEGER; -BEGIN - SYSTEM.CODE( - 056H, (* push esi *) - 057H, (* push edi *) - 053H, (* push ebx *) - 08BH, 075H, 008H, (* mov esi, dword[ebp + 8]; esi <- a *) - 08BH, 07DH, 00CH, (* mov edi, dword[ebp + 12]; edi <- b *) - 08BH, 05DH, 010H, (* mov ebx, dword[ebp + 16]; ebx <- n *) - 031H, 0C9H, (* xor ecx, ecx *) - 031H, 0D2H, (* xor edx, edx *) - 0B8H, - 000H, 000H, 000H, 080H, (* mov eax, minint *) - (* L1: *) - 085H, 0DBH, (* test ebx, ebx *) - 07EH, 017H, (* jle L3 *) - 08AH, 00EH, (* mov cl, byte[esi] *) - 08AH, 017H, (* mov dl, byte[edi] *) - 046H, (* inc esi *) - 047H, (* inc edi *) - 04BH, (* dec ebx *) - 039H, 0D1H, (* cmp ecx, edx *) - 074H, 006H, (* je L2 *) - 089H, 0C8H, (* mov eax, ecx *) - 029H, 0D0H, (* sub eax, edx *) - 0EBH, 006H, (* jmp L3 *) - (* L2: *) - 085H, 0C9H, (* test ecx, ecx *) - 075H, 0E7H, (* jne L1 *) - 031H, 0C0H, (* xor eax, eax *) - (* L3: *) - 05BH, (* pop ebx *) - 05FH, (* pop edi *) - 05EH, (* pop esi *) - 05DH, (* pop ebp *) - 0C2H, 00CH, 000H (* ret 12 *) - ) - RETURN 0 -END strncmp; - - -PROCEDURE [stdcall] strncmpw (a, b, n: INTEGER): INTEGER; -BEGIN - SYSTEM.CODE( - 056H, (* push esi *) - 057H, (* push edi *) - 053H, (* push ebx *) - 08BH, 075H, 008H, (* mov esi, dword[ebp + 8]; esi <- a *) - 08BH, 07DH, 00CH, (* mov edi, dword[ebp + 12]; edi <- b *) - 08BH, 05DH, 010H, (* mov ebx, dword[ebp + 16]; ebx <- n *) - 031H, 0C9H, (* xor ecx, ecx *) - 031H, 0D2H, (* xor edx, edx *) - 0B8H, - 000H, 000H, 000H, 080H, (* mov eax, minint *) - (* L1: *) - 085H, 0DBH, (* test ebx, ebx *) - 07EH, 01BH, (* jle L3 *) - 066H, 08BH, 00EH, (* mov cx, word[esi] *) - 066H, 08BH, 017H, (* mov dx, word[edi] *) - 046H, (* inc esi *) - 046H, (* inc esi *) - 047H, (* inc edi *) - 047H, (* inc edi *) - 04BH, (* dec ebx *) - 039H, 0D1H, (* cmp ecx, edx *) - 074H, 006H, (* je L2 *) - 089H, 0C8H, (* mov eax, ecx *) - 029H, 0D0H, (* sub eax, edx *) - 0EBH, 006H, (* jmp L3 *) - (* L2: *) - 085H, 0C9H, (* test ecx, ecx *) - 075H, 0E3H, (* jne L1 *) - 031H, 0C0H, (* xor eax, eax *) - (* L3: *) - 05BH, (* pop ebx *) - 05FH, (* pop edi *) - 05EH, (* pop esi *) - 05DH, (* pop ebp *) - 0C2H, 00CH, 000H (* ret 12 *) - ) - RETURN 0 -END strncmpw; - - -PROCEDURE [stdcall] _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN; -VAR - res: INTEGER; - bRes: BOOLEAN; - c: CHAR; - -BEGIN - res := strncmp(str1, str2, MIN(len1, len2)); - IF res = minint THEN - IF len1 > len2 THEN - SYSTEM.GET(str1 + len2, c); - res := ORD(c) - ELSIF len1 < len2 THEN - SYSTEM.GET(str2 + len1, c); - res := -ORD(c) - ELSE - res := 0 - END - END; - - CASE op OF - |0: bRes := res = 0 - |1: bRes := res # 0 - |2: bRes := res < 0 - |3: bRes := res <= 0 - |4: bRes := res > 0 - |5: bRes := res >= 0 - END - - RETURN bRes -END _strcmp; - - -PROCEDURE [stdcall] _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN; -VAR - res: INTEGER; - bRes: BOOLEAN; - c: WCHAR; - -BEGIN - res := strncmpw(str1, str2, MIN(len1, len2)); - IF res = minint THEN - IF len1 > len2 THEN - SYSTEM.GET(str1 + len2 * 2, c); - res := ORD(c) - ELSIF len1 < len2 THEN - SYSTEM.GET(str2 + len1 * 2, c); - res := -ORD(c) - ELSE - res := 0 - END - END; - - CASE op OF - |0: bRes := res = 0 - |1: bRes := res # 0 - |2: bRes := res < 0 - |3: bRes := res <= 0 - |4: bRes := res > 0 - |5: bRes := res >= 0 - END - - RETURN bRes -END _strcmpw; - - -PROCEDURE PCharToStr (pchar: INTEGER; VAR s: ARRAY OF CHAR); -VAR - c: CHAR; - i: INTEGER; - -BEGIN - i := 0; - REPEAT - SYSTEM.GET(pchar, c); - s[i] := c; - INC(pchar); - INC(i) - UNTIL c = 0X -END PCharToStr; - - -PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR); -VAR - i, a: INTEGER; - -BEGIN - i := 0; - a := x; - REPEAT - INC(i); - a := a DIV 10 - UNTIL a = 0; - - str[i] := 0X; - - REPEAT - DEC(i); - str[i] := CHR(x MOD 10 + ORD("0")); - x := x DIV 10 - UNTIL x = 0 -END IntToStr; - - -PROCEDURE append (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); -VAR - n1, n2: INTEGER; - -BEGIN - n1 := LENGTH(s1); - n2 := LENGTH(s2); - - ASSERT(n1 + n2 < LEN(s1)); - - SYSTEM.MOVE(SYSTEM.ADR(s2[0]), SYSTEM.ADR(s1[n1]), n2); - s1[n1 + n2] := 0X -END append; - - -PROCEDURE [stdcall] _error* (modnum, _module, err, line: INTEGER); -VAR - s, temp: ARRAY 1024 OF CHAR; - -BEGIN - CASE err OF - | 1: s := "assertion failure" - | 2: s := "NIL dereference" - | 3: s := "bad divisor" - | 4: s := "NIL procedure call" - | 5: s := "type guard error" - | 6: s := "index out of range" - | 7: s := "invalid CASE" - | 8: s := "array assignment error" - | 9: s := "CHR out of range" - |10: s := "WCHR out of range" - |11: s := "BYTE out of range" - END; - - append(s, API.eol + "module: "); PCharToStr(_module, temp); append(s, temp); - append(s, API.eol + "line: "); IntToStr(line, temp); append(s, temp); - - API.DebugMsg(SYSTEM.ADR(s[0]), name); - - API.exit_thread(0) -END _error; - - -PROCEDURE [stdcall] _isrec* (t0, t1, r: INTEGER): INTEGER; -BEGIN - SYSTEM.GET(t0 + t1 + types, t0) - RETURN t0 MOD 2 -END _isrec; - - -PROCEDURE [stdcall] _is* (t0, p: INTEGER): INTEGER; -BEGIN - IF p # 0 THEN - SYSTEM.GET(p - WORD, p); - SYSTEM.GET(t0 + p + types, p) - END - - RETURN p MOD 2 -END _is; - - -PROCEDURE [stdcall] _guardrec* (t0, t1: INTEGER): INTEGER; -BEGIN - SYSTEM.GET(t0 + t1 + types, t0) - RETURN t0 MOD 2 -END _guardrec; - - -PROCEDURE [stdcall] _guard* (t0, p: INTEGER): INTEGER; -BEGIN - SYSTEM.GET(p, p); - IF p # 0 THEN - SYSTEM.GET(p - WORD, p); - SYSTEM.GET(t0 + p + types, p) - ELSE - p := 1 - END - - RETURN p MOD 2 -END _guard; - - -PROCEDURE [stdcall] _dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER; - RETURN API.dllentry(hinstDLL, fdwReason, lpvReserved) -END _dllentry; - - -PROCEDURE [stdcall] _sofinit*; -BEGIN - API.sofinit -END _sofinit; - - -PROCEDURE [stdcall] _exit* (code: INTEGER); -BEGIN - API.exit(code) -END _exit; - - -PROCEDURE [stdcall] _init* (modname: INTEGER; tcount, _types: INTEGER; code, param: INTEGER); -VAR - t0, t1, i, j: INTEGER; - -BEGIN - SYSTEM.CODE(09BH, 0DBH, 0E3H); (* finit *) - API.init(param, code); - - types := API._NEW(tcount * tcount + SYSTEM.SIZE(INTEGER)); - ASSERT(types # 0); - FOR i := 0 TO tcount - 1 DO - FOR j := 0 TO tcount - 1 DO - t0 := i; t1 := j; - - WHILE (t1 # 0) & (t1 # t0) DO - SYSTEM.GET(_types + t1 * WORD, t1) - END; - - SYSTEM.PUT8(i * tcount + j + types, ORD(t0 = t1)) - END - END; - - name := modname -END _init; - - -END RTL. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/Search.ob07 b/programs/develop/cedit/SRC/Search.ob07 index ed224ff672..b9215b0a6f 100644 --- a/programs/develop/cedit/SRC/Search.ob07 +++ b/programs/develop/cedit/SRC/Search.ob07 @@ -20,17 +20,20 @@ MODULE Search; IMPORT - CB := Clipboard, List, Utils, SYSTEM; + CB := Clipboard, List, Utils, SYSTEM; +CONST + itemSize = 64; TYPE - tBuffer* = CB.tBuffer; + tBuffer* = CB.tBuffer; - tIdxTable = ARRAY 65536, 2 OF INTEGER; + tIdxTable = ARRAY 65536, 2 OF INTEGER; - tPos* = POINTER TO RECORD (List.tItem) - pos*: INTEGER - END; + tPos* = POINTER TO RECORD (List.tItem) + cnt*: INTEGER; + pos*: ARRAY itemSize OF INTEGER + END; VAR table: POINTER TO RECORD data: tIdxTable END; @@ -38,50 +41,50 @@ VAR PROCEDURE _index (text: tBuffer; cs: BOOLEAN; VAR table: tIdxTable): tBuffer; VAR - pChar, cnt, i: INTEGER; - c: WCHAR; - res: tBuffer; + pChar, cnt, i: INTEGER; + c: WCHAR; + res: tBuffer; BEGIN - pChar := text.dataPtr; - cnt := CB.bufSize(text) DIV SYSTEM.SIZE(WCHAR); + pChar := text.dataPtr; + cnt := CB.bufSize(text) DIV SYSTEM.SIZE(WCHAR); - FOR i := 0 TO 65535 DO - table[i, 1] := 0 - END; + FOR i := 0 TO 65535 DO + table[i, 1] := 0 + END; - i := cnt; - WHILE i > 0 DO - SYSTEM.GET(pChar, c); - IF ~cs & Utils.cap(c) THEN - SYSTEM.PUT(pChar, c) - END; - INC(table[ORD(c), 1]); - INC(pChar, SYSTEM.SIZE(WCHAR)); - DEC(i) - END; + i := cnt; + WHILE i > 0 DO + SYSTEM.GET(pChar, c); + IF ~cs & Utils.lower(c) THEN + SYSTEM.PUT(pChar, c) + END; + INC(table[ORD(c), 1]); + INC(pChar, SYSTEM.SIZE(WCHAR)); + DEC(i) + END; - res := CB.create(cnt*SYSTEM.SIZE(INTEGER)); + res := CB.create(cnt*SYSTEM.SIZE(INTEGER)); - table[0, 0] := res.dataPtr; - FOR i := 1 TO 65535 DO - table[i, 0] := table[i - 1, 0] + table[i - 1, 1]*SYSTEM.SIZE(INTEGER) - END; + table[0, 0] := res.dataPtr; + FOR i := 1 TO 65535 DO + table[i, 0] := table[i - 1, 0] + table[i - 1, 1]*SYSTEM.SIZE(INTEGER) + END; - pChar := text.dataPtr; - i := 0; - WHILE i < cnt DO - SYSTEM.GET(pChar, c); - SYSTEM.PUT(table[ORD(c), 0], i); - INC(table[ORD(c), 0], SYSTEM.SIZE(INTEGER)); - INC(pChar, SYSTEM.SIZE(WCHAR)); - INC(i) - END; + pChar := text.dataPtr; + i := 0; + WHILE i < cnt DO + SYSTEM.GET(pChar, c); + SYSTEM.PUT(table[ORD(c), 0], i); + INC(table[ORD(c), 0], SYSTEM.SIZE(INTEGER)); + INC(pChar, SYSTEM.SIZE(WCHAR)); + INC(i) + END; - FOR i := 0 TO 65535 DO - DEC(table[i, 0], table[i, 1]*SYSTEM.SIZE(INTEGER)) - END + FOR i := 0 TO 65535 DO + DEC(table[i, 0], table[i, 1]*SYSTEM.SIZE(INTEGER)) + END - RETURN res + RETURN res END _index; @@ -94,42 +97,65 @@ BEGIN END index; +PROCEDURE next* (VAR item: tPos; VAR i: INTEGER): INTEGER; +VAR + res: INTEGER; +BEGIN + IF (item # NIL) & (i >= item.cnt) THEN + item := item.next(tPos); + i := 0; + END; + IF (item # NIL ) & (i < item.cnt) THEN + res := item.pos[i]; + INC(i) + ELSE + res := -1 + END + RETURN res +END next; + + PROCEDURE find* (text: tBuffer; s: ARRAY OF WCHAR; whole: BOOLEAN; list: List.tList); VAR - k, pos, n, x, prev_item_pos: INTEGER; - item: tPos; - c1, c2: WCHAR; - flag: BOOLEAN; + k, pos, n, x, prev_item_pos: INTEGER; + item: tPos; + c1, c2: WCHAR; + flag: BOOLEAN; BEGIN ASSERT(table # NIL); - n := LENGTH(s); - k := table.data[ORD(s[0]), 1]; - pos := table.data[ORD(s[0]), 0]; - prev_item_pos := 0; - WHILE k > 0 DO - SYSTEM.GET(pos, x); - IF Utils.streq(text.dataPtr + x*SYSTEM.SIZE(WCHAR), SYSTEM.ADR(s[0]), n) THEN - flag := whole; - IF flag THEN - IF x > 0 THEN - SYSTEM.GET(text.dataPtr + (x - 1)*SYSTEM.SIZE(WCHAR), c1); - ELSE - c1 := 0X - END; - SYSTEM.GET(text.dataPtr + (x + n)*SYSTEM.SIZE(WCHAR), c2); - flag := Utils.isLetter(c1) OR Utils.isLetter(c2) OR Utils.isDigit(c1) OR Utils.isDigit(c2) OR - (c1 = "_") OR (c2 = "_") - END; - IF ~flag & (x >= prev_item_pos) THEN - prev_item_pos := x + n; - NEW(item); - item.pos := x; - List.append(list, item) - END - END; - INC(pos, SYSTEM.SIZE(INTEGER)); - DEC(k) - END + n := LENGTH(s); + k := table.data[ORD(s[0]), 1]; + pos := table.data[ORD(s[0]), 0]; + prev_item_pos := 0; + WHILE k > 0 DO + SYSTEM.GET(pos, x); + IF Utils.streq(text.dataPtr + x*SYSTEM.SIZE(WCHAR), SYSTEM.ADR(s[0]), n) THEN + flag := whole; + IF flag THEN + IF x > 0 THEN + SYSTEM.GET(text.dataPtr + (x - 1)*SYSTEM.SIZE(WCHAR), c1); + ELSE + c1 := 0X + END; + SYSTEM.GET(text.dataPtr + (x + n)*SYSTEM.SIZE(WCHAR), c2); + flag := Utils.isLetter(c1) OR Utils.isLetter(c2) OR Utils.isDigit(c1) OR Utils.isDigit(c2) OR + (c1 = "_") OR (c2 = "_") + END; + IF ~flag & (x >= prev_item_pos) THEN + prev_item_pos := x + n; + item := list.last(tPos); + IF (item = NIL) OR (item.cnt = itemSize) THEN + NEW(item); + item.cnt := 0; + List.append(list, item) + END; + item.pos[item.cnt] := x; + INC(item.cnt) + END + END; + INC(pos, SYSTEM.SIZE(INTEGER)); + DEC(k) + END END find; diff --git a/programs/develop/cedit/SRC/Tabs.ob07 b/programs/develop/cedit/SRC/Tabs.ob07 index dc634cb342..fae092d5cc 100644 --- a/programs/develop/cedit/SRC/Tabs.ob07 +++ b/programs/develop/cedit/SRC/Tabs.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2021, 2022 Anton Krotov + Copyright 2021-2023 Anton Krotov This file is part of CEdit. @@ -31,12 +31,14 @@ CONST curTabHeight = 26; scrWidth = 15; btnCloseColor* = 0EF999FH; + modifColor = 0FF0000H; + strLen = 30; TYPE tItem = POINTER TO RECORD (List.tItem) - val: RW.tFileName; + val: ARRAY strLen + 1 OF CHAR; modified: BOOLEAN END; @@ -91,7 +93,7 @@ BEGIN K.DrawText866bk(x + K.fontWidth + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, textColor, color, s); IF modified THEN - K.DrawText866bk(x + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, textColor, color, "*") + K.DrawText866bk(x + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, modifColor, color, "*") END; K.CreateButton(id + ORD({30}) + btnID, x + 1, y - 1, width - 1, height - 1, 0, ""); left := x + width - btnCloseSize - 5; @@ -184,14 +186,30 @@ BEGIN END draw; +PROCEDURE setText (item: tItem; s: ARRAY OF CHAR); +VAR + i: INTEGER; +BEGIN + IF LENGTH(s) > strLen THEN + FOR i := 0 TO strLen - 4 DO + item.val[i] := s[i] + END; + item.val[strLen - 3] := 0X; + U.append8(item.val, "...") + ELSE + COPY(s, item.val) + END +END setText; + + PROCEDURE add* (t: tTabs; s: ARRAY OF CHAR); VAR - item: tItem; + item: tItem; BEGIN - NEW(item); - item.val := s; - item.modified := FALSE; - List.append(t.strings, item); + NEW(item); + setText(item, s); + item.modified := FALSE; + List.append(t.strings, item) END add; @@ -212,7 +230,7 @@ VAR item: List.tItem; BEGIN item := List.getItem(t.strings, n); - item(tItem).val := s + setText(item(tItem), s) END rename; diff --git a/programs/develop/cedit/SRC/Text.ob07 b/programs/develop/cedit/SRC/Text.ob07 index 26532b8aaa..845c4b9210 100644 --- a/programs/develop/cedit/SRC/Text.ob07 +++ b/programs/develop/cedit/SRC/Text.ob07 @@ -119,7 +119,7 @@ VAR BEGIN text.fileName := name; U.getFileName(name, ext, "."); - U.upcase(ext); + U.lowcase8(ext); setLang(text, Lang.getLang(ext)) END setName; @@ -352,20 +352,20 @@ VAR END PrintComment; - PROCEDURE cap (c: WCHAR): WCHAR; + PROCEDURE upper (c: WCHAR): WCHAR; BEGIN - IF U.cap(c) THEN END + IF U.upper(c) THEN END RETURN c - END cap; + END upper; PROCEDURE UL (c: WCHAR): BOOLEAN; - RETURN (cap(c) = "U") OR (cap(c) = "L") + RETURN (upper(c) = "U") OR (upper(c) = "L") END UL; PROCEDURE FL (c: WCHAR): BOOLEAN; - RETURN (cap(c) = "F") OR (cap(c) = "L") + RETURN (upper(c) = "F") OR (upper(c) = "L") END FL; @@ -384,7 +384,7 @@ VAR DEC(i); lexLen := getString(line, first, i - first + 1, s); IF ~cs THEN - U.upcase16(s) + U.lowcase(s) END; IF Lang.isKey(s, text.lang, 1) THEN color := colors.key1 @@ -451,16 +451,16 @@ BEGIN k := i; INC(i); c := Lines.getChar(line, i); - IF (cap(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN + IF (upper(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN INC(i); hex := TRUE END; - WHILE U.isHex(cap(Lines.getChar(line, i))) DO + WHILE U.isHex(upper(Lines.getChar(line, i))) DO INC(i) END; - IF (cap(Lines.getChar(line, i)) = "H") & ~hex THEN + IF (upper(Lines.getChar(line, i)) = "H") & ~hex THEN INC(i) END; @@ -508,11 +508,11 @@ BEGIN DEC(i); c := Lines.getChar(line, i) END; - IF (cap(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN + IF (upper(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN REPEAT INC(i); c := Lines.getChar(line, i) - UNTIL ~U.isHex(cap(c)); + UNTIL ~U.isHex(upper(c)); IF UL(c) THEN INC(i) END @@ -531,7 +531,7 @@ BEGIN INC(i) END; c := Lines.getChar(line, i); - IF cap(c) = "E" THEN + IF upper(c) = "E" THEN INC(i); c := Lines.getChar(line, i); IF (c = "+") OR (c = "-") THEN @@ -672,7 +672,7 @@ BEGIN cond := 0 ELSIF U.isDigit(c) THEN k := i; - IF (c = "0") & (cap(Lines.getChar(line, i + 1)) = "X") THEN + IF (c = "0") & (upper(Lines.getChar(line, i + 1)) = "X") THEN isDgt := U.isHex; hex := TRUE; INC(i, 2) @@ -680,7 +680,7 @@ BEGIN isDgt := U.isDigit; hex := FALSE END; - WHILE isDgt(cap(Lines.getChar(line, i))) DO + WHILE isDgt(upper(Lines.getChar(line, i))) DO INC(i) END; IF Lines.getChar(line, i) = "." THEN @@ -688,16 +688,16 @@ BEGIN IF Lines.getChar(line, i) = "." THEN DEC(i) END; - WHILE isDgt(cap(Lines.getChar(line, i))) DO + WHILE isDgt(upper(Lines.getChar(line, i))) DO INC(i) END END; - IF (cap(Lines.getChar(line, i)) = "E") OR hex & (cap(Lines.getChar(line, i)) = "P") THEN + IF (upper(Lines.getChar(line, i)) = "E") OR hex & (upper(Lines.getChar(line, i)) = "P") THEN INC(i); IF (Lines.getChar(line, i) = "-") OR (Lines.getChar(line, i) = "+") THEN INC(i) END; - WHILE isDgt(cap(Lines.getChar(line, i))) DO + WHILE isDgt(upper(Lines.getChar(line, i))) DO INC(i) END END; @@ -771,7 +771,7 @@ BEGIN END; k := i; INC(i); - WHILE U.isHex(cap(Lines.getChar(line, i))) DO + WHILE U.isHex(upper(Lines.getChar(line, i))) DO INC(i) END; DEC(i); @@ -790,7 +790,7 @@ BEGIN WHILE U.isDigit(Lines.getChar(line, i)) DO INC(i) END; - IF cap(Lines.getChar(line, i)) = "E" THEN + IF upper(Lines.getChar(line, i)) = "E" THEN INC(i); IF (Lines.getChar(line, i) = "-") OR (Lines.getChar(line, i) = "+") THEN INC(i) @@ -906,7 +906,7 @@ BEGIN text.cs := cs; text.searchText := s; IF ~cs THEN - U.upcase16(text.searchText) + U.lowcase(text.searchText) END; IF text.searchText # "" THEN plainText := plain(text); @@ -1787,9 +1787,9 @@ BEGIN END; IF upper THEN - func := U.cap + func := U.upper ELSE - func := U.low + func := U.lower END; IF Lines.convert(line, i + 1, text.cursor.X - 1, func) THEN @@ -1815,9 +1815,9 @@ BEGIN cnt := selEnd.Y - selBeg.Y; IF upper THEN - func := U.cap + func := U.upper ELSE - func := U.low + func := U.lower END; IF cnt = 0 THEN @@ -2293,13 +2293,13 @@ END setPadding; PROCEDURE draw* (text: tText); VAR - y, n, cnt, i, x: INTEGER; + y, n, cnt, i, x, pos: INTEGER; line, firstLine, lastLine: tLine; selBeg, selEnd: tPoint; s: ARRAY 12 OF WCHAR; backColor, numWidth, xNum, wNum: INTEGER; - p: Search.tPos; guard: tGuard; + p: Search.tPos; BEGIN IF text.comments THEN Comments(text) @@ -2413,23 +2413,26 @@ BEGIN ELSE lastLine := getLine2(text, MIN(text.scroll.Y + textsize.Y + 1, text.count) - 1) END; + + i := 0; p := text.foundList.first(Search.tPos); - WHILE p # NIL DO + pos := Search.next(p, i); + WHILE pos # -1 DO y := padding.top + inter DIV 2; IF text.smallMove THEN y := y + charHeight*(text.cursor.Y - text.scroll.Y) END; - IF (firstLine.pos <= p.pos) & (p.pos <= lastLine.pos + lastLine.length) THEN + IF (firstLine.pos <= pos) & (pos <= lastLine.pos + lastLine.length) THEN line := firstLine; - WHILE (line.pos <= p.pos) & (line # lastLine) DO + WHILE (line.pos <= pos) & (line # lastLine) DO NextLine(line); INC(y, charHeight) END; - IF (line # lastLine) & (line # firstLine) OR (line = lastLine) & (line.pos > p.pos) THEN + IF (line # lastLine) & (line # firstLine) OR (line = lastLine) & (line.pos > pos) THEN PrevLine(line); DEC(y, charHeight) END; - x := (p.pos - line.pos - text.scroll.X)*charWidth + padding.left; + x := (pos - line.pos - text.scroll.X)*charWidth + padding.left; n := LENGTH(text.searchText)*charWidth; WHILE n > 0 DO IF x >= padding.left THEN @@ -2439,7 +2442,7 @@ BEGIN DEC(n) END END; - p := p.next(Search.tPos) + pos := Search.next(p, i) END END; @@ -2609,40 +2612,41 @@ END open; PROCEDURE findNext* (text: tText; prev: BOOLEAN): BOOLEAN; VAR cursorPos, x, y, X, Y, Len: INTEGER; - p: Search.tPos; line: tLine; res: BOOLEAN; + pos, i, pos0: INTEGER; + p: Search.tPos; BEGIN X := text.cursor.X; Y := text.cursor.Y; text.cursor.X := MIN(text.cursor.X, text.curLine.length); cursorPos := text.curLine.pos + text.cursor.X - ORD(prev) - ORD(~prev & (text.foundSel = 0)); + pos0 := -1; + i := 0; p := text.foundList.first(Search.tPos); - WHILE (p # NIL) & (p.pos <= cursorPos) DO - p := p.next(Search.tPos) + pos := Search.next(p, i); + WHILE (pos # -1) & (pos <= cursorPos) DO + pos0 := pos; + pos := Search.next(p, i) END; IF prev THEN - IF p = NIL THEN - p := text.foundList.last(Search.tPos) - ELSE - p := p.prev(Search.tPos) - END + pos := pos0 END; - res := p # NIL; + res := pos # -1; IF res THEN y := 0; line := text.first(tLine); - WHILE (line.pos <= p.pos) & (line.next # NIL) DO + WHILE (line.pos <= pos) & (line.next # NIL) DO NextLine(line); INC(y) END; - IF (line.next # NIL) OR (line.pos > p.pos) THEN + IF (line.next # NIL) OR (line.pos > pos) THEN PrevLine(line); DEC(y) END; resetSelect(text); searchScroll(text, y); - x := p.pos - line.pos; + x := pos - line.pos; Len := LENGTH(text.searchText); IF x + Len > text.scroll.X + textsize.X THEN text.scroll.X := MAX(x + Len - textsize.X + 3, 0) @@ -2688,9 +2692,9 @@ END replace; PROCEDURE replaceAll* (text: tText; s: ARRAY OF WCHAR; n: INTEGER): INTEGER; VAR - p: Search.tPos; line: tLine; - y, k, d, pos, y0: INTEGER; + y, k, d, pos, y0, i, c: INTEGER; + p: Search.tPos; BEGIN resetSelect(text); SetPos(text, 0, 0); @@ -2699,9 +2703,11 @@ BEGIN y0 := -1; k := 0; d := LENGTH(s) - n; + c := 0; + i := 0; p := text.foundList.first(Search.tPos); - WHILE p # NIL DO - pos := p.pos; + pos := Search.next(p, i); + WHILE pos # -1 DO WHILE (line.pos <= pos) & (line.next # NIL) DO NextLine(line); INC(y) @@ -2719,9 +2725,10 @@ BEGIN SetPos(text, pos - line.pos + k, y); text.foundSel := n; replace(text, s, n); - p := p.next(Search.tPos) + INC(c); + pos := Search.next(p, i) END - RETURN text.foundList.count + RETURN c END replaceAll; diff --git a/programs/develop/cedit/SRC/Utils.ob07 b/programs/develop/cedit/SRC/Utils.ob07 index 0aad7a765c..dc260fb1ff 100644 --- a/programs/develop/cedit/SRC/Utils.ob07 +++ b/programs/develop/cedit/SRC/Utils.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2021, 2022 Anton Krotov + Copyright 2021-2023 Anton Krotov This file is part of CEdit. @@ -152,21 +152,22 @@ END isHex; PROCEDURE isLetter* (ch: WCHAR): BOOLEAN; - RETURN ("a" <= ch) & (ch <= "z") OR ("A" <= ch) & (ch <= "Z") + RETURN ("a" <= ch) & (ch <= "z") OR ("A" <= ch) & (ch <= "Z") OR + (* cyrillic *) + (430X <= ch) & (ch <= 44FX) OR (410X <= ch) & (ch <= 42FX) OR + (ch = 491X) OR (ch = 490X) OR (450X <= ch) & (ch <= 45FX) OR + (400X <= ch) & (ch <= 40FX) END isLetter; -PROCEDURE cap* (VAR ch: WCHAR): BOOLEAN; +PROCEDURE upper* (VAR ch: WCHAR): BOOLEAN; VAR res: BOOLEAN; BEGIN - IF ("a" <= ch) & (ch <= "z") THEN - ch := WCHR(ORD(ch) - (ORD("z") - ORD("Z"))); - res := TRUE - ELSIF (430H <= ORD(ch)) & (ORD(ch) <= 44FH) THEN + IF ("a" <= ch) & (ch <= "z") OR (430X <= ch) & (ch <= 44FX) THEN ch := WCHR(ORD(ch) - 20H); res := TRUE - ELSIF (450H <= ORD(ch)) & (ORD(ch) <= 45FH) THEN + ELSIF (450X <= ch) & (ch <= 45FX) THEN ch := WCHR(ORD(ch) - 50H); res := TRUE ELSIF ch = 491X THEN @@ -176,60 +177,17 @@ BEGIN res := FALSE END RETURN res -END cap; +END upper; -PROCEDURE cap8 (VAR ch: CHAR): BOOLEAN; +PROCEDURE lower* (VAR ch: WCHAR): BOOLEAN; VAR res: BOOLEAN; BEGIN - IF ("a" <= ch) & (ch <= "z") THEN - ch := CHR(ORD(ch) - (ORD("z") - ORD("Z"))); - res := TRUE - ELSE - res := FALSE - END - RETURN res -END cap8; - - -PROCEDURE upcase* (VAR s: ARRAY OF CHAR); -VAR - i: INTEGER; -BEGIN - i := LENGTH(s) - 1; - WHILE i >= 0 DO - IF cap8(s[i]) THEN - END; - DEC(i) - END -END upcase; - - -PROCEDURE upcase16* (VAR s: ARRAY OF WCHAR); -VAR - i: INTEGER; -BEGIN - i := LENGTH(s) - 1; - WHILE i >= 0 DO - IF cap(s[i]) THEN - END; - DEC(i) - END -END upcase16; - - -PROCEDURE low* (VAR ch: WCHAR): BOOLEAN; -VAR - res: BOOLEAN; -BEGIN - IF ("A" <= ch) & (ch <= "Z") THEN - ch := WCHR(ORD(ch) + (ORD("z") - ORD("Z"))); - res := TRUE - ELSIF (410H <= ORD(ch)) & (ORD(ch) <= 42FH) THEN + IF ("A" <= ch) & (ch <= "Z") OR (410X <= ch) & (ch <= 42FX) THEN ch := WCHR(ORD(ch) + 20H); res := TRUE - ELSIF (400H <= ORD(ch)) & (ORD(ch) <= 40FH) THEN + ELSIF (400X <= ch) & (ch <= 40FX) THEN ch := WCHR(ORD(ch) + 50H); res := TRUE ELSIF ch = 490X THEN @@ -239,21 +197,34 @@ BEGIN res := FALSE END RETURN res -END low; +END lower; -PROCEDURE lowcase* (VAR s: ARRAY OF CHAR); +PROCEDURE lowcase* (VAR s: ARRAY OF WCHAR); +VAR + i: INTEGER; +BEGIN + i := LENGTH(s) - 1; + WHILE i >= 0 DO + IF lower(s[i]) THEN + END; + DEC(i) + END +END lowcase; + + +PROCEDURE lowcase8* (VAR s: ARRAY OF CHAR); VAR i: INTEGER; BEGIN i := LENGTH(s) - 1; WHILE i >= 0 DO IF ("A" <= s[i]) & (s[i] <= "Z") THEN - s[i] := CHR(ORD(s[i]) + 32) + s[i] := CHR(ORD(s[i]) + 20H) END; DEC(i) END -END lowcase; +END lowcase8; PROCEDURE str2int* (s: ARRAY OF WCHAR; VAR val: INTEGER): BOOLEAN; @@ -336,19 +307,6 @@ BEGIN END lg10; -PROCEDURE sgn* (x: INTEGER): INTEGER; -BEGIN - IF x > 0 THEN - x := 1 - ELSIF x < 0 THEN - x := -1 - ELSE - x := 0 - END - RETURN x -END sgn; - - PROCEDURE between* (a, b, c: INTEGER): BOOLEAN; RETURN (a <= b) & (b <= c) END between;