Portal | IBM Manuals | Downloads | Products | Refer | Info | Programs | JCLs | Forum Rules*| Site Map | Mainframe CD 
IBMMAINFRAMES.com - IBM Mainframe Support Forums Index
 
Register
 
IBMMAINFRAMES.com - IBM Mainframe Support Forums Index FAQ Search Memberlist Usergroups Profile Log in to check your private messages Log in
 
Is REXX awful ? Or lack of knowledge ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> CLIST & REXX
Author Message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Thu Mar 20, 2008 5:26 pm    Post subject: Is REXX awful ? Or lack of knowledge ?
Reply with quote

Greetings. Did I miss something ? Could you guide me with next items comparing with C/C++?

1. Stem is not like a structure in C++. You can't copy stem to stem by one command, you must do it member by member in cycle.
2. You can't pass stem to function/subroutine. In one source file, you can use EXPOSE to use global stem, but no way at all to pass it to the external function/subroutine. Funny, you have to create a big string from stem and then parse it again.
3. REXX counts DO TO cycle once at the beginning. It doesn't check that last value can be changed.(as C++ does)
4. You can't do BIT operations with HEX values. Better say, there is no HEX variables, it just a string again looks like hex. And decimal=string also. To sum 2 simple bytes, you must call C2D() for both, then sum them, call D2C() and write 1 byte back.

And reading REXX you can't skip any function, because each of them can change everything. Each of them can create new "global" variables.

Do you beleive you can write big programs on REXX ?
Back to top
View user's profile Send private message
References
PostPosted: Thu Mar 20, 2008 5:26 pm    Post subject: Re: Is REXX awful ? Or lack of knowledge ? Reply with quote

enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Thu Mar 20, 2008 6:06 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

be careful before offending rexx

YES You missed almost everyithing about IT

points:
1 - stems are associative arrays ,
the thing after the dot can be anything with any number of dots

2 - yes, thats the only problem with stems, but external function are available
to store/retrieve variables (stems included ) in data spaces

3 - c++ behavior is IRRELEVANT
clarify Your doubts
if the initial limit checking is false the loop will not executed

4 - Yes You can ( check the builtin functions bit... )

Yes You can ( done it )
clarify the meaning of big...
complex certainly YES
check this sample ( it will RECEIVE ) on any platform ( windows,linux,mac osx) a file created by tso IDTF ( xmit )

Code:

#! /bin/rexx
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*                                                                   */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
OPTIONS "STRICT_WHITE_SPACE_COMPARISONS"
OPTIONS "FAST_LINES_BIF_DEFAULT"
OPTIONS "PRUNE_TRACE"
OPTIONS "NOEXT_COMMANDS_AS_FUNCS"

Trace "O"
gl.?myvers = "1.0"
parse arg gl.?myargs

call    rxInit

call   init_const

gl.?binextra    = 0
gl.?suffix      = ".txt"

gl.?dumpflag   = 0
gl.?xmitinfo   = 0
gl.?listflag    = 1
gl.?fextract    = 1

gl.?skipflag   = 0
gl.?keepmemb   = 1

gl.?initflag   = 0
gl.?openflag   = 0

gl.?destpath   = ""

gl.?trtabl      = trtabl   
gl.?chunk      = 80
gl.?offset      = 1
gl.?lprefx      = 7

gl.?ESDrec      = '02c5e2ca'x
gl.?TXTrec      = '02e3e7e3'x
gl.?IEBhdr       = '00CA6D0F'x
gl.?EOFDIR      = 'ffffffffffffffff'x
gl.?XMIofst    = 3
gl.?DEBofst    = 16
gl.?MBRofst    = 23

gl.?optprog    =   "/usr/local/bin/getopt -ngetopt -a -u "   
gl.?optshort    =    "Vhdlq "
gl.?optslong    =    "version,help,verbose,quiet,dump,list,info,binary "
ADDRESS SYSTEM  gl.?optprog   || ,
            " -o " gl.?optshort || ,
            " -l " gl.?optslong  " -- " || ,
            gl.?myargs  ,
             WITH OUTPUT STEM stdout. ERROR STEM stderr.
if    stderr.0 <> 0 then do
   do    i = 1 to stderr.0
      say  stderr.i
   end
   exit 4
end

gl.?myargs  = strip(stdout.1)

do   while word(gl.?myargs,1)  <> "--"
   optchar = word(gl.?myargs,1)
   optarg  = word(gl.?myargs,2)

   if  optchar = "-V" | ,
      optchar = "--version" then do
      say "Source         : " || gl.?source
      say "Program name   : " || gl.?myself
      say   "Version        : " || gl.?myvers
      say   "TimeStamp      : " || gl.?mytime
      exit 0
   end
   if  optchar = "-h" | ,
      optchar = "--help" then do
      say   "Please read the docs :-)"
      exit 0
   end
   if   optchar = "--verbose" then do
      gl.?msglvl = gl.?verbose
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   
   end
   if   optchar = "--quiet" then do
      gl.?msglvl = gl.?quiet
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   
   end
   if  optchar = "-d" | ,
      optchar = "--dump" then do
      gl.?dumpflag   = 1
      gl.?fextract   = 0
      gl.?listflag   = 0
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   
   end
   if  optchar = "-l" | ,
      optchar = "--list" then do
      gl.?fextract   = 0
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   

   end
   if  optchar = "-i" | ,
      optchar = "--info" then do
      gl.?xmitinfo   = 1
      gl.?fextract   = 0
      gl.?listflag   = 0
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   
   end
   if  optchar = "-b" | ,
      optchar = "--binary" then do
      gl.?suffix = ".bin"
      gl.?binextra    = 1
      gl.?myargs = delword(gl.?myargs, 1, 1)
      iterate   
   end



