[comp.lang.rexx] REXX, VM/CMS

kirk@hobbes.catt.ncsu.edu (Kirk Krauss) (01/22/91)

In article 388, Steve Siperas asks how to pull files successively
from a minidisk (in the VM environment).

Here's a quickie that should do the job:


/*  Get filename, filetype, and filemode of each file on mdisk  */

 makebuf
 queue 'SNAME#FILE'
'FILEL'
 dropbuf
 X = 0
 do forever
    X = X + 1
   'EXECIO 1 DISKR 'userid()' FILELIST A 'X
    if RC > 0 then leave
    pull FN.X FT.X FM.X .
 end
 NUMFILES = X - 1


The above EXEC places all the filename, filetype, and filemode information
into an array sorted by filename.  You may choose to type any or all of
the files to your terminal, print them, send them to another account, etc.  
For instance, to type all the files to your terminal screen, just add 
something like the following:


 do Y = 1 to NUMFILES
    'TYPE 'FN.Y FT.Y FM.Y
 end


                                                    Kirk
                                                    kirk@catt.ncsu.edu 

patman@lotus.com (Pat Mancuso) (01/23/91)

In article <1991Jan22.022019.5280@ncsuvx.ncsu.edu> kirk@hobbes.catt.ncsu.edu (Kirk Krauss) writes:
>
>In article 388, Steve Siperas asks how to pull files successively
>from a minidisk (in the VM environment).
>
...
>    X = X + 1
>   'EXECIO 1 DISKR 'userid()' FILELIST A 'X
...
>
>                                                    Kirk
>                                                    kirk@catt.ncsu.edu 

ACK!  Don't do a diskr for each line of the result!  That could
take forever!  There is a *much* more efficient way to do this:

'MAKEBUF'
'LISTFILE * * A (STACK FIFO NOH'
line.0 = queued()
do i = 1 to line.0
  parse pull line.i
end
'DROPBUF'

This gets everything into line.i, but if you wanted to have 'em in
separate variables you could do 'parse pull fn.i ft.i fm.i .' or
something.

If you really *have* to read in a bunch of lines from a file,
use something like:
'EXECIO * DISKR' fn ft fm '(FINIS STEM LINES.'
(the trailing dot is important, as EXEC2 isn't real bright...)

Both of these result in the same thing:
line.0 will be the number stem values that
are valid, and line.1 -> line.(line.0) will be the contents
of the lines of the file. 

--
Pat Mancuso - patman@lotus.com

eric@sejnet.sunet.se (Eric Thomas, SUNET) (01/24/91)

Well, the original program had a lot of examples of things one should not do,
but I didn't want to comment - there's just too many programs like that, and
the original poster hadn't said this way the "right way" to do it, just that
the program works :-)

In article <1991Jan23.135615.20072@lotus.com>, patman@lotus.com (Pat Mancuso) writes...
>ACK!  Don't do a diskr for each line of the result!  That could
>take forever!  There is a *much* more efficient way to do this:
> 
>'MAKEBUF'
>'LISTFILE * * A (STACK FIFO NOH'
>line.0 = queued()
          ^^^^^^^^
>do i = 1 to line.0
>  parse pull line.i
>end
>'DROPBUF'

This will read anything that might have been previously stacked by another
program (possibly the program that called this one). These are don't contain
LISTFILE output, so your program may crash, and the calling program will
most probably issue terminal reads or get a REXX error. What you want to do
is save 'queued()' into some variable before the LISTFILE, and place the
difference between 'queued()' and that variable in line.0; if you don't do
that, there's no point in using MAKEBUF to isolate your data from what was
previously stacked.

