Embed data in a BTM File

#1
Code:
:: This batch file allows you to paste in whatever text that you want,
::   into the batch file,
::   and then place each line of text into an array element.
::
:: This eliminates the need to read text in from a separate file.
::
:: This does not take into account expansion and special characters in the text,
::  such as what might be found in URL addresses.
::
:: RULES:
:: 1) The batch label containing the data must be :the_data
:: 2) The batch label :the_data must be the last label in the batch file
:: 3) Your text must be placed between the :the_data label and the return
::
:: TCC  11.00.50   Windows XP [Version 5.1.2600]
:: TCC Build 50   Windows XP Build 2600  Service Pack 3

@setlocal
@echo off

gosub get_data
::
:: Do whatever you want with the data
:: I am going to display it
::
do i = 1 to %lc
  echo %aData[%i]
enddo
echo.
echo Total Data Items: %lc
::
:: Data elements begin at 1
:: Total number of data elements is stored in %lc
:: The array is called aData
::
:: Remove the array
::
unsetarray aData
endlocal
quit

:get_data
:: Find out where the last label :the_data is in this batch file
::
ffind /klmrt":the_data" "%_batchname" > clip:
::
:: Get rid of everything but the line number
::
set the_data=%@filter[0123456789,%@clip[0]]
::
:: Save the line where the data begins
::
set data_line=%the_data
::
:: Find out how many lines of data there are
::
set lc=0
do forever
  if %@line["%_batchname", %data_line] eq return leave
  set lc=%@inc[%lc]
  set data_line=%@inc[%data_line]
enddo
::
:: Create an array for the data items
::
setarray aData[%@eval[%lc+1]]
::
:: Read the data into the array
::  Arrays begin at 0. I'm starting at 1
::
do i = 1 to %lc
  set aData[%i] = %@line["%_batchname", %@eval[%the_data + %i - 1]]
enddo
return

:the_data
This is line 1
This is line 2
This is line 3
This is line 4
return
 
Nov 2, 2008
180
0
#2
I used a do a lot of data embedding, by setting and changing aliases in the batch, eg

Code:
alias a `something`
alias b `something else`
gosub label

alias a `another thing`
alias b `another thing too`
gosub label

goto :end

:label
a first instance
a second instance
b third instance
a fourth instance
return
The idea is that one edits the label section to reflect the current status of different projects, which would be shown when the batch is run. I used it as a project management case.

The current manner is to use a rexx script, and use the .cmd file as data, eg

Code:
EXTPROC myproc.rex
(data for myproc.rex)
 
#3
| I used a do a lot of data embedding, by setting and changing aliases
| in the batch, eg
...
| The idea is that one edits the label section to reflect the current
| status of different projects, which would be shown when the batch is
| run. I used it as a project management case.

I did its equivalent starting in 4DOS using project-unique definition files
for use with SET/R, ALIAS/R and FUNCTION/R. Similarly for use with different
compilers and different clients. I also took advantage of the UNSET /R etc.
commands. All you need is a single variable PROJECT, which is set to the
name of the current project (or compiler or client ...), if any. To change
projects do this:

Files for a project

--- begin PROJECT.BTM ---
iff defined PROJECT then
do cmd in /L ALIAS FUNCTION SET
set un=%project.un%@left[1,%cmd]
if isfile %un un%cmd /r %project.un
enddo
endiff
set project=%1
iff defined project then
do cmd in /L ALIAS FUNCTION SET
set xx=%project.%@left[3,%cmd]
if isfile %xx %cmd /r %xx
enddo
endiff
--- end PROJECT.BTM ---

This assumes that the name part of all project control files is the name of
the project, and the extension is one of ALI, FUN, SET to define the
project, and UNA, UNF, and UNS to terminate the project. If you execute the
batch file with no parameters, it will remove the current project's
definitions, if any. With a parameter it will replace current definitions,
if any, with those of the new project.

I always found the use of data files loaded via the /R option much more
flexible than issuing many ALIAS etc. commands, because there is no limit on
special character usage, and you can still include environment variables in
the definitions, which will be expanded at the time the entity (alias,
function, or variable definition) is used, i.e., I have delayed expansion.

BTW, typically the "un" files could be the same as the definition files,
because all of the relevant commands (UNALIAS, UNFUNCTION, UNSET) ignore the
line after the first separator (whitespace or equal sign "=").
--
Steve
 
Nov 2, 2008
180
0
#4
Using external files for action might be the way if one is doing the same thing over several data sets, eg setting up different groups of data.

On the other hand, one can reuse aliases names in the same batch by resetting the alias as one goes. This is what i did in my batch files, eg

Code:
gosub todotitle:
set aa = type %1*
set bb = rem
gosub datalist:
gosub calldonetitle:  [info to draw a title for done]
set aa = rem
set bb = echo %1*
gosub datalist:
goto :end
One edits the batch, updating the headers, and then runs the batch.
 
#5
I think the following is a very simple and effective way to handle
embedded data. For larger data structures I'd use @fileopen, @fileread
etc.:


> > Test.btm
> > Embedded data handling example
@echo off
gosub DATA

> > Here you add what you want to do with the data below
do n = %start to %end
echo %@line[%0,%start]
set start=%@inc[%start]
enddo
quit


> DATA
> > Add your data between the text - endtect labels
set start=%@eval[%_batchline+1]
text > nul
1
2
3
4
5
6
7
8
9
blablabla
endtext
set end=%@eval[%_batchline-3]
return
 
#6
I think the following is a very simple and effective way to handle
embedded data.
Much more elegant than what I was using. It also works in 4DOS 8.00. Many thanks.

Joe

Code:
:: This batch file allows you to paste in whatever text that you want,
::   into the batch file, and process accordingly.
::
:: This eliminates the need to read text in from a separate file.
::
:: This does not take into account expansion and special characters in the text,
::  such as what might be found in URL addresses.
::
:: Thanks to Klaus Meinhard for making this much simpler.
::
::
@setlocal
@echo off

gosub data
::
:: Do whatever you want with the data
:: I am going to display it
::
do i = %start to %end
  echo %@line[%_batchname,%i]
enddo

endlocal
quit

:data
set start=%@eval[%_batchline+1]
text > nul
This is line 1
This is line 2
This is line 3
This is line 4
%_isodate
%_batchname
endtext
set end=%@eval[%_batchline-3]
return