end
gl.?myargs = delword(gl.?myargs, 1, 1)

argc    = words(gl.?myargs)
if   argc = 0 then do
    say  "You need to specify a filename"
   exit
end


do    iarg = 1 to argc

   fname   = word(gl.?myargs,iarg)
   rcz = strip(stream(fname,"C","QUERY EXISTS") )
   if  rcz = ""  then do
      say "File not found(" || fname || ") "
      iterate
   end
   rcz = strip(stream(fname, "C" , "OPEN READ"))
   if rcz <> "READY:" then do
      say "Open error '"|| fname || "' " || rcz
      iterate
   end

   gl.?offst   = 1
   xfseq      = 0

   do   forever

      fbuff = xfget(fname)
      if   gl.?dumpflag then ,
         call   EBCdump fbuff

      bflag = substr(fbuff,2,1)

      if    '20'x = bitand(bflag,'20'x) then do

         type = translate(substr(fbuff, gl.?XMIofst+ 0, 6),trtabl)

         interpret "call process_"type

         if   type = "INMR06" then ,
            leave

         iterate

      end

      if   gl.?skipflag then ,
         iterate

      if   gl.?initflag = 0 then ,
         call   xinit

      if   gl.?skipflag then ,
         iterate

      if   gl.?openflag = 0 then ,
         call   xopen

      if   gl.?skipflag then ,
         iterate

      call   xfput      

   end

end

