A bit late to the scene but here goes anyways. Below is an implementation of a stack data structure in Windows batch scripting.
Features:
- You must call the :InitializeStack subroutine before using the stack.
- Push items on the stack by calling the :Push subroutine.
- Pop items off the stack by calling the :Pop subroutine.
- The variable $Count will always contain the count of items in the stack.
- The variable $Top will always contain the most recent item added to the stack.
- The variable $Bottom will always contain the first item added to the stack.
- You can dump the content of the stack by calling the :DumpStack subroutine.
- The type of items that you can push on the stack is anything that can be stored in a variable. For example, Call :Push "String 1", Call :Push "%1", Call :Push "%MyVariable%", etc.
I use the stack in my batch files to keep track of subroutine calls. Every subroutine in my batch files starts with Call :Push %0, which pushes the current subroutine's name onto the stack and ends with Call :Pop.
Some may find it an over-kill for batch scripting but I enjoyed creating it and I hope someone will find this useful, enjoy.
@Echo Off
Cls
SetLocal
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion
Call :InitializeStack
Call :Push "String 1"
Call :Push "String 2"
Call :Push "String 3"
Call :Pop
Echo Total items in stack = !$Count!
Echo Top of stack = !$Top!
Echo Bottom of stack = !$Bottom!
Call :DumpStack
Goto End
:InitializeStack
:------------------------------------------------------------
Set "$Stack[0]=0"
Set "$Count=!$Stack[0]!"
Set "$Top="
Set "$Bottom="
Exit /b
:DumpStack
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
Echo Stack is empty.
) Else (
Echo.
Echo Stack Dump
Echo ----------
For /l %%a In (!$Stack[0]!,-1,1) Do (Echo !$Stack[%%a]!)
)
Exit /b
:Push <String>
:------------------------------------------------------------
Set /a "$Stack[0]+=1"
Set "$Count=!$Stack[0]!"
Set "$Top=%~1"
Set "$Bottom=!$Stack[1]!"
Set "$Stack[!$Stack[0]!]=!$Top!"
Exit /b
:Pop
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
Echo "Stack is empty."
) Else (
Set "$Stack[!$Stack[0]!]="
Set /a "$Stack[0]-=1"
Set "$Count=!$Stack[0]!"
If !$Stack[0]! GTR 0 (
For %%a In (!$Stack[0]!) Do Set "$Top=!$Stack[%%a]!"
Set "$Bottom=!$Stack[1]!"
) Else (
Set "$Top="
Set "$Bottom="
)
)Exit /b
:PushAllEnvironmentVariables
:------------------------------------------------------------
For /f "Tokens=* Delims=" %%a In ('Set') Do Call :Push "%%a"
Exit /b
:PopAllEnvironmentVariables
:------------------------------------------------------------
For /l %%a In (!$Stack[0]!,-1,1) Do (Set !$Stack[%%a]!)
Exit /b
:End
So, to push all environment variables you can call :PushAllEnvironmentVariables, to restore all environment variables, you can call :PopAllEnvironmentVariables
You exclude
PATH
-- just for example or for some reason. I'm especially interested in push/pop the path variable. Is there anything that speaks against backup/restorePATH
? – Wolf – 2017-06-14T12:17:26.077In fact both, an example and in case important changes were applied to the path in the meantime a precaution. @wolf – LotPings – 2017-06-14T12:21:08.810
Well, you cannot be sure in all cases, but if you have to add something to the path for a specific session only, you are definitely interested in restoring the path afterwards. You'd not have to do this if there weren't external tools that call other tools and expecting them to be in the path. – Wolf – 2017-06-14T12:24:07.213
1The code is open to changes, if one wants to restore the whole environment simply replace findstr with type. – LotPings – 2017-06-14T12:29:13.343
Thanks, I just wanted to be sure not to overlook anything important. – Wolf – 2017-06-14T12:52:01.610