-
-
Save mataha/6741751e22dc09666d8e0b71ea70502a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@goto :parse | |
@:: | |
@:: batchouli | |
@:: ========= | |
@:: | |
@:: <FILL THIS CRAP LATER> for Windows command scripts. | |
@:: | |
@:: Usage: %(program)s [OPTIONS] Do the thing | |
@:: | |
@:: Options: | |
@:: -h or -? Print help | |
@:: | |
:main | |
%$daynow% result | |
%$dayadd% result 13 | |
%$putout% "%result.year% %result.month% %result.day%" | |
exit /b 0 | |
#pragma checksum "batchouli.cmd" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "d41d8cd98f00b204e9800998ecf8427e" | |
:exit (exit_code: number, _: string) > Abort | Never | |
setlocal DisableDelayedExpansion | |
::: Without a fully-qualified path, Windows first looks in the application | |
::: directory (`%__APPDIR__%`) and in the current directory (`%__CD__%`) if | |
::: `NeedCurrentDirectoryForExePathW(ExeName)` is true before checking the | |
::: system directories, thus try to avoid executing unqualified `cmd.exe`. | |
::: See also: https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepathw | |
if not defined ComSpec (set "ComSpec=%SystemRoot%\System32\cmd.exe") | |
( | |
(goto) & (goto) & call :exit %~1 || ( | |
if "%~1" equ "1" ( | |
(call) | |
) else if "%~1" equ "0" ( | |
(call ) | |
) else ( | |
"%ComSpec%" /d /c @exit /b %~1 2>nul | |
) | |
) | |
) 2>nul | |
endlocal & exit /b 3221225786 "`exit()` subroutine never returns normally" | |
:error (exit_code: number, message: string?) > Abort | |
setlocal DisableDelayedExpansion | |
if not defined PROGRAM (set "program=%~n0") | |
if """" == ""%2"" ( | |
set "separator=" | |
) else ( | |
set "separator=: " | |
) | |
%$puterr% "%[red]%[%program% error]%[/red]%%separator%%~2" | |
endlocal & call :exit %1 "%~2" | |
:panic (message: string?) > Never | |
() %~* | |
:parse (options: string?) | |
@if not "Windows_NT" == "%OS%" goto :_fini | |
@(verify "" || setlocal DisableDelayedExpansion EnableExtensions) 2>nul || ( | |
(echo(Command Extensions could not be enabled; terminating the program.) | |
) >&2 && goto :EOF "Command Extensions could not be enabled" | |
@if not defined CMD_DEBUG (echo off) | |
@call :_init | |
@set /p "options=" <"%~f0" >nul | |
@for /f "tokens=1,2,* delims==@+.,:; " %\p%m in ("%options%") do @( | |
set "options=" | |
) & if /i "goto" equ "%\p%~m" if /i "parse" equ "%\p%~n" ( | |
set "options=%\p%~o" | |
) | |
@if not defined options (goto :main) | |
set /a "shift=1" | |
::: base/cmd/cbatch.c#L3533 | |
:parse_loop | |
if """" == ""%1"" (goto :parse_end) | |
if ""--"" == ""%1"" (goto :parse_end) | |
set "argument=%~1" | |
setlocal EnableDelayedExpansion | |
set PATH= | |
set PATHEXT= | |
if not defined argument (set /a "shift+=1" & goto :parse_loop) | |
if "-" neq "%argument:~0,1%" (set /a "shift+=1" & goto :parse_loop) | |
if "" equ "%argument:~1,1%" (set /a "shift+=1" & goto :parse_loop) | |
if not defined argument ( | |
set /a "shift+=1" | |
goto :parse_loop | |
) | |
if defined argument if "-" equ "%argument:~0,1%" ( | |
... | |
) else ( | |
if 9 leq %shift% (goto :parse_end) | |
set /a "shift+=1" | |
if ... | |
) | |
:parse_end | |
goto :main | |
:_parse (options: string, arguments: string...) | |
if "%~1" neq "0" (call :error EXIT_FAILURE "parameters are not supported") | |
set ^"options=a:^" | |
::: the plan: | |
::: shift regular parameters to the beginning | |
::: '--' stops option parsing, parameters only from that point | |
::: todo: should there be a variable for accumulating all the parameters? | |
::: todo: for options with arguments, should "" be equal to undefined? | |
::: or should the arguments contain unpeeled quotes? | |
::: todo: should we support options with optional arguments? | |
::: | |
exit /b 255 | |
for %%o in (%options%) do for /f "tokens=1,* delims=:" %%u in ("%%o") do ( | |
set "%%u=%%~v" | |
) | |
set "state=OPTIONS" | |
set "shift=1" | |
:parse_loop | |
if """" == ""%1"" ( | |
goto :parse_end | |
) else ( | |
set /a "shift+=1" | |
shift /? | |
goto :parse_loop | |
) | |
set "test=%~1" | |
setlocal EnableDelayedExpansion | |
if defined test if "!test:~0,1!"=="-" | |
if "!test!"=="-h" (call :usage) | |
if "!test!"=="-?" (call :usage) | |
set "test=!options:*%~3:=! " | |
if "!test!"=="!options! " ( | |
endlocal & call :error %EXIT_USAGE% "invalid option -- %~3" | |
) else if "!test:~0,1!"==" " ( | |
endlocal & set "%~3=1" | |
) else ( | |
setlocal DisableDelayedExpansion & if defined state if "%~4"=="" ( | |
call :error %EXIT_USAGE% "option requires an argument -- %~3" | |
) else ( | |
endlocal | |
) | |
endlocal & set "%~3=%~4" | |
shift /3 | |
) | |
shift /3 | |
goto :parse_loop | |
:parse_end | |
for %%o in (options state) do (set "%%o=") | |
goto :EOF | |
goto :main | |
if defined options if not "%options%" equ "%options::=%" ( | |
call :error 3 "options cannot include a colon" | |
) | |
:parse_loop | |
if """" == ""%1"" (shift /1 & goto :parse_end) | |
if ""--"" == ""%1"" (shift /1 & goto :parse_end) | |
set "test=%~1" & setlocal EnableDelayedExpansion | |
goto :parse | |
:usage (program: string?) > Abort | |
setlocal EnableDelayedExpansion | |
if not defined PROGRAM (set "program=%~f1") | |
set "sections=Description Usage Arguments Options Environment Files Notes" | |
set "synopsis=" | |
for /f usebackq^ delims^=^ eol^= %\p%l in ("%~f0") do ( | |
set "line=%\p%~l" | |
set "text=" | |
set "ignore=" | |
if not "@::" equ "!line:~0,3!" ( | |
if ":::" equ "!line:~0,3!" ( | |
set "ignore=1" | |
) else for /f "delims==@+.,:;/\[] " %\p%# in ("!line!") do ( | |
if /i not "call" equ "%\p%#" if /i not "goto" equ "%\p%#" ( | |
goto :usage_end | |
) | |
) | |
set "ignore=1" | |
) else if "" equ "!line:~3,1!" ( | |
set "text=!line:~3!" | |
) else ( | |
set "text=!line:~4!" | |
) | |
if not defined ignore if "---" equ "!text:~0,3!" ( | |
goto :usage_end | |
) else if not defined synopsis ( | |
if defined program if not defined text (set "synopsis=Usage") | |
if not defined program if defined text (set "program=!text!") | |
) else if defined text ( | |
if not " " equ "!text:~0,1!" ( | |
if not defined program if """" == ""%1"" (set "program=%~f0") | |
for /f "delims=" %\p%b in ("!program!") do ( | |
set "text=!text:%%(program)r=%[b]%%\p%~nxb%[/b]%!" | |
set "text=!text:%%(program)s=%[b]%%\p%~nb%[/b]%!" | |
) | |
for /f "tokens=2 delims=:" %\p%c in (" :!text!") do ( | |
set "header=" | |
for %\p%s in (%sections%) do if not defined header ( | |
if "%\p%~s" equ "%\p%c" ( | |
%$putout% | |
set "text=!text:*%\p%c=%[b]%%[u]%%\p%c%[/b]%%[/u]%!" | |
set "header=1" | |
) | |
) | |
) | |
) else ( | |
for %\p%t in (!text!) do ( | |
set "token=%\p%t" | |
if defined token if "-" equ "!token:~0,1!" ( | |
set "tail=!text:* %\p%t=!" | |
if not defined tail ( | |
set "head=!text!" | |
) else for /f "delims=" %\p%z in ("!tail!") do ( | |
set "head=!text:%\p%z=!" | |
) | |
set "head=!head: %\p%t=!" | |
set "text=!head! %[b]%%\p%t%[/b]%!tail!" | |
) | |
) | |
) | |
%$putout% "!text!" | |
) | |
) | |
:usage_end | |
endlocal & call :exit %EXIT_SUCCESS% | |
:_init () | |
set /a "EXIT_SUCCESS=0, EXIT_FAILURE=1, EXIT_USAGE=2, EXIT_ERROR=3" | |
(set ^"\=^^^ | |
) & (set ^"\n=^ | |
) & if "%=^%=" == "%=%=" ( | |
set ^"\p=%%<nul" | |
) else ( | |
set ^"\p=^%<nul" | |
) | |
for /f %\p%r in ('"copy /y /z "%~f0" nul"') do ( | |
set ^"\r=%\p%~r" | |
set ^"\t= " | |
) | |
set ^"$argc="tokens=1-%\p%~$=_=:$#,*"" | |
set ^"$for=%\p%%\p%~$=_=:$#" | |
for /f "delims== " %\p%! in ( | |
"!=! ^^^!" | |
) do for /f %\p%^^ in ( | |
"^ ^^^^%\p%!=%\p%!" | |
) do set ^"$define=for %\p%$ in ($name) do ^ | |
@for /f "delims== " %\p%%\p%! in ("%\p%!=%\p%! %\p%^%\p%^%\p%^%\p%!") do ^ | |
@for /f %\p%%\p%^^%\p%^^ in ("%\p%^ %\p%^%\p%^%\p%^%\p%^%\p%^%\p%!=%\p%^%\p%!") do ^ | |
@set %\p%^^"%\p%$=" | |
::: debug (variable: string) | |
%$define:name=debug% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 ( %\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=1% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& if "%$for:#=~1%" equ "" ( %\% | |
(echo(%[b]%%\p%$%[/b]%: undefined parameter received: variable) ^& 2^>nul (break)%\% | |
) else ( %\% | |
setlocal EnableDelayedExpansion %\% | |
(set%\p%^^ __variable=%\p%!%$for:#=~1%%\p%!) %\% | |
if not defined __variable ( %\% | |
(echo(%[b]%%$for:#=~1%%[/b]% ::= undefined) %\% | |
) else if "%\p%!__variable%\p%!" equ "-" ( %\% | |
(echo(%[b]%%$for:#=~1%%[/b]% ::= "-") %\% | |
) else (if ERRORLEVEL %\p%!__variable%\p%! call ) ^>nul 2^>^&1 ^&^& ( %\% | |
if not "%\p%!__variable:~0,1%\p%!" equ "-" (set "__sign=") else ( %\% | |
set "__sign=-" %\% | |
set "__variable=%\p%!__variable:~1%\p%!" %\% | |
) %\% | |
for /f "tokens=* delims=0" %$for:#=a% in ("%\p%!__variable%\p%!") do ( %\% | |
if "" == "%$for:#=~a%" ( %\% | |
set "__variable=0" %\% | |
) else ( %\% | |
set "__variable=%\p%!__sign%\p%!%$for:#=a%" %\% | |
) %\% | |
) %\% | |
(echo(%[b]%%$for:#=~1%%[/b]% ::= %\p%!__variable%\p%!) %\% | |
) ^|^| ( %\% | |
for %$for:#=p% in ("s/\/\\/" "s/%\p%!\r%\p%!/\r/" "s/%\p%!\t%\p%!/\t/") do ( %\% | |
for /f "tokens=2,3 delims=/" %$for:#=q% in ("%$for:#=~p%") do ( %\% | |
set "__variable=%\p%!__variable:%$for:#=~q%=%$for:#=~r%%\p%!" %\% | |
) %\% | |
) %\% | |
(echo(%[b]%%$for:#=~1%%[/b]% ::= "%\p%!__variable%\p%!") %\% | |
) %\% | |
endlocal ^& (call ) %\% | |
) ^<nul ^>con %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
::: putout (string: string) | |
%$define:name=putout% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 (%\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=1% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& (echo(%$for:#=~1%) ^& (call ) %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
::: puterr (string: string) | |
%$define:name=puterr% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 (%\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=1% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& (echo(%$for:#=~1%) ^& (call ) %\% | |
) %\% | |
) ^>^&2 else setlocal DisableDelayedExpansion ^& set __args= " | |
::: strhex (out result: string, number: int, prefix: string? = "0x") | |
%$define:name=strhex% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 ( %\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=3% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& if "%$for:#=~1%" equ "" ( %\% | |
call :error %EXIT_ERROR% "%[b]%%\p%$%[/b]%: undefined parameter received: result"%\% | |
) else ( %\% | |
setlocal EnableDelayedExpansion %\% | |
set /a "__number=%$for:#=~2% + 0" ^>nul 2^>^&1 ^& ( %\% | |
set "__prefix=%$for:#=~3%" %\% | |
) ^& if "" == "%$for:#=3%" ( %\% | |
set "__prefix=0x" %\% | |
) %\% | |
set "__map=0123456789abcdef" %\% | |
set "__hex=" %\% | |
set "__digit=" %\% | |
for /l %$for:#=_% in (1, 1, 8) do ( %\% | |
set /a "__digit=__number & 15, __number>>=4" %\% | |
for %$for:#=d% in (%\p%!__digit%\p%!) do ( %\% | |
set "__hex=%\p%!__map:~%$for:#=d%,1%\p%!%\p%!__hex%\p%!" %\% | |
) %\% | |
) %\% | |
for /f "delims=" %$for:#=v% in ("%\p%!__prefix%\p%!%\p%!__hex%\p%!") do ( %\% | |
endlocal ^& set "%$for:#=~1%=%$for:#=v%" ^& (call ) %\% | |
) %\% | |
) %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
::: strlen (out result: int, in? string: string) | |
%$define:name=strlen% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 ( %\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=3% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& if "%$for:#=~1%" equ "" ( %\% | |
call :error %EXIT_ERROR% "%[b]%%\p%$%[/b]%: undefined parameter received: result"%\% | |
) else ( %\% | |
setlocal EnableDelayedExpansion %\% | |
if "%$for:#=~2%" == "%$for:#=2%" ( %\% | |
(set%\p%^^ __string=%\p%!%$for:#=2%%\p%!) %\% | |
) else ( %\% | |
(set%\p%^^ __string=%$for:#=~2%) %\% | |
) %\% | |
if not defined __string ( %\% | |
set "__length=0" %\% | |
) else ( %\% | |
set "__length=1" %\% | |
for %$for:#=#% in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( %\% | |
if not "" equ "%\p%!__string:~%$for:#=#%,1%\p%!" ( %\% | |
set /a "__length+=%$for:#=#%" %\% | |
set "__string=%\p%!__string:~%$for:#=#%%\p%!" %\% | |
) %\% | |
) %\% | |
) %\% | |
for %$for:#=v% in (%\p%!__length%\p%!) do ( %\% | |
endlocal ^& set "%$for:#=~1%=%$for:#=v%" ^& (call ) %\% | |
) %\% | |
) %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
::: dayadd (ref result: {day: int, month: int, year: int}, days: int = 0) | |
%$define:name=dayadd% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 ( %\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=2% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& if "%$for:#=~1%" equ "" ( %\% | |
call :error %EXIT_ERROR% "%[b]%%\p%$%[/b]%: undefined parameter received: result"%\% | |
) else ( %\% | |
setlocal EnableDelayedExpansion %\% | |
set /a "__x=%$for:#=~2% + 0" %\% | |
set /a "__d=%$for:#=~1%.day + 0" %\% | |
set /a "__m=%$for:#=~1%.month + 0" %\% | |
set /a "__y=%$for:#=~1%.year + 0" %\% | |
if %\p%!__m%\p%! leq 2 (set /a "__y-=1") %\% | |
if %\p%!__y%\p%! geq 0 (set /a "__era=__y") else (set /a "__era=__y - 399") %\% | |
set /a "__era/=400, __yoe=__y - __era * 400" %\% | |
if %\p%!__m%\p%! gtr 2 (set /a "__doy=__m - 3") else (set /a "__doy=__m + 9") %\% | |
set /a "__doy=(153 * __doy + 2) / 5 + __d - 1" %\% | |
set /a "__doe=__yoe * 365 + __yoe / 4 - __yoe / 100 + __doy" %\% | |
set /a "__z=__era * 146097 + __doe + __x" %\% | |
if %\p%!__z%\p%! geq 0 (set /a "__era=__z") else (set /a "__era=__z-146096") %\% | |
set /a "__era/=146097, __doe=__z - __era * 146097" %\% | |
set /a "__yoe=(__doe - __doe / 1460 + __doe / 36524 - __doe / 146096) / 365" %\% | |
set /a "__y=__yoe + __era * 400" %\% | |
set /a "__doy=__doe - (365 * __yoe + __yoe / 4 - __yoe / 100)" %\% | |
set /a "__p=(5 * __doy + 2) / 153, __d=__doy - (153 * __p + 2) / 5 + 1" %\% | |
if %\p%!__p%\p%! lss 10 (set /a "__m=__p + 3") else (set /a "__m=__p - 9") %\% | |
if %\p%!__m%\p%! leq 2 (set /a "__y+=1") %\% | |
for /f %$argc:#=3% %$for:#=a% in ( %\% | |
"%\p%!__d%\p%! %\p%!__m%\p%! %\p%!__y%\p%!" %\% | |
) do endlocal ^& ( %\% | |
set /a "%$for:#=~1%.day= %$for:#=a% + 0" %\% | |
set /a "%$for:#=~1%.month=%$for:#=b% + 0" %\% | |
set /a "%$for:#=~1%.year= %$for:#=c% + 0" %\% | |
) ^& (call ) %\% | |
) ^>nul 2^>^&1 %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
::: daynow (out result: {day: int, month: int, year: int}) | |
%$define:name=daynow% for %$for:#=#% in (1 2) do if %$for:#=#% equ 2 ( %\% | |
setlocal EnableDelayedExpansion %\% | |
for /f %$argc:#=1% %$for:#=0% in (": %\p%!__args%\p%!") do ( %\% | |
endlocal ^& endlocal ^& if "%$for:#=~1%" equ "" ( %\% | |
call :error %EXIT_ERROR% "%[b]%%\p%$%[/b]%: undefined parameter received: result"%\% | |
) else ( %\% | |
for /f "skip=1 tokens=1,5,9 delims== " %$for:#=a% in ( %\% | |
'""%SystemRoot%\System32\wbem\WMIC.exe" path Win32_LocalTime get 2>nul"' %\% | |
) do for %$for:#=a% in (%$for:#=a%) do if not "%$for:#=~a%" equ "" ( %\% | |
set /a "%$for:#=~1%.day= %$for:#=a% + 0" %\% | |
set /a "%$for:#=~1%.month=%$for:#=b% + 0" %\% | |
set /a "%$for:#=~1%.year= %$for:#=c% + 0" %\% | |
) ^& (call ) %\% | |
) ^>nul 2^>^&1 %\% | |
) %\% | |
) else setlocal DisableDelayedExpansion ^& set __args= " | |
@goto :EOF | |
:_fini () | |
@set windir= | |
@set winbootdir= | |
@if "" == "%windir%" set OS=DOS | |
@if "" == "%OS%" if "" == "%winbootdir%" set OS=Windows 3.x | |
@if "" == "%OS%" set OS=Windows 95 | |
@echo This program is not compatible with your operating system (%OS%). | |
:EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment