Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Ed Dyreen
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)


#1 Post by Ed Dyreen » 10 Nov 2018 18:59

@echo off &cls &title %~n0
:: --------------------------------------------------------------------------------------------------------------------------
:: 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! )
External binaries are linked as optional classes. Optional classes are included using the include_ macro. Classes are included recursively so you can include entire class hierarchies in a single command. $madplay is an object. All variables and objects use $ as prefix. The § prefix is used for constants, globals and true functions.

Code: Select all

( %include_% "ext\madplay\$madplay" )
( %processStart_% /HIGH, $madplay.fullpathFile, "", "-q -S -z -r ""!$madplay.fullpath!\coolSong.MP3"" ", True )
Next code creates object $. The first True argument will make oFile_ throw an exception if the path argument is malformed or undefined. The second True argument will enable methods for the object.

Code: Select all

( %oFile_% $, "favorite.mp3", True, True )
The True argument tells the move method to throw an exception if any problem occurs, for example if the file does not exist. Most macros set an exitcode so you can implement conditions without checking errorlevels.

Code: Select all

( %$.move% "stupid.file", False ) &&echo.succes ||(

	rem now what ?
Setting it to False prevents the program to halt on any non-critical errors. I use the False explicitly here but I could just have left it out because it is the default setting for this function.

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" )
will remove "C:\my path" but in fact it will try to remove "C:\" because "my path" is a file name destroying the entire OS in the process :!:

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
Of all delimiters only starDelim cannot crash on it's input, it is also the only delimiter that can handle any input.

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
bruteParam_ is associated with starDelim_ because it can handle any character. param_ cannot handle '*' and is associated with the other delimiters.

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" )
For obvious reasons references cannot consist of default delimiters like tab, space, comma or quotes. Do not pass single character long variable names except for char $, most others are cleared. Variable names starting with $ are set and unset faster than variables starting with any other symbol outside local scopes. :idea:

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


 use: ( %oFile_% '$vr,"%~a"', '$file,%b,""', '$setsError,%c,False', '$enableMethods,%d,False' )
 err: 0 for succes, 1 for error
$vr is interpreted byValue because %~a is enclosed in double quotes, it is also required because no optional value is defined like in the 2nd argument $file which %b parameter is not quoted. This means it depends on you whether it is interpreted by value or reference. The other 2 are optional and default to False.

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


 use: ( %fileMove_% '$old,%a,""' ,'$new,%b,""' ,'$setsError,%c,False' )
 err: 0 for succes, 32 for object move failed
When working with objects you never provide the first argument %a as it is provided by the object.

Code: Select all

( %assertFail_% '$1,%%a,""', '$2,%%b,""' )
Here, the 1st rule tells the parser to accept %a byRef and byVal and allow it to be undefined. Similar for the 2nd argument.

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^!" )


) || 	( %assertFail_% )
Testing multiple returns

Code: Select all

( %fileLink_% $, "This work^^ s^!", True ) &&(

	( %assertFail_% $.attributes, "--a------" )
	( %assertFail_% $.fileSize, "0" )
) || 	( %assertFail_% )
Sometimes we wonder why a variable is not returned or errors pop up telling you've reached the maximum number of setlocals. These are typical symptoms of wrong scoping, somewhere we are using too many or too few endlocals. ScopeFail_ can tell whether your code is off. And in a range of +/-9 endlocals accurately.

Code: Select all

( %scopeFail_% /open )
...test this code...
( %scopeFail_% /close )
Let's have a look at replace_

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!" )
This will replace each single double quote in $ with the third argument and print the following lines each time it finds one.

Code: Select all

Yay quotes
Kuch. :)
Some correct parsing examples without further explanation...

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 )
For performance reasons not all functions operate in just any delayed state. The details about which expansion states are supported is commented in the function definition header where:
-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" )
No macro can return complex data to disableDelayed without using CALL which negatively impacts performance.

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.


:: --------------------------------------------------------------------------------------------------------------------------
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	Greets the world
rem 	programmer: tooComplex
:: --------------------------------------------------------------------------------------------------------------------------
:: 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	=%


%=				=%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=^
	:: $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 (


		) 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 :)
	:: (


:: 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 ! -->
Conversion took "00:33:38,230" in a VMWare6 1x3Ghz 512MB.

:: --------------------------------------------------------------------------------------------------------------------------
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.
doskitXPserver2003 v0.1 (20190129).7z
(176.67 KiB) Downloaded 120 times
external binaries.7z.004.7z
remove .7z extension, added to allow upload
(924.4 KiB) Downloaded 104 times
external binaries.7z.003.7z
remove .7z extension, added to allow upload
(1.39 MiB) Downloaded 113 times
external binaries.7z.002.7z
remove .7z extension, added to allow upload
(1.39 MiB) Downloaded 118 times
external binaries.7z.001.7z
remove .7z extension, added to allow upload
(1.39 MiB) Downloaded 105 times
Hello world !.7z
doskitXPserver2003 20181212 DEBUG kernel only.
(180.96 KiB) Downloaded 107 times
Hello world !.7z
doskitXPserver2003 DEMO v20181203
(180.96 KiB) Downloaded 121 times

Sponge Belly
Posts: 200
Joined: 01 Oct 2012 13:32
Location: Ireland

Re: doskit XP/server2003 TEASER

#2 Post by Sponge Belly » 21 Nov 2018 09:19

Hi Ed,

Doskit sounds amazing! 8)

I’d love to try it out, but I’m running Windows 7. :(

What difficulty does Doskit have with Windows 7?

- SB

Ed Dyreen
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)

Re: doskit XP/server2003 TEASER

#3 Post by Ed Dyreen » 21 Nov 2018 09:53

Sponge Belly wrote:
21 Nov 2018 09:19
Hi Ed,

Doskit sounds amazing! 8)

I’d love to try it out, but I’m running Windows 7. :(

What difficulty does Doskit have with Windows 7?

- SB
From what I've read 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.

Also doskit is completely unaware of 64bit capable OSes and it's binaries are all 32bit.

Post Reply