diff --git a/setup_mingw.cmd b/setup_mingw.cmd index 6b313e47c..7fa0a08aa 100644 --- a/setup_mingw.cmd +++ b/setup_mingw.cmd @@ -1,10 +1,9 @@ -@rem QB64-PE MINGW setup script +@rem QB64-PE MinGW setup script @rem -@rem This NT command script downloads and extracts the latest copy of MINGW binaries from: -@rem https://github.com/niXman/mingw-builds-binaries/releases -@rem So, the filenames in 'URL' variable should be updated to the latest stable builds when those are available +@rem This NT command script downloads and extracts the latest copy of LLVM MinGW binaries from: +@rem https://github.com/mstorsjo/llvm-mingw/releases @rem -@rem Specifying 32 for argument 1 on a 64-bit system will force a 32-bit MINGW setup +@rem Specifying 32 for argument 1 on a 64-bit system will force a 32-bit MinGW setup @rem @echo off @@ -16,20 +15,17 @@ if errorlevel 1 ( goto end ) -rem Change to the correct drive letter -%~d0 - -rem Change to the correct path -cd %~dp0 +rem Change to the correct drive & path +cd /d %~dp0 rem Check if the C++ compiler is there and skip downloading if it exists if exist "internal\c\c_compiler\bin\c++.exe" ( echo. - echo Info: MINGW detected. Skipping setup. + echo Info: MinGW detected. Skipping setup. goto end ) -rem Create the c_compiler directory that should contain the MINGW binaries +rem Create the c_compiler directory that should contain the MinGW binaries mkdir internal\c\c_compiler rem Check if were able to create the directory @@ -64,7 +60,8 @@ if "%~1" == "32" set BITS=32 echo %ARCH%-%BITS% platform selected. rem Set some critical variables before we move to the actual setup part -rem MINGW_DIR is actually the internal directory name inside the zip / 7z file +rem The filenames in 'URL' variable should be updated to the latest stable builds when those are available +rem MINGW_DIR is actually the internal directory name inside the zip file rem It needs to be updated whenever the toolchains are updated if "%ARCH%" == "ARM" ( if %BITS% == 64 ( @@ -74,39 +71,27 @@ if "%ARCH%" == "ARM" ( set URL="https://github.com/mstorsjo/llvm-mingw/releases/download/20240619/llvm-mingw-20240619-ucrt-armv7.zip" set MINGW_DIR=llvm-mingw-20240619-ucrt-armv7 ) - set MINGW_TEMP_FILE=temp.zip ) else ( if %BITS% == 64 ( - set URL="https://github.com/niXman/mingw-builds-binaries/releases/download/13.2.0-rt_v11-rev0/x86_64-13.2.0-release-win32-seh-msvcrt-rt_v11-rev0.7z" - set MINGW_DIR=mingw64 + set URL="https://github.com/mstorsjo/llvm-mingw/releases/download/20240619/llvm-mingw-20240619-ucrt-x86_64.zip" + set MINGW_DIR=llvm-mingw-20240619-ucrt-x86_64 ) else ( - set URL="https://github.com/niXman/mingw-builds-binaries/releases/download/13.2.0-rt_v11-rev0/i686-13.2.0-release-win32-dwarf-msvcrt-rt_v11-rev0.7z" - set MINGW_DIR=mingw32 - ) - set MINGW_TEMP_FILE=temp.7z + set URL="https://github.com/mstorsjo/llvm-mingw/releases/download/20240619/llvm-mingw-20240619-msvcrt-i686.zip" + set MINGW_DIR=llvm-mingw-20240619-msvcrt-i686 + ) ) -rem Download MingW files +rem Download LLVM-MinGW package using curl. curl is available in Windows 10 and above since build 17063 +rem https://devblogs.microsoft.com/commandline/tar-and-curl-come-to-windows/ +set MINGW_TEMP_FILE=temp.zip if exist %MINGW_TEMP_FILE% del %MINGW_TEMP_FILE% echo Downloading %URL%... curl -L %URL% -o %MINGW_TEMP_FILE% -rem Extract MingW files -if "%ARCH%" == "ARM" ( - rem Use tar to extract the zip file on Windows on ARM. tar is available in Windows since build 17063 - rem And this includes all ARM64 Windows versions - echo Extracting C++ Compiler... - tar -xvf %MINGW_TEMP_FILE% -) else ( - rem Download 7zr.exe. We'll need this to extract the MINGW archive - echo Downloading 7zr.exe... - curl -L https://www.7-zip.org/a/7zr.exe -o 7zr.exe - - rem Extract the MINGW binaries - echo Extracting C++ Compiler... - 7zr.exe x %MINGW_TEMP_FILE% -y - del 7zr.exe -) +rem Extract LLVM-MinGW files using tar. tar is available in Windows 10 and above since build 17063 +rem https://devblogs.microsoft.com/commandline/tar-and-curl-come-to-windows/ +echo Extracting C++ Compiler... +tar -xvf %MINGW_TEMP_FILE% rem Move the binaries to internal\c\c_compiler\ echo Moving C++ compiler... diff --git a/source/qb64pe.bas b/source/qb64pe.bas index 13fb412e8..496e15bc0 100644 --- a/source/qb64pe.bas +++ b/source/qb64pe.bas @@ -12595,14 +12595,22 @@ IF os$ = "WIN" THEN IF n > 1 THEN a$ = "Unable to resolve multiple instances of sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes IF n = 0 THEN 'attempt to locate simple function name without brackets - s$ = " " + ResolveStaticFunction_Name(x) + s$ = ResolveStaticFunction_Name(x) fh = OpenBuffer%("I", nm_output_file$) + ConvBufToLnxMacEol fh DO UNTIL EndOfBuf%(fh) a$ = ReadBufLine$(fh) IF LEN(a$) THEN 'search for SPACE+functionname - x1 = INSTR(a$, s$) - IF RIGHT$(a$, LEN(s$)) = s$ THEN + ' clang's nm outputs LF line endings + IF OS_BITS = 32 THEN + ' On 32-bit Windows function names are decorated by a leading underscore + ' gcc's nm hides the leading underscore in the output, whereas clang's nm does not + x1 = (RIGHT$(a$, LEN(s$) + 1) = " " + s$) _ORELSE (RIGHT$(a$, LEN(s$) + 2) = " _" + s$) + ELSE + x1 = (RIGHT$(a$, LEN(s$) + 1) = " " + s$) + END IF + IF x1 THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 @@ -12649,14 +12657,22 @@ IF os$ = "WIN" THEN END IF IF n = 0 THEN 'a C dynamic object library? - s$ = " " + ResolveStaticFunction_Name(x) + s$ = ResolveStaticFunction_Name(x) fh = OpenBuffer%("I", nm_output_file_dynamic$) + ConvBufToLnxMacEol fh DO UNTIL EndOfBuf%(fh) a$ = ReadBufLine$(fh) IF LEN(a$) THEN 'search for SPACE+functionname - x1 = INSTR(a$, s$) - IF RIGHT$(a$, LEN(s$)) = s$ THEN + ' clang's nm outputs LF line endings + IF OS_BITS = 32 THEN + ' On 32-bit Windows function names are decorated by a leading underscore + ' gcc's nm hides the leading underscore in the output, whereas clang's nm does not + x1 = (RIGHT$(a$, LEN(s$) + 1) = " " + s$) _ORELSE (RIGHT$(a$, LEN(s$) + 2) = " _" + s$) + ELSE + x1 = (RIGHT$(a$, LEN(s$) + 1) = " " + s$) + END IF + IF x1 THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 diff --git a/source/utilities/s-buffer/readme.txt b/source/utilities/s-buffer/readme.txt index a62c55ee3..c5622e2bc 100644 --- a/source/utilities/s-buffer/readme.txt +++ b/source/utilities/s-buffer/readme.txt @@ -1,8 +1,7 @@ -This is a massively reduced version of "The Simplebuffer System" library -by RhoSigma. The full package with many more functions for bookmarking, -searching, copy'n'paste and EOL conversion, inclusive documentation and -examples is part of the author's "Libraries Collection" and can be found -for download at the respective forum thread here: +This is the full fledged version of "The Simplebuffer System" library +by RhoSigma. The documentation and examples are part of the author's +"Libraries Collection" and can be found for download at the respective +forum thread here: https://qb64phoenix.com/forum/forumdisplay.php?fid=23 Note: The sb_qb64_extension.bi/.bm files are not part of the buffer system. diff --git a/source/utilities/s-buffer/simplebuffer.bi b/source/utilities/s-buffer/simplebuffer.bi index 5d45a16e1..ad25b72f6 100644 --- a/source/utilities/s-buffer/simplebuffer.bi +++ b/source/utilities/s-buffer/simplebuffer.bi @@ -7,19 +7,34 @@ '| ## ## # | ._.' | '| ## ###### | Sources & Documents placed in the Public Domain. | '+---------------+---------------------------------------------------+ +'| | +'| === simplebuffer.bi === | +'| | +'| == Definitions required for the routines in simplebuffer.bm. | +'| | +'+-------------------------------------------------------------------+ +'| Done by RhoSigma, R.Heyder, provided AS IS, use at your own risk. | +'| Find me in the QB64 Forum or mail to support@rhosigma-cw.net for | +'| any questions or suggestions. Thanx for your interest in my work. | +'+-------------------------------------------------------------------+ '--- The internal array for data storage '----- 'never access this directly, use functions in simplebuffer.bm -REDIM SHARED simplebuffer_array$(0 TO 10599) 'init for 100 buffers +REDIM SHARED simplebuffer_array$(0 TO 10599) '--- Simplebuffer Errors (most FUNCTIONs) '----- 'initializer error returns CONST SBE_NoMoreBuffers = -1 +CONST SBE_NoMoreIDs = -2 +CONST SBE_EmptyFind = -3 'operational error returns CONST SBE_UnknownMode = -11 CONST SBE_OutOfBounds = -12 +CONST SBE_BadIDNumber = -13 +CONST SBE_UnusedID = -14 +CONST SBE_ClearedID = -15 '--- Simplebuffer Modes (SeekBuf) --- '----- @@ -28,6 +43,18 @@ CONST SBM_PosRestore = -21 CONST SBM_BufStart = -22 CONST SBM_BufCurrent = -23 CONST SBM_BufEnd = -24 +CONST SBM_LineStart = -25 +CONST SBM_LineEnd = -26 + +'--- Simplebuffer Flags (FindBufFwd/Rev) --- +'----- +'use for method% argument +CONST SBF_FullData = 0 +CONST SBF_Delimiter = 1 +CONST SBF_InvDelimiter = -1 +'use for treat% argument +CONST SBF_AsWritten = 0 +CONST SBF_IgnoreCase = -1 '$INCLUDE: 'sb_qb64pe_extension.bi' diff --git a/source/utilities/s-buffer/simplebuffer.bm b/source/utilities/s-buffer/simplebuffer.bm index a247560fd..62a40e733 100644 --- a/source/utilities/s-buffer/simplebuffer.bm +++ b/source/utilities/s-buffer/simplebuffer.bm @@ -7,11 +7,22 @@ '| ## ## # | ._.' | '| ## ###### | Sources & Documents placed in the Public Domain. | '+---------------+---------------------------------------------------+ +'| | +'| === simplebuffer.bm === | +'| | +'| == Simple string array based buffer system for your storage needs.| +'| | +'+-------------------------------------------------------------------+ +'| Done by RhoSigma, R.Heyder, provided AS IS, use at your own risk. | +'| Find me in the QB64 Forum or mail to support@rhosigma-cw.net for | +'| any questions or suggestions. Thanx for your interest in my work. | +'+-------------------------------------------------------------------+ +'--- docs\CreateBuf.html '--------------------------------------------------------------------- FUNCTION CreateBuf% '--- option _explicit requirements --- -DIM aub&, buf& +DIM aub&, buf&, idx% '--- find next free handle --- aub& = UBOUND(simplebuffer_array$) buf& = 0: CreateBuf% = SBE_NoMoreBuffers @@ -21,24 +32,47 @@ WHILE buf& < aub& IF buf& >= 3473090 THEN EXIT FUNCTION '=> allow max. 32765 buffers WEND '--- expand array, if necessary --- -IF aub& < buf& + 105 THEN REDIM _PRESERVE simplebuffer_array$(0 TO buf& + 10599) 'extend by 100 buffers +IF aub& < buf& + 105 THEN REDIM _PRESERVE simplebuffer_array$(0 TO buf& + 10599) '=> add 100 more buffers '--- init buffer --- simplebuffer_array$(buf& + 0) = SPACE$(16384) ' => the actual buffer (will grow as needed) simplebuffer_array$(buf& + 1) = MKL$(1) + MKL$(0) + "EolU" + MKL$(-1) '=> cursor position + buffer length + EOL mode + change state +simplebuffer_array$(buf& + 2) = "BM|" + SPACE$(404) ' => space for 100 +1 bookmarks +simplebuffer_array$(buf& + 3) = "FP|" + SPACE$(404) ' => space for 100 +1 found at positions +simplebuffer_array$(buf& + 4) = "FL|" + SPACE$(404) ' => space for 100 +1 find data lenghts +FOR idx% = 1 TO 101 + MID$(simplebuffer_array$(buf& + 2), idx% * 4, 4) = MKL$(&HCAFEBABE) + MID$(simplebuffer_array$(buf& + 3), idx% * 4, 4) = MKL$(&HCAFEBABE) + MID$(simplebuffer_array$(buf& + 4), idx% * 4, 4) = MKL$(&HCAFEBABE) + simplebuffer_array$(buf& + idx% + 4) = "" ' => space for 100 +1 find data copies (5-104/105) +NEXT idx% ' => note the +1/105 is reserved for internal use '--- return new handle --- CreateBuf% = buf& \ 106 END FUNCTION +'--- docs\DisposeBuf.html '--------------------------------------------------------------------- SUB DisposeBuf (handle%) '--- option _explicit requirements --- -DIM buf& -'--- erase buffer data --- +DIM buf&, idx%, aub&, oub& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 -simplebuffer_array$(buf& + 0) = "" -simplebuffer_array$(buf& + 1) = "" +'--- erase buffer data --- +FOR idx% = 0 TO 105 + simplebuffer_array$(buf& + idx%) = "" +NEXT idx% +'--- shrink array, if worth 10+ buffers --- +aub& = UBOUND(simplebuffer_array$): oub& = aub& +buf& = aub& - 105 +WHILE buf& >= 1060 + IF simplebuffer_array$(buf& + 1) <> "" THEN EXIT WHILE + buf& = buf& - 106 +WEND +WHILE aub& - 1059 > buf& + 105: aub& = aub& - 1060: WEND +IF aub& < oub& THEN REDIM _PRESERVE simplebuffer_array$(0 TO aub&) END SUB +'--- docs\FileToBuf.html '--------------------------------------------------------------------- FUNCTION FileToBuf% (fileSpec$) '--- option _explicit requirements --- @@ -51,28 +85,38 @@ IF han% >= 0 THEN ff% = FREEFILE OPEN fileSpec$ FOR BINARY LOCK WRITE AS ff% fl&& = LOF(ff%): ext& = fl&& MOD 16384 - '--- load file into buffer & adjust length --- - simplebuffer_array$(buf& + 0) = SPACE$(fl&&) - GET ff%, , simplebuffer_array$(buf& + 0) - IF ext& > 0 THEN - simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(16384 - ext&) + '--- check file length --- + IF fl&& > &H40000000&& THEN + ERROR 7 'buffer overflow (file too big, >1GiB) + 'If the program is continued from here regardless of the error, + 'then the returned buffer will be empty, but ready to use. + ELSE + '--- load file into buffer & adjust length --- + simplebuffer_array$(buf& + 0) = SPACE$(fl&&) + GET ff%, , simplebuffer_array$(buf& + 0) + IF ext& > 0 THEN + simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(16384 - ext&) + END IF + '--- set cursor, buffer length & change state --- + MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(1) + MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(fl&&) + MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(0) END IF - '--- set cursor, buffer length & change state --- - MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(1) - MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(fl&&) - MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(0) CLOSE ff% END IF '--- return new handle --- FileToBuf% = han% END FUNCTION +'--- docs\BufToFile.html '--------------------------------------------------------------------- SUB BufToFile (handle%, fileSpec$) '--- option _explicit requirements --- DIM buf&, ff%, dat$ -'--- write file (overwrite existing !!!) --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- write file (overwrite existing !!!) --- ff% = FREEFILE: dat$ = LEFT$(simplebuffer_array$(buf& + 0), GetBufLen&(handle%)) OPEN fileSpec$ FOR OUTPUT LOCK WRITE AS ff%: CLOSE ff% OPEN fileSpec$ FOR BINARY LOCK WRITE AS ff% @@ -82,12 +126,65 @@ CLOSE ff% MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(0) END SUB +'--- docs\CloneBuf.html +'--------------------------------------------------------------------- +FUNCTION CloneBuf% (handle%) +'--- option _explicit requirements --- +DIM buf&, dhan%, dbuf&, idx% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- create a new buffer --- +dhan% = CreateBuf% +dbuf& = dhan% * 106 +'--- on success, copy buffer values --- +IF dhan% >= 0 THEN + FOR idx% = 0 TO 105 + simplebuffer_array$(dbuf& + idx%) = simplebuffer_array$(buf& + idx%) + NEXT idx% +END IF +'--- return new handle --- +CloneBuf% = dhan% +END FUNCTION + +'--- docs\BufInsertFile.html +'--------------------------------------------------------------------- +SUB BufInsertFile (handle%, fileSpec$) +'--- option _explicit requirements --- +DIM than% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +'--- load file into a temp buffer --- +than% = FileToBuf%(fileSpec$) +'--- on success, insert into buffer --- +IF than% >= 0 THEN + BufInsertBuf handle%, than% + DisposeBuf than% +END IF +END SUB + +'--- docs\BufInsertBuf.html +'--------------------------------------------------------------------- +SUB BufInsertBuf (handle%, fromHandle%) +'--- option _explicit requirements --- +DIM fbuf& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +IF NOT CheckHandle%(fromHandle%) THEN ERROR 258: STOP 'invalid fromHandle +fbuf& = fromHandle% * 106 +'--- insert data of another buffer --- +WriteBufRawData handle%, LEFT$(simplebuffer_array$(fbuf& + 0), GetBufLen&(fromHandle%)) +END SUB + +'--- docs\ReadBufLine.html '--------------------------------------------------------------------- FUNCTION ReadBufLine$ (handle%) '--- option _explicit requirements --- DIM buf&, cur&, cbl&&, brc$, brl%, eol& -'--- prepare values --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): cbl&& = GetBufLen&(handle%) brc$ = BufEolSeq$(handle%): brl% = LEN(brc$) '--- find next line break --- @@ -98,34 +195,56 @@ ReadBufLine$ = MID$(simplebuffer_array$(buf& + 0), cur&, eol& - cur&) MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(eol& + brl%) END FUNCTION +'--- docs\WriteBufLine.html '--------------------------------------------------------------------- SUB WriteBufLine (handle%, text$) '--- option _explicit requirements --- DIM buf&, cur&, txl&, brc$, brl%, cbl&&, chg&, bsz&, ext& -'--- prepare values --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): txl& = LEN(text$) brc$ = BufEolSeq$(handle%): brl% = LEN(brc$) cbl&& = GetBufLen&(handle%): chg& = txl& + brl% -'--- adjust buffer length --- -bsz& = LEN(simplebuffer_array$(buf& + 0)): ext& = 0 -WHILE cbl&& + chg& > bsz& + ext&: ext& = ext& + 16384: WEND -IF ext& > 0 THEN - simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(ext&) +'--- check buffer length --- +IF cbl&& + chg& > &H40000000&& THEN + ERROR 7 'buffer overflow (text$ too long) + 'If the program is continued from here regardless of the error, + 'then the given text was not written into the buffer. +ELSE + '--- adjust buffer length --- + bsz& = LEN(simplebuffer_array$(buf& + 0)): ext& = 0 + WHILE cbl&& + chg& > bsz& + ext&: ext& = ext& + 16384: WEND + IF ext& > 0 THEN + simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(ext&) + END IF + '--- write into buffer --- + MID$(simplebuffer_array$(buf& + 0), cur&) = text$ + brc$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1) + MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + chg&) + MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + chg&) + IF txl& > 0 THEN + IF (INSTR(text$, CHR$(10)) > 0) OR (INSTR(text$, CHR$(13)) > 0) THEN + 'this buffer write could compromise the defined EOL mode + MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolU" 'reset to unknown + END IF + END IF + MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) + '--- adjust bookmarks & find positions --- + RecalcMarks handle%, cur&, chg& + RecalcFinds handle%, cur&, chg& END IF -'--- write into buffer --- -MID$(simplebuffer_array$(buf& + 0), cur&) = text$ + brc$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1) -MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + chg&) -MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + chg&) -MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) END SUB +'--- docs\DeleteBufLine.html '--------------------------------------------------------------------- SUB DeleteBufLine (handle%) '--- option _explicit requirements --- -DIM buf&, cur&, cbl&&, brc$, brl%, eol&, chg& -'--- prepare values --- +DIM buf&, cur&, cbl&&, brc$, brl%, eol&, chg&, ext&, fsz& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): cbl&& = GetBufLen&(handle%) brc$ = BufEolSeq$(handle%): brl% = LEN(brc$) '--- find next line break --- @@ -135,15 +254,29 @@ chg& = (eol& + brl%) - cur& '--- delete from buffer --- MID$(simplebuffer_array$(buf& + 0), cur&) = MID$(simplebuffer_array$(buf& + 0), eol& + brl%, cbl&& - (eol& + brl%) + 1) MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& - chg&) -IF chg& > 0 THEN MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) +IF chg& > 0 THEN + MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) + '--- shrink buffer, if worth 1/4th+ --- + ext& = (((cbl&& - chg& + 1) + 16383) AND -16384) '+1 = avoid zero case + fsz& = LEN(simplebuffer_array$(buf& + 0)) - ext& + IF fsz& >= LEN(simplebuffer_array$(buf& + 0)) \ 4 THEN + simplebuffer_array$(buf& + 0) = LEFT$(simplebuffer_array$(buf& + 0), ext&) + END IF +END IF +'--- adjust bookmarks & find positions --- +RecalcMarks handle%, cur&, -chg& +RecalcFinds handle%, cur&, -chg& END SUB +'--- docs\ReadBufRawData.html '--------------------------------------------------------------------- FUNCTION ReadBufRawData$ (handle%, size&) 'size change intended '--- option _explicit requirements --- DIM buf&, cur&, eob& -'--- prepare values --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1 IF size& > eob& - cur& THEN size& = eob& - cur& '--- read from buffer --- @@ -151,35 +284,414 @@ ReadBufRawData$ = MID$(simplebuffer_array$(buf& + 0), cur&, size&) MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + size&) END FUNCTION +'--- docs\WriteBufRawData.html '--------------------------------------------------------------------- SUB WriteBufRawData (handle%, rawData$) '--- option _explicit requirements --- DIM buf&, cur&, rdl&, cbl&&, bsz&, ext& -'--- prepare values --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): rdl& = LEN(rawData$) cbl&& = GetBufLen&(handle%) -'--- adjust buffer length --- -bsz& = LEN(simplebuffer_array$(buf& + 0)): ext& = 0 -WHILE cbl&& + rdl& > bsz& + ext&: ext& = ext& + 16384: WEND -IF ext& > 0 THEN - simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(ext&) +'--- check buffer length --- +IF cbl&& + rdl& > &H40000000&& THEN + ERROR 7 'buffer overflow (rawData$ too long) + 'If the program is continued from here regardless of the error, + 'then the given raw data were not written into the buffer. +ELSE + '--- adjust buffer length --- + bsz& = LEN(simplebuffer_array$(buf& + 0)): ext& = 0 + WHILE cbl&& + rdl& > bsz& + ext&: ext& = ext& + 16384: WEND + IF ext& > 0 THEN + simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(ext&) + END IF + '--- write into buffer --- + MID$(simplebuffer_array$(buf& + 0), cur&) = rawData$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1) + MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + rdl&) + MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + rdl&) + IF rdl& > 0 THEN + IF (INSTR(rawData$, CHR$(10)) > 0) OR (INSTR(rawData$, CHR$(13)) > 0) THEN + 'this buffer write could compromise the defined EOL mode + MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolU" 'reset to unknown + END IF + MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) + END IF + '--- adjust bookmarks & find positions --- + RecalcMarks handle%, cur&, rdl& + RecalcFinds handle%, cur&, rdl& END IF -'--- write into buffer --- -MID$(simplebuffer_array$(buf& + 0), cur&) = rawData$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1) -MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + rdl&) -MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + rdl&) -IF rdl& > 0 THEN +END SUB + +'--- docs\DeleteBufRawData.html +'--------------------------------------------------------------------- +SUB DeleteBufRawData (handle%, size&) 'size change intended +'--- option _explicit requirements --- +DIM buf&, cur&, cbl&&, eob&, ext&, fsz& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- prepare values --- +cur& = GetBufPos&(handle%) +cbl&& = GetBufLen&(handle%): eob& = cbl&& + 1 +IF size& > eob& - cur& THEN size& = eob& - cur& +'--- delete from buffer --- +MID$(simplebuffer_array$(buf& + 0), cur&) = MID$(simplebuffer_array$(buf& + 0), cur& + size&, cbl&& - (cur& + size&) + 1) +MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& - size&) +IF size& > 0 THEN MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1) + '--- shrink buffer, if worth 1/4th+ --- + ext& = (((cbl&& - size& + 1) + 16383) AND -16384) '+1 = avoid zero case + fsz& = LEN(simplebuffer_array$(buf& + 0)) - ext& + IF fsz& >= LEN(simplebuffer_array$(buf& + 0)) \ 4 THEN + simplebuffer_array$(buf& + 0) = LEFT$(simplebuffer_array$(buf& + 0), ext&) + END IF +END IF +'--- adjust bookmarks & find positions --- +RecalcMarks handle%, cur&, -size& +RecalcFinds handle%, cur&, -size& +END SUB + +'--- docs\GetBufMemData.html +'--------------------------------------------------------------------- +SUB GetBufMemData (handle%, memData AS _MEM) +'--- option _explicit requirements --- +DIM size&&, temp&, datStr$ +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +'--- get memory data size --- +DIM sizeRef AS _MEM +sizeRef = _MEM(memData.SIZE) +IF INSTR(_OS$, "[64BIT]") > 0 THEN + _MEMGET sizeRef, sizeRef.OFFSET, size&& +ELSE + _MEMGET sizeRef, sizeRef.OFFSET, temp& + size&& = temp& +END IF +_MEMFREE sizeRef +'--- read amount of data from buffer --- +datStr$ = ReadBufRawData$(handle%, size&&) +'--- then copy into the memory block --- +_MEMPUT memData, memData.OFFSET, datStr$ +END SUB + +'--- docs\PutBufMemData.html +'--------------------------------------------------------------------- +SUB PutBufMemData (handle%, memData AS _MEM) +'--- option _explicit requirements --- +DIM size&&, temp&, datStr$ +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +'--- get memory data size --- +DIM sizeRef AS _MEM +sizeRef = _MEM(memData.SIZE) +IF INSTR(_OS$, "[64BIT]") > 0 THEN + _MEMGET sizeRef, sizeRef.OFFSET, size&& +ELSE + _MEMGET sizeRef, sizeRef.OFFSET, temp& + size&& = temp& END IF +_MEMFREE sizeRef +'--- read out the memory block --- +datStr$ = SPACE$(size&&) +_MEMGET memData, memData.OFFSET, datStr$ +'--- then write it into the buffer --- +WriteBufRawData handle%, datStr$ END SUB +'--- docs\SetBufMark.html +'--------------------------------------------------------------------- +FUNCTION SetBufMark% (handle%) +'--- option _explicit requirements --- +DIM buf&, fid% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- get new ID, set bookmark on success --- +fid% = FreeID%(handle%, 2) +IF fid% > 0 THEN MID$(simplebuffer_array$(buf& + 2), fid% * 4, 4) = MID$(simplebuffer_array$(buf& + 1), 1, 4) +'--- return ID --- +SetBufMark% = fid% +END FUNCTION + +'--- docs\RemoveBufMark.html +'--------------------------------------------------------------------- +FUNCTION RemoveBufMark% (handle%, markID%) +'--- option _explicit requirements --- +DIM buf& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check ID range --- +RemoveBufMark% = SBE_BadIDNumber +IF (markID% < 1 OR markID% > 100) AND (LEN(simplebuffer_array$(buf& + 1)) = 16) THEN EXIT FUNCTION +'--- remove (unset) bookmark --- +MID$(simplebuffer_array$(buf& + 2), markID% * 4, 4) = MKL$(&HCAFEBABE) +RemoveBufMark% = 0 +END FUNCTION + +'--- docs\GetBufMark.html +'--------------------------------------------------------------------- +FUNCTION GetBufMark& (handle%, markID%) +'--- option _explicit requirements --- +DIM buf&, markPos& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check ID range --- +GetBufMark& = SBE_BadIDNumber +IF (markID% < 1 OR markID% > 100) AND (LEN(simplebuffer_array$(buf& + 1)) = 16) THEN EXIT FUNCTION +'--- return bookmark position, if set --- +markPos& = CVL(MID$(simplebuffer_array$(buf& + 2), markID% * 4, 4)) +SELECT CASE markPos& + CASE &HCAFEBABE: GetBufMark& = SBE_UnusedID + CASE &HDEADBEEF: GetBufMark& = SBE_ClearedID + CASE ELSE: GetBufMark& = markPos& +END SELECT +END FUNCTION + +'--- docs\GotoBufMark.html +'--------------------------------------------------------------------- +FUNCTION GotoBufMark% (handle%, markID%) +'--- option _explicit requirements --- +DIM buf&, markPos& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- goto bookmark, if valid --- +markPos& = GetBufMark&(handle%, markID%) +IF markPos& > 0 THEN + MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(markPos&) + GotoBufMark% = 0 +ELSE + GotoBufMark% = markPos& +END IF +END FUNCTION + +'--- docs\SetBufFind.html +'--------------------------------------------------------------------- +FUNCTION SetBufFind% (handle%, find$) +'--- option _explicit requirements --- +DIM buf&, fid% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check search criteria --- +SetBufFind% = SBE_EmptyFind: IF find$ = "" THEN EXIT FUNCTION +'--- get new ID, set find data on success --- +fid% = FreeID%(handle%, 4) +IF fid% > 0 THEN + MID$(simplebuffer_array$(buf& + 4), fid% * 4, 4) = MKL$(LEN(find$)) + simplebuffer_array$(buf& + fid% + 4) = find$ +END IF +'--- return ID --- +SetBufFind% = fid% +END FUNCTION + +'--- docs\RemoveBufFind.html +'--------------------------------------------------------------------- +FUNCTION RemoveBufFind% (handle%, sbFindID%) +'--- option _explicit requirements --- +DIM buf& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check ID range --- +RemoveBufFind% = SBE_BadIDNumber +IF (sbFindID% < 1 OR sbFindID% > 100) AND (LEN(simplebuffer_array$(buf& + 1)) = 16) THEN EXIT FUNCTION +'--- remove find data --- +MID$(simplebuffer_array$(buf& + 3), sbFindID% * 4, 4) = MKL$(&HCAFEBABE) +MID$(simplebuffer_array$(buf& + 4), sbFindID% * 4, 4) = MKL$(&HCAFEBABE) +simplebuffer_array$(buf& + sbFindID% + 4) = "" +RemoveBufFind% = 0 +END FUNCTION + +'--- docs\FindBufFR.html +'--------------------------------------------------------------------- +FUNCTION FindBufFwd& (handle%, sbFindID%, method%, treat%) +'--- option _explicit requirements --- +DIM buf&, cPos&, eob&, fPos&, fLen&, find$, ch&, bPos&, chv% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check ID range --- +FindBufFwd& = SBE_BadIDNumber +IF (sbFindID% < 1 OR sbFindID% > 100) AND (LEN(simplebuffer_array$(buf& + 1)) = 16) THEN EXIT FUNCTION +'--- prepare & check values --- +cPos& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1 +fPos& = CVL(MID$(simplebuffer_array$(buf& + 3), sbFindID% * 4, 4)) +fLen& = CVL(MID$(simplebuffer_array$(buf& + 4), sbFindID% * 4, 4)) +IF fPos& > 0 AND fPos& < eob& AND cPos& = fPos& THEN cPos& = cPos& + 1 +FindBufFwd& = SBE_UnusedID: IF fLen& = &HCAFEBABE THEN EXIT FUNCTION +'--- perform forward search --- +IF treat% = 0 THEN + find$ = simplebuffer_array$(buf& + sbFindID% + 4) + WHILE cPos& < eob& + SELECT CASE method% + CASE IS < 0: IF INSTR(find$, CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&))) = 0 THEN EXIT WHILE + CASE IS > 0: IF INSTR(find$, CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&))) > 0 THEN EXIT WHILE + CASE ELSE + FOR ch& = 1 TO fLen& + bPos& = cPos& + ch& - 1: IF bPos& >= eob& THEN EXIT FOR + IF ASC(simplebuffer_array$(buf& + 0), bPos&) <> ASC(find$, ch&) THEN EXIT FOR + NEXT ch& + IF ch& > fLen& THEN EXIT WHILE + END SELECT + cPos& = cPos& + 1 + WEND +ELSE + find$ = UCASE$(simplebuffer_array$(buf& + sbFindID% + 4)) + WHILE cPos& < eob& + SELECT CASE method% + CASE IS < 0: IF INSTR(find$, UCASE$(CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&)))) = 0 THEN EXIT WHILE + CASE IS > 0: IF INSTR(find$, UCASE$(CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&)))) > 0 THEN EXIT WHILE + CASE ELSE + FOR ch& = 1 TO fLen& + bPos& = cPos& + ch& - 1: IF bPos& >= eob& THEN EXIT FOR + chv% = ASC(simplebuffer_array$(buf& + 0), bPos&) + IF chv% >= 97 AND chv% <= 122 THEN chv% = chv% - 32 + IF chv% <> ASC(find$, ch&) THEN EXIT FOR + NEXT ch& + IF ch& > fLen& THEN EXIT WHILE + END SELECT + cPos& = cPos& + 1 + WEND +END IF +'--- set & return result --- +IF cPos& < eob& THEN MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cPos&): ELSE cPos& = 0 +MID$(simplebuffer_array$(buf& + 3), sbFindID% * 4, 4) = MKL$(cPos&) +FindBufFwd& = cPos& +END FUNCTION + +'--- docs\FindBufFR.html +'--------------------------------------------------------------------- +FUNCTION FindBufRev& (handle%, sbFindID%, method%, treat%) +'--- option _explicit requirements --- +DIM buf&, cPos&, eob&, fPos&, fLen&, find$, ch&, bPos&, chv% +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check ID range --- +FindBufRev& = SBE_BadIDNumber +IF (sbFindID% < 1 OR sbFindID% > 100) AND (LEN(simplebuffer_array$(buf& + 1)) = 16) THEN EXIT FUNCTION +'--- prepare & check values --- +cPos& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1 +fPos& = CVL(MID$(simplebuffer_array$(buf& + 3), sbFindID% * 4, 4)) +fLen& = CVL(MID$(simplebuffer_array$(buf& + 4), sbFindID% * 4, 4)) +IF fPos& > 0 AND fPos& < eob& AND cPos& = fPos& THEN cPos& = cPos& - 1 +FindBufRev& = SBE_UnusedID: IF fLen& = &HCAFEBABE THEN EXIT FUNCTION +'--- perform reverse search --- +IF treat% = 0 THEN + find$ = simplebuffer_array$(buf& + sbFindID% + 4) + WHILE cPos& > 0 + SELECT CASE method% + CASE IS < 0: IF INSTR(find$, CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&))) = 0 THEN EXIT WHILE + CASE IS > 0: IF INSTR(find$, CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&))) > 0 THEN EXIT WHILE + CASE ELSE + FOR ch& = 1 TO fLen& + bPos& = cPos& + ch& - 1: IF bPos& >= eob& THEN EXIT FOR + IF ASC(simplebuffer_array$(buf& + 0), bPos&) <> ASC(find$, ch&) THEN EXIT FOR + NEXT ch& + IF ch& > fLen& THEN EXIT WHILE + END SELECT + cPos& = cPos& - 1 + WEND +ELSE + find$ = UCASE$(simplebuffer_array$(buf& + sbFindID% + 4)) + WHILE cPos& > 0 + SELECT CASE method% + CASE IS < 0: IF INSTR(find$, UCASE$(CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&)))) = 0 THEN EXIT WHILE + CASE IS > 0: IF INSTR(find$, UCASE$(CHR$(ASC(simplebuffer_array$(buf& + 0), cPos&)))) > 0 THEN EXIT WHILE + CASE ELSE + FOR ch& = 1 TO fLen& + bPos& = cPos& + ch& - 1: IF bPos& >= eob& THEN EXIT FOR + chv% = ASC(simplebuffer_array$(buf& + 0), bPos&) + IF chv% >= 97 AND chv% <= 122 THEN chv% = chv% - 32 + IF chv% <> ASC(find$, ch&) THEN EXIT FOR + NEXT ch& + IF ch& > fLen& THEN EXIT WHILE + END SELECT + cPos& = cPos& - 1 + WEND +END IF +'--- set & return result --- +IF cPos& > 0 THEN MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cPos&) +MID$(simplebuffer_array$(buf& + 3), sbFindID% * 4, 4) = MKL$(cPos&) +FindBufRev& = cPos& +END FUNCTION + +'--- docs\CopyBufBlock.html +'--------------------------------------------------------------------- +FUNCTION CopyBufBlock% (handle%, bound&) +'--- option _explicit requirements --- +DIM buf&, sPo&, ePo& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- get & check positions --- +CopyBufBlock% = SBE_OutOfBounds +IF bound& < 1 OR bound& > GetBufLen&(handle%) + 1 THEN EXIT FUNCTION +sPo& = bound&: ePo& = GetBufPos&(handle%) +IF ePo& < sPo& THEN SWAP sPo&, ePo& +'--- copy block to clip --- +_CLIPBOARD$ = MID$(simplebuffer_array$(buf& + 0), sPo&, ePo& - sPo&) +CopyBufBlock% = 0 +END FUNCTION + +'--- docs\CutBufBlock.html +'--------------------------------------------------------------------- +FUNCTION CutBufBlock% (handle%, bound&) +'--- option _explicit requirements --- +DIM buf&, sPo&, ePo&, old& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- get & check positions --- +CutBufBlock% = SBE_OutOfBounds +IF bound& < 1 OR bound& > GetBufLen&(handle%) + 1 THEN EXIT FUNCTION +sPo& = bound&: ePo& = GetBufPos&(handle%) +IF ePo& < sPo& THEN SWAP sPo&, ePo& +'--- copy block to clip --- +_CLIPBOARD$ = MID$(simplebuffer_array$(buf& + 0), sPo&, ePo& - sPo&) +'--- then delete block --- +old& = SeekBuf&(handle%, sPo&, SBM_PosRestore) +DeleteBufRawData handle%, ePo& - sPo& +CutBufBlock% = 0 +END FUNCTION + +'--- docs\PasteBufBlock.html +'--------------------------------------------------------------------- +FUNCTION PasteBufBlock% (handle%, bound&) +'--- option _explicit requirements --- +DIM sPo&, ePo&, old& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +'--- replace check --- +IF bound& <> 0 THEN + '--- get & check positions --- + PasteBufBlock% = SBE_OutOfBounds + IF bound& < 1 OR bound& > GetBufLen&(handle%) + 1 THEN EXIT FUNCTION + sPo& = bound&: ePo& = GetBufPos&(handle%) + IF ePo& < sPo& THEN SWAP sPo&, ePo& + '--- delete old block --- + old& = SeekBuf&(handle%, sPo&, SBM_PosRestore) + DeleteBufRawData handle%, ePo& - sPo& +END IF +'--- finally paste block from clip --- +WriteBufRawData handle%, _CLIPBOARD$ +PasteBufBlock% = 0 +END FUNCTION + +'--- docs\SeekBuf.html '--------------------------------------------------------------------- FUNCTION SeekBuf& (handle%, displace&, mode%) '--- option _explicit requirements --- DIM buf&, cur&, eob&, brc$, brl%, origin&, newPos& -'--- prepare values --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- prepare values --- cur& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1 brc$ = BufEolSeq$(handle%): brl% = LEN(brc$) '--- select origin --- @@ -188,6 +700,32 @@ SELECT CASE mode% CASE SBM_BufStart: origin& = 1 CASE SBM_BufCurrent: origin& = cur& CASE SBM_BufEnd: origin& = eob& + CASE SBM_LineStart + origin& = cur& + IF cur& > 1 AND cur& < eob& THEN + IF brl% = 2 AND ASC(simplebuffer_array$(buf& + 0), cur& - 1) = 13 AND ASC(simplebuffer_array$(buf& + 0), cur&) = 10 THEN + origin& = cur& - 1 + END IF + END IF + WHILE origin& > 1 + IF MID$(simplebuffer_array$(buf& + 0), origin& - 1, brl%) = brc$ THEN + IF brl% = 2 THEN origin& = origin& + 1 + EXIT WHILE + END IF + origin& = origin& - 1 + WEND + CASE SBM_LineEnd + origin& = cur& + IF cur& > 1 AND cur& < eob& THEN + IF brl% = 2 AND ASC(simplebuffer_array$(buf& + 0), cur& - 1) = 13 AND ASC(simplebuffer_array$(buf& + 0), cur&) = 10 THEN + origin& = cur& - 1 + END IF + END IF + origin& = INSTR(origin&, simplebuffer_array$(buf& + 0), brc$) + IF origin& = 0 THEN origin& = eob& + CASE IS > 0 'bookmarks mode + origin& = GetBufMark&(handle%, mode%) + IF origin& < 0 THEN SeekBuf& = origin&: EXIT FUNCTION CASE ELSE SeekBuf& = SBE_UnknownMode EXIT FUNCTION @@ -202,45 +740,60 @@ ELSE END IF END FUNCTION +'--- docs\GetBufPos.html '--------------------------------------------------------------------- FUNCTION GetBufPos& (handle%) '--- option _explicit requirements --- DIM buf& -'--- return cursor position in buffer --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- return cursor position in buffer --- GetBufPos& = CVL(MID$(simplebuffer_array$(buf& + 1), 1, 4)) END FUNCTION +'--- docs\GetBufLen.html '--------------------------------------------------------------------- FUNCTION GetBufLen& (handle%) '--- option _explicit requirements --- DIM buf& -'--- return actual buffer length --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- return actual buffer length --- GetBufLen& = CVL(MID$(simplebuffer_array$(buf& + 1), 5, 4)) END FUNCTION +'--- docs\EndOfBuf.html '--------------------------------------------------------------------- FUNCTION EndOfBuf% (handle%) +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle '--- return EndOfBuffer condition --- EndOfBuf% = (GetBufPos&(handle%) > GetBufLen&(handle%)) END FUNCTION +'--- docs\IsBufChanged.html '--------------------------------------------------------------------- FUNCTION IsBufChanged% (handle%) '--- option _explicit requirements --- DIM buf& -'--- return BufChanged condition --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- return BufChanged condition --- IsBufChanged% = CVL(MID$(simplebuffer_array$(buf& + 1), 13, 4)) END FUNCTION +'--- docs\BufEolSeq.html '--------------------------------------------------------------------- FUNCTION BufEolSeq$ (handle%) '--- option _explicit requirements --- DIM buf& -'--- return buffer specific EndOfLine sequence --- +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle buf& = handle% * 106 +'--- return buffer specific EndOfLine sequence --- SELECT CASE MID$(simplebuffer_array$(buf& + 1), 9, 4) CASE "EolU", "EolN" 'unknown (maybe mixed) or OS-native EOL mode BufEolSeq$ = CHR$(13) + CHR$(10) 'default is Windows @@ -252,5 +805,188 @@ SELECT CASE MID$(simplebuffer_array$(buf& + 1), 9, 4) END SELECT END FUNCTION +'--- docs\ConvBufToAnyEol.html +'--------------------------------------------------------------------- +SUB ConvBufToNativeEol (handle%) +'--- option _explicit requirements --- +DIM buf& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- convert buffer to OS native EndOfLine sequence --- +IF INSTR(_OS$, "[LINUX]") > 0 THEN 'true for MacOSX too + ConvBufToLnxMacEol handle% +ELSE + ConvBufToWinEol handle% +END IF +MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolN" +END SUB + +'--- docs\ConvBufToAnyEol.html +'--------------------------------------------------------------------- +SUB ConvBufToLnxMacEol (handle%) +'--- option _explicit requirements --- +DIM buf&, res&, po& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check current EndOfLine sequence --- +IF MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolL" THEN EXIT SUB +IF MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolN" AND LEN(BufEolSeq$(handle%)) = 1 THEN EXIT SUB +'--- prepare values --- +simplebuffer_array$(buf& + 1) = simplebuffer_array$(buf& + 1) + CHR$(16) +IF MID$(simplebuffer_array$(buf& + 0), GetBufPos&(handle%), 2) = CHR$(13) + CHR$(10) THEN + res& = SeekBuf&(handle%, 1, SBM_BufCurrent) +END IF +MID$(simplebuffer_array$(buf& + 2), 101 * 4, 4) = MID$(simplebuffer_array$(buf& + 1), 1, 4) 'SetBufMark 101 +MID$(simplebuffer_array$(buf& + 4), 101 * 4, 4) = MKL$(2): simplebuffer_array$(buf& + 101 + 4) = CHR$(13) + CHR$(10) 'SetBufFind 101 +'--- search & convert --- +res& = SeekBuf&(handle%, 0, SBM_BufStart) +DO + po& = FindBufFwd&(handle%, 101, SBF_FullData, SBF_AsWritten) + IF po& > 0 THEN DeleteBufRawData handle%, 1 +LOOP UNTIL po& = 0 +MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolL" +'--- restore old position & cleanup --- +res& = SeekBuf&(handle%, 0, 101) +res& = RemoveBufFind%(handle%, 101) +res& = RemoveBufMark%(handle%, 101) +simplebuffer_array$(buf& + 1) = LEFT$(simplebuffer_array$(buf& + 1), 16) +END SUB + +'--- docs\ConvBufToAnyEol.html +'--------------------------------------------------------------------- +SUB ConvBufToWinEol (handle%) +'--- option _explicit requirements --- +DIM buf&, res&, po& +'--- check handle --- +IF NOT CheckHandle%(handle%) THEN ERROR 258: STOP 'invalid handle +buf& = handle% * 106 +'--- check current EndOfLine sequence --- +IF MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolW" THEN EXIT SUB +IF MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolN" AND LEN(BufEolSeq$(handle%)) = 2 THEN EXIT SUB +IF MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolU" THEN ConvBufToLnxMacEol handle% 'safety measure for unknown (maybe mixed) EOL mode +'--- prepare values --- +simplebuffer_array$(buf& + 1) = simplebuffer_array$(buf& + 1) + CHR$(16) +MID$(simplebuffer_array$(buf& + 2), 101 * 4, 4) = MID$(simplebuffer_array$(buf& + 1), 1, 4) 'SetBufMark 101 +MID$(simplebuffer_array$(buf& + 4), 101 * 4, 4) = MKL$(1): simplebuffer_array$(buf& + 101 + 4) = CHR$(10) 'SetBufFind 101 +'--- search & convert --- +res& = SeekBuf&(handle%, 0, SBM_BufStart) +DO + po& = FindBufFwd&(handle%, 101, SBF_FullData, SBF_AsWritten) + IF po& > 0 THEN WriteBufRawData handle%, CHR$(13) +LOOP UNTIL po& = 0 +MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolW" +'--- restore old position & cleanup --- +res& = SeekBuf&(handle%, 0, 101) +IF MID$(simplebuffer_array$(buf& + 0), GetBufPos&(handle%), 1) = CHR$(10) THEN + res& = SeekBuf&(handle%, 0, SBM_LineEnd) +END IF +res& = RemoveBufFind%(handle%, 101) +res& = RemoveBufMark%(handle%, 101) +simplebuffer_array$(buf& + 1) = LEFT$(simplebuffer_array$(buf& + 1), 16) +END SUB + +'--- undocumented - for internal use only +'--------------------------------------------------------------------- +FUNCTION CheckHandle% (handle%) +'--- option _explicit requirements --- +DIM buf& +'--- check handle --- +buf& = handle% * 106: CheckHandle% = 0 +IF buf& < 0 OR buf& > UBOUND(simplebuffer_array$) THEN EXIT FUNCTION +IF simplebuffer_array$(buf& + 1) = "" THEN EXIT FUNCTION +CheckHandle% = -1 +END FUNCTION + +'--- undocumented - for internal use only +'--------------------------------------------------------------------- +FUNCTION FreeID% (handle%, slot%) +'--- option _explicit requirements --- +DIM buf&, idx% +'--- find a free ID --- +buf& = handle% * 106: FreeID% = SBE_NoMoreIDs +FOR idx% = 1 TO 100 + IF CVL(MID$(simplebuffer_array$(buf& + slot%), idx% * 4, 4)) = &HCAFEBABE THEN + FreeID% = idx%: EXIT FOR + END IF +NEXT idx% +END FUNCTION + +'--- undocumented - for internal use only +'--------------------------------------------------------------------- +SUB RecalcMarks (handle%, bufPos&, change&) +'--- option _explicit requirements --- +DIM buf&, idx%, mark&, absChg& +'--- check special case (no change) --- +IF change& = 0 THEN EXIT SUB +'--- recalc all used bookmarks --- +buf& = handle% * 106 +FOR idx% = 1 TO 101 + mark& = CVL(MID$(simplebuffer_array$(buf& + 2), idx% * 4, 4)) + IF mark& <> &HCAFEBABE AND mark& <> &HDEADBEEF THEN + SELECT CASE change& + CASE IS > 0 + IF bufPos& <= mark& THEN mark& = mark& + change& + CASE IS < 0 + IF bufPos& < mark& THEN + absChg& = ABS(change&) + IF absChg& <= (mark& - bufPos&) THEN + mark& = mark& - absChg& + ELSE + mark& = &HDEADBEEF + END IF + ELSEIF bufPos& = mark& THEN + mark& = &HDEADBEEF + END IF + END SELECT + MID$(simplebuffer_array$(buf& + 2), idx% * 4, 4) = MKL$(mark&) + END IF +NEXT idx% +END SUB + +'--- undocumented - for internal use only +'--------------------------------------------------------------------- +SUB RecalcFinds (handle%, bufPos&, change&) +'--- option _explicit requirements --- +DIM buf&, idx%, found&, length&, absChg& +'--- check special case (no change) --- +IF change& = 0 THEN EXIT SUB +'--- recalc all used found at positions --- +buf& = handle% * 106 +FOR idx% = 1 TO 101 + found& = CVL(MID$(simplebuffer_array$(buf& + 3), idx% * 4, 4)) + length& = CVL(MID$(simplebuffer_array$(buf& + 4), idx% * 4, 4)) + IF found& <> &HCAFEBABE AND found& <> &HDEADBEEF THEN + SELECT CASE change& + CASE IS > 0 + IF bufPos& <= found& THEN + found& = found& + change& + ELSEIF bufPos& > found& AND bufPos& < (found& + length&) THEN + found& = &HDEADBEEF + END IF + CASE IS < 0 + IF bufPos& < found& THEN + absChg& = ABS(change&) + IF absChg& <= (found& - bufPos&) THEN + found& = found& - absChg& + ELSE + found& = &HDEADBEEF + END IF + ELSEIF bufPos& >= found& AND bufPos& < (found& + length&) THEN + found& = &HDEADBEEF + END IF + END SELECT + MID$(simplebuffer_array$(buf& + 3), idx% * 4, 4) = MKL$(found&) + END IF +NEXT idx% +END SUB + +'--- undocumented - for internal use only +'--------------------------------------------------------------------- +FUNCTION VersionSimplebuffer$ +VersionSimplebuffer$ = MID$("$VER: simplebuffer.bm 3.2 (18-Oct-2022) by RhoSigma :END$", 7, 45) +END FUNCTION + '$INCLUDE: 'sb_qb64pe_extension.bm' diff --git a/tests/dist_tests.sh b/tests/dist_tests.sh index b6d4f5975..d7b4a28ef 100755 --- a/tests/dist_tests.sh +++ b/tests/dist_tests.sh @@ -25,7 +25,7 @@ case "$2" in win) # Verify that the Resource information was correctly applied # windres returns an error if the exe has no resource section - windresResult=$($ROOT/internal/c/c_compiler/bin/windres.exe -i ./qb64pe.exe) + windresResult=$($ROOT/internal/c/c_compiler/bin/llvm-objdump -s -j .rsrc ./qb64pe.exe) assert_success_named "Windows Resource Section" printf "\n$windresResult\n" ;;