exit 0

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
rxInit: procedure expose gl.

   gl.?msglvl   = 0
   gl.?stdout   = "<stdout>"
   gl.?stderr   = "<stderr>"
   gl.?dbgout   = "<stdout>"

   parse    source    gl.?source
   parse    var gl.?source gl.?ostype . gl.?source .
   gl.?ostype    = lower(gl.?ostype)

   gl.?myself    = filespec("N",gl.?source)
   parse    var gl.?myself gl.?myself "." .

   gl.?mytime    = stream(gl.?source, "C" , "QUERY TIMESTAMP")


   gl.?verbose   = 9
   gl.?quiet   = 0
      
   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EBCdump: procedure   expose gl.

   chunk   = gl.?chunk 
   offset   = gl.?offset
   lprefx   = gl.?lprefx
   spaces   = copies(" ",lprefx)

   trtabl  =   gl.?trtabl

    parse   arg EBCbuf

   EBCpos  = 1
   EBCres  = length(EBCbuf)

   do  while ( EBCres > 0 )
      
      if  ( EBCres < chunk ) then ,
         chunk = EBCres
      chbuff  = substr(EBCbuf, EBCpos, chunk)

      chline  = translate(chbuff,trtabl)   
      chhead  = left(right(offset,lprefx-1),lprefx)
      say chhead || ">>" || chline || "<<"
      chbuff = c2x(chbuff)   
      
      xline0 = ""
      xline1 = ""
      do i = 1 to chunk * 2 - 1 by 2
         xline0 = xline0 || substr(chbuff, i    , 1 )
         xline1 = xline1 || substr(chbuff, i + 1, 1 )
      end
      say spaces || ">>" || xline0 || "<<"
      say spaces || ">>" || xline1 || "<<"
      say

      EBCpos  = offset + chunk
      EBCres  = EBCres - chunk

      offset  = offset + chunk

   end

   return

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
init_const:

   trtabl = ""     /*  0123456789ABCDEF             */
   trtabl = trtabl || "................"   /* x'00' */ 
   trtabl = trtabl || "................"   /* x'10' */
   trtabl = trtabl || "................"   /* x'20' */
   trtabl = trtabl || "................"   /* x'30' */
   trtabl = trtabl || " ............(+."   /* x'40' */
   trtabl = trtabl || "&.........!$*);."   /* x'50' */
   trtabl = trtabl || "-/.........,%_.?"   /* x'60' */
   trtabl = trtabl || "..........:#@" || "'" || '="'   /* x'70' */
   trtabl = trtabl || ".abcdefghi......"   /* x'80' */
   trtabl = trtabl || ".jklmnopqr......"   /* x'90' */
   trtabl = trtabl || "..stuvwxyz......"   /* x'A0' */
   trtabl = trtabl || "................"   /* x'B0' */
   trtabl = trtabl || ".ABCDEFGHI......"   /* x'C0' */
   trtabl = trtabl || ".JKLMNOPQR......"   /* x'D0' */
   trtabl = trtabl || "..STUVWXYZ......"   /* x'E0' */
   trtabl = trtabl || "0123456789......"   /* x'F0' */

   inmr01c = 0 ; inmr01. = "" ; inmr01.0 = 0 ;list01  = ""
   inmr02c = 0 ; inmr02. = "" ; inmr02.0 = 0 ;list02  = ""
   inmr03c = 0 ; inmr03. = "" ; inmr03.0 = 0 ;list03  = ""
   inmr04c = 0 ; inmr04. = "" ; inmr04.0 = 0 ;list04  = ""
   inmr05c = 0 ; inmr05. = "" ; inmr05.0 = 0 ;list05  = ""
   inmr06c = 0 ; inmr06. = "" ; inmr06.0 = 0 ;list06  = ""
   inmr07c = 0 ; inmr07. = "" ; inmr07.0 = 0 ;list07  = ""
   inmr08c = 0 ; inmr08. = "" ; inmr08.0 = 0 ;list08  = ""

   hextype.1  = '0001'x; inmname.1  = "inmddnam"; inmconv.1   = "c";
   hextype.2  = '0002'x; inmname.2  = "inmdsnam"; inmconv.2   = "c";
   hextype.3  = '0003'x; inmname.3  = "inmmembr"; inmconv.3   = "c";
   hextype.4  = '000B'x; inmname.4  = "inmsecnd"; inmconv.4   = "d";
   hextype.5  = '000C'x; inmname.5  = "inmdir"  ; inmconv.5   = "d";
   hextype.6  = '0022'x; inmname.6  = "inmexpdt"; inmconv.6   = "c";
   hextype.7  = '0028'x; inmname.7  = "inmterm" ; inmconv.7   = "c";
   hextype.8  = '0030'x; inmname.8  = "inmblksz"; inmconv.8   = "d";
   hextype.9  = '003C'x; inmname.9  = "inmdsorg"; inmconv.9   = "x";
   hextype.10 = '0042'x; inmname.10 = "inmlrecl"; inmconv.10  = "d";
   hextype.11 = '0049'x; inmname.11 = "inmrecfm"; inmconv.11  = "x";
   hextype.12 = '1001'x; inmname.12 = "inmtnode"; inmconv.12  = "c";
   hextype.13 = '1002'x; inmname.13 = "inmtuid" ; inmconv.13  = "c";
   hextype.14 = '1011'x; inmname.14 = "inmfnode"; inmconv.14  = "c";
   hextype.15 = '1012'x; inmname.15 = "inmfuid" ; inmconv.15  = "c";
   hextype.16 = '1020'x; inmname.16 = "inmlref" ; inmconv.16  = "c";
   hextype.17 = '1021'x; inmname.17 = "inmlchg" ; inmconv.17  = "c";
   hextype.18 = '1022'x; inmname.18 = "inmcreat"; inmconv.18  = "c";
   hextype.19 = '1023'x; inmname.19 = "inmfvers"; inmconv.19  = "c";
   hextype.20 = '1024'x; inmname.20 = "inmftime"; inmconv.20  = "c";
   hextype.21 = '1025'x; inmname.21 = "inmttime"; inmconv.21  = "c";
   hextype.22 = '1026'x; inmname.22 = "inmfack" ; inmconv.22  = "c";
   hextype.23 = '1027'x; inmname.23 = "inmerrcd"; inmconv.23  = "c";
   hextype.24 = '1028'x; inmname.24 = "inmutiln"; inmconv.24  = "c";
   hextype.25 = '1029'x; inmname.25 = "inmuserp"; inmconv.25  = "c";
   hextype.26 = '102A'x; inmname.26 = "inmrecct"; inmconv.26  = "c";
   hextype.27 = '102C'x; inmname.27 = "inmsize" ; inmconv.27  = "d";
   hextype.28 = '102F'x; inmname.28 = "inmnumf" ; inmconv.28  = "d";
   hextype.29 = '8012'x; inmname.29 = "inmtype" ; inmconv.29  = "x";

   inmkeys      = 29

   inmdsnam_   = '0002'x
   inmdsorg_   = '003C'x
   inmrecfm_   = '0049'x

   inmutiln_   = '1028'x   

   return

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
xfget: procedure expose gl.
   parse arg fnam

   leng       = charin(fnam,gl.?offst,1)
   gl.?offst    = gl.?offst + 1

   flag       = charin(fnam,gl.?offst,1)
   gl.?offst    = gl.?offst + 1

   buff       = leng || flag || charin(fnam,gl.?offst,c2d(leng)-2)
   gl.?offst    = gl.?offst + c2d(leng) - 2

   do  while '00'x = Bitand(flag,'40'x)
        leng       = Charin(fnam,gl.?offst,1)
      gl.?offst    = gl.?offst + 1

        flag       = Charin(fnam,gl.?offst,1)
      gl.?offst    = gl.?offst + 1
   
      temp       = Charin(fnam,gl.?offst,c2d(leng)-2)
      gl.?offst    = gl.?offst + c2d(leng) - 2

        buff       = buff || temp
   
   end

    return buff

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
xinit:
   gl.?initflag    = 1
   xfseq          = xfseq + 1
   select
      when inmr02.xfseq.inmutiln = "IEBCOPY" then do
         if inmr02.xfseq.inmdsorg <> "PO" then do
            say "xinit - mismatched  utilid:" xfseq inmr02.xfseq.inmutiln
            say "                    dsorg :" xfseq inmr02.xfseq.inmdsorg
            gl.?skipflag = 1
         end

          stdheadr    = '00CA6D0F'
         iebheadr   = c2x(substr(fbuff, gl.?XMIofst+0,4))
          if iebheadr <> stdheadr  then do
            say "xinit - mismatched header (expected) : '" || stdheadr || "'x "
            say "xinit -                   (found)    : '" || iebheadr || "'x "
            gl.?skipflag = 1
         end

         r1flag   = c2x(substr(fbuff, gl.?XMIofst+0 ,1))
         r1ident  = c2x(substr(fbuff, gl.?XMIofst+1 ,3))
         r1dsorg  = c2x(substr(fbuff, gl.?XMIofst+4 ,2))
         r1blksz  = c2d(substr(fbuff, gl.?XMIofst+6 ,2))
         r1lrecl  = c2d(substr(fbuff, gl.?XMIofst+8 ,2))
         r1recfm  = c2x(substr(fbuff, gl.?XMIofst+10,2))
         r1optcd  = c2x(substr(fbuff, gl.?XMIofst+12,1))
         r1resvd1 = c2x(substr(fbuff, gl.?XMIofst+13,1))
         r1tblksz = c2x(substr(fbuff, gl.?XMIofst+14,2))
         r1devtyp = c2x(substr(fbuff, gl.?XMIofst+16,20))
         r1resvd2 = c2x(substr(fbuff, gl.?XMIofst+16,10))
         trksxcyl = c2d(substr(fbuff, gl.?XMIofst+26,2))

