A few days ago (as this is being written), I discovered that it is possible to create and manipulate linked lists of environment variables in batch language. Since this concept is so new to me, I really can't say much about its uses.
A linked list is a list of items organized through pointers - each list item contains a pointer to the next item in the list. Doubly linked lists contain pointers to both the previous and following items. The items do not have to be placed in any particular order in memory, since the address, or in this case, the name, of the adjoining items is contained in each item.
The initial proof-of-concept code consists of these three files:
MKLST.BAT
@echo off
set start=x001 head start
set x001=x002 start 001
set x002=x003 x001 002
set x003=stop x002 003
set stop=tail x003 stop
set current=start
:end
which generates a doubly linked list by brute force (and sets the
current item pointer to point to the head of the list),
NEXT.BAT
@echo off
%1 %2
if "%current%" == "" goto start
%0 goto pass2 %current%
:start
%0 goto pass2 start
:pass2
if "%3" == "" goto end
echo set current=%%%3%% > }{.bat
call }{
:end
which changes the pointer to the current item to point to the next
item, and
WALKUP.BAT
@echo off
%1 %2
:loop
%0 goto pass2 %current%
:pass2
if %3 == tail goto end
call next
echo %current%
%0
:end
which walks up the list from head to tail.
Obviously, these could be combined into one program, but at this stage in the development of the concept, it is better that they remain separate.
In the above test list, the structure is
item_name=next_item previous_item data
but there is no reason to consider that to be any sort of limit or
restriction. The data could just as well be code to be executed by an
interpreter or an item in another list (or the name of an item in any
list).
At this point, I have only one reasonable use for linked lists in mind: to provide a solution to the general problem of deleting or replacing batch files that are nominally executing at the time. There is supposed to be a solution to the problem of having a batch file delete itself, but it's difficult to implement, unreliable, and inapplicable to recursive programs - and I have forgotten what it is, and will ignore it here.
To do this, we must have at least one auxiliary file: the interpreter for the list based language that will do the work. This program is one that counts as a general program, to be kept available at all times, rather than a part of the batch file in question, and therefore the inability to delete it without generating an error is not part of the problem at hand.
The idea is that we create a list based language, which I will name BLISP, for Batch LISt Processor. For the purpose at hand, it need only be able to execute a small subset of the batch language, and can therefore be very simple. The interpreter is based on WALKUP.BAT and NEXT.BAT:
BLISP1.BAT
@echo off
%1 %2
:loop
%0 goto pass2 %IP%
:pass2
if exist %TFILE%.bat del %TFILE%.bat
if %3 == tail goto end
echo set INST=%%%3%% > %TFILE%.bat
echo %0 goto pass3 %%INST%% >> %TFILE%.bat
%TFILE%
:pass3
set IP=%3
%4 %5 %6 %7 %8 %9
goto loop
:end
Note that the current item pointer has been renamed IP, for
Instruction Pointer, and that the name of the transient batch file has
been made variable, so that each batch file using the interpreter can
avoid conflict with other batch files running in different DOS
sessions but in the same directory. Note that this version does not
delete the program from memory when it finishes.
The batch file to test the concept will be one that makes a copy of
itself, transfer control to the copy, and deletes the copy. It puts DIR x%0.bat
commands before and after the deletion to demonstrate the deletion.
It also uses a singly linked list.
TEST.BAT
@echo off
if exist xtest.bat goto iscopy
copy %0.bat x%0.bat
x%0.bat
:iscopy
set t001=t002 dir xtest.bat
set t002=t003 del xtest.bat
set t003=tail dir xtest.bat
set IP=t001
set TFILE=}{t
blisp1
echo this line never executes
:end
There is, naturally enough, an easier way to accomplish the task of
making a file delete itself, given that an additional, permanent
utility file can exist:
TEST.BAT
@echo off
dobat del test.bat
:end
where DOBAT.BAT is simply
@%1 %2 %3 %4 %5 %6 %7 %8 %9
and has numerous other uses as well. However, the object here is to
explore the concept of linked lists and their applications. Note that
DOBAT cannot handle multiple commands.
** Copyright 1995, Ted Davis - all rights reserved **
Input and feedback from readers are welcome. NOTE: the subject of the message must contain the word "batch" for the message to get past the spam filter.
Back to the Table of Contents page
Back to my personal links page - back to my home page