1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Embed data in a BTM File

Discussion in 'T&T - Scripting' started by Joe Caverly, Aug 8, 2010.

  1. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    659
    Likes Received:
    8
    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
    
     
  2. w_krieger

    Joined:
    Nov 2, 2008
    Messages:
    175
    Likes Received:
    0
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    | 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
     
  4. w_krieger

    Joined:
    Nov 2, 2008
    Messages:
    175
    Likes Received:
    0
    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. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    311
    Likes Received:
    0
    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.:


    @echo off
    gosub DATA

    do n = %start to %end
    echo %@line[%0,%start]
    set start=%@inc[%start]
    enddo
    quit


    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. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    659
    Likes Received:
    8
    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
    
     

Share This Page