/*
         say "r1flag     :" r1flag
         say "r1ident    :" r1ident
         say "r1dsorg    :" r1dsorg
         say "r1blksz    :" r1blksz
         say "r1lrecl    :" r1lrecl
         say "r1recfm    :" r1recfm
         say "r1optcd    :" r1optcd
         say "r1resvd1   :" r1resvd1
         say "r1tblksz   :" r1tblksz
         say "r1devtyp   :" r1devtyp
         say "trksxcyl   :" trksxcyl
*/

         /* iebcopy 2nd control record */
         fbuff = xfget(fname)
         if   gl.?dumpflag then ,
            call   EBCdump fbuff

         r2deb   = c2x(substr(fbuff, gl.?XMIofst+0 ,16))

         deb_count   = x2d(substr(r2deb,1,2))

         gl.?DEBofst = 16
         deb_reltrk = 0
         do  i = 1 to deb_count
            deb_fmask   = c2x(substr(fbuff, gl.?XMIofst+gl.?DEBofst+0 ,1))
            deb_ucbad   = c2x(substr(fbuff, gl.?XMIofst+gl.?DEBofst+1 ,3))
            deb_bin      = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+4 ,2))
            deb_strcc   = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+6 ,2))
            deb_strhh   = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+8 ,2))
            deb_endcc   = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+10,2))
            deb_endhh   = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+12,2))
            deb_trks   = c2d(substr(fbuff, gl.?XMIofst+gl.?DEBofst+14,2))

/*
            say "deb_fmask  :" i deb_fmask
            say "deb_ucbad  :" i deb_ucbad
            say "deb_bin    :" i deb_bin
            say "deb_strcc  :" i deb_strcc
            say "deb_strhh  :" i deb_strhh
            say "deb_endcc  :" i deb_endcc
            say "deb_endhh  :" i deb_endhh
            say "deb_trks   :" i deb_trks
*/

            deb_start   = deb_strcc * trksxcyl  + deb_strhh
            deb_end      = deb_endcc * trksxcyl  + deb_endhh
            deb_size   = deb_end   - deb_start + 1

/*
            say "deb_start  :" i deb_start
            say "deb_end    :" i deb_end
            say "deb_size   :" i deb_size
*/

            deb_tabl.i.1   = deb_start
            deb_tabl.i.2   = deb_end
            deb_tabl.i.3   = deb_reltrk
            deb_tabl.i.4   = deb_reltrk + deb_size
            deb_reltrk      = deb_reltrk + deb_size
         end
         deb_tabl.0 = deb_count

