Rexx Language Association
2008 Symposium

DUMPVARS

A wrapper for SysDumpVariables

Les Koehler
3 May 2008


Table of Contents

Abstract

Objectives

Syntax

Fileid

Examples - Keep

Examples - Delete

Source code


Abstract

The DUMPVARS function extends the syntax of SysDumpVariables to increase its usability by automatically naming dump files to tie them to the program being executed, allowing multiple generations of dump files and providing a cleanup capability.

The presentation will explain the syntax of DUMPVARS and the results of the various types of invocation.

The presentation includes the code itself, which we will explore as needed.


Objectives


Syntax

 >>- INTERPRET DUMPVARS(-------->
 >---+-----------------------------------+---)--><--
     |                                   |
     +--Keep--+------------+-------------+
     |         |   edit cmd    |         |
     |         +--,varname--+-->         |
     |          >--+-------------+       |
     |             |             |       |
     |             +--,+---------+--+    |
     |                 |            |    |
     |                 +,'.stem'----+    |
     |                                   |
     +--Delete--,--+---------+-----------+
                   |         |
                   +--- * ---+
                   |         |
                   +--first--+-->
                 >----+---, * ---+
                      |          |
                      +--, last--+-->
               >--+-------------+
                  |             |
                  +--,+---------+--+-->
                      |            |
                      +,'.stem'----+
               >--+-------------+
                  |             |
                  +---+---------+-----+
                      |               |
                      +--,'searchid'--+

Or, to look at it another way:
 >>- INTERPRET DUMPVARS(-------->
 >---+ ['Keep'] [,edit command varname]-------------+-->
     |                >--  [,'stem.'             ]--+
     |                                              |
 >---+ ['Delete' , '*' | first ---------------------+-->
            [,'*' | last]] [,'stem.'[,'searchid']]----->

 >--                       ) --><--

Perhaps the easiest way to understand it:

 >>- INTERPRET DUMPVARS(-------->
 >-- ['Keep'] [,edit command varname]               [,,'stem.'           ]-->
 >-- ['Delete' , '*' | first         [,'*' | last]] [,'stem.'[,'searchid']]-->
 >--                       ) --><--
Arg#:    1           2                    3             4       5

Fileid

The fileid consists of:
  • The disk letter of the invoker followed by underscore (e.g. "C_")
  • The filename and extension of the invoker (e.g. macro.the)
  • A generation number,starting with 0. KEEP increments this number to find a unique fileid.
  • An extension of SDV

All nicely concatenated and dotted to yield something like:

     C_macro.the.0.SDV

The dump file will be put in the same folder as the invoker.



Examples - Keep

  Interpret dumpvars()        
  -- Dumps the variables to a file
  -- replacing the previous ".0.SDV"
  -- file.

  Interpret dumpvars(,'edit')
  Interpret edit              
  -- Dumps the vars and edits the file
  -- replacing the previous file.

  Interpret dumpvars('K')     
  -- Dumps the vars to a new file,
  -- keeping the previous file.
  -- The first non-existing ".0.SDV"
  -- fileid is used.

  Interpret dumpvars('K','edit')     
  -- Dumps the vars to a new file,
  -- keeping the previous file and
  -- edits the new file.

  Interpret dumpvars(,,,'mystem.')  
  -- Sets the elements of MYSTEM.
  -- to the commands to Interpret,
  -- perhaps like this:

  do m=1 to mystem.0
    interpret mystem.m
  end


  Interpret dumpvars('K','edit',,'mystem.') 
  -- Similar to above, except
  -- a new file is created
  -- and we can edit it
  -- later, when it suits us.

  do m=1 to mystem.0
    interpret mystem.m
  end

  Interpret edit


Examples - Delete

  Interpret dumpvars('D','*')
  -- Deletes all the program's
  -- SDV files

  Interpret dumpvars('D',3,6)
  -- Deletes generation 3 to 6

  Interpret dumpvars('D',3,'*')
  -- Deletes generation 3 to last

  Interpret dumpvars('D','*',,'mystem.')
  -- Sets the elements of MYSTEM.
  -- to the commands to Interpret,
  -- perhaps like this:

  do m=1 to mystem.0
    interpret mystem.m
  end

  Interpret dumpvars('D','*',,'mystem.',,
   'N:\MyTHEstuff\F_testt.the.')
  -- Similar to above, but searches
  -- in a specific folder for SDV files
  -- that belong to a specific program.
  -- SysFileTree is used to do the search,
  -- with '*' appended to the searchid,
  -- which must end with a period.
  -- The elements of MYSTEM. are set to
  -- the commands to Interpret, just like
  -- the previous example.



Source code


-- NOTE: If not using THE, you will have to
-- tailor EDIT_CMD below and at the line flagged with !!!
-- as well as LEFT= a little further down and the ERR routine.

edit_cmd=' Address THE "x'

Parse Source . how fullme
Parse Value Reverse(fullme) With '.' em '\' .
me=Translate(Reverse(em))':'
Parse Value '0 0 0 0 0 0 0' With del? keep? edit? stem? search? .
If arg()>5 Then Do
  err?=1
  msg='To many arguments ('arg()'). Only five are allowed.'
  Signal err