>If you really *have* to read in a bunch of lines from a file,
>use something like:
>'EXECIO * DISKR' fn ft fm '(FINIS STEM LINES.'
>(the trailing dot is important, as EXEC2 isn't real bright...)

EXEC2? Did you mean EXECIO? It was designed to allow you to write the result
into LINE1, LINE2, LINE3... if such is your desire. Consider the case of a
file which you know to have only 2 lines, ie where you are not going to do a
'Do i = 1 for line.0'; it makes sense to have the result in LINE1 and LINE2,
which REXX can also access more efficiently (whereas each access to a stem
variable involves the overhead of evaluating the tail).

  Eric

patman@lotus.com (Pat Mancuso) (01/25/91)

In article <2848@sunic.sunet.se> eric@sejnet.sunet.se writes:
><stuff about the stack>

Granted- I stand corrected.  

>
>EXEC2? Did you mean EXECIO? 
>
>  Eric
No, I meant EXEC2, 'cause EXECIO originated from EXEC2-land.  

(Disclaimer: I have had nothing but bad experiences with EXEC2,
and as such, I am thouroughly biased against EXEC2 and convinced
that it is the root of all evil... :) 

As EXEC2 has no concept of stem variables (see disclaimer), EXECIO's 
STEM option was set up to cater to both REXX and EXEC2.  EXECIO only 
knows enough to create variables with a base name, and suffix them 
with a number.  If you want to use 'em in EXEC2, the base would be LINE, 
and if you want a rexx stem, you use LINE. and it 'just works out' that it
ends up looking (to rexx) like a stem variable.  If there were no EXEC2,
EXECIO (or something better) would not need to be told that its STEM
option should create stem variables (intuitive, no?).  

Yes, you can still use them in REXX as LINE1 and LINE2, but for the cases 
where you *don't* know the number of lines in a data source (such as a list
of the files on a disk...) a stem seems more appropriate.  The overhead
in accessing line.1 and line.2 over line1 and line2 is minimal (given
that you know n=2) and considering that someday n might change to 3 (or 37 for
that matter), the maintenance/code-clarity benefits outweigh it in my
opinion.  

(Hmmm...maintenance?, performance?...what was the question again? ;)

--
Pat Mancuso - patman@lotus.com

eric@sejnet.sunet.se (Eric Thomas, SUNET) (01/25/91)

In article <1991Jan24.170939.11582@lotus.com>, patman@lotus.com (Pat Mancuso) writes...
>As EXEC2 has no concept of stem variables (see disclaimer), EXECIO's
>STEM option was set up to cater to both REXX and EXEC2.

While I am not one of the developers of EXECIO (god forbid!) and have not heard
anything from them to back up this statement, I am fairly convinced that this
is not the case. Remember, the STEM option appeared in CMS release 4, and was
not available before. REXX was introduced in CMS release 3, and EXECCOMM was
already there. I believe the STEM option was created specifically for REXX, to
make life easier for the programmers and also to get rid of the 255 bytes
(stack) limitation.

>Yes, you can still use them in REXX as LINE1 and LINE2, but for the cases
>where you *don't* know the number of lines in a data source (such as a list
>of the files on a disk...) a stem seems more appropriate.

I agree, of course. I was just pointing out that there ARE cases, in REXX,
where the use of non-stem variables is ALSO appropriate.

>The overhead
>in accessing line.1 and line.2 over line1 and line2 is minimal (given
>that you know n=2) and considering that someday n might change to 3 (or 37 for
>that matter), the maintenance/code-clarity benefits outweigh it in my
>opinion.

I do not agree. When you write 'line.2', REXX first evaluates the expression
'2', finds out that its value is '2', builds up the resulting variable name,
finds out that it is 'line.2' (really?), and then calls the fetch-that-variable
routine. With 'line2', the routine is called directly. If you use that variable
in a loop, it can make a difference; the overhead for each fetching operation
is an extra 125% or so.

Granted, if 2 changes to 3, you will have to c/line2/line3/* *, but then how
does this differ from having to change all occurences of line.2 to line.3? Or
did you mean something like 'line.parmline'? THAT is cleaner, but also 4 times
slower... It may or may not matter, depending on how often you access the
variable. 

  Eric