/*
          say "deb_count  :" deb_count
         do    i = 1 to deb_tabl.0
            say   "deb_tabl   :"    ||   deb_tabl.i.1 || " " ,
                             ||   deb_tabl.i.2 || " " ,
                           ||    deb_tabl.i.3 || " " ,
                           ||    deb_tabl.i.4
         end
*/

         /* process directory */
         kentry    = 0
         kmembr    = 0
         kalias    = 0
         mbtext  = "members"

         do  forever
            fbuff  = xfget(fname)
            if   gl.?dumpflag then ,
               call   EBCdump fbuff

            dir_blks = ( length(fbuff) - gl.?XMIofst ) % 276
            do d = 1  to dir_blks
               dir_blk = substr(fbuff, gl.?XMIofst+0 +(d-1)*276,276)
               blk_len = c2d(substr(dir_blk,21,2))

                ptr = gl.?MBRofst
               do while (    (ptr < blk_len + 20 ) & ,
                        ( substr(dir_blk,ptr,8) <> gl.?EOFDIR ) )
                  ttr   = lower(c2x(substr(dir_blk,ptr+8,3)))
                  
                  flg   = '00'x
                  flg   = bitand(substr(dir_blk,ptr+11,1),'80'x)
                  udl   = c2d(bitand(substr(dir_blk,ptr+11,1),'1F'x))

                  if   flg = '00'x then do
                     kentry = kentry + 1   
                     mbrname.ttr = strip(translate(substr(dir_blk,ptr,8),trtabl))

/*
                     say "member :"mbrname.ttr "ttr :"ttr
                     say "member :"mbrname.ttr "ulen:"udl
*/

                  end
                  else ,
                     kalias = kalias + 1

                  ptr   = ptr + 12 + udl * 2
               end
            end
            if substr(dir_blk,ptr,8) = gl.?EOFDIR  then ,
               leave
         end

         fbuff = xfget(fname)
         if   gl.?dumpflag then ,
            call   EBCdump fbuff

/* time to create the destination directories
*/

          end

      when inmr02.xfseq.inmutiln = "INMCOPY" then do
         if inmr02.xfseq.inmdsorg \= "PS" then do
            say "xinit - mismatched utilid:" xfseq inmr02.xfseq.inmutiln
            say "                   dsorg :" xfseq inmr02.xfseq.inmdsorg
            gl.?skipflag = 1
         end

      end

      otherwise do
         say "xinit - invalid utilid   :" xfseq inmr02.xfseq.inmutiln
         gl.?skipflag = 1
      end

   end

   return

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
xopen:
   gl.?openflag   = 1
   select
      when inmr02.xfseq.inmutiln = "IEBCOPY" then do

         r3cc = c2d(substr(fbuff, gl.?XMIofst+4,2))
         r3hh = c2d(substr(fbuff, gl.?XMIofst+6,2))
         r3r  = c2x(substr(fbuff, gl.?XMIofst+8,1))
         trk  = r3cc * trksxcyl  + r3hh

         do i = 1 to deb_tabl.0
            if ( trk >= deb_tabl.i.1 ) & ( trk <= deb_tabl.i.2 ) then do

               leave
            end
         end

         ttr    = lower(right(d2x(trk - deb_tabl.i.1 + deb_tabl.i.3),4,'0') || r3r)
         mbrkey    = lower("mbrname." || ttr)
         member    = strip(mbrname.ttr)
         member    = lower(member)

         UXMrecs = 0

         if  member = mbrkey then ,
            gl.?keepmemb   = 0
         else do
            gl.?keepmemb   = 1
            kmembr = kmembr + 1
            UXMfile   = gl.?destpath  || member  || gl.?suffix
            if gl.?fextract then ,
               rc = stream( UXMfile, "C" ,"OPEN WRITE REPLACE" )
         end

         r3offst = gl.?XMIofst

      end

      when inmr02.xfseq.inmutiln = "INMCOPY" then do
         UXMfile = inmr02.xfseq.inmdsnam
         UXMfile = lower(UXMfile)
         UXMfile   = gl.?destpath  || UXMfile

         if gl.?fextract then ,
            rc = stream( UXMfile, "C" ,"OPEN WRITE REPLACE" )
         UXMrecs = 0
      end

      otherwise do
         say "xopen - invalid utilid "inmr02.xfseq.inmutiln
         gl.?skipflg = 1
      end

   end

   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
