Here's some rough ASIS code for those who want to try write their own.
This is all from memory.  I don't have a TSO Pipes platform to test and
debug on.  I'm sure there's lots of room for improvement.  So post your
results, and I'll try to help out.  If we can come to a consensus, maybe
someone can suggest somewhere to post the final product for future use.


If you have to write to more than one member of a PDS, add this logic to
the code below instead of the second CALLPIPE:  Write the primary input
to a stem in one CALLPIPE, and when that finishes at EOF, use another
CALLPIPE to write the data to the output data set.

When invoking, follow the dsn (and any member) with one or more blanks,
and any overriding or additional ALLOC parms.  A following stage is ok;
it will receive a copy of the data written to the dataset/member.

E.g. "pipe literal data | outdsn 'myuid.local.data(xyz)' lrecl(80)
like(abc) | count lines | terminal"

I don't recall how or if I handled appending to a dataset.  It didn't
come up much.

CALLPIPE TSO for alloc and free write any error messages to the console.

/* REXX - Pipe stage to write (to) a TSO dataset. */
Trace e
parse var Source OpSys CallType ExecName ExecType ExecRes UsedName Rest

Arg DSN Overrides
Parse var DSN DSN "(" Member ")" DSNRest
DSN = DSN || DSNRest /* Reattach quote if member present. */
DSNStat = sysdsn(DSN)
If word(DSNStat, 1) = "INVALID" then do
    "callpipe var DSNStat | terminal"
    exit -32
    end

DDN = DDGen()

OutStageParms = ""
If DSNStat = "OK" | DSNStat = "MEMBER NOT FOUND" then /* DS exists */
    AllocParms = "shr"
Else do /* New DS; set defaults. */
    AllocParms = "new cyl sp(10 10) recfm(v b) lrecl(8192) block(0)
unit(sysda)" /* add your SMS options if needed*/
    If Member /= "" then do
        OutStageParms = "ispfstats"        
        if pos("DIR(", Overrides) = 0 then 
            AllocParms = AllocParms "dsntype(library) dir(1)"
        end
    end

Signal on error
/* Allocate the DD. */
"callpipe (listerr end ? name" UsedName"."ExecType"."LineNo()")",
  "tso allocate ddname("DDN") dataset("DSN")" AllocParms Overrides "|
terminal"

If member = "" then 
    Target = "ddname="DDN /* DSORG PS */
Else 
    Target = Member DDN /* DSORG PO */

/* Write the data. */
"callpipe (listerr end ? name" UsedName"."ExecType"."LineNo()")",
  "*: | fo: fanout | >" Target "coerce" OutStageParms,
  "? fo:" CondConn("*.out.0")

/* Free the DD. */
"callpipe (listerr end ? name" UsedName"."ExecType"."LineNo()")",
  "tso free ddname("DDN") | terminal"

Error:
exit RC

DDGen:  /* Return next available DD beginning with prefix. */
DDPrefix = "PIP$" /* You can choose your own. */
/* Find highest used. */
"callpipe (listerr end ? name" UsedName"."ExecType"."LineNo()")",
  "tso lista st sy | strfind \"DDPrefix"\ | sort desc | not chop 4 | var
DDNumb"
If DDNumb = "DDNUMB" then DDNumb = 0
Return DDPrefix || right(DDNumb + 1, 8 - length(DDPrefix), "0") /* Use
the next number */

/*--------------------------------------------------------------------*/
/* Return source statement number of caller.       LINENO EXEC HS0508 */
/*--------------------------------------------------------------------*/
LineNo:                                                                 
trace n                                                                 
return sigl                             /*         LINENO EXEC HS0507 */

/*--------------------------------------------------------------------*/
/* If stream is connected, emit connector to it.    REXX X0312 HS0708 */
/*--------------------------------------------------------------------*/
ConnCond:                               /* Conditional connector.     */
arg Pt1 "." Pt2 "." Pt3                 /*  ISONEOF REXX X0312 HS0708 */
if RC("streamstate" Pt2 Pt3) >= 0 & RC <= 8 then                        
    return "|" arg(1)                   /*  ISONEOF REXX X0312 HS0708 */
                                                                        
return ""                               /*  ISONEOF REXX X0312 HS0708 */

-----Original Message-----
From: CMSTSO Pipelines Discussion List
[mailto:[EMAIL PROTECTED] On Behalf Of Ian S. Worthington
Sent: Tuesday, April 08, 2008 6:20 AM
To: [email protected]
Subject: Re: [CMS-PIPELINES] novice BatchPipes data set question

Doesn't tso alloc support models?  I don't have a reference to hand but
iirc
you can do something like:

alloc f(this.one) like(that.one)

warning: its been a while since I did this...

i

------ Original Message ------
Received: Tue, 08 Apr 2008 10:16:37 AM BSTou can do s
From: "John P. Hartmann" <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: novice BatchPipes data set question

>  RE: novice BatchPipes data set question
> 
>  Use PDSEs instead of flat files, but keep in mind that even in a
PDSE,
>  you cannot write more than one member at a time.
> 
>  Allocating at the > is probably the most-often-asked-for enhancement,
>  but that means implementing all of SVC 99, which is, to say the
least,
>  a bit tedious.
> 
>  There are a few shortcuts in coping with ISPF 4.2.  If you list (I
>  from a 3.4 panel) a data set similar to the one you wish to allocate
>  prior to going to 4.2, you have all the defaults set up.
> 
>  But if the creator had intended man (m/f) to use TSO, we would all
>  have infinite time on our hands.
> 
>      j.
[EMAIL PROTECTED]
> 

Reply via email to