End
del?=Translate(Left(Arg(1),1))='D'
keep?=Translate(Left(Arg(1),1))='K'
If Arg(5,'O') | \del? Then Do
  left=fpath.1()fmode.1()'_'filename.1()'.'    /* C:\folder\X_fileid. */
End
else do
  if del? & arg(4,'O') then do
    err?=1
    msg='A stemname [Arg(4)] must precede "'arg(5)'"'
    Signal err
  End
end
If Arg(4,'E') Then Do /* Check stem */
  stem?=Left(Reverse(Arg(4)),1)='.'
  If \stem? Then Do
    err?=1
    msg='Stemname"'Arg(4)'" must end with "."'
    Signal err
  End
  stemname=Arg(4)
  If del? Then Do    /* Might have a searchid! */
    If Arg(5,'E') Then Do     /* Looks like we do. Verify it */
      searchid=Arg(5)
      Parse Var searchid drive'\' rest
      If \sysisfiledirectory(drive'\') Then Do
        err?=1
        msg='"'searchid'" must start with a directory.'
        Signal err
      End
      Parse Upper Value Reverse(searchid) With '\' -3 '_'mode '\' .
      hit=Pos(mode,'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
      If mode='' | hit=0 Then Do
        err?=1
        msg='"'searchid'" must contain "fmode_" as a prefix to the fileid.'
        Signal err
      End
      If Left(Reverse(searchid),1)\='.' Then Do
        err?=1
        msg='"'searchid'" must end with "."'
        Signal err
      End
      z=sysfiletree( searchid ||'*','test.','FL')
      If z\=0 Then Do
        err?=1
        msg='SysFileTree yielded Result='z 'for "'searchid'*"'
        Signal err
      End
      If test.0=0 Then Do
        err?=1
        msg='No files found by SysFileTree("'searchid'*")'
        Signal err
      End
      search?=1
      left=searchid
    End
  End
End
right='.SDV'
exists?=1
str=''
middle=0
If \del? Then Do
  If \keep? Then Do
    str='Call SysFileDelete "'left||middle||right'";'
  End
  Else Do                                            /* Find unused N */
    Do n=0 While exists?
      exists?=sysisfile(left||n||right)
    End
    middle=n-1
  End
  If Arg(2,'E') Then Do
    varname=Arg(2)
    If Symbol(varname)='BAD' Then Do
      err?=1
      msg='You must specify a second argument with "Delete"'
      Signal err
    End
    edit?=1
  End
  edit_cmd=edit_cmd left||middle||right'"' /* !!! */
  str=str ,
   || 'Call sysdumpvariables "'left||middle||right'";'
  If edit? Then Do
    If \stem? Then Do
      str=str||varname"='"edit_cmd"';"
    End
    Else Do
      str=str||varname"=''"edit_cmd"'';" /* two single quotes */
    End
  End
End
Else Do                                             /* Must be Delete */
  If Arg(2,'O') Then Do
    err?=1
    msg='You must specify a second argument with "Delete"'
    Signal err
  End
  first=Arg(2)
  first_is_num?=Datatype(first,'Whole')
  first_is_all?=first='*'
  If \first_is_num? & \first_is_all? Then Do
    err?=1
    msg='Argument"'first'"must be a number or "*".'
    Signal err
  End
  last?=Arg(3,'E')
  If last? Then Do
    last=Arg(3)
    last_is_num?=Datatype(last,'Whole')
    last_is_all?=last='*'
    If \last_is_num? & \last_is_all? Then Do
      err?=1
      msg='Argument"'last'"must be a number or "*".'
      Signal err
    End
    If first_is_num? & last_is_num? Then Do
      If last=first Then Do                  /* We have a cadidate! */
          If last? Then Do
            If last_is_all? Then Do /* Save fileid to delete */
              Parse Value del.0+1 left||num||right ,
               With ix del.ix 1 del.0 .
            End
            Else Do
              If num<=last Then Do
                Parse Value del.0+1 left||num||right With ix del.ix 1 del.0 .
                If first_is_num? & last_is_num? Then Do
                  If ix=last-first+1 Then Leave f /* All done! */
                End
              End
            End
          End
          Else Do
            Parse Value del.0+1 left||num||right ,
             With ix del.ix 1 del.0 .
          End
        End
      End
    End
  End
  str=''
  If del.0\=0 Then Do /* Build the delete string */
    Do d=1 To del.0
      str=str||'Call SysFileDelete "'del.d'";'
    End
  End
End
If stem? Then Do /* Stem desired? */
  stem=''
  ctr=0
  Do While str\='' /* Pick apart the string and put it in stem */
    Parse Var str m';'str
    ctr=ctr+1
    stem=stem||stemname||ctr"='"m"';"
  End
  stem=stem||stemname'0='ctr /* Set stemname.0 */
  str=stem
End
Return str
ERR:
Return ,
 "'emsg'" "'" me msg"'"
Return 4
Exit