xfput:
   select
      when inmr02.xfseq.inmutiln = "IEBCOPY" then do
         r3offst = gl.?XMIofst

         if    inmr02.xfseq.inmrecfm = "F" then do
            do while r3offst < length(fbuff)
               r3blksz = c2d(substr(fbuff,r3offst+10,2))
               if r3blksz = 0 then do
                  if gl.?fextract then ,
                     rc = stream(UXMfile, "C", "CLOSE")
                  gl.?openflag = 0
                  if gl.?listflag then ,
                     say   left(mbtext,20) || ": " || left(member,20) ,
                        || " records(" || right(UXMrecs,5) || ")"
                  mbtext   = " "
               end

               r3offst = r3offst + 12
               do r3blksz % r1lrecl
                  if gl.?keepmemb then do
                     if gl.?fextract then do
                        if gl.?binextra then ,
                           call charout UXMfile, substr(fbuff,r3offst,r1lrecl)
                        else do
                           UXMbuff = translate(substr(fbuff,r3offst,r1lrecl),trtabl)
                           call lineout UXMfile, UXMbuff
                        end
                     end
                     UXMrecs = UXMrecs + 1
                  end
                  r3offst = r3offst + r1lrecl
               end
            end
         end
         else ,
         if inmr02.xfseq.inmrecfm = "V" then do
            do while r3offst < length(fbuff)
               r3blksz = c2d(substr(fbuff,r3offst+10,2))
               if r3blksz = 0 then do
                  if gl.?fextract then ,
                     rc = stream(UXMfile, "C", "CLOSE")
                  gl.?openflag = 0
                  if gl.?listflag then ,
                     say   left(mbtext,20) || ": " || left(member,20) ,
                        || " records(" || right(UXMrecs,5) || ")"
                  mbtext   = " "
                  leave
               end

               r3offst = r3offst + 12
               r3blksz = c2d(substr(fbuff,r3offst,2))
               r3limit = r3offst + r3blksz
               r3offst = r3offst + 4 /* rdw */
               lrecl   = c2d(substr(fbuff,r3offst,2))
               do while ( r3offst < r3limit)
                  lrecl = c2d(substr(fbuff,r3offst,2))
                  if gl.?keepmemb then do
                     if gl.?fextract then do
                        UXMbuff = translate(substr(fbuff,r3offst+4,lrecl-4),trtabl)
                        call lineout UXMfile, UXMbuff
                     end
                     UXMrecs = UXMrecs + 1
                  end
                  r3offst = r3offst + lrecl
               end
            end

         end

      end

      when inmr02.xfseq.inmutiln = "INMCOPY" then do
         if gl.?fextract then do
            UXMbuff = translate(substr(fbuff,gl.?XMIofst),trtabl)
            call lineout UXMfile, UXMbuff
         end
         UXMrecs = UXMrecs + 1
      end

      otherwise do
         say   "xfput - invalid utilid "inmr02.xfseq.inmutiln
         gl.?skipflg = 1
      end
   end


   return



/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
process_INMR01:

   inmr01c    = inmr01c + 1
   i          = inmr01c
   inmr01.i.0 = 0
   list01.i   = ""

   fbuff = substr(fbuff, gl.?XMIofst+ 6)
   do while ( length(fbuff)  > 0 )
      offs = fextract(fbuff)
      nfnd = 1
      do k = 1 to inmkeys
         if tokn = hextype.k then do
            nfnd   = 0
            knam   = "inmr01." || i || "." ||  inmname.k
            list01.i   = list01.i || " " || knam
            select
               when inmconv.k = "d" then kval = c2d(value.1)
               when inmconv.k = "x" then kval = c2x(value.1)
               otherwise ,
                  kval = translate(value.1,trtabl)
            end
            interpret knam "=" kval
            leave
         end
      end
      if nfnd then ,
         say "INMR01  unsupported key " c2x(fbuff,1,16)

      fbuff = substr(fbuff,offs)
   end

   if gl.?xmitinfo then do
      say  copies("- ",30)
      say "inmr01" i
      do v = 1 to words(list01.i)
         knam = word(list01.i,v)
         kval = value(word(list01.i,v))
          say left(knam,20) || "=" kval
      end
      say
   end

   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
process_INMR02:

   inmr02c    = inmr02c + 1
   i          = inmr02c
   inmr02.i.0 = 0
   list02.i   = ""
   inmr02.i.inmfseq = c2d(substr(fbuff, gl.?XMIofst+6,4))
   list02.i = list02.i || " " || "inmr02."||i||".inmfseq"

   fbuff = substr(fbuff,gl.?XMIofst+10)
   do while ( length(fbuff)  > 0 )
      offs = fextract(fbuff)
      nfnd = 1
      select

         when tokn = inmdsorg_ then do
            dsorg = substr(value.1,1,1)
            if dsorg = '02'x then ,
               inmr02.i.inmdsorg =  "PO"
            else ,
            if dsorg = '40'x then ,
               inmr02.i.inmdsorg =  "PS"
            else ,
               inmr02.i.inmdsorg =  "?"
            list02.i = list02.i || " " || "inmr02."||i||".inmdsorg"
            nfnd = 0
         end

         when tokn = inmrecfm_ then do
            recfm = substr(value.1,1,1)
            if   bitand(recfm,'C0'x) = 'C0'x then ,
               inmr02.i.inmrecfm = "?"
            else ,
            if   bitand(recfm,'80'x) = '80'x then ,
               inmr02.i.inmrecfm = "F"
             else ,
            if   bitand(recfm,'40'x) = '40'x then ,
               inmr02.i.inmrecfm = "V"
            else ,
               inmr02.i.inmrecfm = "?"
            list02.i = list02.i || " " || "inmr02."||i||".inmrecfm"
            nfnd = 0
         end

         when tokn = inmdsnam_ then do
            inmr02.i.inmdsnam =  translate(value.1,trtabl)
            do v = 2 to value.0
               inmr02.i.inmdsnam =  inmr02.i.inmdsnam || "." || translate(value.v,trtabl)
            end
            inmr02.i.inmdsnam   = lower(inmr02.i.inmdsnam)

            list02.i = list02.i || " " || "inmr02."||i||".inmdsnam"
            nfnd = 0
            if gl.?listflag then ,            
               say   left("source dataset",20) || ": " || inmr02.i.inmdsnam
            
         end

         otherwise ,
            do   k = 1 to inmkeys
               if   tokn = hextype.k then do
                  nfnd = 0
                  knam  = "inmr02." || i || "." ||  inmname.k
                  list02.i  = list02.i || " " || knam
                  select
                     when inmconv.k = "d" then kval = c2d(value.1)
                     when inmconv.k = "x" then kval = c2x(value.1)
                     otherwise ,
                        kval = translate(value.1,trtabl)
                  end
                  interpret knam "=" kval
                  leave
               end
            end
      end
      if nfnd then ,
         say " INMR02 unsupported key " c2x(substr(fbuff, gl.?XMIofst+1,16))

      fbuff = substr(fbuff,offs)
   end

   if gl.?xmitinfo then do
      say  copies("- ",30)
      say "inmr02" i
      do v = 1 to words(list02.i)
         knam = word(list02.i,v)
         kval = value(word(list02.i,v))
          say left(knam,20) || "=" kval
      end
      say
   end

   if   inmr02.i.inmdsorg = "?" then do
      say left(" ",20) || ": " || "dsorg(" || c2x(dsorg) || ") not supp."
      gl.?fextract = 0
   end   
   if   inmr02.i.inmrecfm = "?" then do
      say left(" ",20) || ": " || "recfm(" || c2x(recfm) || ") not supp."
      gl.?fextract = 0
   end   

   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
