:: --------------------------------------------------------------------------------------------------------------------------
:: tooComplex's doskitXPserver2003 v0.1 (20190129) (
::
:: supported platforms: winXP/server2003 - 32bit - x86
:: supported language: dutch, english, international ( experimental )
::
:: ) special thanks to : DirtyOperatingSystemTips.COM team and members.
:: --------------------------------------------------------------------------------------------------------------------------
Everything I need to be able to do good old dos. First being released as a function library for mass deployment. Learned vbs and converted the entire library to vbsKit. In the end vbsKit is just the next step for me but at times I still escape to dos.
Started various fun projects and optimizing with new tricks I found useful. You can find almost any trick that was found useful by the community used in some way in the code or otherwise documented. Doskit includes testing examples, explanations and debugging features. My latest addition is a compiler, it converts doskit language to cmd batch.
This document will introduce the latest version as it is being written, older versions may not fully comply with this documentation. The compiler is not available for versions below 1.0.
Save below and drag'ndrop the file onto compile.CMD to start the conversion.
Code: Select all
( %getKey_% $name, "enter username:" )
( %getKey_% $pass, "enter password:", True )
( %echo_% Welcome !$name! )
Code: Select all
( %include_% "ext\madplay\$madplay" )
::
( %processStart_% /HIGH, $madplay.fullpathFile, "", "-q -S -z -r ""!$madplay.fullpath!\coolSong.MP3"" ", True )
Code: Select all
( %oFile_% $, "favorite.mp3", True, True )
Code: Select all
( %$.move% "stupid.file", False ) &&echo.succes ||(
rem now what ?
)
Doskit implements the convention that a valid path must end with a backslash. You may falsely assume that
Code: Select all
( %dirDelete_% "C:\my path" )
A delimiter is a function that splits the arguments into 26 alphabetically addressable tokens. A function usually starts with one of these delimiters:
Code: Select all
:: support: '<SPACE>,<,>' '?' delays '<^>,<!>' '*' '<CR>,<LF>'
:: starDelim yes yes yes yes yes
:: naDelim_ yes yes yes no no
:: nMDelim_ yes yes yes no no
:: oMDelim_ yes yes yes no no
:: onDelim_ yes yes yes no no
:: vsDelim_ yes yes no no no
:: xsDelim_ no no no no no
A parser is a function that interprets a function's arguments. A function usually starts with one of these parsers:
Code: Select all
:: support: '*'
:: bruteParam_ yes
:: param_ no
To pass arguments by value enclose them in double quotes. If you want to pass a double quote you need to double it. All carets and exclamation marks need to be escaped. The parser can be crashed by passing an argument by value with unescaped double quotes.
To pass arguments by reference leave out any surrounding double quotes. If a function enforces byValue and you provide a reference it will be interpreted byValue. oFile_ enforces %a byValue.
Code: Select all
( %oFile_% "$", "my file" )
( %oFile_% $, "my file" )
The parser accepts format 'argument', 'argument', 'etc..' Each argument is of format: '%a,%b,%c'
%a is the name of the variable that will be assigned.
%b is the user's argument.
%c is the default value.
If no default value is set, %b cannot be empty.
If the default value is substituted by an empty string "", %b is optional.
doskit.NFO is created when doskit runs. In it you find the class hierarchy. Only required functions are part of class kernel.
Code: Select all
kernel\object\file\oFile_
use: ( %oFile_% '$vr,"%~a"', '$file,%b,""', '$setsError,%c,False', '$enableMethods,%d,False' )
err: 0 for succes, 1 for error
Methods are currently not documented, to figure out how to use an objects methods a simple rule is applied. Replacing [object].[method] and substituting it with [class][method]_ gives the function associated with a method, in this case fileMove_.
Code: Select all
kernel\IO\file\fileMove_
use: ( %fileMove_% '$old,%a,""' ,'$new,%b,""' ,'$setsError,%c,False' )
err: 0 for succes, 32 for object move failed
Code: Select all
( %assertFail_% '$1,%%a,""', '$2,%%b,""' )
assertFail_ demands we provide it with at least one parameter or it will throw an exception and halt even though it's parsing allows %a to be empty initially. Tests can be based upon the exitcode of the previous command. If pushd_ is successful then 'cd' must contain "C:\This work^^ s^!" otherwise assertFail_ fails. But if pushd_ fails, assertFail_ fails per definition.
Code: Select all
( %pushd_% "C:\This work^^ s^!" ) &&(
( %assertFail_% cd, "C:\This work^^ s^!" )
popd
) || ( %assertFail_% )
Code: Select all
( %fileLink_% $, "This work^^ s^!", True ) &&(
( %assertFail_% $.attributes, "--a------" )
( %assertFail_% $.fileSize, "0" )
) || ( %assertFail_% )
Code: Select all
( %scopeFail_% /open )
::
...test this code...
::
( %scopeFail_% /close )
Code: Select all
( %replace_% '$vr,"%~a"', '$match,%b', $replace,%c,"", '$setsError,%d,False', $caseSense,%e,False )
Code: Select all
( %replace_% $, """", "!$lf!aaah quotes again ? I mean...!$cr!Yay pps!$bs!!$bs!!$bs!!$bs! quotes.!$lf!Kuch. :)!$lf!" )
Code: Select all
Yay quotes
Kuch. :)
Code: Select all
( %fileCopy_% "inputFile", "output.file", True )
( %fileCopy_% "????*.DAT", "concat.DAT", True )
( %fileCopy_% " ""inputFile.A"" + ""inputFile.B"" ", "outPut.file" )
( %fileCopy_% """inputFile.A"" + ""inputFile.B""", "outPut.file" )
( %fileCopy_% "nul + nul", "output.file", True )
-offDelayed means only works in disDelayed.
-onDelayed means only works in enaDelayed.
-naDelayed means works regardless delayedState.
Objects can only be declared in disableDelayed if wrapped in the new_ macro.
Code: Select all
( %new_% oFile_, $, "my file" )
In the code are some definitions with the characters LH added at the end. LH stands for Local and Hidden. These functions do not set errors and are undocumented because they are smaller, faster and easier to embed duplicates. One of these is reDelayLH_ a minimized version of reDelay_.
On occasion, changes are made to very primitive kernel functions. At this point I increase the alphaVersionNumber and disable any dependencies. The next time the program runs these functions are then forced into unitTests which need to be manually re-enabled. It is possible that a release contains such disabled classes. You may attempt to use it anyways but do prepare to potentially die.
Doskit can interface with:
- cmdow: window operations: retrieve winHandle, identify self, move/hide/maximize/enumerate etc...
- mode: change console buffers
- choice: available because many people use it but doskit does not need it as it uses the more powerful getKey_ macro in pure dos.
- eval: advanced math
- stackey: emulate keystrokes
- setACL: edit system registry AccessControlLists.
- regfind: system registry search and replace (BULK).
- reschangecon: adjust various display settings, resolution depth etc...
- csound: access internal speaker
- madplay: play various audio formats
- 7zip: pack/unpack a wide array of compression formats
If you download the optional external binaries listed below. Some programs like cmdow may give you a false positive virus alert ( because it can hide windows ). All binaries are 32bit. Make sure that the ext folder is a sub folder of the folder where doskit.CMD is or it won't find the binaries.
I try to write code that is international, still there are functions that are language dependent.
DOES NOT support win7/server2008.
There is a minor difference with the 'set' command. In 7 'set/P=' without double quotes will eat spaces at the beginning of the line, this is a break from previous windows versions. Since 'set' is the most important command in dos, I predict this minor difference has big consequences that may cause all kinds of visual and file formatting issues.
Please do report bugs and post logs as attachment, so it can be fixed in a next version.
Any suggestions are welcome.
Thanks.
:: --------------------------------------------------------------------------------------------------------------------------
doskit output for the "Hello World !" program.
Code: Select all
<!-- : As far as WSF is concerned, this is all just comment.
@echo off &cls &title %~n0
rem -------------------------------------------------------------------------------------------------------------------------
rem Hello world ! -
rem -------------------------------------------------------------------------------------------------------------------------
rem last updated: v2018^12^03
rem
rem Greets the world
rem
rem programmer: tooComplex
rem
:: --------------------------------------------------------------------------------------------------------------------------
:: byteCode (
::
:: sourceFile : W:\ED\VIP\PROJ\DEV\doskit\doskitXPserver2003 v20181203\Hello world !\Hello world !.CMD
:: sourceFunction : §label0
:: )
:: --------------------------------------------------------------------------------------------------------------------------
:: --------------------------------------------------------------------------------------------------------------------------
:: doskit library (
::
:: supported platforms: winXP/server2003 - 32bit - x86
:: supported languages: dutch, english ( experimental ), international ( experimental )
:: programmer : tooComplex
:: special thanks to : Peter, jeb, dBenham, aGerman from www.DOSTips.COM, the DOSTips team and members.
:: )
:: --------------------------------------------------------------------------------------------------------------------------
:: --------------------------------------------------------------------------------------------------------------------------
:§parser_ ( '$function,"%%~a","§label0"', '$arguments,"%%~b*",""' )
:: --------------------------------------------------------------------------------------------------------------------------
:: last updated : 2018^12^03
:: support : naDelayed
:: languages : N/A
::
:: Calls :§!$function! !$arguments!
::
:: - DOES NOT SUPPORT variableNames with delimiters that cannot be processed by 'if defined %variableName%' !
:: - Functions are onDelayed by parser.
::
:: (
rem ( echo.&<nul set/P= inside §parser_^( %* ^) ) >con
< :§return.notDelayed %( * )% <nul rem^ &if /I "%~1" NEQ "§return.notDelayed" goto :§return.notDelayed "()"
:: (
( set "%a%=" &setlocal enableDelayedExpansion%= var 'a' must be in code block to allow reset =%
rem ( %n2echo_% a=!a!_ )
rem ( %necho_% b=!b!_ )
rem ( %necho_% c=!c!_ )
%endlocalRF_% (%= var 'a' must be unset to detect overflow =%
endlocal
%= =%set "%a%=%b%%c%"
if "%b%" NEQ "" if not defined %a% call :§endSimple "§return.notDelayed: data overFlow: '%a%'"
)
)
:: )
< :§return.notDelayed %( * )% <nul rem^ &exit /B 0
if not defined $kernel (%= initialize doskit environment =%
for /F "tokens=1,2 delims==" %%a in (
'set ^|findstr.EXE /BRIC:"[^\$]"'
) do set "$sysVar.%%~a=%%~b"%= backup caller's environment =%
( call :§init_ "( * )" ) &&(
set /A $kernel = 1
) || call :§endSimple "§parser_: 'call :§init_ ( * )' failed."
)
setlocal &set "$notDelayedFlag=!"%= local, got caller's delayedState =%
:: (
setlocal enableExtensions disableDelayedExpansion
:: (
< :§callSetVarSafe %( * )% <nul rem^ &set "ó=%pathext%" &set "ô=%path%" &set "pathext=;" &set "path="
:: (
(call set ?=%%^*)%= call prevents * to break code =%
%= $lf prevents 'input corrupt or incorrectly escaped' exception =%
:: )
set "pathext=%ó%" &set "path=%ô%" &set "ó=" &set "ô="
setlocal enableDelayedExpansion &set "$rA="%= function scope reached, reset 8k returnables =%
:: (
if "!?:~,1!" NEQ "§" (%= no function marker, not a doskit call =%
set "?=§label0 !?!"
set "?=!?:^=^^!"%= used call ?, double carets =%
)
rem ( %necho_% ?=!?! ) >con
set "?=!?:"=""!^"%= disable doubleQuotes =%
( %callSetVarSafe_% "?=%%^?:^!=#"#"^!%%" ) &set "?=!?:#"#"=^!"%=delay exclamation mark =%
(set "?=%?%" ! )%= make carets inside doubleQuotes retract as expected =%
set "?=!?:""="!^"%= enable doubleQuotes =%
rem ( %necho_% ?=!?! ) >con
:: initialize function
:: (
set "?=!?! " &set "*=!?:* =!" &for /F "tokens=1 delims= " %%@ in (
"!?!"
) do ( %setLocal_% "%%~@" )
:: )
:: call function, warn: call failures cannot be detected if £e is set to none 0 by caller.
::
rem if defined $debug.sub ( %necho_%pre call :!$trace! !*! ^! ) >con
:: (
( call :!$trace! !*! ) ||if !£e! EQU 0 (%= call failed with exitCode zero =%
call :§endSimple "call failed with exitCode zero." ^"§parser_: ^( :!$trace! !*! ^)^"
)
:: )
rem if defined $debug.sub ( %necho_%post call :!$trace! !*! ^! ) >con
:: )
:: )
:: )
:: 8k returnables maximum is 9.
:: (
>nul ( %advancedRF% )
:: )
rem ( %n2echo_% endlocal_ 3, $r, $rA, !$r! )
rem ( %necho_% $rA=!$rA!_ ) &%forQ_% ( !$rA! ) do ( %necho_% %%~?=!%%~?!_ )
::
rem (%n2echo_% a1=!a1!_ )
rem ( %necho_% b1=!b1!_ )
rem ( %necho_% c1=!c1!_ )
::
rem (%n2echo_% a2=!a2!_ )
rem ( %necho_% b2=!b2!_ )
rem ( %necho_% c2=!c2!_ )
::
%endlocalRF_% (
( %endlocal_% 3, $r, $rA, !$r! )%= simple returns addressable range is 8k =%
%= =%set "%a1%=%b1%%c1%"!%= 8k returnables maximum is 9 =%
%= =%set "%a2%=%b2%%c2%"!
%= =%set "%a3%=%b3%%c3%"!
%= =%set "%a4%=%b4%%c4%"!
%= =%set "%a5%=%b5%%c5%"!
%= =%set "%a6%=%b6%%c6%"!
%= =%set "%a7%=%b7%%c7%"!
%= =%set "%a8%=%b8%%c8%"!
%= =%set "%a9%=%b9%%c9%"!
if "%b1%" NEQ "" if not defined %a1% call :§endSimple "§parser_: data overFlow: '%a1%'"
if "%b2%" NEQ "" if not defined %a2% call :§endSimple "§parser_: data overFlow: '%a2%'"
if "%b3%" NEQ "" if not defined %a3% call :§endSimple "§parser_: data overFlow: '%a3%'"
if "%b4%" NEQ "" if not defined %a4% call :§endSimple "§parser_: data overFlow: '%a4%'"
if "%b5%" NEQ "" if not defined %a5% call :§endSimple "§parser_: data overFlow: '%a5%'"
if "%b6%" NEQ "" if not defined %a6% call :§endSimple "§parser_: data overFlow: '%a6%'"
if "%b7%" NEQ "" if not defined %a7% call :§endSimple "§parser_: data overFlow: '%a7%'"
if "%b8%" NEQ "" if not defined %a8% call :§endSimple "§parser_: data overFlow: '%a8%'"
if "%b9%" NEQ "" if not defined %a9% call :§endSimple "§parser_: data overFlow: '%a9%'"
)
:: )
exit /B %£e%
:: --------------------------------------------------------------------------------------------------------------------------
:: --------------------------------------------------------------------------------------------------------------------------
:§init_ ( doskit environment ) [requires disableDelayedExpansion]
:: --------------------------------------------------------------------------------------------------------------------------
:: (
:: $bs, ascii-0x08-08
for /F "delims=#" %%? in (
'"prompt #$H# &echo on &for %%? in (1) do rem"'
) do set "$bs=%%?"
::
set "$bs=%$bs:~0,1%"
:: $tab ascii-0x09
for /F "skip=4tokens=2delims=pR " %%? in (
'reg.EXE query hkcu\environment /v temp'
) do set "$tab=%%?"
:: $lf ascii-0x0A
( set $lf=^
%= ! EMPTY LINE REQUIRED, DO NOT REMOVE ! =%
)
:: $cr ascii-0x0D
for /F %%? in (
'copy /Z "%~f0" nul'
) do set "$cr=%%?"
:: $sub ascii-0x1A
>nul copy /Z /A nul + nul "%temp%\$sub.TMP"
:: (
for /F "useback" %%? in (
"%temp%\$sub.TMP"
) do set "$sub=%%?"
:: )
>nul del /F /Q "%temp%\$sub.TMP"
:: $esc ascii-0x1B-27
for /F "delims=#" %%? in (
'"prompt #$E# &echo on &for %%? in (1) do rem"'
) do set "$esc=%%?"
:: $c1, Line continuation [ 1 expansions ] =
set ^"$c1=%%~#^<nul ^^"
:: $n1c, newline + continuation [ 1 expansions; 1 echo ]
set ^"$n1c=^^^%$lf%%$lf%^%$lf%%$lf%^<nul ^^"
:: constants
set /A False = 0
set /A True = 1
:: common errors
set /A £e = 0
::
for /L %%? in (
1, 1, 99
) do set "£error[%%~?]=error unidentified"
::
set "£error[0]=ok" &::%= range 0-99 doskit =%
set "£error[1]=error unidentified"
set "£error[2]=argument not specified"
set "£error[3]=invalid input format"
set "£error[4]=variable undefined"
set "£error[5]=invalid argument V variable undefined"
set "£error[6]=undefined array $debug"
set "£error[7]=undefined array"
set "£error[8]=array at end, must undeclare manually"
set "£error[9]="
set "£error[10]=invalid fileName"
set "£error[11]=invalid fileExtension"
set "£error[12]=invalid drive"
set "£error[13]=invalid fullPath"
set "£error[14]=invalid fullPathFile"
set "£error[15]=invalid path"
set "£error[18]=invalid file"
set "£error[19]=insufficient privileges"
set "£error[20]=object delete failed"
set "£error[21]=object type invalid"
set "£error[22]=input type invalid"
set "£error[23]=object copy failed"
set "£error[24]=object creation failed"
set "£error[25]=stack overflow"
set "£error[26]=invalid share"
set "£error[28]=pattern not in file"
set "£error[29]=acces denied"
set "£error[30]=object not declared"
set "£error[31]=object not physicall"
set "£error[32]=object move failed"
set "£error[97]=only one instance can be active simultaneously"
set "£error[98]=violation of rule, restart without $jumpLabel"
set "£error[99]=a required resource is missing"
set "£error[1128]=the image name is invalid" &::%= range 1000-1100 taskKill =%
:: common variables
set "$function.fullPathFile=%~f0"
:: --------------------------------------------------------------------------------------------------------------------------
echo(&<nul set/P= restoring memory...
:: --------------------------------------------------------------------------------------------------------------------------
:: (
:: (n2echo_:disDelayed) '26' bytes on file, '23' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"n2echo_=echo(^&echo(^&^<nul set/P=" !
:: )
:: (necho_:disDelayed) '19' bytes on file, '17' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"necho_=echo(^&^<nul set/P=" !
:: )
:: (endlocalRF_:disDelayed) '92' bytes on file, '77' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"endlocalRF_=for /F ^"useback tokens=1-3^" %%1 in ('%%,^^^",^!$cr^!,^^^"') do for %%4 in (^"^!$lf^!^") do" !
:: )
:: (callSetVarSafe_:disDelayed) '332' bytes on file, '262' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"callSetVarSafe_=for %%? in (1,2) do if %%?==2 (setlocal enableDelayedExpansion%$n1c%
%= =%for /F ^"usebacktokens=1-3eol=¦delims=¦^" %%r in ('^!_^!¦^!pathext^!¦^!path^!') do (endlocal^&endlocal%$n1c%
%= =%set pathext=;^&set path=%$n1c%
%= =%call set %%r%$n1c%
%= =%set pathext=%%s^&set path=%%t))else setlocal disableDelayedExpansion^&set _=" !
:: )
:: (setLocal_:disDelayed) '255' bytes on file, '180' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"setLocal_=for %%? in (1,2) do if %%?==2 (for %%? in (^!~^!) do (set/A$debug+=1,£e=0%$n1c%
%= =%set $trace=%%~?%$n1c%
%= =%set $debug[^!$debug^!]=%%~?%$n1c%
%= =%set %%~?.p=^!*^!^&if ^!*:~^^,1^!==^^^^^^^! set %%~?.p=^!*:~1^!%$n1c%
%= =%set $r=£e))else set ~=" !
:: )
:: (advancedRF:disDelayed) '1084' bytes on file, '738' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"advancedRF=(echo.^&if defined $notDelayedFlag (set/P= notDelayed^<nul)else set/P= delayed^<nul%$n1c%
%= =%set *=^!$rA^!%$n1c%
%= =%for /L %%i in (1,1,9) do (set ?=^&set ~=^&set _=^&for %%? in (^!*^!) do if ^!~^!.==. (set ~=%%~?%$n1c%
%= =%set _=^!%%~?^!)else set ?=^!?^!,%%~?%$n1c%
%= =%set *=^!?^!%$n1c%
%= =%set ?1=^&set ?2=^&set ?=^&set ?=^!_^!^&^&(set ?1=^!?:~,4096^!^&set ?2=^!?:~4096^!^&for %%? in (1,2) do if defined ?%%~? (set ?=^!?%%~?^!%$n1c%
%= =%set ?=^!?:%%=%%1^!%$n1c%
%= =%set ^"?=^!?:^"=%%2^!^"%$n1c%
%= =%for %%r in (^"^!$cr^!^") do set ?=^!?:%%~r=%%3^!%$n1c%
%= =%for %%r in (^"^!$lf^!^") do set ?=^!?:%%~r=%%~4^!%$n1c%
%= =%if ^!$notDelayedFlag^!.==. (for /F ^"usebacktokens=1-2eol=¦delims=¦^" %%r in ('^!pathext^!¦^!path^!') do (set pathext=;^&set path=%$n1c%
%= =%call set ^"?=%%^^?:^^^!=^"^"^^^!%%^"^!%$n1c%
%= =%set pathext=%%r^&set path=%%s)%$n1c%
%= =%set ^"?=^!?:^^=^^^^^!^"^&set ^"?=^!?:^"^"=^^^!^")%$n1c%
%= =%set ?%%~?=^!?^!))^|^|if ^!~^!.==. set ~=?%$n1c%
%= =%set a%%i=^!~^!%$n1c%
%= =%set b%%i=^!?1^!%$n1c%
%= =%set c%%i=^!?2^!))" !
:: )
:: (forI_:disDelayed) '13' bytes on file, '12' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"forI_=for /L %%i in" !
:: )
:: (deq_:disDelayed) '7' bytes on file, '7' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"deq_=if 1==0" !
:: )
:: (forQ_:disDelayed) '10' bytes on file, '9' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"forQ_=for %%? in" !
:: )
:: (endlocal_:disDelayed) '1825' bytes on file, '1240' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"endlocal_=for %%? in (1,2) do if %%?==2 (for /F ^"usebacktokens=1-4eol=¦delims=¦^" %%i in ('%%^!^"^"^!1¦%%^!^"^"^!2¦%%^!^"^"^!3¦%%^!^"^"^!~4') do for /F ^"usebacktokens=1-2eol=¦delims=¦^" %%r in ('^!pathext^!¦^!path^!') do (set pathext=;^&set path=%$n1c%
%= =%set ¤=^&for %%? in (^!º^!) do if ^!¤^!.==. set/A¤=%%~?0/10^&if ^!¤^! NEQ 0 (call set º=%%º:*^!¤^!=%%^&set/A¤+=1)else set/A¤=2%$n1c%
%= =%set _=^&for %%? in (^!º^!) do (set ?=^!%%~?^!^&if defined ? (set ?=^!?:%%=%%i^!%$n1c%
%= =%for /F %%r in (^"^!$cr^! ^") do set ?=^!?:%%r=%%k^!%$n1c%
%= =%set ?=^!?:^^^%$lf%%$lf%^%$lf%%$lf%=%%l^!%$n1c%
%= =%set ?=^!?:%%=%%i^!)%$n1c%
%= =%set _=^!_^!%%l%%~?#=^!?^!)%$n1c%
%= =%set _=^!_:^"=%%j^!%$n1c%
%= =%set ^"_=^!_:^^=%%9^!^"^&call set ^"_=%%^^_:^^^!=^"^"%%^"%$n1c%
%= =%for /F delims^^= %%r in (^"^!_:~3^!^") do (for /L %%i in (1,1,^!¤^!) do endlocal%$n1c%
%= =%set ?=^!^&setlocal enableDelayedExpansion%$n1c%
%= =%set _=%%r%$n1c%
%= =%call set ^"_=%%^^_:^"^"=^"^"^^^!%%^"^&if ^!?^!.==. (set ^"_=^!_:%%9=^^^^^!^"^&set ^"_=^!_:^"^"=^^^!^"%$n1c%
%= =%set _=^!_:%%j=^^^"^!)else set ^"_=^!_:%%9=^^^!^"^&set _=^!_:^"^"=^!%$n1c%
%= =%for %%@ in (^"^!$lf^!^") do set _=^!_:%%l=%%~@^!%$n1c%
%= =%set _=^!_:%%i=%%^!%$n1c%
%= =%for %%? in (^"^!$function.fullPathFile^!^") do for /F ^"tokens=1,*eol=#delims=#^" %%r in (^"^!_^!^") do (endlocal%$n1c%
%= =%if ^!.==. (set _=%%s^!%$n1c%
%= =%if defined _ (set _=^!_:%%l=^^^%$lf%%$lf%^%$lf%%$lf%^!%$n1c%
%= =%for /F %%r in (^"^!$cr^! ^") do set _=^!_:%%k=%%r^!%$n1c%
%= =%set _=^!_:%%i=%%^!)%$n1c%
%= =%set ^"%%r=^!_:~1^!^"^!)else (set a=%%r^&set b%%s^&set c=%$n1c%
%= =%call %%? §return.notDelayed)%$n1c%
%= =%setlocal enableDelayedExpansion)%$n1c%
%= =%endlocal)%$n1c%
%= =%set pathext=%%r^&set path=%%s))else setlocal enableDelayedExpansion^&set º=" !
:: )
:: (forP_:disDelayed) '2816' bytes on file, '1879' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"forP_=setlocal disableDelayedExpansion^&set $=^"^"^&(for /F usebackdelims^^=^^ eol^^= %%? in ('^!*^!') do set $=%%?)2^>nul^&(setlocal enableDelayedExpansion%$n1c%
%= =%for /F ^"delims=^" %%? in (^"^!$^!^") do set $=%%?%$n1c%
%= =%set ?=^&if defined $ (set $=^!$:^"=^"^"^!%$n1c%
%= =%set ^"$=^!$:^^=^^^^^^^^^!^"%$n1c%
%= =%for /F ^"usebacktokens=1-2eol=¦delims=¦^" %%r in ('^!pathext^!¦^!path^!') do (set pathext=;^&set path=%$n1c%
%= =%call set ^"$=%%^^$:^^^!=#^"#^"^^^!%%^"^!%$n1c%
%= =%set pathext=%%r^&set path=%%s)%$n1c%
%= =%set ^"$=^!$:#^"#^"=^^^^^^^!^"^&set $=^!$:^"^"=^"^!%$n1c%
%= =%for %%? in (^!$^!) do set ?=^!?^!¦%%?)%$n1c%
%= =%if ^!?^!.==. set ?=^"^")^&for /F ^"tokens=1-26delims=¦^" %%a in (^"^!?^!^") do endlocal^&endlocal ^&for %%? in (1,2) do if %%?==2 (for /F ^"usebacktokens=1-2eol=¦delims=¦^" %%r in ('^!pathext^!¦^!path^!') do (set pathext=;^&set path=%$n1c%
%= =%set ?=^!~:~1^!%$n1c%
%= =%set ?=^!?:§=§0^!%$n1c%
%= =%set ?=^!?:^"=^"^"^!%$n1c%
%= =%set ^"?=^!?:^^=§9^!^"^&call set ^"?=%%^^?:^^^!=§3%%^"%$n1c%
%= =%set ?=^!?:^"^"=^"^!%$n1c%
%= =%set ?=^!?:\%$bs%*=\*^!%$n1c%
%= =%set ?=^!?:\*=§4^!%$n1c%
%= =%set ?=^!?:?=§6^!%$n1c%
%= =%set ?=^!?:,,=§1,^"^",^!%$n1c%
%= =%set ~=^&for %%? in (^!?^!) do set ^"?=%%?^"^&set ~=^!~^!,^!?^!^&if ^!?:~-1^!==' (set ó=^&set ô=^&set ò=%$n1c%
%= =%set ?=^!~:~2,-1^!%$n1c%
%= =%for %%? in (^!?^!) do set ~=%%?^&for %%? in (ó,ô,ò) do if ^!%%?^!.==. if defined ~ set %%?=^!~:§1=^!^&set ~=%$n1c%
%= =%set ó=^!ó:§0=§^!%$n1c%
%= =%set #=^&if defined ò set #=1%$n1c%
%= =%for %%? in (ô,ò) do (set *=^&if ^!%%?:~^^,1^!==^^^" if ^!%%?:~-1^!==^^^" set *=1%$n1c%
%= =%if ^!*^!==1 (set %%?=^!%%?:~1,-1^!%$n1c%
%= =%if defined %%? set %%?=^!%%?:^"^"=^^^"^!)else set º=^!%%?:§0=§^!^&if defined ^!º^! (for %%@ in (^!º^!) do set %%?=^!%%@^!%$n1c%
%= =%set %%?=^!%%?:§=§0^!)else set %%?=)%$n1c%
%= =%if ^!ô^!.==. if defined ò (set ô=^!ò^!)else if ^!#^!.==. for %%? in (1,2) do if %%?==2 (call ^"^!$function.fullPathFile^!^" §panic_ ^!~^!^^^!^&set/A£e=errorlevel%$n1c%
%= =%exit ^!£e^!)else set ~=^"2^"%$n1c%
%= =%if defined ô for %%? in (^"^!$lf^!^") do (set ô=^!ô:%%~?=§2^!%$n1c%
%= =%set ô=^!ô:^"=^"^"^!%$n1c%
%= =%set ^"ô=^!ô:^^=§9^!^"%$n1c%
%= =%call set ^"ô=%%^^ô:^^^!=§3%%^"%$n1c%
%= =%set ô=^!ô:\%$bs%*=\*^!%$n1c%
%= =%set ô=^!ô:\*=§4^!%$n1c%
%= =%set ô=^!ô:?=§6^!%$n1c%
%= =%set ^"ô=^!ô:§9=^^^!^"%$n1c%
%= =%call set ^"ô=%%^^ô:§3=^^^!%%^"%$n1c%
%= =%set ô=^!ô:^"^"=^"^!%$n1c%
%= =%set ô=^!ô:§2=%%~?^!%$n1c%
%= =%set ô=^!ô:§4=\%$bs%*^!%$n1c%
%= =%set ô=^!ô:§6=?^!%$n1c%
%= =%set ô=^!ô:§0=§^!)%$n1c%
%= =%if ^!$debug.sub^!==^!$trace^! echo(^>con^&^>con^<nul set/P= set '^!ó^!=^!ô^!'^^^^^^^!%$n1c%
%= =%set ^!ó^!=^!ô^!)%$n1c%
%= =%set pathext=%%r^&set path=%%s))else set ~=^^^^^^^!" !
:: )
:: (endoftest:disDelayed) '52' bytes on file, '47' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"endoftest=(echo(^&^<nul set/P= endoftest ^&pause^&exit 0)^>con" !
:: )
:: (exception.nPrint:disDelayed) '271' bytes on file, '201' bytes in memory.
:: (
%= =%for %%# in ("") do set ^"exception.nPrint=echo(^&(setlocal enableDelayedExpansion%$n1c%
%= =%if ^!£e:~^^,1^!==- (set ?=^!£e:~1^!)else set ?=^!£e^!%$n1c%
%= =%for %%? in (^"£error[^!?^!]^") do if ^!?^!==0 (^<nul set/P= [^!%%~?^!:^!£e^!])else ^<nul set/P= [error:^!£e^!] ^!%%~?^! ^^^^^^^!%$n1c%
%= =%endlocal)" !
:: )
<nul set/P=%$bs%%$bs% [done]
:: )
exit /B %£e%
:: --------------------------------------------------------------------------------------------------------------------------
:: --------------------------------------------------------------------------------------------------------------------------
:§label0 %( 'null,%%a,""' )%
:: --------------------------------------------------------------------------------------------------------------------------
:: last updated : 2018^12^03
:: supported languages: N/A
::
::
::
rem ( %forP_% 'null,%%a,""' )
:: (
:: Let's create some bytecode :)
:: (
%endoftest%
:: Maybe cache usage.° and then join into usage.NFO
:: filegetmacro in the creation of objects is better replaced by callmacro.
:: this is possible through dependencies.
:: and allows bytecode to get a reference point.
:: if forP_ uses onDelim_ instead of _xsDelim_ then char '?' may be supported by functions.
:: eliminating the need for filelookup_ to pass those regular expressions as reference instead of value.
:: percent should return percentage in variable given,
:: not in default $percent variable.
:: I can use forT_ for the kernel includer instead of for§ because
:: forT_ is nasty and not very handy in macro's anyways.
:: all macros using forT_ will simply have to use another token.
:: I could design a macro _ultraDelim_ that replaces any * or ? wildcards by enumerating each char.
:: Then all macros using _ultraDelim_ can support regular expressions.
:: If this is fast enough then I may reconsider every advEnc /KCF situation.
:: Many macros that call their functions delay themselves
:: but if they just use call %%var%% this may not be necessary
:: bytecode should also support §EndOldOS.
:: if filewrite defaults to /noLock then it is fast enough to be used in include_
:: kernel\IO\reg\key\regKeyRead_ should query the default value with /ve if key missing.
:: not just enumerate them all.
:: )
( %n2echo_% All done )
:: )
::
::
set "$r=!$r!" &set "$rA=" &( %exception.nPrint% ) &exit /B !$err!
:: --------------------------------------------------------------------------------------------------------------------------
:: --------------------------------------------------------------------------------------------------------------------------
:§endSimple ( * )
:: --------------------------------------------------------------------------------------------------------------------------
:: last updated : 2018^11^20
:: supported languages: N/A
:: (
>con (echo.)
:§endSimpleLoop "()"
:: (
>con (call echo.%%~1)
::
shift &if "%~1" NEQ "" goto :§endSimpleLoop "()"
:: )
>con ( <nul set/P"= " &pause )
:: )
exit 1
:: --------------------------------------------------------------------------------------------------------------------------
:skip () disable embedded WSF comment, must be last line in batch ! -->
:: --------------------------------------------------------------------------------------------------------------------------
DEMO version 20181203 in attachment below.
-In §parser, now supports bytecode initialization.
-In §parser, fixed broken overflow detection and shorter algorithm.
-Excluded several tests, to allow to be run by 'the world' which would never pass them.
-Fixed: 'kernel\system\include_' would not link if directory did not exist.
-Loosened input format restrictions on several macros, "%%a" is now "%%~a" per default.
-In §parser, fixed broken call failure detection crash if input contained '<'.
-Doskit no longer runs in low priority so it suffers less when caching is happening in the background.
-In §toByteCode_ added optional arguments: /supportParser /supportOldOS /supportDebug /clearCache.
-In §byteAddPre_ fixed broken $lf, $n1c definition.
-In §byteAddPre_ added $c1 definition.
-In §byteAddPre_ added constants: ( False, True ).
-Depreciated function: byteAddMain_, byteAddPost, use toByteCode_.
:: --------------------------------------------------------------------------------------------------------------------------
DEBUG version 20181212 in attachment below.
-In §byteAddPre_ fixed function pointers were not updated correctly to work with byteCode.
-In dateTime\timerStart_, dateTime\timerStop_ now use a default return $timer, so it is no longer necessary to pass it as argument if only using a single timer.
-In kernel\math\percent_ now returns percentage in variable given, not in default $percent variable.
-In kernel\IO\reg\key\regKeyRead_ now queries the default value with /ve if key missing, instead of enumerating all key values.
-In §filePutMacro fixed a bug causing a wrong logFile to be used.
-Depreciated StringInString_: use replace_
-Update: now supports all special characters except NUL byValue: All §functions and macros if they implement starDelim &bruteParam_.
-New kernel\function\encode_, decode_. More powerful but slower brute force encoding of '*', '=', '$lf', '$cr', '"', '^', '!', '?'.
-Depreciated kernel\function\advEnco_, advDeco_, enco_, deco_: use kernel\function\encode_, decode_.
-Dropped: kernel\function\unDelay_ due to lack of use.
-In §filePutMacro.session fixed crash on verify if written macro is syntactically fraud.
-Update: now supports all characters except '*' and '?' by value: kernel\function\*Delim_ except xsDelim_
-Update: IO\drive\driveGetMounted_, faster detection and set to cache using filewrite_.
-Update: background caching is now controlled through filePutMacroBulk_, this speeds up kernel pre-caching.
-Update: filePutINI_ now supports delayed characters '^' and '!' in $key and $value of '*.INI' files.
-Update: include_ enforced includeOnce_ and no longer overwrites existing macros.
-Update: in kernel\math\percent_ no longer locks files before writing, all file- write/read errors are now silent, this is faster.
-Update: in process\processGetCPULoad_ fixed a bug where returned value would always be 0 using a smaller and faster algorithm.
-Update: All definitions are loaded alphabetically and doskit reserves 1MB of memory for user environment for performance reasons described here.
-Update: endlocal_ now supports character '#' as part of variable name.
-Fixed a bug in window\winWaitOpen_ that would cause redirection failures causing more serious scope failure.
-Fixed a bug in kernel\function\endlocal_ that would cause the scope to remain open if no variables are provided to be returned.
-Update: With bruteParam_ in place there is no more need to encode any arguments, coParam_,coParamL_,deEndLocal_ and deEndLocalL_ have been deleted.
-Fixed a bug in kernel\string\stringLen_ where it would return a wrong length if return variable matches '$vr' used internally.
-Fixed a bug in kernel\function\bruteParam_ that would fail to properly support '$cr' AND '$lf'.
-update: object constructors no longer create objects from cache but directly from memory to make them compatible with byteCode_.
-Fixed a problem in kernel\debug\debug_ causing malformed output to be returned.
-Update: various kernel classes have been moved deeper in the class hierarchy to keep amount of members per class reasonable.
-Update: In kernel\unitTest\assertFail_ now can compare any two values when deciding whether a test is successful.
-Fixed: a bug in class encryption\mask_ that would cause it to not encrypt at all.
-Update: kernel\string\trim_,trimLeft_,trimRight_,eatLeft_,eatRight_ now support any character except NUL as byVal.
-Update: kernel\delim\coDelim_ has been deleted, there is no more need for encoding tokens by coDelim_, use starDelim_/bruteParam_ or forP_.
-Update: changed behavior of kernel\math\eval_ no longer erases the value if expression is empty but returns error 'variable undefined'.
-Fixed: a bug in kernel\scope\endlocalBig_ where it would clear the variable if it matched an internally used name.
-Fixed: excluded some more tests 'The World' cannot pass, that would prevent caching to complete.
:: --------------------------------------------------------------------------------------------------------------------------
v0.1 (20190129) in attachment below.
- Update: applying standardized versioning from now on just vAlphaVersionNumber.betaVersionNumber ( date ).
- Update: kernel\unitTest\unitTest_ no longer can be controlled with arguments and was renamed to unitTest.
- Update: In window\winGetInfo_ rewritten without loss of functionality because it was too large to be cached.
- Update: in window\winGetInfo_ now supports english language OS.
- Fixed a performance bug in reDelayLH_ that would add useless returns.
- New: scopeFail_ can tell whether a function is off. And in a range of +9 to -9 endlocals correct the problem.
- Update: added call-/file- macro support to dirDelete_.
- Update: Applied more precise rules to 'The World' cannot pass tests to reduce chance of false positives.
- Fixed a bug in workFileClose_ that would accept $vr byRef and then fails because it can't determine the mutex.
- Fixed in IO\file\fileDeleteAtboot_ added missing class dependency IO\file\autoRun_.
- Fixed in IO\file\fileReplaceString_ would return an unresolvable errorCode.
- Performance update: §cacls_ .
- Dropped: kernel\loop\forT_, this is a difficult token to work with, is not as efficient as the other tokens, and is not required.
- Update: kernel\unitTest\unitTest more informative errorMessage.
- Fixed: some tests where not cleaning up fully, leaving garbage files behind.
- Fixed: bruteParam_ was using inverted dequoting rules.
- Update: In kernel\IO\file\fileCopy_ now supports regular expressions as part of argument.
- Update: In :IO\keyboard\$cmdGetKey, slightly improved algorithm.
- Performance update: getDosKeyMacro_, setDosKeyMacro_, filePutMacro_ from 4 to 3 variables for encoding(worstCase 300% covered 300%).
- Performance update: getDosKeyMacro_ rewritten as macro.
- Dropped: §getDosKeyMacro_, no longer required.
- Dropped: echon2_, nechon2_, due to lack of use.
- Fixed: debugger was not initialized if loaded from cache.
- Fixed: external program failes when running from a cmd /K initiated environment.
- Update: IO\reg\path\regPathTouch_ now supports any char but NUL to appear in it's arguments.
- New: IO\net\shareRemove_ remove mountpoint.
- New: method shareRemove of type Share.
- Fixed: In process\processGetCPULoad_ now enums 'Idle' performance counters instead of 'Total' because it turns out to be broken on XP.
- Fixed: in object\reg\key\regKeyTouch added missing dependency IO\reg\key\regKeyTouch_
- Fixed: in object\reg\key\regKeyEnum added missing dependency IO\reg\key\regKeyEnum_
- Fixed: in kernel\IO\reg\path\getRegPath_ now removes ending backslash that causes reg.EXE to fail.
- Fixed: in kernel\IO\reg\key\regKeyWrite_ now invokes getRegPath_ to make sure regPath is properly formed.