process_INMR03:

   inmr03c    = inmr03c + 1
   i          = inmr03c
   inmr03.i.0 = 0
   list03.i   = ""

   fbuff = substr(fbuff,gl.?XMIofst+6)
   do while ( length(fbuff)  > 0 )
      offs = fextract(fbuff)
      nfnd = 1
      do    k = 1 to inmkeys
         if tokn = hextype.k then do
            nfnd = 0
            knam  = "inmr03." || i || "." ||  inmname.k
            list03.i  = list03.i || " " || knam
            select
               when inmconv.k = "d" then kval = c2d(value.1)
               when inmconv.k = "x" then kval = c2x(value.1)
               otherwise ,
                  kval = translate(value.1,trtabl)
            end
            interpret knam "=" kval
            leave
         end
      end
      if    nfnd then ,
         say " INMR03 unsupported key " c2x(fbuff,1,16)

      fbuff = substr(fbuff,offs)
   end

   if gl.?xmitinfo then do
      say  copies("- ",30)
      say "inmr03" i
      do v = 1 to words(list03.i)
         knam = word(list03.i,v)
         kval = value(word(list03.i,v))
          say left(knam,20) || "=" kval
      end
      say
   end

   gl.?initflag   = 0
   gl.?openflag   = 0

   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
process_INMR06:
   
   fbuff   = ""

   return

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
fextract:
   parse arg xbuff
   tokn   = substr(xbuff,1,2)
   count   = c2d(substr(xbuff,1+2,2))
   value.0 = 1
   value.1 = ""
   p       = 5
   do    v = 1 to count
      l       = c2d(substr(xbuff,p,2))
        value.v = substr(xbuff,p+2,l)
        p       = p + l + 2
    end
   value.0 = count
   return p


there are gazillions ( almost all the other l) of languages worse than REXX
PL/I excluded

and I have been messing around with C compilers and REXX interpreters
( modifying the C compiler, writing a rexx interpreter )
long enough to know what I am talking about

In C++ You are not making mistakes, You inherit them
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Thu Mar 20, 2008 6:45 pm    Post subject:
Reply with quote

Good. Thanks for the answer. Let's clarify some items(one by one)

1. stem - array ?
How it can be an array, if I can't work with it as with array ?
I said I can't easy create a copy of stem. Correct ? In C++ I can memcpy either array or structure, without bothering of member names inside.

That's why, in real, stem is just a set of separate variables. And only good thing that you can limit them by setting variable value between dots in name.

Correct ?
Back to top
View user's profile Send private message
enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Thu Mar 20, 2008 6:58 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

You missed one word - associative

stems tokens are not limited to numerics

Code:
say "stem.var" stem.var

var = "AAA"
stem.var = "bbb"
say "stem.var" stem.var


I have coded many thousandth lines of rexx in quite complex applications
and I have never had the need to copy a stem ( as is )
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Thu Mar 20, 2008 7:35 pm    Post subject:
Reply with quote

stem.AAA="bbb"

associative = set of separate variables. So I guess I am correct.

Real situation: Load file into stem, then remove 1 line by condition. Then again process original stem and remove 1 lines by another condition.

Is there a way instead of creating 2 new stem and coping all lines - 1 to both?(coping one by one line)
Or call execio twice for different stems ? (disk operations are slow)

btw, I see REXX "execio * diskw" writes all stem without checking .0 member. So I must call it only as "execio "num" diskw"
Why it use .0 at diskr time(fill it), but not at diskw time ?
Back to top
View user's profile Send private message
enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Thu Mar 20, 2008 7:46 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

"EXECIO * DISKW" should stop writing when encountering a non existent stem entry


execio * diskr ... (stem stemvar.

suppose it reads 100 rcords

drop "STEMVAR.8"

a diskw * will write 7 records

for heavy stem manipulation the best thing is to look for external function packages

stemadd stemdelete stemsort
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Thu Mar 20, 2008 8:12 pm    Post subject:
Reply with quote

I see, I have just changed middle record with last one and decreased .0

Don't see in REXX Reference anything about stemadd, so guess can't use it.(can't install anything)

Now, I would like to go to the 2nd point:
Could you give me a link or example of using dataspace from REXX ? (can't find in reference)

From my knowledge, I used dataspace in C++ to have data more than 2GB, but it's obsolete now, as we can use AMODE 64. It was like a big file, so can't imagine how you can store to it stems like stem.AAA and stem.BBB.
Back to top
View user's profile Send private message
enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Thu Mar 20, 2008 8:31 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

all of these are not standard functions, they are implemented as rexx externals functions

I wrote them for my personal use many ( too many ) years ago

I' ll dig around and see if I can find them

the function implemented are

rxclip write/read a stem to a named dataspace used for ISPF cut/paste before data spaces were available on the standard ISPF

stemsort the name tells

stemdelete same ...

stemadd same ...

rxvars return all the variables with a certain prefix

rxvsam for vsam access

rxpds read/write pds/pdse with ispf integrity

rxsql name tells before it was available on the official db2 distribution
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Thu Mar 20, 2008 8:52 pm    Post subject:
Reply with quote

ok. So in general I am correct for point 2 also. I can use stack with same result. Main idea was - there is no normal way.

point 3. Agree, REXX can have his behavior. Good point, that you can change TO variable inside without problems. REXX already counted how many times execute the cycle. (just was a surprise for me)

ps: see you tomorrow for point 4. It can be big discussion...
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Fri Mar 21, 2008 5:26 pm    Post subject:
Reply with quote

Hi again. Let's see next example

Code:
/* rexx */                 
var1=19                   
var2=2                     
var1x=d2x(var1)           
say 'VAR1 - 'var1x         
var2x=d2x(var2)           
say 'VAR2 - 'var2x         
res=BITAND(var1x,var2x)   
say 'RES - 'C2X(res)       
                           
var1c=d2c(var1)           
var2c=d2c(var2)           
res=BITAND(var1c,var2c)   
say 'RES - 'C2X(res)       


Output:
Code:
VAR1 - 13 
VAR2 - 2   
RES - F0F3
RES - 02   


From this it is clear, that all BIT functions work with string, not numbers. C2X creates again string looks like hex. And to survive, I have to create string with non-printable symbols and do my BIT. For that I have to use D2C - funny, no any hex in name. So REXX works with STRINGs only, just some function can process these STRINGs like they are numbers. It is awful for C++ programmer! icon_confused.gif
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Fri Mar 21, 2008 5:55 pm    Post subject:
Reply with quote

yes - and it's awful, especially that there is no BIT functions work with HEX-STRING...

No problem, as you see, I can survive. The project is already set up on REXX, so it's not a good idea to use C++ for changes. (yes - I am crying)

And before I supported another REXX project for 2 year without any problems. Troubleshooting and bug fixing... but only now I realised how difficult to write on REXX(not support). icon_lol.gif
Back to top
View user's profile Send private message
enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Fri Mar 21, 2008 6:00 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

You are the first person i find that complains, without any reason, about REXX

show an example of what You are trying to achieve please
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Fri Mar 21, 2008 6:27 pm    Post subject:
Reply with quote

Relax, In this topic I complain about REXX behavior, not about something that I don't know how to do. All reasons above. No one can help me here, it happens in real life. Thanks for participating. icon_smile.gif
Back to top
View user's profile Send private message
enrico-sorichetti

Global Moderator


Joined: 14 Mar 2007
Posts: 2562
Location: italy

PostPosted: Fri Mar 21, 2008 6:33 pm    Post subject: Reply to: Is REXX awful ? Or lack of knowledge ?
Reply with quote

again...
show an example of what You are trying to achieve please
Back to top
View user's profile Send private message
XOpen

New User


Joined: 19 Mar 2008
Posts: 24
Location: Russia

PostPosted: Fri Mar 21, 2008 7:28 pm    Post subject:
Reply with quote

I would like that REXX has real data types, structures, memory pointers... Am I asking too much? icon_smile.gif

In near topic, I am tring to create one more function, that will allow REXX programmers start remote replications. Not DB2, but disk.(SRDF on symmetrix) We already have REXX api to some functions, but don't have their sources. So I am going to extend it. And as there can be a lot of disks, it's resonable to get stem as a parameter to this my new function.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> CLIST & REXX All times are GMT + 6 HoursGoto page 1, 2  Next
Page 1 of 2