INDEX to uvcopy INSTRUCTIONS

 add - add op2 data to op1 data & store result in op1                    - 29
 anc - ANd Character (erase bits in op1 with corresponding 0 bits in op2 - 17
 bal - branch & link to a subroutine                                     - 84
 bcr - Branch on Condition & Return                                      - 87
 bcr example - testbcr1 test/demo job for bcr instruction                - 88
 cat - concatenate op2 data onto op1 data (within op1 limits)            - 13
 can - cancel the uvcopy job                                             - 82
 chx - convert character representation of hex to true hex data          - 93
 clr - clear the op1 area to the op2 byte value                          - 14
 cls - close a file                                                      - 45
 cmc - compare and set internal condition code for following skp         - 36
 cmn - compare numeric & set condition code for following skp            - 38
 cnt - count the number of op2 patterns in the op1 area                  -142
 ctr - center data within the op1 area                                   -145
 data type & sign codes
 dat - convert dates between: calendar,julian,& days-since-1900          -155
 del - delete a record in an Indexed file                                - 77
 debug - uvcopy DEBUGGER - Contents                                      -209
 div - divide the op1 data by the op2 data & store result in op1         - 32
 dlm - convert Fixed-Field to "delimited","format"                       -152
 dtf - Delimited To Fixed-field                                          -201
 edt - edit op2 data into op1 area controlled by op3 mask                - 15
 env - get value for any specified environmental variable                -167
 eoj - end the job                                                       - 82
 evt - get & table the values for all environmental variables            -168
 evs - copy text, expanding any environmental variables                  -169
 expandevs1 - using "evs" to expand $VARIABLEs in DB2 scripts            -170
 fix - convert variable field format to fixed length fields              -146
 ftd - Fixed-field To Delimited                                          -200
 fxt - add a uvcopy instruction to the execution table                   -166
 get - next record from a sequential file & store in the op2 area        - 46
 getrecsizes1 - demo recsizes stored in register 'v' by 'get'            - 50
 getcopydir1 - demo 'get' filenames from directory & copy all files      - 51
 hxc - convert hex data to hex character representation                  - 93
 ins - insert op2 data prior to op1 data                                 -144
 lck - lock a D-ISAM Indexed file                                        - 78
 lok - look-up a table of data (op1) for match to argument (op2)         -162
 mpy - multiply op1 data by op2 data & store result in op1               - 31
 msg - display a msg (1 or 2 lines) on stdout                            - 79
 msgw - display message & wait for reply (option "w" of msg)             - 80
 mvc - move character data from op2 to op1 for op1 length                -  8
 mvf - move op2 to op1 for lth op2 & fill excess op1 with op3 char       -  9
 mvr - move data from op2 to op1 right adjusted, left filled with op3    - 11
 mvp - move op2 to op1, if all EBCDIC blanks, convert to ASCII blanks    - 12
 mvn - move numeric data depending on op1/op2 types & lengths            - 21
 mvu - move op2 data to op1 area until the op3 pattern detected          -106
 opn - open a file - or all files declared if op1 = 'all'                - 44
 orc OR Character - set 1 bits in op1 with corresponding 1 bits in op2   - 18
 pac - pack the op2 data into the op1 area                               - 33
 pop - process option string into process/user option storage            -165
 put - a record to a sequential file                                     - 52

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

INDEX to uvcopy INSTRUCTIONS (continued)

 ran - generate random numbers                                           -202
 rel - set file pointer (relative record# or relative byte#)             - 58
 red - read a record from an indexed file                                - 68
 ret - return from a subroutine (to the instruction following the bal)   - 86
 rep - scan op1 replacing all op2 patterns with the op3 data             -103
 rpt - replace by table                                                  -121
 rtb - read a table of data into the op1 area (at run time)              - 60
 rts - scan a table for a pattern & replace with an alternate            -133
 rtt - replace patterns in data table via search/replace table           -136
 scn - scan op1 area for op2 pattern & set cc equal if found             - 96
 sct - scan by table                                                     -109
 set - set key of reference & file pointer in an Indexed file            - 67
 shf - shift data a specified number of bits left or right               - 20
 skeleton1 - template job to copy, rename,& modify as required           -  5
 skp - skip to a tag (or number of instrns) if condition code matches    - 39
 skptable - demo job lookup table of Record-Types & Processing-Labels    - 40
 sort (external) - sxo, sxp, sxs, sxg, sxc                               -173
 sqz - squeeze out occurrences of the op2 character from op1             -139
 sqf - squeeze multiple contiguous fields & blank fill at the end        -141
 srt - internal sort (tables, record arrays, etc)                        -171
 sst - scan using table patterns to match or not-match                   -111
 sta - search data tables & count matches in a pattern table             -125
 sts - scan a table for a character string                               -127
 stt - search data tables for any match to a pattern table               -130
 sub - subtract the op2 data from the op1 data & store result in op1     - 30
 subrtn example - cymd compare 6 digit dates for Year 2000               - 85
 swp - swap left & right sides of data in op1 based on op2 separator     -154
 sys - issue system commands - call the shell to execute op1 string      -159
 table overview - build tables in memory to dump at EOJ                  -179
 table formats - supplied formats available (f1-f12)                     -191
 table entry layout - dumped by tbd (unedited)                           -194
 tbl - build tables in memory to be dumped at end of job                 -180
 tbf - declare formats to be used when editing tables to output files    -182
 tbh - declare table column (field) headings                             -183
 tbp - print (edit) the table entries into a file (usually at eoj)       -184
 tbd - dump (unedited) the table entries into a file (usually at eoj)    -186
 tbl examples - sample problem & solution                                -187
 tim - get current date & time & store in area y for user access         - 83
 tra - translate to ASCII (from EBCDIC)                                  - 89
 tre - translate to EBCDIC (from ASCII)                                  - 90
 trl - translate to lower case (any UPPER case present)                  - 90
 tru - translate to UPPER case (any lower case present)                  - 90
 trt - translate via user specified (or modified) translate table        - 91
 trs - translate/search command                                          - 92
 tst - test each op1 sub-field for match to any op2 sub-field            - 41
 tsb - test 1 byte of data for any match to the bits in the 1 byte op2   - 43
 tts - scan data table lines for matches to pattern table                -116
 ttx - scan data table groups for matches to pattern table               -118
 ulk - unlock a D-ISAM Indexed file                                      - 78
 unp - unpack the op2 data into the op1 area                             - 34
 und - convert "delimited","format" to Fixed-Field                       -153
 update_rel reldemo1 - update in place                                   - 58
 upd - update a record in an Indexed file                                - 74
 upw - update/write record depending on key present/absent               - 76

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

INDEX to uvcopy INSTRUCTIONS (continued)

 var - convert multi fixed length fields to a variable length string     -150
 vhx - convert data to vertical hexadecimal representation               - 94
 vnf - Verify Numeric Field                                              -203
 wat - wait a specified number of seconds                                - 83
 wrt - write a new record into an Indexed file                           - 73
 wtb - write a table of data from the op1 area (at run time)             - 65
 xft - crossfoot multiple op2 fields & store the result in op1           - 35
 xor - eXclusive OR (bit manipulation)                                   - 19
 xxa - call user subfunction (written in C & linked to uvcopy)           -207

creating the INDEX to uvcopy INSTRUCTIONS

The index was created by uvcopy 'uvindex3' (documented in 'UVjobs2.doc')


        uvcopy uvindex3,fili1=doc/uvcopy3.doc,filo1=tmp/uvcopy3_index
        =============================================================

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

uvcopy documentation - uvcopy1,2,3,4,5.doc + uvtrain.doc

uvcopy1.doc - FUNCTIONS

Functions are declarations (not executed as are instructions). Functions are processed once only at setup time. '@run' separates Functions from Instructions.

            initial:  prm,opr,rop,uop,was
          arguments:  arg1,arg2,...,arg9
   file declaration:  fil__,typ,rcs,isk
  special functions:  lod
 begin instructions:  @run

uvcopy2.doc - Work areas, $symbols, options, etc

 Work Areas - 26 work areas (a-z)
 $symbols   - for registers, counters, system values (date,time,filenames,etc)
 Options    - user options, run options, file type options
 Index Registers - explanations & examples
 Debugging  - step thru program, display work areas, breakpoints, etc

uvcopy3.doc (this doc) - INSTRUCTIONS

Instructions follow the '@run' function & are stored in memory at 'setup time'. Instructions are executed at 'run time' (after validation at setup time). Instructions are usually executed repeatedly (eg: for each record in a file)

  1. logical: mvc,mvf,mvr,mvp,cat,clr,edt,anc,orc,xor,shf
  2. arithmetic: mvn,add,sub,mpy,div,pac,unp,xft
  3. comp/test/skip: cmc,cmn,skp,nop,tst,tsb
  4. sequential I/O: opn,cls,get,put,rel,rtb,wtb
  5. Indexed I/O: set,red,wrt,upd,upw,del,lck,ulk
  6. message&control: msg,can,eoj,tim,wat,bal,ret,bcr
  7. translation: tra,tre,trl,tru,trt,hxc,chx,vhx
  8. scan&replace: scn,rep,mvu,sct,sst,tts,ttx,rpt,sta,sts,stt,rts
  9. squeeze-insert: sqz,sqf,jus,cnt,ins,ctr
  10. conversion: fix,var,dlm,und,swp,dat
  11. special: sys,lok,pop,fxt,env,evt,evs
  12. sort: sxo,sxp,sxs,sxg,sxc,srt
  13. table: tbl,tbf,tbh,tbp,tbd
  14. delimit/undelimit: ftd,dtf
  15. misc: ran,vnf,xxa,xxb,xxc

    uvcopy4.doc - uvcopy sample jobs

translations, edited reports, sorts, table lookups, convert tabs to blanks

uvcopy5.doc - uvcopy advanced examples

convert fixed length fields to delimited (comma,pipe,etc), split files, Indexed file random access to update sequential files.

uvtrain.doc - uvhd, uvcp, uvsort, uvcopy

Probably the best place to start learning the Vancouver Utilities.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`skeleton1` - template job to copy, rename,& modify as required

 # skeleton1 - uvcopy Parameter File from UVSI stored in: /home/uvadm/pf/demo/
 # skeleton1 - uvcopy template job, copy, rename,& modify as required
 #           - be sure to update these lines with new name & job description
 # - unmodified, this job copies any text file (max rcsz 256)
 # - see 'skeleton2' (vs skeleton1) for fixed length records w/o LineFeeds
 # Example - to copy tf/test100, with options to bypass/copy spcfd no of records
 #
 # uvcopy skeleton1,fili1=tf/test100,filo1=tmp/test100,rop=b20c10
 # ==============================================================
 # ',rop=b20c10' above bypasses 1st 20 records,copies next 10,& closes files
 #
 opr='$jobname - uvcopy skeleton1 job, copy, rename,& modify as required'
 fili1=?tf/test100,typ=LST,rcs=256   # code filenames or leave ? for prompt
 filo1=?tmp/$fili1,typ=LSTt,rcs=256  # output file same name, different subdir
 @run
       opn   all                    open files
 # begin loop to get & put records until EOF
 loop  get   fili1,a0               get record into area 'a'
       skp>  eof                    (condition code set > at EOF)
 #-----------------------------
       mvc   b0(256),a0             move input record to output area 'b'
 #     ---   -----,-----         ** add your instructions here **
 #-----------------------------
       put   filo1,b0               write record to output file
       skp   loop                   return to get next record
 #
 eof   cls   all                    close files
       eoj                          end job

The 'skeleton1' job shown above is provided for you as a starting point intended for you to copy, rename,& modify as required.

The following example suggests how you would use the uvcopy skeleton1 job, if you wished to create a new uvcopy job called 'fix1'.

 #1. Login --> your homedir

 #2. mkdir pf                - make a sub-directory for your uvcopy jobs
     ========                  (pf is already in PATH of supplied profiles)

 #3. cp pf/skeleton1 pf/fix1  - copy skeleton1 to your sub-directory
     ======================    renaming as you wish (fix1 in this case)

 #4. vi pf/fix1       - modify as required, inserting your instructions
     ==========       - modifying file names, types,& record sizes
                      - change comment lines to new name & job description

 #5. uvcopy pf/fix1   - execute uvcopy to interpret your job
     ==============
    - - if errors - - - correct errors & rerun
 Please see notes on the next page --->

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

customizing the 'skeleton1' job to solve your current problem

When you want to make a new job, the following steps are recommended:

  1. Copy the 'skeleton1' job to whatever name you decide to assign to your new job. I strongly recommend you keep your prmfiles in a sub-directory from your home directory similar to the 'pf' directory which is a subdir in the 'uv' home directory. Note that $HOME/pf is in the supplied profile $PFPATH, which uvcopy uses to search for its jobs to be interpreted.

  2. Edit your new job. Be sure to change the jobname on line 1; you don't need to change on the 'opr' statement since it is coded as '$jobname'. Be sure to fill in your job description on line 1 & on the 'opr' statement.
  3. Modify the input/output file declarations if required. Note that the skeleton1 job file declarations are as follows:
      fili1=?tf/test100,typ=?LST,rcs=256
      filo1=?$fili1,typ=?LSTt,rcs=256
 #3a. You might as well hard-code your specific filenames, replacing
      "?tf/test100 & ?$fili1". You could leave the "?" prefix if you
      anticipate using the job with various files. The "?" causes an
      an operator prompt for a new filename (null reply for default).
 #3b. The file types default to 'LST' (variable-length LF Terminated).
      Change to 'RST' if your records are fixed-length, LF Terminated,
      or to 'RSF' if your records are fixed-length, without LineFeeds.
      The 't' on 'typ=LSTt' is the option to truncate output records
      after the last non-blank (vs 256 byte records + LF).
 #3c. The record size defaults to 256, which is OK if your file types
      are 'LST' & do not exceed 256.
      For fixed-length records, you must change to the correct values.
      (see complete details re 'typ' & 'rcs' in uvcopy1.doc)
  1. Insert your instructions as required into the get/put loop:
      #-----------------------------
            mvc   b0(256),a0             move record to output area 'b'
      #     ---   -----,-----          *** add your instructions here ***
      #-----------------------------

If you did not change anything, all this skeleton1 job would do is copy text file records with no changes.

  1. Debug your job. You probably wont get it right 1st time, but the diagnostics usually pinpoint your clerical errors. The logic is up to you, but the interpretive nature of uvcopy allows you to change & rerun very quickly. See the uvcopy debug feature at 'uvcopy2.doc#J1'.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

Example - modifying 'skeleton1' to solve a problem

given
  • COBOL programs originally from a mainframe that have sequence#s in cols 1-6 & program-ids in cols 73-80. But they have not been maintained (some lines have & some do not).
required
  • Resequence cols 1-6 by 10 & Blank out columns 73-80.
  • This will clean up the source code & also save disc space since the 't' option of 'LSTt' truncates trailing blanks. (blank lines become 2 bytes vs 81 bytes)
solution
  • copy /home/uvadm/pf/demo/skeleton1 to your $HOME/pf/... & rename ('cobol_cleanup1' in my example).
  • Add the following instructions to the skeleton1 job.
       #-----------------------------
       #     ---   -----,-----         ** add your instructions here **
             add   $ca1,10                count lines by 10
             mvn   b0(6),$ca1             insert new seq#
             mvc   b72(8),' '             clear cols 73-80
       #-----------------------------

skeleton1 copied/modified/renamed to cobol_cleanup1

 # cobol_cleanup1 - cleanup COBOL source code, resequence 1-6, clear 73-80
 #                - uvcopy job created by copy/rename from skeleton1
 #
 # uvcopy cobol_cleanup1,fili1=cbls/cobolprgmxx,filo1=tmp/cobolprgmxx
 # ==================================================================
 #
 opr='$jobname - cleanup COBOL source code, resequence 1-6, clear 73-80'
 fili1=?cbls/cobolprgmxx,typ=LST,rcs=256
 filo1=?tmp/$fili1,typ=LSTt,rcs=256
 @run
       opn   all                    open files
 # begin loop to get & put records until EOF
 loop  get   fili1,a0               get record into area 'a'
       skp>  eof                    (condition code set > at EOF)
 #-----------------------------
       mvc   b0(256),a0             move input record to output area 'b'
 #     ---   -----,-----         ** add your instructions here **
       add   $ca1,10                increment line counter (by 10)
       mvn   b0(6),$ca1             insert sequence# in cols 1-6
       clr   b72(8),' '             clear cols 73-80
 #-----------------------------
       put   filo1,b0               write record to output file
       skp   loop                   return to get next record
 #
 eof   cls   all                    close files
       eoj                          end job

 uvcopyx cobol_cleanup1 cbls tmp uop=q0i7
 ========================================
 - use 'uvcopyx' script to repeat cobol_cleanup1 for all files in directory
 - inspect outputs in tmp/... subdir, then copy back to cbls/...

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - "mvc", mvf, mvr, mvp, cat, clr, edt, anc, orc, xor, shf

`mvc` - move character data from op2 to op1 for op1 length

    mvc  tobyte(lth),frombyte      - instruction format
    mvc  op1dsp(op1lth),op2dsp     - op2 may be an area address
    mvc  op1dsp(op1lth),'constant'   or a constant

examples

    mvc  b100(30),a0            - move from the 1st byte of area 'a'
                                  to area b starting at byte #101
                                  & proceeding for 30 bytes
    mvc  b130(07),'updated'     - move the op2 constant to bytes
                                  131-137 of area 'b'
    mvc  b137(02),x'0D0A'       - move the hex constant 0D0A (CR/LF)
                                  to bytes 138 & 139 of area b

condition code

The condition code is unchanged as of version 0005 may 2000. Some earlier versions set cc = if resulting op1 was all blank, but not changing cc allows code such as:

    cmc   ---,---              - set condition code
    mvc   ---,---
    skp=  xxx                  - test condition code

IBM 360 instruction format

Note that operand 1 is the destination/receiving area & operand 2 is the origin/sending area. This follows the IBM 360+ assembler rules. The length is coded on operand 1 & may be omitted from operand 2 for instructions such as mvc where it is the same.

uvcopy is an 'interpretive assembler' - all the power of assembler, without the complexity of compiles, just modify the parameter file & rerun.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, "mvf", mvr, mvp, cat, clr, edt, anc, orc, xor, shf

`mvf` - move op2 to op1 for lth op2 & fill excess op1 with op3 char

    mvf   b0(80),a20(60),' '      <-- move 21-80 of op2 to op1 1-60
                                      then fill 61-80 of op1 with blank
    mvf   b0(30),a0,' ','"'       <-- may specify op4 char to enclose data
    mvf   h0(70),'--constant--'   <-- op3 defaults to a blank if omitted

Use 'mvf' vs 'mvc' when storing long constants, because 'mvc' could pick up garbage if your constant is not long enough, but mvf will always fill any extra length with blanks.

condition code
  • unchanged as of version 0003 & all future versions
option 't'
  • fill op1 backwards with op3 until rt most nonblank
  • default fills extra length op2 with blanks (op3 unspecified)
option 't1'
  • fill op1 backwards with nulls x'00's vs blank default
  • following 2 mvf instructions have the same effect
    mvft  c0(10),$reply(10),x'00' <-- move reply data to 1-10 of area 'c'
    mvft1 c0(10),$reply(10)       <-- same, option t1 sets op3 fill to x'00'
 option v1  - replace any $symbols with data using $symtbl & area q
        v2  - replace any ${symbols} with data from env-vars
        v4  - disable stop replace on 1st space, enable endrep on tilde
        v8  - inhibit stop on '.' period
        v16 - override stop replace options v4 (1st space) or v8 ('.' period)
            - use replace length from $symbol table
            - see 'uvsoftware.ca/uvcopy2.htm#B7'
      mvfv1 h0(70),'$jobname: date/time=$datetime user=${LOGNAME}'
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).
  • the op1 area must be large enough to hold the expanded values

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"mvf" instruction continued

"mvf" is very useful with special symbols that may be null terminated such as $fil_ names, which are 80 bytes & null filled on the right.

The following examples move the 80 byte filename to a 90 byte area:

  1. filename-example...................... (null filled 80)
  2. filename-example......................__________ (+ blanks to 90)
  3. filename-example________________________________ (blank fill to 90)
  4. filename-example................................ (null fill to 90)
 #1.   mvc   b0(80),$fili1          - move (mvc) filename to area b
                                      (80 bytes unchanged, still null filled)
 #2.   mvf   b0(90),$fili1          - move (mvf) filename to area b & blank
                                      fill remainder of op1 (see #2 above)
 #2a.  mvf   b0(90),$fili1,' '      - same as above (blank fill default)
 #3.   mvft  b0(90),$fili1          - option 't' causes an additional
                                      backward blank fill of the result
                                      until the right most significant data
                                      is found (see #3 above)
 #4.   mvft1 b0(90),$fili1          - same as above but option 't1' fills
                                      with nulls (see #4 above)
 #4a.  mvft  b0(90),$fili1,x'00'    - same as above
Note
  • the op1 area must be large enough to hold the expanded values

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, "mvr", mvp, cat, clr, edt, anc, orc, xor, shf

`mvr` - move data from op2 to op1 right adjusted, left filled with op3

      mvr   op1adrs(op1lth),op2adrs(op2lth)[,op3fillchar]   - format
      mvr   b0(20),a0(15)          - move op2 to op1 6-20 (1-5 blanks)
      mvr   b0(10),a0(8),'0'       - move op2 to op1 right adjusted
                                     & zero left filled
Note
  • op1 length is expected to be greater than op2 length, but if not this instruction would act the same as 'mvc'
  • op1 is left filled with the op3 character which defaults to blank
condition code
  • unchanged as of version 0003 & all future versions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, "mvp", cat, clr, edt, anc, orc, xor, shf

`mvp` - move op2 to op1, if all EBCDIC blanks, convert to ASCII blanks

  mvp - same as mvc, but if field all EBCDIC blanks, set to ASCII blanks
      - to assist conversion of mainframes to UNIX
      - some COBOL programs expect unused table(occurs) group fields to
        be all blanks, even if some items are packed fields.
    mvp  b50(5),a50       - move area a bytes 50-54 to area b 50-54
                            if all EBCDIC blanks, set to all ASCII blanks

condition code

cc set '=' if op1 was in fact converted to ASCII blanks

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, "cat", clr, edt, anc, orc, xor, shf

`cat` - concatenate op2 data onto op1 data (within op1 limits)

      cata1 b0(80),a0(20)         - append data in a to data in b

'cat' scans op1 from rt to left for last significant data > x'20', appends the op2 data, & then rescans op1 from right to left for last significant data > x'20'.

 option b  - inserts before op2 data appended (at end of op1 data)
        b1 - 1 blank
        b2 - 1 line-feed
        b4 - 2nd line-feed
        b8 - 1 NULL
option c1
  • drop leading blanks in op2 before appending onto op1
 option a  - inserts after op2 data appended (at end of op2 data)
        a1,a2,a4,a8 - same as above
register 'x'
  • set to the first blank on the right hand side (or the data length on the left side)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, "clr", edt, anc, orc, xor, shf

`clr` - clear the op1 area to the op2 byte value

    clr  tobyte(lth),'constant'   - instruction format (op2 constant)
    clr  tobyte(lth),frombyte                          (op2 address)
    clr  b0(500),' '              - blank out 1st 500 bytes of area 'b'
    clr  h100(100),x'ff'          - fill 101-200 of area h to x'ff's
    clr  h100(100),g0             - fill 101-200 of area h with the
                                    value from byte 1 of area 'g'
                                  - op2 length always 1 byte
                                    & need not be coded

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, clr, "edt", anc, orc, xor, shf

`edt` - edit op2 data into op1 area controlled by op3 mask

     edt   b40(10),a20(4p),'zz,zzz.99-'

The example above edits the 4 byte packed (7 digit) field in cols 21-24 of area 'a' into cols 41-50 of area 'b' controlled by the mask in op3.

Symbols allowed in edit mask:

  z  - digit position to be zero suppressed
  9  - digit position NOT zero suppressed (1st '9' stops zero suppression)
  -  - minus sign, floating if on left, fixed position if on right
     - replaced by blank if numeric field is positive
  +  - sign indicator, shows '+' if positive, '-' if negative
     - may specify on left for floating, on right for fixed
  ?  - any other characters will be stored (unless zero suppress is still on)

The following are some examples of data, edit mask,& results:


        edt    b0(12),a0(8),'zz,zzz.99-'
        ================================
     data a0(8)       edit mask       results b0(12)
       1234567-       zz,zzz.99-     12,345.67-
       0000000-       zz,zzz.99-           .00
       0000000-       zz,zzz.zz-
       0000567-       zz,zzz.99-*         5.67-*
       0000567-            z.99-          5.67-   (auto left z's supplied)
       0000567-            z.99+          5.67+
       0000567-            -z.99          -5.67   (leading floating sign)
       0000567-            +z.99          +5.67
       1234567+       zz,zzz.99-     12,345.67
       0000000+       zz,zzz.99-           .00
       0000000+       zz,zzz.zz-
       0000567+       zz,zzz.99-*         5.67 *
       0000567+            z.99-          5.67    (auto left z's supplied)
       0000567+            z.99+          5.67+
       0000567+            -z.99           5.67   (leading floating sign)
       0000567+            +z.99          +5.67
condition code
  • set depending on op2 input value (< if negative, = if zero, > if positive)
register 'w'
  • stores number of non-blank characters in edited result

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'edt' options

option 'a1'
  • left adjust, example below:

         edta1  b0(12),a0(8),'zz,zzz.99-'
         ================================
          value        edit-pattern      result
          1234567-       zz,zzz.99-    12,345.67-   <--default right adjust
          0000567-            z.99-    5.67-        <-- option 'a1' left adjust
 option x#  - repeat # times, incrementing op1 by its length
             (also increment op2 if an address & not a constant)
        j#  - alternate length to increment op1 (vs op1 lth coded)
        k#  - alternate length to increment op2 (vs op2 lth coded)
            - example below:

         edtx12  p10(10),a20(5p),'zzzz,zzz.99-'
         ===***================================
         - edit 12 fields (each 5 bytes packed) cols 21-80 of area a
           into area p starting at column 11 (10 bytes each)

More 'edt' examples

     edt   b60(10),$date1(8),'9999/99/99'       edit system date
     edt   b72(5),$date1+8(4),'99:99'           edit system time
  • $date1 is the symbolic address of the 1st byte of the system date & time string - yyyymmddhhmmss
  • you would not use $time1 since that is UNIX time in seconds since 1970, used for calculating time intervals
     edt   p30(13),$ca1,'z,zzz,zzz.99-'
     edt   p30(13),x200(4b),'z,zzz,zzz.99-'
  • the above 2 instructions edit the same value $ca1 is counter #1 of counter group "a" & is at address x200(4b) (4 bytes binary)
     edt   p50(9),a20(7z),'zzzzz.99-'
     edt   p50(9),a20(7z),'z.99-'
  • the above 2 instructions are the same since 'z's are automatically assumed on the left side of the edit mask
     edt   p50(9),a20(7z),'-z.99'
  • if the 1st byte of the mask is '-' or '+' then a leading floating sign is inserted (-,+,blank)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, clr, edt, "anc", orc, xor, shf

`anc` - ANd Character (erase bits in op1 with corresponding 0 bits in op2

"anc" erases bits in op1 whose corresponding bits in op2 are 0. (0 bits prevail)

 ie:  0+0=0,  0+1=0,  1+0=0,  1+1=1
    anc  op1dsp(lth),'constant'    (op2 usually a 1 byte constant)
    anc  b20(10),x'0f'       - clear the zones of bytes 21-30 of area 'b'
    anc  b20(10),a10(1)      - op2 could be an adrs & op2 lth
                               could be > 1 but unusual
    ancm h20(3),x'0f0c0f'    - mask 21-23 of area 'h' with 3 byte mask
Note
  • op2 is usually only 1 byte & that 1 byte is 'and'd with each byte of the op1 data.
  • if op2 is > 1 byte, then it is assumed to be the same length as op1 & op2 is 'and'd byte for byte with the op1 data.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, clr, edt, anc, "orc", xor, shf

`orc` OR Character - set 1 bits in op1 with corresponding 1 bits in op2

"orc" inserts 1 bits in op1 for corresponding 1 bits in op2. (1 bits prevail)

 ie:  0+0=0,  0+1=1,  1+0=1,  1+1=1
    orc  op1dsp(lth),'constant'        (op2 usually a 1 byte constant)
    orc  b20(10),x'30'     - set zones of 21-30 of area 'b' to 0x30
    orc  b20(10),a15(1)    - op2 could be an adrs & op2 lth
                             could be > 1 but unusual

orcm h20(3),x'0f0c0f' - mask 3 bytes as shown

Note
  • op2 is usually only 1 byte & that 1 byte is 'or'd with each byte of the op1 data.
  • if op2 is > 1 byte, then it is assumed to be the same length as op1 & op2 is 'or'd byte for byte with the op1 data.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, clr, edt, anc, orc, "xor", shf

`xor` - eXclusive OR (bit manipulation)

xor (exclusive OR) creates 1 bits in the op1 result, only when the corresponding bits add to exactly 1.

 ie:  0+0=0,  0+1=1,  1+0=1,  1+1=0
   'xor'  - eXclusive OR character
    xor  op1dsp(lth),'constant'        (op2 usually constant)
    xor  h20(10),x'FF'     - xor all 1's reverses bits (complements)
    xor  h20(10),w15(10)   - op2 could be an adrs & op1 lth
                             could be > 1 but unusual
Note
  • if op2 lth > 1 it is assumed to be same lth as op1 vs 1 byte that is 'xor'd with each byte of op1
Example
  • copy 1st key to 2nd key area & 'xor' to created inverted key.
  • reverse sequence key for Indexed file systems that don't provide reading keys in reverse sequence.
  • assume 1st key in cols 1-30, create inverted 2nd key in 31-60
     mvc   b30(30),b0       - copy 1st key to 2nd key area
     xor   b30(30),x'FF'    - xor (complement bits in 2nd key)
                            - convert 1 bits to 0 bits,& 0 bits to 1 bits

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 1 (logical) - mvc, mvf, mvr, mvp, cat, clr, edt, anc, orc, xor, "shf"

`shf` - shift data a specified number of bits left or right

     shfr  dsplcmnt(length),bits    - shift right
     shfl  dsplcmnt(length),bits    - shift left
     shfr  b20(5),4                - shift data in cols 21-25 4 bits right
                                   - will zero the 4 bits on the left

sample input = x'1234567890' sample output = x'0123456789'

max length = 256 bytes

max no of shift bits = 8

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - "mvn", add, sub, mpy, div, pac, unp, xft

`mvn` - move numeric data depending on op1/op2 types & lengths

mvn todsp(tolth/typ),fromdsp(fromlth/typ) mvn todsp(tolth/typ),numconstant

    mvn  b100(9),a20(7)       - move 21-27 of area 'a' to 101-109 in 'b'
                                right adjusted, left zero filled
                                (defaults to zoned ascii numeric)
    mvn h30(-9za),r30(9za-)   - moves 31-39 input to 31-39 output
                                shifting sign trailing to leading
                              - negative indicated by '-' symbol
                                positive indicated by absence
                                (use '+' to show positive as '+')
    mvn b200(4bs),r50(9za)    - converts 51-59 from zoned ascii
                                to 201-204 binary long word
                              - 's' means switch bigend/littleend
    mvn b160(5pa),235-        - store constant neg 235 in 161-165
                                packed ascii (sign in zone)
    mvnx12 b100(5p),0         - move zero to the 12 5 byte packed
                                fields that start at byte 101 of area b
    mvnx6j10 b100(5p),0        - move zero to every 2nd field of the
                                 12 5 byte packed fields that start
                                 at byte 101 of area b (6 fields cleared)
    mvn  b80(9za),a20(5pe)    - unpacks 21-25 of 'r' into 81-89 of 'h'
                                21-25 is packed EBCDIC
                                81-89 will be zoned ASCII (sign in zone)
    mvn  b80(9za),a80(9zx)    - convert 81-89 zoned type 'x' (see below)
                                to zoned ASCII numeric
                              - type 'x' corrects zoned numeric signs
                                translated from EBCDIC to ASCII
                                before testing possible zoned signs
                                (see explanation next page)
    mvn  b0(10),a0(8f)        - convert floating point double to numeric
    mvn  b0(10),a0(4f)        - convert floating point single to numeric
    mvn  c0(8f),a0(4f)        - convert floating point single to double

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`data type & sign codes`

Data types & signs may be coded within the (length), for example:

      mvn   b100(-9za),a20(5p)

1st alpha letter defines the data type

z
  • zoned numeric (default)
p
  • packed decimal
b
  • binary - length should be either 1,2,3,or 4 bytes - usually 2 or 4 on a halfword or fullword boundary
k
  • Burroughs 'comp' data (similar to packed decimal, may have nosign)
  • fields may start &/or end on 1/2 byte boundaries
  • 1/2 byte alignment must be specified via options c1,c2,c3 (c1 field start 1/2 byte left, c2 field end 1/2 byte right, c3 both)
f
  • floating point (double if length 8, single if length 4)

2nd alpha letter defines the codeset (or indicates binary switch)

a
  • ASCII (default)
e
  • EBCDIC (probably from a mainframe)
s
  • causes a big-end/little-end switch when converting data between INTEL chip machines & others
x
  • ASCII zoned (unpacked) numeric translated from EBCDIC that may have had signs in the units zone (see explanation below)

separate sign byte codes

 "-" sign indicates a separate sign byte (vs zone of units digit)
     ('-' is coded if negative, else positive is assumed)
 "+" sign indicates a separate sign byte, but code '+' for positive
     as well as '-' for negative
 "-" or '+' in the 1st byte of the length indicates a leading sign byte
     else the sign byte will be trailing

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

data type code 'x' ASCII zoned numeric translated from EBCDIC

Data type code 'x' is provided to correct the units position of numeric zoned (unpacked) fields that have been translated from EBCDIC to ASCII without allowing for possible zoned signs.

      EBCDIC zone + sign is x'C0', + 0123456789 becomes {ABCDEFGHI
      EBCDIC zone - sign is x'D0', - 0123456789 becomes }JKLMNOPQR

Code 'x' converts positive units digits to 0123456789 (numeric zones) but negative units digit depends on whether the uvcp/uvcopy/uvsort utility has been generated with D-ISAM for Microfocus COBOL or not since conventions are different for Microfocus COBOL & MBP COBOL

      Microfocus zone - sign is x'70', - 0123456789 becomes pqrstuvwxy
      MBP COBOL zoned - sign is x'40', - 0123456789 becomes @ABCDEFGHI
Note
  • The 'trtsea' & 'trtsae' translate tables are a better solution to this problem, because you can correct multiple contiguous fields with 1 instruction. See details under the 'trt' instruction.

mvn - condition code

condition code
  • set < = > depending on op1 result neg, zero, pos
  • would reflect condition of last field if option x
    mvn   b20(8),$ca2         - store acum #2 in outrec & test zero ?
    skp!  1
    ---   ----,----           - do something if zero ??

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

options for 'mvn' & other numeric instructions

The following options also apply to mvn,add,sub,mpy,div,pac,unp,edt.

 option x#  - repeat the instrn # times, incrementing op1 by its length
             (also increment op2 if an address & not a constant)
        j#  - alternate length to increment op1 (vs op1 lth coded)
            - might use to process every 2nd field,etc
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option c  - 1/2 byte alignment for field type 'k' (Burroughs 'comp' data)
             (similar to packed, may have no sign, may be 1/2 byte aligned)
           - fields may start &/or end on 1/2 byte boundaries
        c0 - field is byte aligned on both left & right
        c1 - field starts in low  order 1/2 byte on the left
        c2 - field  ends  in high order 1/2 byte on the right
        c3 - both of above (c1 + c2 = c3)
 option d  - for Invalid digits in Numeric fields
        d0 - drop invalid digits
        d1 - convert invalid digits to '0's in zoned (unpacked) fields
        d2 - convert invalid digits to '0's in packed fields
option i1
  • inhibit the sign test in the units digit of zoned fields
  • useful when you are relying on the mvn instructions ability to select only the numeric digits from mixed fields & do not want to misinterpret a negative sign from alpha
  • for example if you were extracting the 'occurs' value from:
                05   fldgrp  AAA occurs 20 times.
                scn   a0(80),'occurs' <-- set rgstr 'x' to 'occurs'
                mvn   $ca1,ax7(4)     <-- MoVe Numeric digits from $rx+7(4)
                mvni1 $ca1,ax7(4)     <-- use option 'i1' to prevent sign detect
  • the 1st mvn above would load $ca1 with -205, because the "t" of "20 times" would be interpreted as negative 5
  • uvcopy compiled with D-ISAM option for compatibility to Microfocus COBOL expects negative zones to be lower case 'p' through 'y'
option i2
  • inhibit recognizing '-' sign in numeric character fields
option i3
  • inhibit both '-' signs & zoned signs
note
  • option 'i' on 'mvn' was option 't' prior to April 2003
  • changed because option 't' (tbl#) on 'tbl' caused sign problems on acums

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

options for 'mvn' & other numeric instructions

option q1
  • stop selecting digits on 1st non-digit
  • normally mvn selects digits from op1 (bypassing non-digits such as punctuation, etc)
  • negative sign '-' still accepted if option 'i' not coded
option s
  • controls packed decimal sign creation
        s0 - create packed sign output (op1) same as last input (op2)
             also validate & if not C/F, create as x'_C'
        s1 - create packed decimal signs as x'_C'
        s2 - create packed decimal signs as x'_F'
        s4 - same as s0 (copy last input packed sign for next output)
             but validation will create as x'_F' if invalid (not C/F)
        s8 - leave packed sign as is (may be invalid)
        s16- inhibit storing input sign from this instruction for next output
 option v# - adjust value depending on actual & implied decimal places
           - for implied decimal points in numeric fields
        v2 - example for option v2 & values 12345 with various dcml places

        mvnv2  a10(8),a0(8)
        ===================
           12345     01234500   - no dcml, *100
           1234.5    00123450   - 1 dcml,  *10
           123.45    00012345   - 2 dcmls, OK as is
           12.345    00001234   - 3 dcmls, /10 to drop extra place
option w#
  • used with v2 adjust value depending on implied decimal palces
  • sets the default decimal places when no '.' decimal point specified

        mvnv2w2  a10(8),a0(8)
        =====================
           12345     00012345   - no dcml with optn w2 (dflt 2 if no '.')
Note
  • all numeric instrns (mvn,add,etc) have the above options
  • There are also global 'run options' (rop=s0/s1/s2/s4) but instruction options s0/s1/s2/s4 over-ride run options.
  • Micro Focus COBOL requires x'_F' signs for pic 9 comp-3 fields, but x'_C' signs for pic S9 comp-3 fields.
  • this applies to linked programs, '.int's work either way

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"mvn" examples for signed fields +/-

  1. mvn zoned to zoned (default when field type not coded)
       mvn   a20(7z),a10(7z)      - mvn zoned to zoned (default)
       mvn   a20(7),a10(7)        - do not need to code the 'z' type
           -input-   -output-     note results shown as op2,op1 (reversed)
            a10(7)   a20(7)
           1234567   1234567      - all digits -> no change
           123456w   123456w      - sign in zone of units (w = -7)
            1234     0001234      - digits right adjusted & left zero filled
           1234-     000123t      - signs may be '-' or units zone x'70'
              123t   000123t      - t is x'74' for -4 vs x'34' for +4
           -1234     000123t      - signs may be leading or trailing
           1234 AB   001234r      - any non-numerics are ignored
  1. mvn zoned to zoned with trailing separate '-' sign byte on output
       mvn   a20(7-),a10(7)        - trailing sign if '-' trailing in (..)
           1234567   1234567
           123456w   234567-       - may lose data if out field not bigger
              1234   0001234       - positive assumed if no sign
           1234-     001234-       - negative digits offset 1 left for sign
           -1234     001234-       - leading input sign converted to trailing
  1. mvn zoned to zoned with leading separate '-' sign byte on output
       mvn   a20(-7),a10(7)        - leading sign if '-' leading in (..)
           1234567   1234567
           123456w   -234567
              1234   0001234
           1234-     -001234
           -1234     -001234
  1. mvn zoned to zoned with leading separate '+' sign byte on output
       mvn   a20(+7),a10(7)        - leading -/+ sign if '+' leading in (..)
           1234567   +234567
           123456w   -234567
              1234   +001234
           1234-     -001234
           -1234     -001234

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"mvn" examples - packed/binary conversions

  1. mvn zoned to packed
       mvn   a20(4p),a10(7z)       - convert zoned op2 to packed op1
           -input-   - - - output - - -
                     packed   hexadecimal
           1234567   .4V|      1234567C
           123456w   .4V}      1234567D
              1234   ..#L      0001234C
           -1234     ..#M      0001234D
Note
  • unprintable bytes in packed output field shown as '.' periods
  • hex representation shows signs 'C' positive & 'D' negative
  1. mvn zoned to binary
       mvn   a20(4b),a10(7z)       - convert zoned op2 to binary op1
           -input-   - - - output - - -
                     binary   hexadecimal
           1234567   ....      87D61200
           123456w   y)..      7929EDFF
              1234   ....      D2040000
           -1234     ....      2EFBFFFF
Note
  • this was run on an INTEL (little-end) machine vs RISC (big-end).
  • binary bytes reversed (little bytes on left, big bytes on right)
  • x'7B' is: 7*16 + B(11)*1 = 112 + 11 = 123
  • negative values are 2's complements

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"mvn" examples for floating point single/double

  1. mvn zoned to binary (switched from Little-end to Big-end) 's' option
       mvn   a20(4bs),a10(7z)       - convert zoned op2 to binary switched
           -input-   - - - output - - -
                     binary   hexadecimal
           1234567   ....      0012D687
           123456w   ..)y      FFED2979
              1234   ....      000004D2
           -1234     ....      FFFFFB2E
Note
  • the 's' option of (4bs) is used to 'switch' bytes
  • use this to send data from an INTEL machine to a RISC machine.
  1. mvn zoned to floating point (double)
      mvn   b0(8f),a0(8)
           -input-   - - - output - - -
                     binary    hexadecimal
           00000000  ........  0000000000000000
           00000001  ........  000000000000F03F
           00000002  ........  0000000000000040
           00000004  ........  0000000000001040
           00000008  ........  0000000000002040
           00000256  ........  0000000000007040
           00004096  ........  000000000000B040
           00065536  ........  000000000000F040
           01048576  ........  0000000000003041
           16777216  ........  0000000000007041
           00000010  ........  0000000000002440
           00000100  ........  0000000000005940
           00001000  ........  0000000000408F40
           00010000  ........  000000000088C340
           00100000  ........  00000000006AF840
           01000000  ........  0000000080842E41
           10000000  ........  00000000D0126341
           99999999  ........  000000FC83D79741

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, "add", sub, mpy, div, pac, unp, xft

`add` - add op2 data to op1 data & store result in op1

'add' will pack, unpack, convert to binary or decimal as required depending on the data type codes (in the length specification).

    add   op1dsplcmnt(length&type),op2dsplcmnt(length&type)
                                    ---OR---
    add   op1dsplcmnt(length&type),op2constant
    add  b100(9),a20(7)    - add op2 (21-27 of area 'a') to op1 (101-109 of 'b')
                             & store result in op1 (101-109 of area 'b')
                             (data types default to zoned ascii numeric)
    add  h160(5pa),235-      - adds  constant neg 235 to 161-165
                               161-165 packed ascii (sign in zone)
condition code
  • set < = > depending on op1 result neg, zero, pos
 option x#  - repeat the instrn # times, incrementing op1 by its length
             (also increment op2 if an address & not a constant)
        j#  - alternate length to increment op1 (vs op1 lth coded)
            - might use to process every 2nd field,etc
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option i1 - inhibit test for negative sign in units digit of zoned fields
        i2 - inhibit recognizing separate sign '-' in numeric fields
           - see more explanation under the 'mvn' instruction
 option d  - for Invalid digits in Numeric fields
        d0 - drop invalid digits
        d1 - convert invalid digits to '0's in zoned (unpacked) fields
        d2 - convert invalid digits to '0's in packed fields
 option s  - controls packed decimal sign creation
        s0 - create packed sign output (op1) same as last input (op2)
             also validate & if not C/F, create as x'_C'
        s1 - create packed decimal signs as x'_C'
        s2 - create packed decimal signs as x'_F'
        s4 - same as s0 (copy last input packed sign for next output)
             but validation will create as x'_F' if invalid (not C/F)
        s8 - leave packed sign as is (may be invalid)
        s16- inhibit storing input sign from this instruction for next output
Note
  • all numeric instrns (mvn,add,etc) have the above options
  • There are also global 'run options' (rop=s0/s1/s2/s4) but instruction options s0/s1/s2/s4 over-ride run options.
  • Micro Focus COBOL requires x'_F' signs for pic 9 comp-3 fields, but x'_C' signs for pic S9 comp-3 fields.
  • this applies to linked programs, '.int's work either way

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, "sub", mpy, div, pac, unp, xft

`sub` - subtract the op2 data from the op1 data & store result in op1

sub todsp(tolth/typ),fromdsp(fromlth/typ) sub todsp(tolth/typ),numconstant

    sub  b80(9za),a20(5pe)   - subtract 21-25 of 'a' from 81-89 of 'b'
                               21-25 of 'a' is packed EBCDIC
                               81-89 of 'b' is zoned ASCII (zoned sign)
    sub  b30(-9za),100      - subtract constant 100 from work area 'b'
                              leading '-' sign if neg,else zero
                            - negative indicated by '-' symbol
                              positive indicated by absence
                              (use '+' to show positive as '+')
    sub  h200(4bs),r50(9za)  - subtract 51-59 from  201-204
                               51-59 is zoned ascii
                               201-204 is a binary long word
                             - 's' means switch bigend/littleend
                               on both retrieval & store result
condition code
  • set < = > depending on op1 result neg, zero, pos
 option x# - repeat the instrn # times, incrementing op1 by its length
            (also increment op2 if an address & not a constant)
        j# - alternate length to increment op1 (vs op1 lth coded)
           - might use to process every 2nd field,etc
        k# - alternate length to increment op2 (vs op2 lth coded)
 option d  - for Invalid digits in Numeric fields
        d0 - drop invalid digits
        d1 - convert invalid digits to '0's in zoned (unpacked) fields
        d2 - convert invalid digits to '0's in packed fields
 option i1 - inhibit test for negative sign in units digit of zoned fields
        i2 - inhibit recognizing separate sign '-' in numeric fields
           - see more explanation under the 'mvn' instruction
 option  s   - controls packed decimal sign creation
         s0  - (default) create packed sign output same as last input
             - if packed sign not C/F, create x'_C'
         s1  - create packed decimal signs as x'_C'
         s2  - create packed decimal signs as x'_F'
         s4  - same as s0, but create sign x'_F' if not C/F
             - see full explanation under the 'mvn' or 'add' instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, sub, "mpy", div, pac, unp, xft

`mpy` - multiply op1 data by op2 data & store result in op1

mpy todsp(tolth/typ),fromdsp(fromlth/typ) mpy todsp(tolth/typ),numconstant

    mpy  b80(9za),a20(5pe)   - multiply 81-89 of 'a' by 21-25 in 'b'
                               21-25 is packed EBCDIC
                               81-89 is zoned ASCII (zoned sign)
    mpy  b30(-9za),115       - multiply bytes 31-39 of work area 'b'
                               by constant 115
                             - negative indicated by '-' symbol
                               positive indicated by absence
                               (use '+' to show positive as '+')
    mpy  h200(4bs),r50(9za)  - multiply 51-59 by 201-204
                               51-59 is zoned ascii
                               201-204 is a binary long word
                             - 's' means switch big-end/little-end
                               on both retrieval & store result
condition code
  • set < = > depending on op1 result neg, zero, pos

options

 option x#  - repeat # times, incrementing op1/op2 by spcfd lengths
        j#  - alternate length to increment op1 (vs op1 lth coded)
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option d   - for Invalid digits in Numeric fields
 option i1  - inhibit test for negative sign in units digit of zoned fields
        i2  - inhibit recognizing separate sign '-' in numeric fields
 option s   - controls packed decimal sign creation
        s0  - (default) create packed sign output same as last input
        s1  - create packed decimal signs as x'_C'
        s2  - create packed decimal signs as x'_F'
        s4  - same as s0, but create sign x'_F' if not C/F
            - see full explanation under the 'mvn' or 'add' instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, sub, mpy, "div", pac, unp, xft

`div` - divide the op1 data by the op2 data & store result in op1

div todsp(tolth/typ)fromdsp(fromlth/typ) div todsp(tolth/typ):constant

    div  b100(9),a20(7)      - divide 101-109 by 21-27
                               & store result in 101-109 (op1)
                               (defaults to zoned ascii numeric)
                               op1 dflts to recout, op2 to recordin
    div  h160(5pa):235-      - divs 161-165 by constant -235
                               161-165 packed ascii (sign in zone)
remainder
  • will be left in $rem same as x104(4b)
      div   c50(9),24            divide hours by hrs/day
      cmn   $rem,12              remainder > or < 12 hrs ?
condition code
  • set < = > depending on op1 result neg, zero, pos

options

 option x#  - repeat # times, incrementing op1/op2 by spcfd lengths
        j#  - alternate length to increment op1 (vs op1 lth coded)
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option d   - for Invalid digits in Numeric fields
 option i1  - inhibit test for negative sign in units digit of zoned fields
        i2  - inhibit recognizing separate sign '-' in numeric fields
 option s   - controls packed decimal sign creation
        s0  - (default) create packed sign output same as last input
        s1  - create packed decimal signs as x'_C'
        s2  - create packed decimal signs as x'_F'
        s4  - same as s0, but create sign x'_F' if not C/F
            - see full explanation under the 'mvn' or 'add' instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, sub, mpy, div, "pac", unp, xft

`pac` - pack the op2 data into the op1 area

    pac  op1dsp(op1lth),op2dsp(op2lth)    - instruction format
    pac  h100(5),r50(9)      - pack bytes 51-59 of area r
                               into bytes 101-105 of area h
 option x#  - repeat # times, incrementing op1/op2 by spcfd lengths
        j#  - alternate length to increment op1 (vs op1 lth coded)
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option d   - for Invalid digits in Numeric fields
 option i1  - inhibit test for negative sign in units digit of zoned fields
        i2  - inhibit recognizing separate sign '-' in numeric fields
 option s   - controls packed decimal sign creation
        s0  - (default) create packed sign output same as last input
        s1  - create packed decimal signs as x'_C'
        s2  - create packed decimal signs as x'_F'
        s4  - same as s0, but create sign x'_F' if not C/F
            - see full explanation under the 'mvn' or 'add' instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, sub, mpy, div, pac, "unp", xft

`unp` - unpack the op2 data into the op1 area

unp op1dsp(op1lth),op2dsp(op2lth) - instruction format

    unp  b100(9),a50(5)         - unpack 51-55 of area a
                                  into 101-109 of area b
 option x#  - repeat # times, incrementing op1/op2 by spcfd lengths
        j#  - alternate length to increment op1 (vs op1 lth coded)
        k#  - alternate length to increment op2 (vs op2 lth coded)
 option d   - for Invalid digits in Numeric fields
 option i1  - inhibit test for negative sign in units digit of zoned fields
        i2  - inhibit recognizing separate sign '-' in numeric fields
 option s   - controls packed decimal sign creation
        s0  - (default) create packed sign output same as last input
        s1  - create packed decimal signs as x'_C'
        s2  - create packed decimal signs as x'_F'
        s4  - same as s0, but create sign x'_F' if not C/F
            - see full explanation under the 'mvn' or 'add' instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 2 (arithmetic) - mvn, add, sub, mpy, div, pac, unp, "xft"

`xft` - crossfoot multiple op2 fields & store the result in op1

  • the number of fields is specified by op3
  • op2 defines the 1st of the multiple fields & all must be the same size & contain the same type of data
      xft   d0(4b),a100(5p),12
      skp=  allzero
  • crossfoots the 12 5 byte packed fields in 101-160 & stores the result in long word in 1st 4 bytes of area 'd'
  • also sets cc = if result zero, > if positive,& < if negative
      xft   $ca1,a100(5p),12
  • same as above, but cross-foots into user accumulator $ca1 rather than the 1st 4 bytes of area 'd'
 option  s   - controls packed decimal sign creation
         s0  - (default) create packed sign output same as last input
             - if packed sign not C/F, create x'_C'
         s1  - create packed decimal signs as x'_C'
         s2  - create packed decimal signs as x'_F'
         s4  - same as s0, but create sign x'_F' if not C/F
             - see full explanation under the 'mvn' or 'add' instructions

$ci1 = number of significant (non-zero) fields

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 3 (compare/test) - "cmc", cmn, skp, nop, tst, tsb

`cmc` - compare and set internal condition code for following skp

       cmc  op1dsp(op1lth),op2dsp     - instrn format (op2 area address)
       cmc  op1dsp(op1lth),'constant'                 (op2 constant)
       cmc   a0(2),'25'     - compare cols 1-2 of area a to constant '25'
       skp=  2                skip next 2 instrns if cc was set '='
       cmc   b50(5),b55     - compare cols 51-55 to 56-60 in area 'b'
       skp>               if cc was set '>' skip to label tagx
 tagx  ---                  - labelled target instrn for the skp above
 tagx  nop                  - may use a no-operation instruction when you
                              have nothing else to do at the target
       cmc   b0(100),' '    - 'ALL' assumed when op1 multi-byte & op2 1 byte
option 'p'
  • to allow pattern matching characters in op2
  • @ = any alpha, # = any numeric, etc
  • see the 'scn' instruction for the complete list
       cmcp    b70(6),'@#@#@#'  - validate the Canadian postal code
       skp=    ok
option 'p1'
  • inhibit pattern match for 1st 1 byte (use direct compare)
option 'p9'
  • inhibit pattern match for 1st 9 bytes (use direct compare)
       cmcp1   a0(2),'##'   <-- compare '#' in 1st byte + any digit 0-9 in 2nd
option 'i1'
  • case insensetive, translates to lower case before compare
  • translates both op1 & op2 to lower case before compare
       cmci1   a0(3),b0(3)  <-- compare 1st 3 bytes area a to 1st 3 area b
                              - case insensetive
       cmci1   a0(3),'hdr'  <-- compare 1st 3 bytes area a to 'hdr' or 'HDR'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"cmc" - compare character and set cc for following skp (continued)

cmc - registers modified

register 'w'
  • will hold the displacement of the 1st non-matching byte or will hold dsplcmnt of 1st byte beyond op1 if all match

You might use to mark the 1st non-match between 2 areas, for example: (assuming you knew same number of records in each file)

test data for uvcopy job to mark mismatches between files * test data for uvcopy job to mark mis-matches between files

 loop   get    fili1,a0(80)        get record from file#1
        get    fili2,b0(80)        get record from file#2
        cmc    a0(80),b0(80)       area a = area b ?
        skp=   loop                yes - return to get next pair
        put    filo1,a0(80)        no - write line from 1st file
        mvc    cw0(1),'*'          - mark 1st nonmatch in area c (blank)
        putb   filo1,c0(80)        - write marker line & clear
        put    filo1,b0(80)        - write line from 2nd file
        put    filo1,' '           - space between groups
        skp    loop                - return to get next pair of recs

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 3 (compare/test) - cmc, "cmn", skp, nop, tst, tsb

`cmn` - compare numeric & set condition code for following skp

       cmn   op1dsp(op1lth),op2dsp(op2lth)  - instrn format (op2 adrs)
       cmn   op1dsp(op1lth),numconstant       (op2 numeric constant)
       cmn   a20(4b),25         - compare area a 21-24 binary to const 25
       skp>  3                    & skip 3 instrns if >
       cmn   a80(9za),a90(5pe)  - compare 81-89 zoned ascii to 91-95
       skp=  tagx                 packed ebcdic & skip to tagx if '='
 tagx  ---                      - labelled target instrn for the skp above

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 3 (compare/test) - cmc, cmn, "skp", nop, tst, tsb

`skp` - skip to a tag (or number of instrns) if condition code matches

The skip is taken if the internal condition code (set by a prior instruction) matches the condition coded in the byte 4 (& 5 if required).

    =  >  <  ! <>  =>  <=  ..  blank

The condition code would have been set by a preceding instruction (cmc,rep,scn,add,sub,mpy,div,etc). '..' might be coded when the actual condition is stored in op2

      skp??  9                - skip a number of instrns (if cc matches)
                              - ?? may be any of above
      skp??  tag              - skip to a label/tag
      skp??  g0(8)            - skip to the label stored in op1 area
                              - max 8 blank filled (new as of Sep 2018)
Note
  • 'tags' must have 3 alpha before any numerics
      cmc    a0(2),'25'       - compare cols 1-2 to constant '25'
      skp=   2                  & skip next 2 instrns if cc was set '='
      cmn    b50(5p),b55(3p)  - compare packed cols 51-55 to 56-58 in area 'b'
      skp=>  tagx               & skip to tagx if 51-55 => 56-58
      cmc    a0(2),'25'
      skp..  tag,c0(1)    <--- op2 may contain the condition code
                              '..' indicates condition stored in op2
 If op2 is present on the 'skp' instruction, it will be assumed to hold
 the condition code in 1 or 2 bytes (=, !, >=, <=)
 NOTE - 'tags' (instruction labels) must have 3 alpha before any numerics.
 tag1   ---              <-- valid tag
 rt2    ---              <-- INVALID label (only 2 alpha before numeric)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`skptable` - demo job lookup table of Record-Types & Processing-Labels

 # citytax2a - alt citytax2 to demo 'skp' to label in an area (vs fixed constant)
 #           - this demo job stored at $UV/mvstest/cnvdata/pf/citytax2a
 # Demo lookup table of Record-Types & Processing-Labels
 # - using demo file $UV/mvstest/cnvdata/d1ebc/citytax2 with 3 record-types
 # - But, demo's technique, could apply to other situations with hundreds of R/Ts
 # - six times faster than using cmc/skp multiple times
 uop=q0,was=a64000b64000
 fili1=?d1ebc/citytax2,rcs=00128,typ=RSF
 filo1=?d2asc/citytax2,rcs=00128,typ=RSF
 # fili2=?ctl/citytax2_RecType_Lookup,rcs=80,typ=LST
 # - could code RecordType Lookup table in a file
 # - but coded in this job as follows:
 lodc1=t0(80)
 # R/T   ProcessLabel   Record description (optional)
 H       typH           file Header record
 T       typT           Tax record
 P       typP           Payment record
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 @run
        opn    all
 loop   get    fili1,a0
        skp>   eof
        mvc    b0(00128),a0         move rec to outarea before field prcsng
        tra    b0(00128)            translate entire outarea to ASCII
 #      ---                <-- insert R/T tests for --> citytax2
 # Lookup table of Record-types & corresponding Processing-Laabel
        lok    t0(80),t0(1),b8(1)   lookup match to current record type ?
        skp=   typOK
        msgw   'nomatch in table of RecordTypes, will assume no packed/zoned'
        skp    put1                 go output with tra only (no pack/zone fixes)
 #
 # RecordType match found - skip to the corresponding processing label
 typOK  skp   t8(8)                 skip to ProcessLabel
 #
 typT   mvc    b88(4),a88           bns post-date
        mvc    b92(15),a92          pns land-value:face-value
        trt    b107(9),$trtsea       ns maint-tax
        skp    put1
 #      ---                    redef typ__ for --> Payment record
 typP   mvc    b20(60),a20          pns mthpayments
        skp    put1
 #      ---                    redef typ__ for --> Header record
 typH   nop                         (could have coded put1 in R/T table)
 put1   put    filo1,b0             common point output for all RecordTypes
        skp    loop                 return to get next record
 #
 eof    cls    all                  close files & end job
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 3 (compare/test) - cmc, cmn, skp, nop, "tst", tsb

`tst` - test each op1 sub-field for match to any op2 sub-field

    tst   a0(1),'xyz'           - test col 1 for x,y,or z
    skp=  hit                     cc set = if col1 is x,y,or z
    tst   r0(10),'abc'          - test cols 1-10 for a,b,c
    skp=  all                     cc set = if all cols a,b,or c
    skp>  some                    cc set > if some cols match
    skp<  nomatch                 cc set < if no matches
    tstl2 r0(10),'aabbcc'       - test 5 x 2 byte subfields in 1-10
    ---                           for matches to op2 2 byte subflds
option 'l'
  • may specify the sub-field length (default 1 byte)
  • always applies to the op2 search patterns
  • also applies to the op1 data field, but option 'i' overrides
option 'i'
  • specifies the op1 data search increment
  • defaults to option 'l' (which defaults to 1)
  • option l > 1 assumes op1 data has fixed size sub-fields but option 'i1' will scan the op1 data (like scn or sct)

post instruction status

 condition code: = if all subflds in op1 have a match in op2
                 < if no matches
                 > if some but not all op1 subflds match an op2 subfld
 instrn counter: $ci1 - counts the no of matching op1 subflds
                 $ci2 - counts the no of nonmatching op1 subflds
 index register: x - will hold dsplcmnt of 1st match in op1 (else end op1)
                 y - will hold dsplcmnt of 1st match in op2 (else end op2)
                 u - will hold dsplcmnt of 1st nonmatch in op1 (else end op1)

lottochk1 - uvcopy job to demo 'tst'

'lottochk1' is listed below to illustrate using the 'tst' instruction. You can run it from /home/uvadm by entering just 'uvcopy lottochk1' & entering the 6 numbers when prompted. Or enter the 6 #s via arg1=... & take the defaults for the demo file. You might modify it for your lottery if they supply a csv file of all past winning#s.


 uvcopy lottochk1,arg1=01:10:16:19:36:49
 =======================================

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

lottochk1 - uvcopy job to demo 'tst'

 # lottochk1 - check favorite#s to history file of winning#s (OT, Nov2009)
 #           - uvcopy job to demo the 'tst' instruction
 #
 # uvcopy lottochk1,fili1=tf/649.csv,filo1=tmp/649wins,arg1=01:10:16:19:36:49
 # ==========================================================================
 #
 # "649",1,"1982-06-12",3,11,12,14,41,43,13   <-- 1st 3 lines of history win#s
 # "649",2,"1982-06-19",8,33,36,37,39,41,9      - 7th # is Bonus (I ignore)
 # "649",3,"1982-06-26",1,16,23,24,27,49,34   <-- my fav#s match 3 of these
 #
 # "649",3,"1982-06-26",1,16,23,24,27,49,19 03 <-- output if 3+ matches to arg1=
 #
 # field#s 4,5,6,7,8,9 are the 6 winning#s, 10th field is bonus# (I ignore)
 # 'tst' - tests each op1 subfield for matches to any subfield in op2
 #       - sets cc = if all match, > if some match, < of no matches
 #       - also counts matches in $ci1 (we will use that)
 # - would have been easier if win#s all zero filled 2 digits (but not)
 # - we use 'fix' to split csv fields 20 bytes apart, longest is 10 (date)
 # - then use 'clr' 21 bytes of area c to ':'s & 'mvn' to zero fill 2 byte#s
 # - then we can 'tst' to our arg1=01:10:16:19:36:49
 #
 rop=r1   # Run OPtion r1 prompts for outfile disposition (reply vi,more,cat,etc)
 fili1=?tf/649.csv,rcs=256,typ=LST    #<-- input of BCLC win# history file
 filo1=?tmp/649wins,rcs=256,typ=LSTt
 @run
        opn    all
        msga1cnw 'enter 6 2-digit#s separated by ":" colons'
        mvc    d0(18),$arg1          save $arg1 in area d for match
 #
 # begin loop to get/match/select 3+ matches to output file
 man20  get    fili1,a0
        skp>   man90
        fix    b0(20),a0(80),10,','
 #      ===
        clr    c0(21),':'
        mvn    c00(2),b060(2)
        mvn    c03(2),b080(2)
        mvn    c06(2),b100(2)
        mvn    c09(2),b120(2)
        mvn    c12(2),b140(2)
        mvn    c15(2),b160(2)
        mvn    c18(2),b180(2)
        tstl3  c0(18),d0(18)
 #      =====
        cmn    $ci1,3                 3+ matches ?
        skp<   man20
        mvn    a50(2),$ci1            store matches on right side
        put    filo1,a0
        skp    man20
 #
 # EOF - close files & end job
 man90  cls    all
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 3 (compare/test) - cmc, cmn, skp, nop, tst, "tsb"

`tsb` - test 1 byte of data for any match to the bits in the 1 byte op2

     tsb   data,mask         - instruction format
     skp=  match               cc set = if any bits match
     tsb   a0(1),x'01'       - test 1st byte of area 'a' for x'01' bit
     skp=  odd                 (might be testing for an odd or even number)

condition code set for following 'skp_' instruction

 "=" (equal)        - if ALL  bits in the mask are matched in the data byte
 ">" (greater than) - if SOME but not all bits in the mask match bits in data
 "<" (less than)    - if  NO  bits in the mask are matched in the data byte

Notes

  1. The op1 data can only be 1 byte.
  2. If there is only 1 bit in the mask (usually the case) you can always use the '=' condition to test for a match. When there are multiple bits in the mask you must be careful not to use "skp=" if you want to test ANY match vs ALL matches. Of course you could use "skp=>" for any or all matches.

  3. The op2 mask is usually a 1 byte hex constant, but could be an area address.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - "opn", cls, get, put, rel, rtb, wtb

`opn` - open a file - or all files declared if op1 = 'all'

      opn  fili1               - open a specific file
      opn  all                 - open all files that have been declared
                                 via the fil__, rcs,& typ functions
register z
  • will hold the size of the file last opened
  • not normally required
register u
  • will hold the record size of the last input file opened
  • you do not need to code this on 'get's to an Indexed file (as long as big enough), but you would need to code on 'put's to a sequential file if converting Indexed to sequential.
  • This value will be correct for valid Indexed ISAM input files, but may not be correct for other file types if rcs=XXX were not declared correctly on the 'fili_/filr_ functions
register v
  • will hold the slot size after open input (all file types)
  • slot size is 1 greater for typ=ISF & typ=RSR
 $fstat     - will store the file status structure in work area x2800(32)
              (see area 'x' documentation in previous section)
            - of interest only to UNIX gurus
option e1
  • do not end the job if the open fails (default)
  • instead, return with cc set < (vs = if ok)
  • usually the default errmsg & endjob is ok since most jobs cannot procede without the files being present but some jobs have files of secondary importance or process all files in a directory & don't want to bomb out due to 1 missing file.
  • could also be used simply to test for the existence of a file that might be created by some other job as a signal.
      opne1  fili1              - open file & test if present ?
      skp<   nofile

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - "opn", "cls", get, put, rel, rtb, wtb

"opn" - open file (continued)

Notes re D-ISAM variable length records

Option 'v' for D-ISAM variable length records is specified on the file typ function, not here on the 'opn'. File 'typ' options are documented in uvcopy1.doc, but here is a brief review & example:

 filo1=xxx,typ=ISFv5000,rcs=50,isk1=0(6)

This specifies max rcsz 5000 (option v on typ) & minimum rcsz 50 (on rcs=). The max rcsz option 'v' must be correct for output files but you can specify anything to indicate variable input files (v999). After open INPUT variable length, register 'v' will hold the max rcsz.

`cls` - close a file

'cls' - closes a file, or all files that are open if op1 = 'all'

      cls  fili1               - close a specific file
      cls  all                 - close all files that are open
option s1
  • inhibit EOF stats (record counts)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, "get", put, rel, rtb, wtb

`get` - next record from a sequential file & store in the op2 area


   get  file,recordarea[,fillchar,altstopchar]   - instruction format
   ===========================================
 loop  get  fili1,a0(128)          - example
       skp> eof                    - cc set > at EOF
       skp< locked                 - cc set < for ISAM locked records
       ---                         - valid record retrieved
       get  fili1,a0               - record size may be omitted from get
                    ^^^^^
 record size - if omitted from the get (& put,etc), the record size
               defaults from the 'rcs' parameter on the file declaration
             - record size specified on the 'get' will override the 'rcs'.
             - record size may depend upon file type

file types (typ=RSF,RST,LST,ISF,IDX,DIR)

LST
  • System Line Terminated or variable length text file
  • rcsz depends on stop chars (LF) in variable size recs
  • if stop char not found reading stops at op2 length spcfd
RSF/RST
  • Sequential Fixed length (optionally Terminated by LF)
  • op2 lth determines record size read & should match file data of course
ISF
  • Proprietary Isam Fixed length records
  • record size predetermined when file created
DIR
  • System Directory Fixed (filenames, system independent access)
  • may specify rcsz up to 256 (suggest 80 enough) (traditional UNIX systems only allowed 14 bytes)
IDX
  • Indexed Sequential Variable length record files (IDXFORMAT3)
RSV
  • Record Sequential Variable length record files (compatible with Micro Focus COBOL IDXFORMAT3, data partition)
  • see RSV file formats documented at 'https://uvsoftware.ca/uvcp.htm#I2'
STL
  • STandard Language file system, used by AIX COBOL
  • STLs=Sequential, STLi=Indexed, STLr=Relative
  • see STL file formats documented at 'https://uvsoftware.ca/uvhd.htm#5J1'
fillchar
  • Operand 3 is an optional fill character that defaults to a blank
  • the input area is initialized to all fillchars before each read
altstopchar
  • Operand 4 is an optional alternate stop character. It defaults to a tilde '~', but it is not used unless selected by option 's8'
  • the default option 's' is 's2' which selects the LineFeed x'0A'
  • see all options explained on the next page --->

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"get" instruction (continued)

condition code

The condition code set greater than '>' at end of file. uvcopy also stores '~EOF' in the 1st 4 bytes & fills the rest to '~'s. This is not usually required, but sometimes useful for more complex jobs that still have processing to do at EOF.

The condition code is set '<' for locked records if option 'l4' is coded for ISAM files. You may also code option 'w' (wait, default w1, 1 second) & opion 'r' (retries, default r8, 8 times). These options more commonly used on the random read instruciton 'red'.


 fili1=dat1/custmast,typ=ISFl4,rcs=256   #<-- must code option l4 on typ=ISFl4
 =====================================
 getr  getl4w1r8 fili1,a0
       skp=   ok
       skp>   eof
 # cc < (locked record) - prompt for retry
       msgw   'locked record - enter to retry'
       skp    getr

get options for typ=ISF


 fili1=dat1/custmast,typ=ISFl4,rcs=256   #<-- must code option l4 on typ=ISFl4
 =====================================
l4 (typ=ISFl4)
  • manual lock option for ISAM files
  • must code typ=ISFl4 to allow lock option 'l4' on 'getl4'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"get" instruction (continued)

get options for typ=LST

 fili1=dat1/test100,typ=LST...,rcs=80  #<-- file declaration for typ=LST...
    get     file,recordarea[,fillchar][,arg4char]
                           - fillchar defaults to ' ' space x'20'
                           - arg4char defaults to '~' tilde x'7E'
    get     fili1,a0    <-- normal get instruction
    gets2   fili1,a0    <-- default option 's2' stop read on LF
 ======****=========
c1
  • convert any unprintable chars to blanks
c2
  • convert any unprintable chars to periods
c4
  • convert nulls to blanks
c8
  • convert tabs to blanks
c16
  • minimize remove trailing blanks, nulls, LFs Note - minimize set by any LST unless LSTt4 both in/out
c32
  • also blank CR on scanback if c16/0x100000 set
c64
  • getlin1 NEW force stop read on formfeed x'0C'
c128
  • putlin1 determine length by 1st null vs last nonblank
d1
  • delete CR's, d2 delete LF's, d4 delete NULL's, d8 delete tildes '~'
  • N/A to fili typ=LST... only to getd...
e1
  • convert CR's to blanks, e2 LF's to blanks, e4 NULL's to blanks, e8 tildes '~'
  • N/A to fili typ=LST... only to gete...
s1
  • stop read/write on CR
s2
  • stop read/write on LF <-- default
s4
  • stop read/write on NULL
s8
  • stop read/write on arg4 (tilde '~')
t1
  • terminate write with CR
t2
  • terminate write with LF
t4
  • terminate write with NULL
t8
  • terminate write with arg4 (tilde '~')
  • t1,t2,t4,t8 used for input only by uvcopy on gett... instruction
  • option t# usually on typ=LSTt# fili# definition, not on gett# instruction
  • unusual on Input, usually only on Output
  • option 'm' only for uvcopy getm#/putm# instrns
m1
  • minimize remove trailing blanks,nulls,LFs
m2
  • scanback also remove trailing CR x'0D'
m4
  • getlin1 NEW uvcopy getm4 FORCE stop read on x'0C'
m8
  • putlin1 determine length by 1st null vs last nonblank
n1
  • no errmsg/halt if no LineFeed before op2 area full
  • end get & return as normal (same as file option LSTn1)
Note
  • options on get... override options on fili typ=LST...
  • many more options available on get... (vs typ=LST...)
  • some option combinations would conflict (take care)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"get" instruction (continued)

file typ options (vs options on get instruction)

There are also some related 'file options' specified on the file "typ" function. See file typ options in uvcopy1.doc or uvcopy2.doc.

Some examples of file typ options relevant to the 'get' are:

typ=LSTm2000
  • change the monitor progress default from 10,000 to 2000
typ=RSFu
  • file option type 'u'
  • UNIX system file unbuffered (open/read vs fopen/fread)
  • required for 9 track tape reads on 2145-03 especially unlabeled tapes where block size is unknown (see job t9copy2 in section TAPEjobs.doc)

fill-character op3

Op3 is the record area pre-fill character (default blank usually OK). Used for more complex jobs such as 'unws2' (unwordstar) which reads the file as blocks of binary characters. unws2 specifies the fill character as x'00' which is squeezed out (would occur in short block at EOF)

register 'z' & 'v'

Register 'z' & 'v' will hold the return code from the get instruction. This is usually the record size (or -1/0 on EOF/error) Register 'z' or 'v' might be used when processing a file as fixed blocks (vs linefeed terminated or fixed record size). For mag tape register 'z' or 'v' would be used to get size of partial block at EOF (for example see the 'unws1' job in UVjobs2).

Variable length files (register 'v')

Register 'v' will hold the record size of the record just read.

If you were copying variable length records, you would specify this value on the 'put' instruction, for example:

      get    fili1,a0(9999)     - don't need to specify lth on get
 #                                (but area a must be allocated big enough)
 #                              - get stores rcsz in rgstr 'v'
      put    filo1,a0($rv9999)  - rgstr v specifies size to be written
 #                                (to maximum of 9999)

For variable length output, the last input record size will automatically be used if the output record size is omitted. This is most useful for: typ=RDW, typ=STLs/STLi/STLr, typ=IDXf3v, typ=IDXf8v

      put    filo1,a0           - op2 length omitted uses $rv
                                - probably from last get
Note
  • defaulting 'put' record size to $rv is independent of input file type
  • 'get' for all input types stores size in $rv (all same if fixed)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`getrecsizes1` - demo recsizes stored in register 'v' by 'get'

 # getrecsizes1 - create summary table of record-sizes in a text file
 #           - by Owen Townsend, June 6, 2007
 #           - demonstrates uvcopy registers & instructions
 # $rv - register 'v' holds record-size from last 'get' instruction
 # tbl - build table in memory (summary count for each record-size)
 # tbp - dumps table to output file at EOF
 # rop=r1x2 - prompts for outfile disposition, default x2=more
 #
 # uvcopy recsizes1,fili1=dat1/customers,filo1=tmp/custrecsizes
 # ============================================================
 #                   ** sample report **
 #
 # recsizes1  2007/06/07_13:54:02  summary of record-sizes in: dat1/customers
 # tbl#001 pg#001     -argument-
 # line#  count    %  record-size
 #     1       1   3  0079
 #     2      10  31  0086
 #     3       2   6  0098
 #     4      19  59  0102
 #            32*100   *TOTAL*
 #
 rop=r1x2      # option r1=display outfile at EOJ, x2=more (default command)
 was=a8192     # increase area 'a' to allow recsizes up to 8192 bytes
 fili1=?infile,rcs=8192,typ=LST
 filo1=?recsizesummary,rcs=128,typ=LSTt
 @run
         opn     all
 #
 # begin loop to get records & table record-size, until EOF
 # - 'get' instrn stores binary recsize in rgstr 'v' ($rv)
 # - use 'mvn' to convert binary $rv to 4 numerics for table argument
 man20   get     fili1,a0(8192)         get next record
         skp>    man80
         mvn     c0(4),$rv              store recsize in digits
         tblt1   c0(4),'record-size'    build table of record-sizes
 #       =====
         skp     man20                  return to get next record
 #
 # EOF - dump table to outfile, close files & end job
 man80   tbpt1v1 filo1,'summary of record-sizes in: $fili1'
 #       =====
         cls     all
         eoj

'get' - get directory records (from fild1,etc)

 loop  get  fild1,d0(80)           - get record from a directory
       skp> eof                    - cc set > at EOF
       skp< loop                   - cc set < if not an ordinary file
                                     (probably a subdirectory)
Note
  • see 'copydir1' sample/demo job on the next page
  • to copy all files from 1 directory to a 2nd directory
  • you can copy/rename & insert your code to modify the files

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`getcopydir1` - demo 'get' filenames from directory & copy all files

 # copydir1 - copy all files from 1 directory to a 2nd directory
 #          - copies files with no changes (except removing trailing blanks)
 #          - you may modify output by inserting instructions at man30 below
 # copydir2 - alt job copies all files from 1 dir into 1 COMBINED OUTPUT FILE
 #
 #usage: uvcopy copydir1,fild1=indir,fild2=outdir
 #       ========================================
 # copydir1 is intended as a framework to be copied/renamed/modified
 opr='$jobname - copy all files in 1 dir to a 2nd dir
 fild1=?indir,typ=DIR,rcs=80           #input directory
 fili1=xxxxxxxx,typ=LST,rcs=4096       #current input file from directory
 fild2=?tmp,typ=DIR,rcs=80             #output directory
 filo2=xxxxxxxx,typ=LSTt,rcs=4096      #current output file
 fili3=tmp/infiles,typ=LST,rcs=256     #file of input filenames
 @run
        opn    fild1                    open input directory
        msgwy 'did you create empty outdir (or remove all files)'
        opn    fild2                    open output directory (must exist)
        mvfv1t1 s0(80),'ls $fild1 >tmp/infiles'  expand $fild1
        sys    s0(80)                   create file of filenames (in sequence)
        opn    fili3                    open file of filenames
 #
 # begin outer loop to read directory for next filename
 man10  get    fili3,a0(80)             get next record (filename) in directory
        skp>   man90                    (cc set > at EOD)
 # create input filename by concat: indir/infile & open
        clr    f0(300),' '
        mvu    f100(80),$fild1,x'00'    move dirname until ending null
        cat    f100(80),'/'             concat the '/'
        cata8  f100(80),a0(80)          concat current filename (a8 null terms)
        mvc    $fili1,f100              store input filename before open
        opn    fili1                    open current input file
 # create same filename in output subdir & open
        mvu    f200(80),$fild2,x'00'    move output dirname until null reached
        cat    f200(80),'/'             concat the '/'
        cata8  f200(80),a0(80)          concat current filename (a8 null terms)
        mvc    $filo2,f200              store output filename before open
        opn    filo2                    open current output file
 #
 # begin inner loop: get/put records from/to current file until EOF
 man20  get    fili1,b0(4096)           get each record into area 'b'
        skp>   man80
        mvc    d0(4096),b0              copy input area to output area
 man30  nop
 # --- INSERT YOUR INSTRUCTIONS HERE TO MODIFY RECORDS AS DESIRED ---
 #      ...    d..,...              <-- insert instructions to modify output
        put    filo2,d0(4096)           output record
        skp    man20                    return to get next record from current file
 #
 # EOF current file - output counts, close files,& return for next file pair
 man80  cls    fili1                    close current input file
        cls    filo2                    close current output file
        skp    man10                    return to get next filename from directory
 #
 # end input directory - display stats, close all dirs & files, & eoj
 man90  cls    all
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, get, "put", rel, rtb, wtb

`put` - a record to a sequential file

 filo1=dat1/test100,typ=LST,rcs=80  #<-- file declaration for typ=LST...
    put   filo1,b0(128)      - write to output file #1 from area 'b'
                             - writes 128 bytes if file typ=RSF or RST
                             - option 't' on typ=LSTt shortens to last nonblank
                             - up to 40 output files (filo1 - filo40)

put filo1,b0($rx128) - lth determined by rgstr x max 128

    putb  filo1,b0(80)       - option 'b' to blank after
    put   filo1,x'0C'        - write a formfeed control character
                             - illustrates op2 constant possible
    put  filo1,b0            - record size may be omitted from the 'put'
                 ^^^^^

record size

 If omitted on the put instruction, the record size will default from the
 'rcs=...' parameter on the file declaration (fili1=..., or filo1=..., etc).

Any record size specified on the 'put' will override the 'rcs=... on fili/filo. The actual record size may be modified depending on the file type (typ=RSF,RST,LST,ISF,IDX,DIR). See file types discussed on the next page.

op3/op4 - fillchar/stopchar

registers stored by 'put'

Register 'z' & 'v' will hold the return code from the put instruction. This is usually the record size, but would be -1 or less than rcsz if an error occurs.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"put" - a record to a sequential file - continued

put options

 filo1=dat1/test100,typ=LST...,rcs=80  #<-- file declaration for typ=LST...

      put   file,recordarea[,fillchar][,stopchar]  - instruction format
      ==========================================
                            - fillchar defaults to ' ' space x'20'
                            - arg4char defaults to '~' tilde x'7E'

      putt2 filo1,b0(256)   - default option is 't2' for any typ=LST
      ===================   - default recsize is op2 size or rcs=size
      put   filo1,b0        - may omit recsize from op2 area
b
  • blank record area after put
b1
  • clear record area to nulls all x'00's
b2
  • clear record area to blanks (same as b with no digit)
c1
  • convert any unprintable chars to blanks
c2
  • convert any unprintable chars to periods
c4
  • convert nulls to blanks
c8
  • convert tabs to blanks
c16
  • minimize remove trailing blanks, nulls, LFs
  • minimize set by any LST unless LSTt4 both in/out
c32
  • blank CR on scanback if minimize c16/0x100000 set
c64
  • getlin1 NEW force stop read on formfeed x'0C'
c128
  • putlin1 determine length by 1st null vs last nonblank
d1
  • delete CR's, d2 delete LF's, d4 delete NULL's, d8 delete tildes '~'
  • unusual on filo typ=LST..., could use on putd...
e1
  • convert CR's to blanks, e2 LF's to blanks, e4 NULL's to blanks, e8 tildes '~'
  • N/A to filo typ=LST... could use on pute...
s1
  • stop write on CR
s2
  • stop write on LF
s4
  • stop write on NULL
s8
  • stop write on tilde '~'
  • write size usually determined by last non-blank
  • option s# not used on Output filo# defs, possible but unusual on putt# instruction
t1
  • terminate with CR
t2
  • terminate with LF <-- DEFAULT, use t3 for CR+LF
t4
  • terminate with LF <-- make outrecs same lth as inrecs
  • terminate with LF (default t4) or CR+LF if t5/t6
t8
  • terminate with tilde '~'
x1
  • also display output on console, max 255, shortened to last non-blank
  • any unprintables converted to '.' periods
  • option 'm' only for uvcopy getm#/putm# instrns
m1
  • minimize remove trailing blanks,nulls,LFs
m2
  • scanback also remove trailing CR x'0D'
m4
  • getlin1 NEW uvcopy getm4 FORCE stop read on x'0C'
m8
  • putlin1 determine length by 1st null vs last nonblank

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"put" - a record to a sequential file - continued

file TYPes

RSF
  • Sequential Fixed length
  • op2 lth determines record size written & would normally match the length specified on the file 'rcs' function
RST
  • same as RSF with a Line Feed inserted in the last byte of rcsz
  • if file option 't3' (typ=LSTt3) a Carriage Return is inserted in the 2nd last byte of rcsz (followed by LF).
LST
  • System Line Terminated or variable length text file
  • an LF is inserted in the last byte of rcsz (& a CR in the 2nd last byte if file typ=LSTt3)
  • see the options below that apply to LST files
ISF
  • C-Isam/D-ISAM Fixed length records
  • rcsz determined by the 'rcs' file function
  • put used only when creating a new file (also see wrt, upd, upw)
IDX
  • Indexed Sequential Variable length record files (IDXFORMAT3)
RSV
  • Record Sequential Variable length record files (compatible with Micro Focus COBOL IDXFORMAT3, data partition)
STL
  • STandard Language file system, used by AIX COBOL
  • STLs=Sequential, STLi=Indexed, STLr=Relative

file typ options (vs options on put instruction)

There are also some related 'file options' specified on the file "typ" function. See file typ options in uvcopy1.doc or uvcopy2.doc

Some examples of file typ options relevant to the 'put' are:

typ=LSTt
  • file typ option 't' (applies only to typ+LST)
  • truncates trailing blanks (t1 leaves 1, t2 leaves 2, etc)
  • will be overridden by the 't' option on the 'put'
typ=LSTw2
  • file typ option 'w2' enable overwrite warning message
  • see the meaning of w1,w2,w4,w8 in uvcopy1.doc under the subject of file typ options
typ=LSTt1
  • terminate record with CR only
typ=LSTt2
  • terminate record with LF only
typ=LSTt3
  • terminate record with CR + LF
Note
  • option 't' on file type (typ=LSTt?) is similar to option 't' on put

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"put" - a record to a sequential file - continued

file typ options for typ=IDX

Note
  • these options apply only to 'uxcopy' (not 'uvcopy')
  • 'uxcopy' includes the Micro Focus COBOL file handler (EXTFH)
  • to support variable length Indexed files
IDXf1
  • fixed length Indexed records, compatible with C-ISAM, same as typ=RSF
IDXf3
  • variable length Indexed files (file size < 2 gig)
IDXf8
  • variable length Indexed files (allowing file size > 2 gig)
  • IDXF3 & IDXf8 could be fixed records in variable format
v9999
  • minimum record size option for typ=IDX & typ=RSV files For example: 'typ=IDXv400,rcs=5000' v400 declares minimum size 400 while rcs=5000 declares the maximum size 5000.
  • if option v is not specified, all records will be fixed size rcs=____ and the file type will be fixed (vs variable)
  • if option v is specified with no value, min size is set = max size and the file type will be variable
  • also see type 'y4' below to determine record size by scanning back from max size to the last nonblank/nonnull beyond min size
  • any option 'v' forces option 'y2' (variable format)
x
  • file organization for typ=IDX files
x1
  • Sequential, no Index created
x2
  • Indexed, assumed if 'isk' (Indexed Seqntl Key) is declared
y
  • Recording Mode
y1
  • Fixed Length records, all records forced to size spcfd by rcs=____
  • default for if option 'v' NOT specified (w or w/o min recsize)
y2
  • Variable Length records
  • default if option 'v' IS specified (w or w/o min recsize value)
  • min recsize specified by option 'v', max recsize by rcs=____
y4
  • determine the record size for each record by scanning back from max size to last non-blank or non-null beyond the min size
y8
  • fixed length records in variable length format
  • in case you want to copy a variable length file & output all records as the max size specified on rcs=___ (but in variable length format

variable length output record size

If output record size is explicitly specified on op2 of the 'put' instruction, then the variable length record will be written with that record size.

But if op2 of the 'put' is not specified, then the record size will be taken from register 'v' ($rv), which is probably the last input record size since the 'get' instruction stores the record length in $rv.

Note
  • see 'uvcopy6.doc' for test/demo uxcopy jobs to read/write IDXf3/IDXf8.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"put" - a record to a sequential file - continued

Variable length ISAM files (register 'v')

The 'put' instruction may specify the length of the variable length record to be written. This is usually done by a register in the length of operand 2 on the put instruction.

If you were copying variable length records, the 'get' instruction stores the length of the last record read in register 'v', so you might use the following coding:

      get    fili1,a0(9999)     - don't need to specify lth on get
 #                                (but area a must be allocated big enough)
 #                              - get stores rcsz in rgstr 'v'
      put    filo1,a0($rv9999)  - rgstr v specifies size to be written
 #                                (to maximum of 9999)

As of May 2007, the last input record size will automatically be used if the output record size is omitted. This is most useful for IDXFORMAT3 & 8.

      put    filo1,a0           - op2 length omitted uses $rv
                                - probably from last get

Note that typ=ISF Variable length Indexed files are NOT commonly used. The more popular type of Variable length files is typ=RSV or typ=IDXf3/IDXf8 which are compatible with Micro Focus COBOL IDXFORMAT3/IDXFORMAT8 files.

 See discussion & example on the next page --->

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

get/put for typ=RSV & typ=IDX files

typ=RSV & typ=IDXf3/IDXf8 provide compatibility with Micro Focus COBOL Variable length files. Note that typ=IDX (Indexed Variable) is provided by an alternate version of uvcopy, 'uxcopy' which is linked with Micro Focus EXTFH. You should first study the detailed documentation for typ=RSV files on pages 'I1' to 'I3' of uvcp.doc to understand this file type.

sample get/put for typ=RSV files

 # RSVtest2 - test Record Seqntl Variable (typ=RSV) file I/O Dec 2002
 #          - compatible with Micro Focus COBOL IDXFORMAT3
 #
 # typ=RSV can read an IDXFORMAT3 Indexed file in Sequential mode
 # - can be used on uvcopy,uvsort,etc (vs uxcopy,uxsort,etc that support IDX)
 #   (IE - can be used at sites that don't have Micro Focus COBOL)
 #
 # On filo1 below, rcs=254 specifies max, v option of typ=RSVv64 specifies min
 # - record size for each record is determined by scanning back for last
 #   nonblank & rounding up to multiple of 4 (considering the 2/4 byte rechdr).
 #
 fili1=?dat1/testIDXf3.dat,rcs=512,typ=RSV
 filo1=?tmp/testrsv2,rcs=254,typ=RSVv64
 # filo1=?tmp/testrsv2,rcs=254,typ=LSTt   #<-- optional text file output
 @run
        opn    all
 #
 # begin loop to get/put records until EOF
 man20  get    fili1,a0           get next record
        skp>   eof                (cc set > at EOF)
        mvc    b0(512),a0         copy input area to output area
        put    filo1,b0           writes variable lth (see NOTE below)
        skp    man20
 #
 # EOF - close files & end job
 eof    cls    all
        eoj
  1. RSV 'get' delivers only record data into the read area ('a' in this example). The record header (1st 2 or 4 bytes) is omitted.
  2. On--> filo1=?tmp/testrsv2,rcs=254,typ=RSVv64 <-- rcs=254 is max, v64 is min
  3. If minimum rcsz (option v) is not specified, all output records will be written with maximum record size & blank padded as necessary.
  4. If op2 length is explicitly specified, it will be used if between min & max.
  5. If op2 length is omitted, the record size is automatically determined by scanning back to the last non-blank & rounding up to multiple of 4 (but must be between min & max, else min or max will be used).
Note
  • see 'uvcopy6.doc' for test/demo uxcopy jobs to read/write IDXf3/IDXf8.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, get, put, "rel", rtb, wtb

`rel` - set file pointer (relative record# or relative byte#)

           for Unix type files - usually with fixed record sizes
           (use the 'set' instrn for keyed Indexed files)
    relr  fili1,50         - set rel rec# 50 of fili1
    relr  fili2,r20(5z)    - set rel rec# to the value in 21-25
    relb  fili4,68         - set to rel byte# 68 of fili4

`update_rel` reldemo1 - update in place

 # reldemo1 - demo 'rel' instruction to update in place by relative record#
 #          - by Owen Townsend, UV Software, May 22/2008
 #
 # Demo will update specified rec# with '*updated*' in bytes 70-78
 #  - will prompt for record# to be updated, for example:
 #  - enter n2 at the prompt to update rec#2 (3rd record since zero relative)
 #
 # 1. cp /home/uvadm/dat1/custmas1 tmp/   <-- copy demo file to tmp
 # 2. uvcopy reldemo1,filr1=tmp/custmas1  <-- run demo job
 # 2a. --> n2 <--          - enter n2 to update 3rd record in the file
 # 3. uvhd tmp/cm1 r256  <-- examine results, browse forward
 #                         - ensure specified record updated
 # Relative record numbers are zero relative (not 1 as per COBOL)
 # In code below:
 # - 1st 'relr' sets fileptr & 'get' reads the record
 # - 2nd 'relr' is REQUIRED to reset fileptr to spcfd record
 #   (since get advances fileptr to next record)
 #
 opr='$jobname - demo rel instrn to update randomly by record#'
 opr='- using custmas1 demo file, 256 byte records'
 opr='- will update specified record# with "*updated*" in bytes 70-78'
 opr='uop=n0    - record# to update, n0 would update 1st record in file'
 opr='    n10   - update rec#10(0 rel) rec#11(1 rel) (offset 10*256=2560)'
 uop=q1n0       # option defaults
 filr1=tmp/custmas1,rcs=256,typ=RSF
 @run
        opn    filr1               open the file
        relr   filr1,$uopbn        set file ptr to spcfd rec#
        get    filr1,a0(256)       get the record into area 'a'
        relr   filr1,$uopbn        re-set file ptr to spcfd rec#
        mvc    a70(9),'*updated*'  update the record
        put    filr1,a0(256)       re-write the record
        cls    filr1               close the file
        eoj
Note
  • if you specify typ=RSR, rcs=... is the logical data size
  • physical recsize is 1 more (status byte, x'0A' good, x'00' deleted)
  • for Micro Focus COBOL, uvcopy always writes x'0A' on 'put' to typ=RSR

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, get, put, "rel", rtb, wtb

rel ex#2 copy1r - copy from a spcfd rec#

 # copy1r - copy a fixed record size file from a specified record#
 #        - using the 'rel' instruction to set the file pointer
 opr='$jobname - copy a fixed record size file from a specified record# '
 opr='uop=q1r040b0c999999 - option defaults'
 opr='      r040          - record size'
 opr='          b0        - begin copy at record #0 (1st record by default)'
 opr='            c999999 - copy 999999 records (all recs in file)'
 uop=q1r40b0c999999                     # declare option defaults
 was=a8192b8192                         # increase max I/O sizes areas a & b
 fili1=?tf/test100,typ=RST,rcs=8192     # default input  may be used for test
 filo1=?tmp/$fili1,typ=?RST,rcs=8192    # default output will be tmp/test100
 @run
      mvn   $fili1+224(4b),$uopbr     store input file rcsz from option r
      mvn   $filo1+224(4b),$uopbr     store output file rcsz from option r
      opn   all                       open files
 #-------------------------------
      relr  fili1,$uopbb              set begin copy relative record#
 #-------------------------------
      mvn   $rr,$uopbr                store rcsz in rgstr r for get/mvc/put
 # begin loop to copy records until EOF
 loop get   fili1,a0($rr8192)         get rec (rcsz in rgstr r max 8192)
      skp>  eof
      mvc   b0($rr8192),a0            move to out area lth rgstr r max 8192
      put   filo1,b0($rr8192)         write record to output file
      add   $ca1,1                    count records
      cmn   $ca1,$uopbc               reached copy count ?
      skp<  loop
 # reached end record# or EOF - close files & end job
 eof  cls   all
      eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, get, put, rel, "rtb", wtb

`rtb` - read a table of data into the op1 area (at run time)

"rtb" reads a table of data into the op2 area from the op1 file

Note
  • must load tables at the begining of an area (a-t, not q)
  • IE: op1 displacement must be '0'
    rtb   fili2,k0(80),k0(40)  - read fili2 & store the 1st 40 bytes of record
                                 in 1st 40 bytes of 80 byte table entries
                                 (might later add other info on right ?)
                               - continues until end of file, or until
                                 a record is found with '~~' col 1 & 2
    skp<  toobig               - cc set < if area too small for file
    skp>  eof                  - cc set > if eof before col1 eod
    rtb   fili2,k0(80),k20(40),'~','~'
                               - store bytes 20-59 of each record in 1st 40 bytes
                                 of each table entry
                               - illustrates the '~' defaults for op4/op5
                                 (stop read & end table markers - see below)
op1
  • defines the file to be read
op2
  • defines the 1st table entry
op3
  • usually the same as op2, but in the example above bytes 20-59 of each record read from the file will be stored in 1st 40 bytes of each table entry. (op3 allows an offset into data record).
op4
  • is the stop read char (defaults to a '~' tilde)
  • 2 of these are normally required in cols 1&2, but see option m1 on the next page to reduce this to 1 '~' in column 1.
op5
  • is the table end marker (defaults to a '~' tilde).
  • 2 of these are normally stored in cols 1 & 2, but see option m1

The 'rtb' instruction is similar to the 'lod' function but since it is an instruction rather than a function it is executed at '@run' time vs setup time & may be executed several times rather than just once as are all functions.

The table data file usually has '~~' in col 1&2 of last record to mark the end of the table. The 'lok' lookup instrn is ended by 2 '~' tildes or by 2 x'00's in 1st 2 bytes of any entry.

"rtb" now (as of June99) respects the file type declared on the fili? fili1=xxx,rcs=80,typ=LST fili1=xxx,rcs=256,typ=RSF

Previously the file was assumed to be typ=LST. This change allows us to read fixed length records without LineFeeds, and to table just the 1st part of longer records.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rtb" instruction (continued) - options, counters,& registers

options

 option b1 - drop any blank lines in the file (don't load into the table)
        b2 - end table load on a blank line (after at least 1 data line)
        b4 - store the blank line ending table load, code b6 (b2+b4)
        b8 - drop all blank lines (mutually exclusive with b1,b2,b4)
option c1
  • drop any script comment lines '#' col 1 & ' ' blank col 2 when loading records from the file into the memory table
option c2
  • drop COBOL comment lines '*' col 7
option c4
  • drop JCL comment lines '//*' cols 1-3
option e
  • exclude the end of table marker
  • EOT marker is 1 entry of all op5 chars (default '~' tilde)
     note  - any existing '~~' record in the file ends table loading
             but this record is not stored in the table
           - An all '~' entry will then be generated unless you specify
             option 'e' to exclude it
 option f1 - inhibit stop read on FormFeed (inhibit End of Line action)
        f0 - default treats FormFeed like LineFeed (End of Line)
 option m# - sequence number of End Table marker to stop tabling
           - EOT marker is 2 op4 chars (default '~~') in columns 1 & 2
             (but usually we code a full line of '~'s to match entry length)
        m2 - would bypass the 1st EOT marker line & stop on the 2nd marker line
 option s1 - remove leading blanks, shift data left to col1 (word spacing unchanged)
        s2 - same as s1, but leave column 1 blank
        s4 - squeeze entire line to 1 blank between words
           - may combine with s1 or s2 = s5 or s6
option s4
  • squeeze to 1 blank between words
option t1
  • translate to lower case as entries are loaded into the table
option x1
  • display the records while loading the table
  • was option d prior to May2019

counters stored by rtb

instrn counter $ci1 - counts lines loaded into the op1 area

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rtb" instruction (continued) - options, counters,& registers

registers stored by rtb

registers
  • if any register is coded in op2, it will be updated (added to) with the number of bytes actually loaded
  • might be used to load a table from 2 files since after the 1st rtb, the register would point to the next entry
     rtbz2 fili1,bt0(20),bt0(20)  - load area b with file #1
                                  - register 't' will point to last entry + 1
     rtb   fili2,bt0(20),bt0(20)  - append data from file #2
                                  - starting at displacement in register 't'
  • option z2 clears rgstr 't' at the beginning, so that rgtsr 't' will point to the end of the fili1 data
  • option 'z2' is of course omitted from 2nd rtb
  • table 1 should not have the '~~' end marker record & option 'e' is not required to exclude adding it since it will get overlaid by the 1st record of fili2

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

sample job to demo 'rtb'

We will demo 'rtb' by tabling a product master file, then looking it up by product# to extend a sales item file using the product master price & description.

dat1/productmaster - to be tabled in memory

 Product#  Description      unit-price
          1         2         3         4
 1234567890123456789012345678901234567890
 ========================================
 BBQ010    BAR-B-Q             0019500
 HAM010    CLAW HAMMER         0000950
 HAM020    BALL HAMMER         0001200
 HAM035    JACK HAMMER         0029500
 SAW011    HAND SAW            0001975
 SAW012    RIP SAW             0002500
 SAW051    POWER SAW           0008500

dat1/salesitems - input file

 cust#  slsmn  date  invoice#  product quantity
          1         2         3         4
 1234567890123456789012345678901234567890
 ========================================
 cust#    date   invoice# product qty
 130140 20200802 IN001001 HAM035 000010
 139923 20200802 IN001002 SAW011 000020
 139923 20200802 IN001003 HAM020 000030
 250825 20200804 IN001104 BBQ010 000040
 250825 20200804 IN001004 SAW012 000050
 401210 20200816 IN001005 SAW051 000060

dat1/salesextended - output extended with product price & dscrptn

 cust#  slsmn  date  invoice#  product quantity  price   amount  product-dscrptn
          1         2         3         4         5         6         7         8
 12345678901234567890123456789012345678901234567890123456789012345678901234567890
 ================================================================================
 cust#    date   invoice# product qty     price   extended product description
 130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
 139923 20200802 IN001002 SAW011 000020  0001975 000039500 HAND SAW
 139923 20200802 IN001003 HAM020 000030  0001200 000036000 BALL HAMMER
 250825 20200804 IN001104 BBQ010 000040  0019500 000780000 BAR-B-Q
 250825 20200804 IN001004 SAW012 000050  0002500 000125000 RIP SAW
 401210 20200816 IN001005 SAW051 000060  0008500 000510000 POWER SAW

 uvcopy salesextend,rop=d  <-- execute uvcopy job to demo 'rtb' & 'lok'
 ========================    - ',rop=d' to debug (display instructions before executing)
 - see the uvcopy job listed below:

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

 # salesextend - demo uvcopy table load (rtb) & table lookup (lok)
 #             - load product master file into memory table at begin job
 #             - extend sales items by looking up product master for price & dscrptn
 #             - see documentation at 'https://uvsoftware.ca/uvcopy3.htm#rtb'
 #Note - also used to demo uvcopy debugging, see 'https://uvsoftware.ca/uvcopy2.htm#J1'
 #
 # uvcopy salesextend,fili1=dat1/salesitems,fili2=dat1/productmaster,filo1=tmp1/salesextended
 # ==========================================================================================
 # uvcopy salesextend   - same as above (files default as shown)
 # ==================
 #  ** sample 1st record from input salesitems,productmaster,& output salesextended **
 #          1         2         3         4         5         6         7         8
 # 12345678901234567890123456789012345678901234567890123456789012345678901234567890
 # cust#    date   invoice# product qty
 # 130140 20200802 IN001001 BBQ010 000010
 #          1         2         3         4
 # 1234567890123456789012345678901234567890
 # Product#  Description      unit-price
 # BBQ010    BAR-B-Q             0019500
 #        1         2         3         4         5         6         7         8
 # 12345678901234567890123456789012345678901234567890123456789012345678901234567890
 # cust#    date   invoice# product qty     price   extended product description
 # 130140 20200802 IN001001 BBQ010 000010  0019500 000195000 BAR-B-Q
 #
 rop=r1       # EOF option prompt to view output file (vi,cat,more,etc)
 fili1=dat1/salesitems,rcs=80,typ=LST      # sales item file
 fili2=dat1/productmaster,rcs=80,typ=LST   # product master file
 filo1=tmp1/salesextended,rcs=100,typ=LST  # output items extended w price/dscrptn
 @run
        opn    all                      open all files
        rtb    fili2,p0(40),p0(40)      read product master into memory area 'p'
 #      ===
 # begin loop: read sales items, extending with price & dscrptn from table lookup
 man20  get    fili1,a0                 read next sales item record
        skp>   man90                    (cc set > at EOF)
        mvc    b0(80),a0                copy input to output area
        lokz1  pp0(40),pp0(6),a25(6)    lookup table by product code
 #      ===
        skp!   man30                    (cc unequal if nomatch)
        mvn    b40(7),pp30(7)           price from table
        mvn    b48(9),pp30(7)           price to amount for extension
        mpy    b48(9),b32(6)            master price * item qty = amount
        mvc    b58(16),pp10             product dscrptn from table
 man30  put    filo1,b0                 write output
        skp    man20                    return to get next record
 # EOF - close files & end job (rop=r1 prompts to show output file)
 man90  cls    all
        eoj
 #                    ** demonstration notes **
 # rtb  - stores the product master file in a memory table at begin job
 # lok  - looks up the table via sales item product# to get master price/dscrptn
 # lok  - option 'z1' clears register 'p' before lookup begins.
 # lok  - op1 'pp0(40)' defines table entries - in area 'p' indexed by rgstr 'p'
 # lok  - op2 'pp0(6)' defines the table lookup key (1st 6 bytes of entry)
 # skp! - lok sets cc not-equal if prod# not found, skip to man30 bypassing extension
 # cc=  - register 'p' will hold the displacement to the amtching entry
 # mvn  - b40(7),pp30(7)' retrieves price (displaced 30 bytes in matching entry)
 # mpy  - b48(9),b32(6)   master price * item qty = extended amount
 # mvc  - b58(16),pp10    retrieves description (displaced 10 bytes in matching entry)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 4 (Sequential I/O) - opn, cls, get, put, rel, rtb, "wtb"

`wtb` - write a table of data from the op1 area (at run time)

Write a table of data out to a file (opposite of the 'rtb' instruction). Data is written from each entry offset by op3 dsp with op3 lth The default end table marker (in the memory table being written to a file) is 2 tildes '~~' or 2 nulls x'0000' in cols 1-2. Note that 1 null in col 1 causes that entry to be bypassed (write inhoibited)

    wtb   filo1,b0(80),b0(80)  - write op2 table to op1 file until an entry found
                                 with 2 tildes or 2 nulls in cols 1-2
    wtb   filo2,m0(80),m20(60) - write out 60 byte records from cols 21-80
                                 of the 80 byte entries
    wtb  filo1,b0(80),b0(80),b40(9),'0' - op4,op5 to drop entries
                               - may code op4 & op5 test to drop entries
                                 with op4 matches to the op5 constant
                               - only need to code 1st byte if all bytes same
op1
  • defines the file to be written
op2
  • defines the 1st table entry
op3
  • defines the data area within the 1st table entry to be written
  • usually the same as op2, but in the 2nd example above columns 21-80 of each entry will be stored in cols 1-60 of the output records
op4
  • optional, may define a table entry subfield in that if matched by op5 will cause the entry to be dropped
op5
  • optional, may define a constant for matching to op4 (above)
  • a 1 byte constant will be replicated to match the length of op4

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'wtb' - write a table of data from op1 area - continued

wtb options

 b1  (default) - bypass entries with 1 null in col 1
 b0  - disable bypass entries with null col 1
 b2  - inhibit writing all blank lines
 b3  - bypass entries with null col 1 & inhibit writing blank lines
 b16 - disable bypass entries with null col 1
c1
  • bypass entries with '#' column 1
e2
  • end table on 2 "!!" exclamation marks
  • might combine with 't0' to disable end on 2 '~~' tildes
 n1  (default) - bypass entries with null col 1
 n2  - end table if 2 nulls cols 1-2
 n3  - bypass entries with null col 1 & end table 2 nulls cols 1-2
 n16 - disable bypass entries with null col 1
 t2  (default) - end table on 2 '~'s cols 1-2
 t1  - end table on  tilde 1
 t4  - end table on 4 tildes cols 1-4
 t8  - end table on x'0C' FormFeed  col1
 t16 - disable end table on 2 tildes
 t0 - disable end table on 2 tildes
s1
  • seq# output records in cols 1-4 (col 5 blank) shifting the text to 6-??
x1
  • also display table records on console while writing to output file
  • changed from option 'd' for compatibility with putx1
Instrn ctr $ci1
  • will hold the number of lines written out

file type & rcsz written by wtb

                                --- different possible file types ---
 filo2=xxx,rcs=80,typ=LSTt  <-- text file with LF after last nonblank
 filo2=xxx,rcs=80,typ=LST   <-- text file with blank fill to rcsz+LF
 filo2=xxx,rcs=80,typ=RSF   <-- fixed length records with NO LineFeeds
 filo2=xxx,rcs=80,typ=RST   <-- fixed length records with LF in last byte

wtb filo1,b0(80),b0(80)

possible future updates

    wtb   filo2,bb0(80),bc20(60)  - write out entries from area 'b' offset
                                 by the displacement in rgstr 'b', until
                                 we reach a displacement > rgstr 'c'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - "set", red, wrt, upd, upw, del, lck, ulk

`set` - set key of reference & file pointer in an Indexed file

    mvc   c60(6),'SMITH'      - store key value desired
                                in proper position in record area
    setk2m7 filr1,c0          - select key 2 & set ptr to rec whose
                                key is = or > than value stored
    skp=  found                 cc set = if record found & no err
    skp!  nofind                cc set not= if no matching record found
    setk3m0 filr1,d0          - select key 3 & set file ptr to the
                                beginning of file
    set     filr1,d0(200)     - record size may be specified
    set     filr1,d0          - or omitted (recommended)
                    ^^^^^

'set' will change the current record position (file pointer) to the key value stored in the record area. See option 'm' below which determines the comparison between the key value & the record position set.

The set instruction would usually be followed a 'redm7' (read => key value) instruction to read the record contents pointed to by the set. Or you might use a code loop of 'redm2' (read next) instructions to read a series of sequential records (the series might be ended by a change in the high part of the key such as customer#, etc)

option 'k' used to set key of reference (default 1).

option 'l' to set key on less than full key length.

     setk3m7l3 filr1,d0       - would set key#3 => than 1st 3 bytes of
                                key value stored in area d
 option 'm' (or cc) used to indicate file position desired
         m0 - 1st record in file
         m1 - last record in file
         m5 - record whose key =  key stored in record area
         m6 - record whose key >  key stored in record area
         m7 - record whose key => key stored in record area (default)
 option 'e1' - errmsg if 'set' instruction fails (for the specified key)
        'e3' - also wait for reply (null to continue, or interupt to kill job)
             - option e1/e3 can save having to test condition code after 'set'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, "red", wrt, upd, upw, del, lck, ulk

`red` - read a record from an indexed file

    mvc   r10(6),c'123456'    - store key of record to be read
                                in proper position in record area
    redm7 filr1,r0            - read rec whose key => stored key
    skp=  found                 cc set = if record found & no err
    skp!  nofind                cc set not= if no matching record found
    redk2m5 filr1,r0          - set key#2 & read equal
    skp=    found               cc set = if key= record found
    ---     -------             code here for key not found (cc not=)
    redm2 filr1,r0(200)       - read next record (sequentially)
                                (probably after redm7 read by key =>)
                              - record size (200) should be omitted

The record size should be omitted from I/O instructions. For Indexed files the record size is determined when the file is created.

A 'red' is often preceded by a 'set' as described on the previous page. The record read by the 'red' instruction depends on option 'm' as follows:

 option 'm' - used to indicate type of read desired
         m0 - 1st record in file
         m1 - last record in file
         m2 - next record (from current position)
         m3 - previous record
         m4 - current record (use after set by key)
         m5 - record whose key =  key stored in record area
         m6 - record whose key >  key stored in record area
         m7 - record whose key => key stored in record area (default)
 option 'k' - select key of reference
         k1 - default
         k2 - select key#2
         ..
         k9 - select key#9
 option 'e1' - errmsg if 'red' instruction fails (record not found for key)
        'e3' - also wait for reply (null to continue, or interupt to kill job)
             - option e1/e3 can save having to test the condition code after
               the 'red' instruction (see skp= or skp! coding above)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, "red", wrt, upd, upw, del, lck, ulk

Record Lock options for "red"


 filr1=dat1/custmast,typ=ISFl4,rcs=256  #<-- must code option l4 on 'typ=ISFl4'
 =====================================     - to allow record lock optns on 'red'
 read  redm5l4 filr1,c0
       skp=    ok
       skp>    eof
 # cc < (locked record) - prompt for retry
       msgw   'locked record - enter to retry'
       skp     read
Note
  • 'l4' (on redm5l4) is the manual lock option (for ISAM files)
  • you must code typ=ISFl4 to allow lock option 'l4' on 'redm5l4'
Note
  • could code options 'w' (wait) & 'r' (retries)
  • or accept the defaults as follows:

 read  redm5l4w1r8 filr1,c0
 ==========================
option l4
  • manual lock (requires option l4 on file typ=ISFl4)
option w#
  • record lock wait time before retry (default w1 = 1 second)
option r#
  • record lock retries (default r8 = 8 retries)
  • then return with cc < (record locked by another process)

 updt  updl4  filr1,c0    <-- update record read by prior redm5l4
 =====================      - and release the lock
option l4
  • manual lock (requires option l4 on file typ=ISFl4)
Note
  • see sample coding of both redm5l4 & updl4 under 'upd' instruction

sample jobs to demo ISAM updates

Please study the following 2 demo jobs to understand how to read Indexed files. You can run these demo jobs (assuming you are in /home/uvadm).


 uvcopy prodlookup1 <-- lookup Indexed product master (key= on product#)
 ==================   - transfer description & price to sales item file

 uvcopy feelookup1  <-- lookup fee master with key FeeCode+EffectiveDate+Rate
 =================    - to get appropriate rate for fee services depending on date

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

demo redm5 - lookup Indexed file key=

 # prodlookup1 - lookup an Indexed file of product#, description,& price
 #             - to transfer description & price to sales item file
 #             - by Owen Townsend, UV Software, Nov 2012
 #             - may run demo as follows (assuming in /home/uvadm)
 #
 # uvcp "fili1=dat1/prodmaster,rcs=80,typ=LST\
 #      ,filo1=dat1/prodmasterI,rcs=63,typ=ISF,isk1=0(6)"
 # ======================================================
 # - load prodmaster text file into Indexed file for lookup by sales transactions
 #
 # uvcopy prodlookup1,fili1=dat1/prodsales1,filr2=dat1/prodmasterI,filo1=tmp/prodsales2
 # ==============================================================================
 # - lookup prodmaster Indexed file to get description & price
 #
 #    ** sample records: prodmaster, prodsales1 input,& prodsales2 output
 # BBQ010   BAR-B-Q              0019500  <-- prodmaster Indexed file
 # CHR015   LAWN CHAIR           0004500    - 1st 3 records of 9 in demo file
 # HAM010   CLAW HAMMER          0000950
 # cust#  slsmn  date  invoice#  product    qty
 # 130140    21 990802 IN111001  HAM010  000020 <- prodsales1 INPUT sales trans
 # 139923    35 980802 IN111002  TAB012  000010  - 1st 3 input records of 5
 # 150825    44 010804 IN1122    HAM010  000030  output records below -->
 # 1234567890123456789012345678901234567890123456789012345678901234567890
 # 130140    21 990802 IN111001  HAM010  000020      CLAW HAMMER         0000950
 # 139923    35 980802 IN111002  TAB012  000010      LAWN TABLE          000850W
 # 150825    44 010804 IN1122    HAM099  000030
 opr='$jobname - demo lookup Indexed file from traansaction file'
 fili1=dat1/prodsales1,rcs=80,typ=LST
 filr2=dat1/prodmasterI,rcs=63,typ=ISF,isk1=0(6)
 filo1=tmp/prodsales2,rcs=80,typ=LSTt
 @run
        opn    all                  open files
 # begin loop to read sales, lookup master, transfer dscrptn/price,& write
 man20  get    fili1,a0             get next product sales record
        skp>   man90                (cc set > at EOF)
        mvc    b0(80),a0            copy sales record to output area
 # insert product-code in blank filled area for master lookup,
 # read master key= (option m5),& copy product dscrptn/price to sales record
        clr    m0(63),' '           clear master read area
        mvc    m0(6),a30            insert product# 31-36 into master key area
        redm5  filr2,m0(63)         read 1st master with key =
        skp!   man28                if nofind -> go output sales unchanged
        mvc    b50(30),m10          copy product master dscrrptn/price to sales
 man28  put    filo1,b0             write output tran with master rate coded
        skp    man20                return to get next tran record
 # EOF - close files & end job
 man90  cls    all
        msgw   'EOF demo Indexed file lookup - enter to show sales input'
        sysv1  'cat $fili1'
        msgw   '- enter to show master file'
        sysv1  'cat dat1/prodmaster'
        msgw   '- enter to show sales output (with dscrptn/price from master)'
        sysv1  'cat $filo1'
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

demo redm7 lookup key=> & redm2 read next

 # feelookup1 - lookup an Indexed file of feecode,effective-date,rate
 #            - to get effective rate for transaction file of fee services
 #            - by Owen Townsend, UV Software, Nov 2012
 #            - may run demo as follows (assuming in /home/uvadm)
 #
 # uvcp "fili1=dat1/feemaster,rcs=80,typ=LST\
 #      ,filo1=dat1/feemasterI,rcs=63,typ=ISF,isk1=0(30)"
 # ======================================================
 # - load feemaster text file into Indexed file for lookup by transactions
 #
 # uvcopy feelookup1,fili1=dat1/feetran1,filr2=dat1/feemasterI,filo1=tmp/feetran2
 # ==============================================================================
 # - lookup feemaster Indexed file to get appropriate rate for fee item
 #
 #    ** sample records: feemasterI, feetran1 input,& feetran2 output
 #
 # 0000100   20000101  00010000   <-- feemasterI Indexed file
 # 0000100   20010101  00011000     - 1st 5 records of 10 in demo file
 # 0000100   20020101  00012000
 # 0000200   20000101  00020000
 # 0000200   20020101  00022000
 #
 # 0000100   20010331  00000000   <-- feetran1 INPUT transaction file
 # 0000200   20031210  00000000     - 1st 2 records only of 5 in demo file
 #
 # 0000100   20010331  00011000   <-- feetran2 OUTPUT transaction file
 # 0000200   20031210  00022000     - with rate transferred from feemasterI
 #
 opr='$jobname - demo lookup Indexed file from traansaction file'
 fili1=dat1/feetran1,rcs=64,typ=LST
 filr2=dat1/feemasterI,rcs=63,typ=ISF,isk1=0(30)
 filo1=tmp/feetran2,rcs=64,typ=LSTt
 @run
        opn    all                  open files
 #
 # begin loop to read trans, lookup master, transfer rate, write tran out
 man20  get    fili1,a0             get next fee service transaction
        skp>   man90                (cc set > at EOF)
        mvc    b0(64),a0            copy tran record to output area
 #
 # insert tran fee-code in blank filled area for master lookup
        clr    m0(63),' '           clear master read area
        mvc    m0(7),a0             insert fee-code only into master area
        redm7  filr2,m0(63)         read 1st master with key = or >
        skp!   err1
 #
 # begin loop to save current master & read next, until next fee-code reached
 man30  mvc    c0(63),m0            save current master
        redm2  filr2,m0(63)         read next master with higher key
        skp!   err1
        cmc    m0(20),a0             feecode+date > tran feecode+date ?
        skp<=  man30
 #

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

 # reached next higher fee code - use rate from prior saved master
 # - 1st ensure that fee-code matches tran record
 man40  cmc    c0(7),a0             saved fee-code = tran fee-code ?
        skp!   err2
        mvc    b20(8),c20           move rate from saved master to tran out
 man44  put    filo1,b0             write output tran with master rate coded
        skp    man20                return to get next tran record
 #
 # EOF - close files & end job
 man90  cls    all
        msgw   'EOF demo Indexed file lookup - enter to show tran input'
        sysv1  'cat $fili1'
        msgw   '- enter to show master file'
        sysv1  'cat dat1/feemaster'
        msgw   '- enter to show tran output (with rates transferred from master)'
        sysv1  'cat $filo1'
        eoj
 #
 # Error routines
 # err1 - master file nofind - will not happen with high-key 9's rec in master
 err1   msg    a0(64)              show current tran record
        msgw   'master record not found (should not happen if highkey 9s record)'
        skp    man44               go output tran record unchanged
 #
 # err2 - master not found for transaction fee-code
 err2   msg    a0(64)              show current tran record
        msgw   'no master found with matching fee-code for current transaction'
        skp    man44               go output tran record unchanged
 #

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, "wrt", upd, upw, del, lck, ulk

`wrt` - write a new record into an Indexed file

     wrt   filr1,b0            - write record b0(rcsz) to filr1
     skp=  ok                    cc set = if no errors
     skp!  dup                   cc set not= if duplicate key
                                 (record already exists)
     wrt     filr1,d0(200)     - record size may be specified
     set     filr1,d0          - or omitted (recommended)
                     ^^^^^     - defaults to rcs= on filr1= declaration

The data record to be added must be stored in the op2 area. The record will be added to file & all key indexes updated. uvcopy does not allow duplicates on the primary key and will display a warning, but allow you to continue (dropping the duplicate record).

The current record position in file is not changed; you could be sequentially processing 1 area of a file & perform a write by key anywhere else in the file & not lose your sequential position.

The record size should be omitted from I/O instructions. For Indexed files the record size is determined when the file is created.

 option 'e1' - errmsg if 'set' instruction fails (if record already exists)
        'e3' - also wait for reply (null to continue, or interupt to kill job)
             - option e1/e3 can save having to test the condition code after
               the 'wrt' instruction (see skp= or skp! coding above)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, wrt, "upd", upw, del, lck, ulk

`upd` - update a record in an Indexed file

    upd   filr1,r0            - update record r0(rcsz) in filr1
    skp=  ok                    cc set = if no errors
    skp!  nofind                cc set not= if record not found

The record to be updated must be stored in the op2 record area and must already exist. The primary key is used to access & rewrite the record. uvcopy does not allow duplicates on the primary key.

'upd' is often preceded by a 'red' to determine whether the keyed record is already onfile or not. If not onfile you could use a 'wrt' to add it. The following example assumes a detail file (fili1) is read sequentially into area 'a' & used to update a master file (filr2) using area 'b'.

The following example codes 'Record Lock' option 'l4' on 'redm5l4' & 'updl4', and is only required if there could be 2 jobs processing the same records at the same time. The 'filr2' ISAM must be declared as 'typ=ISFl4'.


 fili1=dat1/cusupdts,typ=LST,rcs=128    #<-- updating records (test file)
 #==================================
 filr2=dat1/custmast,typ=ISFl4,rcs=256  #<-- ISAM file to be updated
 #====================================     - must code option l4 on 'typ=ISFl4'
                                           - to allow record lock optns on 'red'
 loop  get     fili1,a0             might get updating records from a seqntl file
       skp>    eof                  ('fili1' vs 'filr2' below for ISAM file)
       mvc     b0(80),a0            store record with key (cust#, etc) to read
       redm5l4 filr2,b0             read key=
       skp=    updt
       wrt     filr2,b0             write new record
       skp     loop
 #
 updt  mvc     b10(30),a10          modify master record (description, etc)
       updl4   filr2,b0             update (rewrite) the updated record
       skp     loop

The 'red' before 'upd' is not necessary if there is no master data in the record that needs to be preserved (data not in the updating detail records). In this case, you can simply replace the entire record or insert if not already on file. The 'upw' instruction (see 3 pages ahead) makes this case easy since it combines the functions of 'upd' & 'wrt'.

The current record position in file is not changed; you could be sequentially processing 1 area of a file & perform an update by key anywhere else in the file & not lose your sequential position.

Area 'u' will hold the record image as it was before the update (in case it is of any value to the programmer).

 option 'e1' - errmsg if 'upd' instruction fails (record not found for key)
        'e3' - also wait for reply (null to continue, or interupt to kill job)
             - option e1/e3 can save having to test the condition code after
               the 'upd' instruction (see skp= or skp! coding above)
option 'l4'
  • release Record Lock acquired by prior read (redl4)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, wrt, "upd", upw, del, lck, ulk

uvcopy6.doc separate test/demo section

Please see a separate section uvcopy6.htm that documents several uvcopy & uxcopy jobs to test/demo updating random Indexed files (illustrating: set, wrt, upd, upw, del).

uvcopy is used for typ=ISF Fixed length Indexed records (C-ISAM, IDXFORMAT1). uxcopy is used for typ=IDXf3/f8 Variable length Indexed MF COBOL IDXFORMAT3/8.

uvcopy6.doc uses a product master file & a product detail update file to illustrate the test/demo jobs. The test files are listed before & after updates. You are encouraged to run these jobs & verify your results.

test jobs to demo Indexed updates (red, upd, del)

produpISF1
  • update typ=ISF Indexed master file with details (add,update,delete)
  • applies when detail updating records contain all master fields
  • see uvcopy job produpISF1 listed in uvcopy6.doc
produpIDX2
  • update typ=IDXf3 Indexed file with details (add,update,delete)
  • applies when master records contain fields that must be preserved
  • see uxcopy job produpIDX2 listed in uvcopy6.doc

Record Locking test/demo

The following 2 jobs are provided to test manual record locking, using option 'l4' on filr1 typ=ISFl4, redl4,& updl4. See the 2 jobs documented & listed begining at 'uvcopy6.doc#Part_3'

ISFlock1
  • reads (with lock) record key 'HAM020' in tmp/prodmas1
  • pauses until operator reply
  • updates 41-57 with jobname & time
ISFlock2
  • reads (with lock) same record key 'HAM020' in tmp/prodmas1
  • using options l4w2r5 (lock, wait 2 seconds, retry 5x)
  • updates 61-77 with jobname & time
  • report failure & prompt for retry

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, wrt, upd, "upw", del, lck, ulk

`upw` - update/write record depending on key present/absent

    upw   filr1,r0            - update record r0(rcsz) in filr1
    skp=  updted                cc set = if existing record updated
    skp<  inserted               cc set < if new record inserted
    skp>  error                 cc set > if any other condition error
                                (or program may be aborted depending on err)

'upw' combines the functions of 'upd' & 'wrt'. upw will update the record if the key already exists, otherwise it will insert(write) a new record. 'upw' makes the coding simpler (can omit condition code testing), when you don't have to care whether the record is already present or not.

The record to be updated must be stored in the op2 record area and may or may not already exist. The primary key is used to access & rewrite the record. uvcopy does not allow duplicates on the primary key.

Note that 'upw' can be used only when the detail updating records contain all fields possible in the master records. 'upw' can not be used when the master file record contains fields which must be preserved. For example see job 'produpISF2' in 'uvcopy6.doc' where the master file contains YTD sales history fields & the updating detail records contain only the new product description & price (& the product# key of course).

The current record position in file is not changed; you could be sequentially processing 1 area of a file & perform an update by key anywhere else in the file & not lose your sequential position.

Area 'u' will hold the record image as it was before the update (in case it is of any value to the programmer).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, wrt, upd, "del", lck, ulk

`del` - delete a record in an Indexed file

    del   filr1,r0            - delete record r0(rcsz) in filr1
    skp=  ok                    cc set = if no errors
    skp!  nofind                cc set not= if record not found

The key of the record to be deleted must be stored in its proper location in the op2 record area & the record must already exist. uvcopy does not allow duplicates on the primary key.

The current record position in file is not changed; you could be sequentially processing 1 area of a file & perform an delete by key anywhere else in the file & not lose your sequential position.

Area 'u' will hold the record image as it was before the delete (in case it is of any value to the programmer).

 option 'e1' - errmsg if 'del' instruction fails (record not found for key)
        'e3' - also wait for reply (null to continue, or interupt to kill job)
             - option e1/e3 can save having to test the condition code after
               the 'del' instruction (see skp= or skp! coding above)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 5 (Indexed I/O) - set, red, wrt, upd, del, "lck", "ulk"

`lck` - lock a D-ISAM Indexed file

    lck   fili1                   - lock a D-ISAM file
    lck   filr1                     (for input or random files)
Note
  • The file type must have been specified as 'typ=ISFl4' (NOLOCK).
  • See the file typ locking options in uvcopy1.doc
  • This would make the file 'READONLY' & would be the same as specifying 'typ=ISFl2' without the 'lck' instruction. IE - typ=ISFl2 issues the 1st 'lck' instruction automatically.
  • There would be no need to use lck & ulk unless you wanted to turn on & turn off the READONLY or NOLOCK file attribute within 1 file open ... close time frame.

`ulk` - unlock a D-ISAM Indexed file

    ulk   fili1                   - unlock a D-ISAM input/random file

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - "msg",can,eoj,tim,wat,bal,ret,bcr

`msg` - display a msg (1 or 2 lines) on stdout

    msg    'x-------text msg -------x' - constant format
    msg    op1dsp(op1lth)              - area address format
    msgw   'enter date'                - option w wait for reply
    msgl2  'error bad record',b0(80)   - option l2 for 2 lines out

msgwy 'stopped beating wife yet ? y/n' - option y forces y/n response

option w
  • wait for reply
  • any reply will be stored in ($reply) y1000(100)
  • reply data length will be stored in rgstr x
  • may be inhibited by uop=i64 or rop=i64
 option a  - reply area, default $reply/$arg0/y1000(100)
        a1 - reply in $arg1/y1100(100), byte count in $ch1
        ..          ... etc ...
        a9 - reply in $arg9/y1900(100), byte count in $ch9
option c
  • suppress prompt if argument specified on command line, via arg1-9, see next page --->
option y
  • used with option 'w', forces reply 'y' or 'n'
option n
  • used with option 'w', forces a non-blank reply
option b
  • blank the op1 msg area after the msg output
option j1
  • prefix output msg with 'JOBID:date:time' stamp
  • see $jobstamp described in $symbols in uvcopy2.doc

option l1 insert LF before part1, l2 after part1, l4 after part2 option s1 insert ' ' before part1, s2 after part1, s4 after part2 option u1 insert '_' before part1, u2 after part1, u4 after part2 option f2 drop leading spaces in part2 scan Forward to 1st NonSpace

 option v1 - expand uvcopy internal $symbols
        v8 - do not stop $symbol match on '.' period
        v9 - specify as v9 (v1+v8=v9)
 option x1 - convert line1 data to hex representation (Sep10/08)
        x2 - convert line2 data to hex representation
        x_ - default to x3
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).
register x
  • will hold the length of the reply (if option w present)
 condition code: "<" if null or blank reply made
                 "=" if 1st letter of reply is a 'y'
                 ">" if any other nonblank reply

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`msgw` - display message & wait for reply (option "w" of msg)

option 'a' ,entry length, $args,& command line arguments

 loop  msgwa1 'enter your search pattern'
       cmn    $ch1,0              any data entered ? (including blanks)
       skp=   loop                no - repeat request loop
       mvc    ----,$arg1          yes - store data entered

option 'a' specifies the area where the reply data will be stored

     msgwa0 - reply data stored in $arg0 or y1000(100) & length in $ch0
                            (same as $reply)
     msgwa1 - reply data stored in $arg1 or y1100(100) & length in $ch1
     msgwa2 - reply data stored in $arg2 or y1200(100) & length in $ch2
      -etc-            - - - etc - - -
     msgwa9 - reply data stored in $arg9 or y1900(100) & length in $ch9
Note
  • As of Feb 2000 length stored in $ch0-$ch9 NOT $cd0-$cd9
Note
  • command line arguments also store data here, for example:

      uvcopy scan1d,fild1=cobols,arg1=xxx,arg2=yyy,arg3=zzz
      =====================================================

The uvcopy job can test $arg1 or $ch1 to see if the operator had entered the data on the command line, & if not prompt for the data via the 'msgwa1' instruction. Option 'a1' means the data will be in the same place regardless of whether entered on the command line or in response to the msgwa1 prompt.

option 'c'
  • will suppress the 'msg' prompt, if the operator had entered the data on the command line (arg1=xxx).
      msgwa1c 'enter data ...'
            ^

Option 'c' tests the data length stored in the $arg area, & suppresses the prompt if non-zero. This saves you from having to code the following:

      cmn    $ch1,0             any data stored in the $arg1 area ?
      skp>   1                  yes - bypass the prompt for entry
      msgwa1c 'enter data ...'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"msg" - display message - options

option e1/e2

 option e1 - translate line1 data from EBCDIC to ASCII
        e2 - translate line2 data from EBCDIC to ASCII
        e3 - translate both lines from EBCDIC to ASCII

option x1/x2

 option x1 - convert line1 data to hex representation
        x2 - convert line2 data to hex representation
        x3 - convert both line1 & line 2 to hex rep ('x_' defaults to x3)

uvcopy job to demo msgx1/x2

 # testmsgx1x2 - test option x1/x2 convert to hex rep Sep10/08
 @run
        mvf     a0(24),'testmsgx1x2'
        msgx1   a0(24),'<--testmsgx1x2'
        msgx2   'testmsgx1x2-->',a0(24)
        mvn     $ra,123456789
        msgx2v1 'register a \$ra = $ra, hex value = ',x0(4b)
        mvn     $rb,513
        msgx2v1 'register b \$rb = $rb, hex value = ',x4(4b)
        eoj

run testmsgx1x2 & observe output


 uvcopy testmsgx1x2  <-- execute demo job (/home/uvadm/pf/adm/testmsgx1x2)
 ==================    - observe output below:
      746573746D736778317832<--testmsgx1x2
      testmsgx1x2-->746573746D736778317832
      register a \$ra = 123456789, hex value =15CD5B07
      register b \$rb = 513, hex value =01020000

notes re testmsgx1x2

  1. register 'a' is stored at x0(4b). See area 'x' layout at 'uvcopy2.doc#A1'
  2. register 'a' $ra is escaped (preceded by '\') to prevent expansion of 1st instance of '\$ra = $ra'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - msg, "can","eoj",tim,wat,bal,ret,bcr

`can` - cancel the uvcopy job

     can  'error - program cancelled',99

'can' displays a msg to stdout if coded in op1. op2 is an optional exit code (dflt 99)

option j
  • prefix output msg with 'JOBID:date:time' stamp
  • see $jobstamp described in $symbols in uvcopy2.doc
option v1
  • expand uvcopy internal $symbols
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).

`eoj` - end the job

'eoj' closes all files that are open & exit with users exit code (op1).

      eoj  [exitcode]

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - msg,can,eoj,"tim","wat",bal,ret,bcr

`tim` - get current date & time & store in area y for user access

      tim  0              - if no operands (or op1 0), tim gets the current
                            date/time & stores in $date2,$time2,& $datetime2
      tim  g0(8b)         - if op1 is an 8 byte area, it is assumed to contain
                            a UNIX time, which will be stored in $time2
                            & converted into $date2 & $datetime2.

The 'tim' instruction stores the date & time in work area 'y' as follows: (use the $symbolic addresses but the actual locations are also given).

 $datetime18c y50(18)     Current date/time Not edited ccyymmddHHMMSS0mmm(18)
 $date8c      y50(8)      system date when execution began
 $time6c      y58(6)      system time HHMMSS
 $msecs4c     y64(4)      milliseconds 4 digits (0mmm) within current second

Note that these areas are initially set to the uvcopy program startup time (even if no 'tim' instruction is executed). The uvcopy program startup time is always available in the folowing areas:

 $datetime18  y0(18)      Begin date/time Not Edited ccyymmddHHMMSS0mmm (18)
 $date8       y0(8)       system date when execution began
 $time6       y8(6)       system time HHMMSS
 $msecs4      y14(4)      millisecs 4 digits (0mmm) within current second
 $datetimems  y20(23)     Begin date/time Edited 'ccyy/mm/dd_hh:mm:ss_mmm'
Note
  • above is only a few of the date/time fields stored by tim
  • see 'uvsoftware.ca/uvcopy2.htm#B7' for all date/time $fields
  • see 'uvsoftware.ca/uvcopy2.htm#B7b' for date/time BINARY $fields

Examples of using 'tim' & the stored values:

      tim                  - get current date/time
      msg  $datetime2      - display date & time string ccyy/mm/dd:hh:mm:ss
      tim  a8(4b)             - convert date/time stamp in TIPix JOURNAL file
      mvc  b64(19),$datetime2 - store result in the output record
                              - used by 'tipjrnx2' (see TIPjobs.doc vol 3)

`wat` - wait a specified number of seconds

      wat   60            - wait 60 seconds
      ---                   then proceed to next instruction
      wat   $ra          - wait the number of seconds in register 'a'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - msg,can, eoj,tim,wat,"bal",ret,bcr

`bal` - branch & link to a subroutine

        bal   subr3       - bal to subr3
        ---               - returns here via 'ret' instrn which
                             must be coded at end of subroutine
 subr3  ---               - the subroutine coded elsewhere (at end)
        ---
        ret               - return to instrn following the bal
Notes
  • subroutines allow a group of instructions to be coded once & executed from several points in the prmfile
  • may be nested up to 10 deep
      bal    g0(8)     <-- may specify the subrtn label in any area
                         - max 8 blank filled
Note
  • could do a table lookup of record-types & processing labels
  • see the example for 'skp'

op2/op3/op4 optional to pass data to the subroutine

If op2,op3,&/or op4 are coded, the data will be moved to work area 'w' for use by the subroutine & stored as follows:

 op2 data (if <= 200) ----> stored at w0(200) & blank right filled
 op2 data (if  > 200) ----> stored at w0(max 4000)
 op3 data (if declared) --> stored at w200(200) & blank right filled
 op4 data (if declared) --> stored at w400(200) & blank right filled
      bal   subr              - bal op2/op3/op4 optional
                                work area 'w' unchanged if op2 omitted
      bal   subr,a0(80)               - op2/op3/op4 may be area addresses
      bal   subr,'abc'                - or constants
      bal   subr,a0(80),b0(50),'xxx'  - or any combination

The effect of the instructions above is the same as if the bal instruction were preceded by 'mvf' instructions:

   [  mvf   w0(200),a0(80)   ]
   [  mvf   w200(200),b0(50) ]
   [  mvf   w400(200),'xxx'  ]
      bal   subr2

Also note that op2 may be up to 4000 bytes (op3 & op4 would be omitted)

   [  mvf   w0(4000),a0(4000) ]
      bal   subr2

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`subrtn example` - cymd compare 6 digit dates for Year 2000

"bal" subroutine example

Here is a practical example of a 'bal' subroutine. This could be useful for Year 2000 bridge programs where you need to compare 2 dates using the windows technique of inferring the century from the 2 digit year.

 # cymd - uvcopy subrtn to compare 6 digit dates windowing at 1940
 #      - returns with cc set < = > for skp? testing by calling mainline
 #
 #   bal   cymd,a50(6),d0(6)   - example of use
 #   skp<  xxx                 - subrtn sets cc <=>
 #
 #note - bal instrn stores op2 & op3 at w0(max200) & w200(max200)
 #
 #logic- we will prefix 2 dates with '19'
 #     - then change to 20 if year is < '40'
 #
 cymd   mvc    w100(6),w0            move op2 to allow prefix
        mvc    w098(2),'19'          prefix op2 with century 19
        cmc    w100(2),'40'          check op2 for 19 or 20 century ?
        skp=>  1
        mvc    w098(2),'20'          change op2 century to 20
 #
        mvc    w198(2),'19'          prefix op3 with century 19
        cmc    w200(2),'40'          check op3 for 19 or 20 century ?
        skp=>  1
        mvc    w198(2),'20'          change op3 century to 20
 #
        cmc    w098(8),w198          compare dates & set cc for return
        ret                          return with cc set < = >
Note
  • this subroutine is present in the uvadm/pf directory
Your assignment
  • copy & rename the 'cymd' subrtn as 'cmdy' & modify the code to compare dates in the 'mmddyy' format.
NOTE
  • in fact the cmc instruction now has option 'y' to perform the windows compare function (see the 'cmc' instruction doc).
        cmcy   a50(6),d0(6)    - compare 2 dates using window 1950 default

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - msg,can, eoj,tim,wat,bal,"ret",bcr

`ret` - return from a subroutine (to the instruction following the bal)

Subroutines allow a group of instructions to be coded once & executed from several points in the prmfile (may be nested up to 10 deep).

        bal   subr3       - bal to subr3
        ---               - returns here via the 'ret' instrn
 subr3  ---               - the subroutine code (elsewhere in program)
        ---
        ret               - return to instrn following the bal

The 'ret' instruction may optionally specify the condition code which would tested in the calling subroutine. This is a convenient way of passing some information back to the caller.

        ret<        - would return with the condition code '<'
        ret=        - would return with the condition code '='
        ret>        - would return with the condition code '>'
        ret         - would return with the condition code unchanged
                      by the 'ret' instruction
                    - the condition code would remain as set by some
                      previous instruction.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 6 (message & control) - msg,can,eoj,tim,wat,bal,ret,"bcr"

`bcr` - Branch on Condition & Return

'bcr' is similar to 'bal', but branches 'conditionally' vs unconditionally. It also offers an option of returning to a label (if op2 coded), vs always returning to the next instruction (following the 'bcr').

        ---              <-- preceding instruction to test something & set cc
        bcr=  sub1       <-- branch to sub1 if condition code '=' (or < > <= >=)
        ---              <-- returns here via 'ret' instrn (at end subrtn)
 sub1   ---                - the subroutine coded elsewhere
        ---
        ret                - return to instrn following the bcr
        ---
        bcr<  sub2,getr  <-- branch to sub2 if cc <
                             return to op2 label vs next instr
        ---              <-- gets here only if branch not taken
 getr   ---              <-- op2 label could be anywhere in program
        ---
        bcr>  sub3,,'ABC' <-- branch to sub3 cc >, 1st store 'ABC' in w0(3)
        ---               <-- return here (since op2 not coded)

op3/op4 optional to pass data to the subroutine

If op3,&/or op4 are coded, the data will be moved to work area 'w' for use by the subroutine & stored as follows:

op3 data
  • will be stored at w0(200) & blank right filled
op4 data
  • will be stored at w200(200) & blank right filled

'bcr' demo jobs provided

You may run the following 'bcr' demo jobs as shown below. No input files are required.


 uvcopy testbcr1   <-- run demo#1, see listing on next page, with test output
 ===============

 uvcopy testbcr2   <-- run demo#2, not shown here
 ===============

 vi /home/uvadm/pf/adm/testbcr2   <-- can inspect demo#2 with 'vi'
 ==============================

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`bcr example` - testbcr1 test/demo job for bcr instruction

"bcr" test/demo

 # testbcr2 - new instrn March 19/2008
 @run
         msg    'test "bcr" instrn, testbcr2 same as testbcr1 but also tests:'
         msg    '- optional label in op2 for return (vs next instrn)'
         msg    '- optional data in op3 stored in w0(200) for subrtn use'
 loop    msg    ' '
         msgwa1 '      Enter 1 character ("q" to quit)'
         mvc     a0(1),$arg1(1)
         cmc     a0(1),'q'              quit ?
         skp=    quit
         tsb     a0(1),x'01'
         bcr=    one
         tsb     a0(1),x'02'
         bcr=    two,twoR               test return to op2 label (vs next instrn)
         tsb     a0(1),x'04'
         bcr=    four,,'--> this data passed to subrtn from op3 of bcr'
         skp     loop
 #
 one     msg     '--> character has bit x"01"'
         ret=
 two     msg     '--> character has bit x"02"'
         ret=
 four    msg     '--> character has bit x"04"
         msg     w0(64)      - show data passed from op3 of bcr
         ret=
 quit    eoj
 #Sep15/18 - test return to a lable
 twoR    msg     '--> returned to label twoR & then skp"d to loop'
         skp     loop

 uvcopy testbcr2  <-- run testbcr2 (to test the 'bcr' instruction)
 ===============
 test "bcr" instrn, testbcr2 same as testbcr1 but also tests:
 - optional label in op2 for return (vs next instrn)
 - optional data in op3 stored in w0(200) for subrtn use
       Enter 1 character ("q" to quit)
 1 --> character has bit x"01"
       Enter 1 character ("q" to quit)
 2 --> character has bit x"02"
   --> returns to label twoR & then skps to loop
       Enter 1 character ("q" to quit)
 4 --> character has bit x"04"
   --> this data passed to subrtn from op3 of bcr
       Enter 1 character ("q" to quit)
 7 --> character has bit x"01"
   --> character has bit x"02"
   --> character has bit x"04" (but only uses bit 1 & bit 2)
   --> returns to label twoR & then skps to loop

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - "tra", "tre", trl, tru, trt, trs, hxc, chx, vhx

`tra` - translate to ASCII (from EBCDIC)

tra op1dsp(lth) - instruction format

    tra   b0(100)       - translate  1-100 of area 'b' to ASCII
    trat2 b0(100)       - option 't2' translate table for Germany
                        - see options for various countries below
t0
  • ebc2ascUS.c EBCDIC to ASCII - United States
t1
  • ebc2ascBE.c EBCDIC to ASCII - BElgium
t2
  • ebc2ascDE.c EBCDIC to ASCII - DEutschland (Germany)
t3
  • ebc2ascES.c EBCDIC to ASCII - ESpana (Spain)
t4
  • ebc2ascFI.c EBCDIC to ASCII - FInland
t5
  • ebc2ascFR.c EBCDIC to ASCII - FRance
t6
  • ebc2ascGB.c EBCDIC to ASCII - Great Britain
t7
  • ebc2ascL1.c EBCDIC to ASCII - Latin-1
t8
  • ebc2ascL2.c EBCDIC to ASCII - Latin-2
t9
  • ebc2ascPT.c EBCDIC to ASCII - PorTugal
t10
  • ebc2ascUV.c EBCDIC to ASCII - UV Software legacy
t11
  • ebc2ascUVDE.c EBCDIC to ASCII - UV Software legacy Germany
    trat2 b0(100)       - option t2 EBCDIC to ASCII for Germany

Also note run option 'rop=t#' to specify translate table for all 'tra' instructions in the uvcopy job without having to code option t1 on each 'trat1' instruction. For example, to run the demo job $UV/pf/util/toascii1 using the Germany translate table


 uvcopy toascii1,fili1=dat1/vendormas0,filo1=tmp1/vendormas0.asc,rop=t2
 ======================================================================
  - see details for this demo at 'https://uvsoftware.ca/testdemo.htm#U1'

 uvcopy toascii1,rop=t2   <-- same as above, I/O files default as above
 ======================

OR, you could export 'UVCOPYROP" with your desired translate option 't#' to be applied to all 'tra' instructions in all uvcopy jobs - unless oover-ridden by option t# on a trat# instruction or rop=t# on uvcopy.


 export UVCOPYROP=t2   <-- can set rop=t# for all uvcopy jobs until you logoff
 ===================

You could add 'export UVCOPYROP=t2' to your profile if you always wanted the Germany translate table without having to code it on each uvcopy command or each tra instruction.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - "tra", "tre", trl, tru, trt, trs, hxc, chx, vhx

`tre` - translate to EBCDIC (from ASCII)

    tre  op1dsp(lth)        - instruction format
    tre  b0(100)            - translate area b 1-100 to EBCDIC
    tre  c180(20)           - translate area c 181-200 to EBCDIC

Run option 'rop=t2' or 'export UVCOPYROP=t2' is available to invoke an aalternate ASCII to EBCDIC transalte table that ensures any hi-bit ASCII characters will be translated to EBCDIC spaces x'40's.

group 7 (translate) - tra, tre, "trl", "tru", trt, trs, hxc, chx, vhx

`trl` - translate to lower case (any UPPER case present)

    trl   op1dsp(lth)      - instruction format
    trl   b20(60)          - translate 21-80 of area 'b' to lower case
    trlq3 b0(80)           - translate 80 col rec to lower case
                             with 'q' optn to inhibit translation
                             within quotes single or double
 option  q1 - inhibit translation within single quotes
         q2 - inhibit translation within double quotes
option f1
  • translate 1st char of each word to UPPER case (after translating all text to lower case)

`tru` - translate to UPPER case (any lower case present)

    tru   op1dsp(lth)     - instruction format
    tru   b20(60)         - translate 21-80 of area 'b' to upper case
    truq3 b0(80)          - translate 80 col rec to upper case
                            with 'q' optn to inhibit translation
                            within quotes (single or double)
 option  q1 - inhibit translation within single quotes
         q2 - inhibit translation within double quotes

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - tra, tre, trl, tru, "trt", trs, hxc, chx, vhx

`trt` - translate via user specified (or modified) translate table

      trt   b0(80),c0            - translate area b
                                   using the translate table in area c
Note
  • the translate instruction replaces each byte of op1 from the op2 translate table, depending on the binary value of the op1 character
  • for example the character 'A' is x'41' or binary value 65 & would get replaced by whatever character is at displacement 65 in the table
  • a neutral translate table is supplied at x2100(256) which the user may modify or copy to alternate areas & modify.
  • you may use the $symbol $trt to address this table
example
  • translate any unprintable characters to blanks
  • unprintable characters are x'00' to x'1f' & x'80' to x'ff'
        mvc   c0(256),$trt          - copy neutral translate table to area c
        clr   c0(32),' '            - set low control characters to blanks
        clr   c128(128),' '         - set high control characters to blanks
        trt   b0(80),c0(256)        - translate the data
                                    - translates any ctl chars to blanks
                                    - printable characters will be unchanged

In fact, the above translate table is provided as a '$' symbol and you can use it directly with only the 'trt' instruction:

        trt   b0(80),$trtchr        - translate area b to printable characters
                                    - translates any unprintables to blanks
        trt   b0(80),$trtper        - translates any unprintables to periods

sign correction translate tables

A special translate table '$trtsea' is provided for correcting signs in zoned numeric fields that have been translated from EBCDIC to ASCII with no special consideration. See examples in DATAcnv1.doc.

        tra    b0(64)               - entire record translated to ASCII
                                      without consideration for zoned
                                      signed fields in cols 39-62
        trt    b38(24),$trtsea      - correct the signs in the multiple
                                      zoned numeric fields in cols 39-62
        trt    b38(24),$trtsae      - the reverse correction is also
                                      available for ASCII to EBCDIC

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - tra, tre, trl, tru, trt, "trs", hxc, chx, vhx

`trs` - translate/search command


     trs   aa0(500),t0(256)     translate/scan for desired bytes
 ===============================================================

"trs" translates op1 using a neutral translate table (previously modified to detect desired characters), stops on the first change, leaving the op1 index register pointing to the character in op1 whose value was modified in the translate table.

The translate table would have been created at program initialization by copying the neutral translate table ($trt) to a work area and modifying the desired character byte offset values.

In a neutral translate table, the value in each of the 256 bytes is equal to its offset, byte 0 has value 0, byte 255 has value 255, etc. An unmodified neutral table would not change any data if used by trt.

It does not matter what the modified value is since as long as it is different than the neutral value at that offset.

example
  • to detect negative zeros packed &/or unpacked
  • packed zero = x'0D' decimal value (offset) = 13
  • unpacked zero = x'D0' decimal value (offset) = 13*16+0=208
     mvc   t0(256),$trt         copy neutral translate table to ws
     mvc   t13(1),'*'           modify offset to detect x'0D' packed -0
     mvc   t208(1),'*'          modify offset to detect x'D0' unpacked -0
     ...
     trs   aa0(500),t0(256)     translate/scan for desired bytes
     skp=  hit                  cc set = if desired byte found
     skp!  endrec               cc set ! if end data with nofind
op1
  • must specify a register (so detection may continue)
op2
  • must specify a translate table (modified as discussed above)
 option a# (trsa1,trsa2,etc) - increment op1 register by specified value
           - would use to continue scan after a match (or mismatch actually)

option r1 (trsr1) - replace data byte with translate table byte (like trt)

The instruction ends on first op1 byte whose value offset modified in op2. The condition code is set = to indicate a desired byte found & the op1 register will hold displacement of that data byte within op1.

The displacement in the register is within the entire op1 area, ignoring any op1 displacement coded (unlike most other instructions).

If no desired bytes found, cc is set < to indicate no mismatches found & the op1 register will hold displacement to 1st byte beyond op1 data.

See /home/uvadm/pf/signscan1 as a good example of using the 'trs' instruction.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - tra, tre, trl, tru, trt, "hxc", "chx", vhx

`chx` - convert character representation of hex to true hex data

    chx  op1dsp(lth),op2dsp    - instruction format
    chx  b0(50),a0             - converts 1st 100 bytes of area a
                                 into 1st 50 bytes of area b
    chx  b0(6),x'313241426162' - convert the hexadecimal constant
                 12ABab       <--- would be the result in area b

`hxc` - convert hex data to hex character representation

    hxc  op1dsp(lth),op2dsp     - instruction format
    hxc  b0(100),a0             - converts 1st 50 bytes of area a
                                  into 1st 100 bytes of area b
    hxc  b0(12),c'12ABab'       - convert character constants
                  313241426162 <--- result in area b (in hex representation)
Note
  • output will be twice as long as input (op2 lth not required)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - tra, tre, trl, tru, trt, hxc, chx, "vhx"

`vhx` - convert data to vertical hexadecimal representation

     vhx        op1       , op2  , op3   ,  op4          - format
           printable chars, zones, digits, input-data
           --------- output -------------,-- input --
     vhx   b0(100),b100(100),b200(100),a0(100)           - example
     vhx   b0(100),b100,b200,a0(80)           - op2&op3 lths default to op1

"vhx" converts the op4 data to vertical hexadecimal as follows:

op1
  • printable characters, any unprintable characters shown as periods
op2
  • zones (hexadecimal representation of the zones of each data byte)
op3
  • digits (hexadecimal representation of the digits of each data byte)
op4
  • the input data (may be shorter but not longer than op1 length)
option a1
  • translate characters from EBCDIC to ASCII
  • before replacing any unprintables with periods
option b1
  • clear leading blanks on the zones & digits lines
option b2
  • clear trailing blanks on the zones & digits lines
option b4
  • start test for 1st blank at column 8 (for COBOL)
 Please see the 'vhx' example on the next page --->

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 7 (translate) - tra, tre, trl, tru, trt, hxc, chx, "vhx"

vhx example

 # vhex1.dat - test data file for uvcopy vhex1 job
 2276673266722276772667626666266727766772766732666
 3068581E4140D0453404141069C506F20563F090685810AF2
 # - to convert data files to vertical hex rep
 222276266676772667626666727627677666626672767
 30D04F03FE652404141069C5304F06524931C08580250

 uvcopy vhex1   - pre-programmed job to convert any text file to
 ============     vertical hex representation
                - writes a file named vhex1.tmp, which you can examine
                  with the editor, or print with lp, or whatever
                - this job is listed below (see vhex2 for fixed lengths)
 # vhex1 - convert a file to vertical hex representation
 #       - for variable length text files LF terminated
 #       - see vhex2 for fixed length records (with no LF's)
 fili1=?tf/vhex1.dat,rcs=100,typ=LST
 filo1=$jobname.tmp,rcs=100,typ=LSTt
 @run
        opn    all
 loop   get    fili1,a0(100)
        skp>   eof
        vhx    b0(100),b100,b200,a0($rz100)
        put    filo1,b0(100)
        put    filo1,b100(100)
        put    filo1,b200(100)
        skp    loop
 eof    cls    all
        eoj
Note
  • the op4 length of vhx is coded as '$rz100' since the last record in the file may be less than 100 bytes
  • the get instruction always stores record length in $rv & $rz

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - "scn",rep,mvu,sct,sst,tts,ttx,rpt,sta,sts,stt,rts,rtt

`scn` - scan op1 area for op2 pattern & set cc equal if found

    scn   op1dsp(lth),'constant'     - instruction format
    skp=  found                      - cc set = if match found

scn op1dsp(lth),op2dsp(lth)

    scn    b0(128),'IBM'      - scan for 'IBM' & set cc = if found
    skp!   1
    mvc    bx0(3),'XXX'       - replace IBM with XXX via register x
                                which holds displacement of found data
    scnm   b0(80),',.;:'      - option 'm' to scan for multi 1 byte patterns
    scnp   b0(80),'@#@ *#@#'  - scan for cdn postal code (option p)
                                allowing 0,1,or more blanks in centre
    scne1  bb0(80),'next'     - option 'e1' stores dsplcmt of found
                                pattern in rgstr coded vs rgstr 'x' dflt
    scn    b0(80),<x'20'      - scan area b for 1st byte < a space
                              - allowed if no option 'p' & op2 lth = 1
    scn    b0(80),'comp-3'    - scan for 'comp-3' fields (COBOL program)
    skp!   1                    (condition code unequal '!' if not found)
    msg    b0(80)             - display all 'comp-3' fields
Note
  • the last example above is somewhat similar to the pre-programmed jobs in 'SCANjobs.doc' (scan1,scan1d,scan2,etc)
  • those jobs create an audit file which you can re-examine (vs using the 'msg' display which rolls off the screen)
  • By examining the many pre-programmed jobs listed , you should be able to learn a lot about uvcopy programming techniques.
condition code
  • will be = equal if the op2 pattern was found in op1
  • will be < unequal if the pattern was not found
register 'x'
  • will hold the displacement of the found search data
  • or the end of op1 if not found
  • register 'x' is always stored, even if option 'e' is coded to update 'explicitly' coded register.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'scn' option summary

 'b' - inhibit multi-blank-bypass
     - would slow the instruction down
       but would allow more than 1 leading blank in search data
Warning
  • you must specify option 'b' when scanning for 1 or more blanks or when the pattern is preceded by more than 1 blank
 'd' - allow ';' in search pattern to match any 1 of: blank,
       period, comma, semicolon,or right paren - to prevent unintended
       matches to a pattern that could be part of longer words.
     - normally used in last byte of search pattern for cobol
       programs where periods & commas are common
 'e1' - updates ie 'adds' to any existing value in any explicitly coded
        register (as well as 'replacing' existing value in register 'x'
        which is always performed by default)
 'a1' - also add pattern length to any explicitly coded register in op1
      - only if the search pattern is found
Note
  • 'scn' always 'stores' the scan length in rgstr x
Note
  • you may use option 'z1' to init the explicitly coded rgstr
  • on the 1st scn, omit on subsequent scns to continue search same area
 'u1' - may be coded on any instruction to update the op1 register
      - do not use with option 'e' which performs a similar function
        & is specific to the 'scn' instruction
 'g' - option 'g' modifies the fixed op2 length specified
  g1 - length of op2 search pattern determined by first NULL
  g2 - length of op2 search pattern determined by first TILDE
  g4 - length of op2 search pattern determined LAST NON-BLANK
  g7 - 'g7' (1+2+4) searches for all 3 situations in that order

'h1' inhibit scan if 1st char of pattern = '~' & set cc > 'h2' inhibit scan if 1st char of pattern = '~' & set cc = 'h4' unhibit scan if op2 pattern blank - return cc > 'h8' inhibit scan if op2 pattern blank - return cc =

 'i1' - case insensetive
      - translates op1 to all lower case (in working storage)
        so you should code your op2 (usually a constant) in lower case

'p' - scan using pattern match chars

 'p1' - inhibit pattern match for 1st byte (use direct compare)
 'p2' - inhibit pattern match for 1st 2 bytes, etc p3,p4,p5...,p99
      - example: scan for actual '#' followed by any digit 0-9
    scnp1 a0(80),'##'     <-- scan for '#' in 1st byte + any digit 0-9 in 2nd

q1 - inhibit recognition in single quotes q2 - inhibit recognition in double quotes

'm' - multiple 1 byte patterns

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'scn' options (continued)

'n' - match occurrence number desired n1 - the default scans for the 1st occurrence of the pattern n3 - would scan for the 3rd occurrence of the pattern

 'r' - scan from right to left
     - option 'm' not available for option 'r'
  w1 - match only on the 1st word (or part of) encountered in op1
       (vs the default of testing all data in op1)
  w2 - would match on the 2nd word in op1
     - words counted by 1 leading blank + a non-blank
  w0 - could be used if you know there is no leading blank in op1
  z1 - clear the op1 register before scn begin
     - this option applies to many similar instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'scn' instruction examples

problem
  • find 'comp-3' fields in a COBOL program & change to comp-4
  • the COBOL statement might be as follows:
            =========================================================
                  05 gross-pay          pic  s9(5)v99    comp-3.
            =========================================================

solution #1

        scn    a0(80),'comp-3'             scan for 'comp-3'
        skp!   xx                          cc = if found, unequal(!) if not
        mvc    ax0(6),'comp-4'             found - change to comp-4
 xx     ---

"scn" leaves the displacement of the 1st byte of the found pattern in register 'x' (displacements are 0 relative vs 1 relative column#s). For example, if 'comp-3' started in column 50, rgstr x would hold 49 & 'ax0' would address (area 'a' byte 0 + 49) = column 50.

solution #2

        scn    a0(80),'comp-3'             scan for 'comp-3'
        skp!   1                           skip over next instrn if nofind
        mvc    ax5(1),'4'                  found - change '3' to '4'

In this solution, we are changing only the '3' of 'comp-3' to a '4' "ax0" points to the 1st byte of the found pattern 'comp-3', Therefore 'ax5' points 5 bytes higher (the 6th byte of 'comp-3') since this is zero relative.

solution #3

        scn    a7(65),'comp-3'             scan for 'comp-3'
        skp!   2                           skip over next instrn if nofind
        mvc    ax7(6),'comp-4'             found - change 'comp-3' to 'comp-4'
        mvc    ax12(1),'4'           -or-  found - change '3' to '4'

"a7(65)" is often used to address the COBOL statement area which is columns 8-72 (zero relative displacements 7-71) The found pattern is then addressed as 'ax7(6)' The alternative solution shown above uses 'ax12(1)' to address only the '3' of the 'comp-3' (7+5 = 12 bytes higher than register 'x')

solution #4

       rep    a7(65),'comp-3','comp-4'

This is an easier solution to the stated problem, but does not illustrate the finer points of the 'scn' instruction which was our intention here.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

more complex examples using the 'scn' instruction

             continuing the scan for a 2nd following pattern
             -----------------------------------------------
problem
  • find any 'comp-3' that follows a 'pic' & change to 'comp-4' for example the COBOL statement might be:
            ==========================================================
                   05 gross-pay        pic  s9(5)v99  comp-3.
            ==========================================================
        scn   a0(80),' pic '        - find any COBOL picture clause
        skp!  xx
        scne  ax0(80),' comp-3'     - find any following 'comp-3'
        skp!  xx
        mvc   ax6(1),'4'            - change 'comp-3' to 'comp-4'

The 1st scn leaves rgstr 'x' with the displacement of ' pic ' The 2nd scn codes op1 as 'ax0(80)' so that the scan will continue from the ' pic ' & not start over from the begining of area 'a'

        mvc  ax6(1),'4'

This moves the '4' 6 bytes higher than rgstr 'x' which points to the 1st byte of ' comp-3'.

Option 'e' is necessary on the 2nd scan in order not to clear the existing value in rgstr 'x' from the 1st scan.

The following is a simpler solution but does not illustrate the finer points of the 'scn' instruction.

        scn   a0(80),' pic '
        skp!  xx
        rep   a0(80),' comp-3',' comp-4'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

scanning from the right & continuing to a 2nd following pattern

problem
  • isolate surnames as in the following example:
              =============================================
   input -->            William F. Buckley
                        Thomas J. K. Edison
              =============================================
              =============================================
  output -->            Buckley
                        Edison
              =============================================
       scnr   a0(80),>' '     - scan from right for 1st byte > than a blank
       scnr   a0($rx80),' '   - continue scan for blank before surname
       mvc    b0(25),ax1      - move surname to area 'b'

Your 1st thought might be to code 'ax0(80)' for op1 of the 2nd scan but this would not work since the right hand starting position would be to the right of the 80 byte area.

       scnr   a0($rx80),' '
                 ^^^
 This works because the x rgstr determines the right hand byte
 (the length is in rgstr 'x', the 80 is a maximum in case x > 80)

The 'mvc' op2 is 'ax1' to address the 1st byte of the surname which is 1 higher than the displacement in rgstr x which points to the blank found by the 2nd scan

The following is a simpler solution using the 'p' option (special pattern match characters - see next page)

       scnrp  a0(80),' !'     - scan from right for 1 blank & 1 non-blank
       mvc    b0(25),ax1      - move the surname to area 'b'

For more complex examples of 'scn', 'rep', 'mvu', please see the discussion of 'index registers' near the end of section uvcopy2.doc.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

`pattern match characters` - used by: scn, rep, mvu, sct, rpt, rts, rtt, cnt

Note
  • pattern match characters are activated by instruction option 'p'
  • available on scn, rep, mvu, sct, rpt, rts, rtt, cnt
  • NOT available on 'sst'

@ - any alpha (upper or lower)

> - any upper case x'41' - x'5a'

< - any lower case x'61' - x'7a'

 # - any numeric x'30' - x'39'
 & - any alphanumeric
   - any numeric, UPPER case alpha,or lower case alpha
   - NOT blank, NOT punctuation

? - any printable character x'20' - x'7e'

! - any non-blank character (all except x'20')

% - any punctuation (non alphanumeric printable)

^ - any control character x'00' - x'1f'

* - previous character may repeat 0,1,or more times

; - any 1 of a blank, period, comma, semicolon,or right paren

` (backquote) - hexchar 0-9, A-F (or a-f)

option 'p1'
  • inhibit pattern match for 1st byte (use direct compare)
option 'p2'
  • inhibit pattern match for 1st 2 bytes, etc p3,p4,p5...,p99
  • example: scan for actual '#' followed by any digit 0-9
      scnp1 a0(80),'##'   <-- scan for '#' in 1st byte + any digit 0-9 in 2nd

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,"rep",mvu,sct,sst,tts,ttx,rpt,sta,sts,stt,rts,rtt

`rep` - scan op1 replacing all op2 patterns with the op3 data

     rep   b0(80),'AS400','UNIX' - replace all AS400's with UNIX
     skp=  repmade               - set cc = if any replacement made
     cmn   $ci1,1                - replacement count in $ci1 instrn ctr#1
     skp>  multi
     rep    b0(80),<' ','.'      - replace any byte < space with a period
                                 - allowed if no option 'p' & op2 lth = 1
     repm   b0(80),'ABC','XYZ'   - option 'm' for multiple 1 byte replacements
                                   (replaces A with X, B with Y, C with Z, etc)

condition code

condition code
  • will be '=' if any replacements were made
  • will be '<' if no replacements were made

instruction counters

instruction counter #1 ($ci1) will hold a count of total replcmnts made

registers

rgstr 'x'
  • will hold the dsplcmnt of the 1st byte of the 1st match in the data (or the last byte of op1 +1 if no matches)
rgstr 'u'
  • will hold the dsplcmnt of the 1st byte of the last match in the data (or the last byte of op1 +1 if no matches)

condition codes on search pattern

Allowed only if 'p' option absent & the op2 pattern length = 1.

 Any condition code is allowed, 1 or 2 bytes as follows:
 = (default)   ! (not equal)   <   <=   =>   >

rep options

a1
  • ignore 1 leading blank in search pattern if we are testing at the 1st byte of the op1 data area
a2
  • allow for adjacent patterns with 1 leading blank & 1 trailing blank (otherwise we would get nomatches after the 1st match)
b
  • inhibit multi-blank bypass (when pattern has > 1 leading blank)
Warning
  • you must specify option 'b' when scanning for 1 or more blanks or when the pattern is preceded by more than 1 blank

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

rep options continued

c1
  • perform replacements only on matches that begin in the 1st column of the op1 data field
d
  • ';' in search pattern match: blank,period,comma,semicolon,right-paren
  • ';' in replacement pattern will be replaced by actual character
  • prevents unintended matches to a parts of longer words.
  • normally used in last byte of search & replace patterns for cobol programs where periods & commas are common
f
  • modifies the fixed op3 length specified or implied by a constant
f1
  • length of replacing data (op3) determined by first NULL - often used for filename replacements ($fili1, etc)
f2
  • length of replacing data (op3) determined by first TILDE
f4
  • length of replacing data (op3) determined LAST NON-BLANK
f7
  • 'f7' (1+2+4) would test for all 3 in that order & use 1st match
    Example - replacing patterns with filenames which are null terminated
            mvc   b0(50),'file = fff'
            repf  b0(50),'fff',$fili1
g
  • option 'g' modifies the fixed op2 length specified
g1
  • length of op2 search pattern determined by first NULL
g2
  • length of op2 search pattern determined by first TILDE
g4
  • length of op2 search pattern determined LAST NON-BLANK
g7
  • 'g7' (1+2+4) searches for all 3 situations in that order
i1
  • case insensetive, translates to lower case before search/replace
  • translates both op1 & op2 to lower case before compare
       repi1   a0(80),'abc','xyz'  <-- replace any 'abc' or 'ABC' with 'xyz'
       repi3   a0(80),b0(3),'xyz'  <-- replace matches anywhere in 1st 80 bytes of area 'a'
                                       to 1st 3 bytes area 'b' with 'xyz'
q1
  • inhibit replacements within single quotes
q2
  • inhibit replacements within double quotes
m
  • multiple 1 byte replacements (corresponding pairs in op2 & op3)
n#
  • specifies the number of match replacements to make from r# match occurrence
p
  • activates special pattern match characters
r#
  • replace occurrence# in op1 area (ignore other matches in op1 area)
r1
  • replace only the 1st match, r2 replace only the 2nd match, etc
r#
  • But if n# specified, r# identifies 1st match occurrence to be replaced and n# specifies the number of consecutive match replacements to make
r2n3
  • would replace match occurrences 2,3,4

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

rep options continued

s
  • allow special pattern match characters within the replacement data as well as within the search data (use with option p)
  • allows constants to be inserted within the found data pattern example1: rep b0(80),'@#@#@#','@#@ - #@#' would insert ' - ' in CDN postal codes 'V5P3V8' to 'V5P - 3V8' example2: rep b0(80),'###-###-####','(###) ###-####' would convert tel#s from 'AAA-XXX-NNNN' to '(AAA) XXX-NNNN'
v1
  • expand uvcopy internal $symbols
  • op1 area must be large enough to hold the expanded values of $symbols
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).
x1
  • reduce multiple consecutive identical chars (matching rep op2) to 1 occurrence of rep op3, for example:

      repx1  b0(100),' ','_'
      ======================

      Input  data   to      test   repx1    <-- sample input
      ==================================
      Input_data_to_test_repx1              <-- sample output results

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,"mvu",sct,sst,tts,ttx,rpt,sta,sts,stt,rts,rtt

`mvu` - move op2 data to op1 area until the op3 pattern detected

    mvu     b0(80),a0,'cat'        move until 'cat' found
    skp!    nofind                 set cc = if found & rx to dsp
    mvc     bx0(3),'dog'           replace cat with dog
    mvuz3a7 bx0(80),ay0,'concat'   move until 'concat' found
    skp!    nofind
    mvcu1   bx0(5),'enate'         append to make 'concatenate'
                                   (see optns z,a,e below)
    mvum    h0(80),r0,'.,;:'       move until period,comma,semi,colon
                                   option 'm' multi 1 byte tragets
    mvu    b0(80),a0,<' '          move a to b until 1st byte < space
                                   (if no option 'p' & op2 lth = 1)
condition code
  • will be set equal '=' if the search pattern is found & the move stops at that point
  • will be set unequal '!' if search pattern not found & the max length (op1) will have been moved
register 'x'
  • stores the move length for op1
register 'y'
  • stores the move length for op2
  • x & y always stored (no need to code explicitly)

explicitly coded registers in op1 & op2

Might use option 'e1/e2' to add the data move length to explicitly coded op1/op2 rgstrs. Might use option 'a4' to move the found search pattern to op1. Might use option 'a1/a2' to add the found pattern length to op1/op2 registers.

You might use option 'z1/z2' to init explicitly coded op1/op2 registers on the 1st mvu & omit on subsequent to continue moving data in the same area.

mvu Options

Options may be appended following the 3 character instruction code. Options are lower case alphas (a-z) & may have a following numeric value.

b1
  • blank op1 before moving data from op2 (until op3 detected)
t1
  • null terminate op1 after data moved
m
  • multiple 1 byte search targets in op3
p
  • invokes the special pattern match characters

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

mvu options (continued)

d
  • allow ';' in search pattern to match any 1 of: a blank, period, comma, semicolon,or right paren - to prevent unintended matches to a pattern that could be part of longer words.
  • normally used in last byte of search pattern for cobol programs where periods & commas are common
g
  • option 'g' modifies the fixed op3 length specified
g1
  • length of op3 search pattern determined by first NULL
g2
  • length of op3 search pattern determined by first TILDE
g4
  • length of op3 search pattern determined LAST NON-BLANK
g7
  • 'g7' (1+2+4) searches for all 3 situations in that order
q1
  • inhibit matches within single quotes
q2
  • inhibit matches within double quotes
q3
  • inhibit matches within either single or double quotes
a4
  • also move the found data pattern from op2 to op1 (vs default stop with op2 register pointing to found data)
a2
  • also update the op2 register over the found data pattern
a1
  • also update the op1 register over the found data pattern
e2
  • add the op2 data move length to the 'explicitly' coded op2 register
e1
  • add the op1 data move length to the 'explicitly' coded op1 register
register 'x'
  • count of data bytes moved to op1 output area
  • index to next byte in op1 or byte following last op1 if max data
register 'y'
  • index in op2 area to 1st byte of pattern if found
  • OR index in op2 area to last byte of pattern +1 if NOT found
Note
  • 'mvu' always 'stores' move length in rgstr x (for op1) & y (for op2)
Note
  • option 'e' updates ie 'adds' to any existing value in any explicitly coded registers in op1 & op2

generic register options

Note
  • processed by the instruction control processor & not by mvu (ie - common to all instrns not just mvu)
z1
  • zero the op1 rgstr (if coded) before executing the instruction
z2
  • zero the op2 rgstr (if coded) before executing the instruction
z3
  • zero both op1 & op2 registers (if any) before execution
u1
  • update the op1 register by length of data moved
u2
  • update the op2 register by length of data moved
u3
  • update both op1 & op2 rgstrs by lth of data moved
Note
  • you would not code option 'u' on the 'mvu' instrn because option 'a1' is provided as the mvu equivalent (see the explanation on the next page)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"mvu" options & registers example

given
  • cobol source programs
required
  • insert 'sync' following any 'comp-4' field as shown below (before & after)
            05 sale-quantity  pic  9(5) comp-4 value 0.
            05 sale-quantity  pic  9(5) comp-4 sync value 0.
                                               ****
 1      mvuz3e3a7 bb0(80),aa0,' comp-4 '   move until comp-4 (or end line)
 2      skp!      2                        skip next 2 instrns if comp-4 nofind
 3      mvcu1     bb0(5),'sync '           insert sync (mvc not mvu)
 4      mvue3a7   bb0(80),aa0,'. '         move rest of stmnt or line
  1. option z3 clears op1 & op2 rgstrs (b & a) before move until begins.

option e3 causes the explicitly coded rgstrs (b & a) to be updated (rather than the default x & y rgstrs when no op1 & op2 rgstrs coded) this applies to the displacements up until the target pattern is found

option a7 (1+2+4) causes the move of the found pattern & an additional update of the rgstrs over the found pattern

  1. option u1 (on mvc not mvu) causes the op1 rgstr to be updated with the length of the moved data, so that the op1 on any following mvc/mvu instruction continuing the move of the same record may be coded as bb0 (vs bb5) to allow for the length of moved data 'sync 'in this case

  2. moves the remainder of the stmnt (until the '. ' found) option e3 updates the explicitly coded rgstrs ('a' & 'b') option a7 updates the rgstrs past the found pattern
Note
  • see more examples in the 'index register' discussion near the end of section uvcopy2.doc

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,"sct",sst,tts,ttx,rpt,sta,sts,stt,rts,rtt

`sct` - scan by table

sct area(length),tablebase(entrylth),entryoffset(patternlth),'stopchar'

    sct  b0(256),m0(80),m0(30),'~'
           op1  - defines the data area to be scanned
           op2  - defines the table start address & table entry length
           op3  - offset to the pattern within each entry (usually 0)
                  & max length for each pattern (usually same as op2)
                  (length for any 1 pattern is determined by 1st tilde)
                - op3 allows you to define a scan table as 1 portion
                  of a multi-purpose table
           op4  - end-of-table (EOT) character (2 of which are required)
                - default is tilde '~' (2 tildes '~~" in columns 1 & 2)
Note
  • entries with only 1 tilde '~' in col 1 & non-tilde in col 2 will be automatically bypassed
     sct   b0(80),m0(12),m0(12)    - scan area b using table in area m
     skp=  match                   - set cc = if any match found

The table might have been loaded as follows (before @run).

 lod=m0(12)
 Mr.~~~~~~~~~
 Mrs.~~~~~~~~
 Doctor~~~~~~
 ~~~~~~~~~~~~               '~~' in col 1&2 marks end of table

'sct' condition codes

condition code
  • will be '=' if a match is found
  • will be '<' if no match is found

'sct' registers

register 'x'
  • will point to the matched data in op1 (or end of op1+1)
register 'y'
  • will point to the matching table entry or to the table end marker if no match
register 'w'
  • will hold the length of the data matched or 0 if no match found

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"sct" options

option b
  • inhibit multi-blank bypass (use when pattern has > 1 leading blank)
Warning
  • you must specify option 'b' when scanning for 1 or more blanks or when the pattern is preceded by more than 1 blank
option c1
  • matches must begin in the 1st column of the op1 data field
option d
  • ';' in search pattern will match: blank, period, comma, semicolon,or right paren.
  • prevents unintended matches to a parts of longer words.
  • normally used in last byte of search patterns for cobol programs where periods & commas are common
 option  h1 - inhibit the scan if 1st byte of op2 pattern tilde '~'
            - returns with condition code set > unequal
         h2 - same but return with cc set = equal
              (if 1st byte of pattern was a tilde '~')
option i1
  • insensetive to case
  • translates op1 to lower case (in working storage) so you should code the table entries in lower case to match
option p
  • activates special pattern match characters
option p1
  • inhibit pattern match for 1st byte (use direct compare)
option p2
  • inhibit pattern match for 1st 2 bytes, etc... p2,p3,...p99
 option q1  - inhibit matches within single quotes
        q2  - inhibit matches within double quotes
option w1
  • match on 1st word in op1

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,"sst",tts,ttx,rpt,sta,sts,stt,rts,rtt

`sst` - scan using table patterns to match or not-match


      sst  area(length),tablebase(entrylth),tablebase(patternlth)  <-- format
      ===========================================================
               op1             op2                  op3

      sst  b0(256),p0(50),p0(50)      <-- example
      ==========================
           op1  - defines the data area to be scanned
           op2  - defines the table start address & table entry length
                - op2 length could be longer than op3 to store counts beside patterns
           op3  - defines table patterns
                - displacment same as op2
                - max length for each pattern (usually same as op2)
                  (length for any 1 pattern is determined by 1st tilde)
                - end of table marked by entry of all '~' tildes
 #  ----- sample pattern table - from test/demo job pf/adm/testsst1 -----
 #    - select if "Townsend" anywhere AND "Canada" in 60-79, but not if "Owen" in 0-19
 lod=p0(50)
 Townsend~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     "Townsend" anywhere
 +2@60[20]Canada~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AND "Canada" in 60-79
 -@0[20]Owen~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOT "Owen" in 0-19
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       sst      a0(100),p0(50),p0(50)  search table for matches/nomatches
       skp=     match                  (cc set = if criteria met)
condition code
  • will be '=' if a match is found
  • will be '<' if no match is found
register x
  • will point to first match in op1 data (or end of op1 data)
register y
  • will point to first matching table entry (or end table)
counter $ci1
  • count pattern matches
counter $ci2
  • count records matched - 1 or 0 for 'sst', but could be > 1 for 'tts' instrn which scans multi records in a table
option i0
  • sensetive to case
option i1
  • insensetive to case

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'sst' Instruction RULES

  1. op1 defines the data-area(length) to be searched.
  2. op2 defines the FIRST entry of the pattern search table p0(50) example. The end of the search table is marked with an all '~' tildes entry.
  3. op3 defines the FIRST search pattern p0(50) usually same as op2, and must have same entry displacement. In our example both start at 'p0' (1st byte area 'p').
  4. If desired op2 entry length could be greater than op3. You might store counts of that pattern found in the extra space, since register 'y' $ry is loaded with the displacement of the 1st matching pattern in the table.
  5. You must provide at least 15 bytes extra space in table pattern lengths to allow for the preformatting of table entries with default dsplcmnts and search conditions as shown in the 'lod' table above. Suggested minimum length 50 bytes to allow 30 byte patterns.

  6. You may code 1st byte of pattern as '+' (default) to indicate the pattern must be present and '-' to indicate the pattern must be absent (NOT found). You must code all '+' patterns prior to any '-' patterns.
  7. You can code '>' & '<' conditions, but only if you specify the field location and length, for example: 'arg1=@90[4]>2015' from 'SelectJobs.doc#3E3' - selects Members of Parliament elected after 2015.
  8. The 'sst' instruction sets the condition code '=' for a match. The default assumes a match if any '+' pattern is found, and assumes a mismatch of any '-' pattern is found. All '+' patterns must be specified before any '-' patterns.

  9. You can not code ' ' spaces in the arg1 patterns (for testsst2 & select jobs below), because these jobs convert spaces to tildes when storing patterns in the table, & because the uvcopy command line does not allow embedded spaces.
  10. You may code spaces as '^' circumflexes, which will be converted to ' ' spaces.
  11. You can not code ',' commas in arg1 patterns, because the uvcopy command line uses ',' commas to spearate arguments.
  12. You may code commas as '%' percents, which will be converted to ',' commas.

The next few pages will present several examples using the 'sst' instruction.

Also see 'https://uvsoftware.ca/selectjobs.htm' which documents the SelectJobs (selectlf1,selectlfd1,selectlgfd1,selectlgfd2,selectfd1), pre-programmed jobs that allow you to use the power of select instructions (sst,tts,ttx) to select desired items from your files (scripts, programs, any directory of text files).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

sst Pattern Examples illustrating Pattern Rules

We will illustrate the "sst Pattern Rules" using the arg1=... format used by the SelectJobs (selectlf1,selectlfd1,selectlgfd1,selectlgfd2,selectfd1).


 arg1=+1@Townsend:+2@Canada:-3@Owen  <-- arg1=... patterns for 'sst' instruction
 ==================================

The SelectJobs reformats the patterns from arg1=... into the 'table format' required for the 'sst' instruction (as shown on the pprevious paage).

Here is a sample 'uvcopy selectlf1' command to select lines from dat1/nameadrs1 that have "Townsend" AND "Canada", but NOT "Owen"


 uvcopy selectlf1,fili1=dat1/nameadrs1,arg1=+1@Townsend:+2@Canada:-3@Owen
 ========================================================================
          ------------- Input - dat1/nameadrs1 ----------------
 Owen Townsend       4667 Hoskins Rd     North Vancouver, BC Canada V7K2R3
 Jenny Townsend      21 Canada Place     Vancouver, BC       Canada V5P3V8
 John Horgan         123 Townsend Ave.   Townsend City, BC   Canada V1P2G3
 John Townsend       2121 Owen Drive.    St. John, NB        Canada M5W1E6
 John Owens          24 Owen Avenue      Owenville, ON       Canada M5K3B3
 Donald Trump        1600 Pennsylvannia  Washingtom, DC      USA 00001
 Bill Gates          1 Microsoft Way     Seattle, WA         USA 98052-6399
 Peter Townsend      24 Johnson Road     London, England     UK EC1A 1HQ
  ----- Output - dat1_nameadrs1_+1@Townsend:+2@Canada:-3@Owen -----
 Jenny Townsend      21 Canada Place     Vancouver, BC       Canada V5P3V8
 John Horgan         123 Townsend Ave.   Townsend City, BC   Canada V1P2G3

 #1. arg1=+Townsend:+Canada:-Owen  <-- match if ANY '+' found, not if '-' found
     ============================

 #2. arg1=+1@Townsend:+2@Canada:-1@Owen:-2@BC  <-- multiple conditions +1,+2,etc
     ========================================
     - match if "Townsend" AND "Canada" found anywhere
     - mismatch if  "Owen" AND "BC" found anywhere
     You may specify "multiple conditions" with a sequence# (single digit max 9).
     All conditions in the series must be met for a match.

The '+1' indicates the First condition & '+2' the Second condition of a series (9 max). You must code the '@' between the sequence# & the pattern. The '@' is recognized only in 1st 3 bytes (to allow you to search for patterns with @ signs beyond 3rd byte).


 #3. arg1=+@0[60]Townsend:+@60[20]Canada:-@0[20]Owen  <-- restricted search areas
     ===============================================
     - match if "Townsend" in 0-59 OR "Canada" in 60-79, But not if "Owen" in 0-19.
       (may omit the '+'s since that is the default)
     You may specify a "restricted search area" by coding the Displacement[Length]
     following the '@' identifier.

 #4. arg1=+1@0[60]Townsend:+2@60[20]Canada:-1@0[20]Owen:-2@40[20] <-- all combinations
     ============================================================
     - match if "Townsend" in 0-59 AND "Canada" in 60-79
     - mismatch if  "Owen" in 0-19 AND "BC" in 40-59
     May combine all of above (+/-, restricted search areas, multiple condtions)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

testsst1 - test/demo using multi-pattern table to match or notmatch

 # testsst1 - test sst instrn, by Owen Towsnend, UV Software, Apr25/2019
 #          - search data using table with multiple patterns to match or notmatch
 # testsst2 <-- better test, prompts for various patterns
 #
 # uvcopy testsst1   <-- run this 'testsst1' test/demo, no keyins required
 # ===============     - patterns hard-coded (vs testsst2 prompts for patterns)
 #
 #     ----- tf/nameadrs1 - testfile patterns in various positions -----
 # Owen Townsend       4667 Hoskins Rd     North Vancouver, BC Canada V7K2R3
 # Jenny Townsend      21 Canada Place     Vancouver, BC       Canada V5P3V8
 # John Horgan         123 Townsend Ave.   Townsend City, BC   Canada V1P2G3
 # John Townsend       2121 Owen Drive.    St. John, NB        Canada M5W1E6
 # John Owens          24 Townsend Dr.     Owenville, ON       Canada M5K3B3
 # Bill Gates          1 Townsend Way      Port Townsend, WA   USA 98052-6399
 # Melinda Gates       600 Pacific Ave.    Owentown, WA        USA 98052-6399
 # Peter Townsend      24 Johnson Road     London, England     UK EC1A 1HQ
 #
 #            --------------- data matches below ------------------
 # Jenny Townsend      21 Canada Place     Vancouver, BC       Canada V5P3V8  matches=1,datadsp=6,tbldsp=0
 # John Horgan         123 Townsend Ave.   Townsend City, BC   Canada V1P2G3  matches=1,datadsp=24,tbldsp=0
 # John Townsend       2121 Owen Drive.    St. John, NB        Canada M5W1E6
 #
 opr='$jobname - test uvcopy "sst" instruction'
 fili1=?tf/nameadrs1,rcs=256,typ=LST
 filo1=?tmp/$fili1,rcs=256,typ=LST
 # load table of patterns to match or !notmatch
 lod=p0(50)
 +1@Townsend~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     "Townsend" anywhere
 +2@60[20]Canada~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AND "Canada" in 60-79
 -3@0[20]Owen~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOT "Owen" in 0-19
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # selects if "Townsend" anywhere AND "Canada" in 60-79, but not if "Owen" in 0-19
 @run
         opn      all                    open files
         sys      'cat tf/nameadrs1'     display input file for user compare to output
         msg      '    ----- test data above, search table below -----'
         wtbex1   filo1,p0(50),p0(50)
         msg      '    ----- search patterns above, data matches below -----'
 #
 # begin loop to get records & select matches to table of patterns
 man20   get      fili1,a0               get next record
         skp>     man90                  (cc set > at EOF)
         ssti1    a0(100),p0(50),p0(50)  search table for matches/nomatches
         skp!     man20                  (cc set = if criteria met)
 #
 man30   mvfv1    a80(60),'mps=$ci1,mds=$ci2,dsp=$rx,tbl=$ry'
         put      filo1,a0               write selections to outfile
         msg      a0(160)                display selections
         skp      man20                  return to get next
 #
 # EOF - close files & end job
 man90   cls      all
         eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

demo jobs to test 'sst' instruction


 #1. uvcopy testsst1,fili1=tf/nameadrs1
     ==================================
     uvcopy testsst1   <-- same as above, input file defaults as shown
     ===============
     - patterns hard-coded (vs testsst2 prompts for patterns)

 #2. uvcopy testsst2,fili1=tf/nameadrs2,arg1=...:...
     ===============================================
     uvcopy testsst2,arg1=...:...  <-- may omit fili1=... (defaults to tf/nameadrs2)
     uvcopy testsst2,arg1=...:...  <-- code your own pattern, examples above
     ============================
     uvcopy testsst2               <-- may omit arg1=pattern (will prompt)
     ===============

summary of SELECT jobs based on sst,tts,ttx instructions

 See 'https://uvsoftware.ca/selectjobs.htm' documenting several uvcopy utility jobs
 based on  the 'sst', 'tts',& 'ttx' instructions. Here is a brief summary:

 #1. uvcopy selectlf1,fili1=infile,arg1=pattern1:pattern2:etc (max 9)
     ================================================================
     - select Lines from 1 File depending on arg1=... +matches & -nomatches

 #2. uvcopy selectlfd1,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     ================================================================
     - select Lines from all Files in a Directory depending on arg1=...

 #3. uvcopy selectlgfd1,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     =================================================================
     - select Line Groups from all Files in a Directory depending on:
       arg1/arg2 define begin/end group & arg3 selection patterns
     - multi condition series 1,2,3,etc based on patterns within each line

 #4. uvcopy selectlgfd2,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     =================================================================
     - select Line Groups from all Files in a Directory depending on:
       arg1/arg2 define begin/end group & arg3 selection patterns
     - multi condition series based on patterns on any line in the group

 #5. uvcopy selectlfdd1,fild1=indir,fild2=outdir,arg1=pattern1:pattern2:etc
     ======================================================================
     - select Files from 1 directory into a 2nd directory
     - arg1 specifies patterns that must be found on the SAME line
     - arg2 specifies patterns that may be on ANY line in the file

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,"tts",ttx,rpt,sta,sts,stt,rts,rtt

`tts` - scan data table lines for matches to pattern table


      tts  datatable(entrylth),dt(el),patterntable(entrylth),pt(patternlth)
      =====================================================================
               op1             op2              op3              op4

      tts  b0(200),b0(200),p0(50),p0(50)   <-- example
      ==================================
      - scan data table in area 'b' with pattern table in area 'p'
           op1  - defines the 1st entry of the data table to be scanned
                - start displacement within area & length of all data entries
           op2  - same as op1 (format compatible with other table instructions)
           op3  - defines the 1st entry of the pattern table
                - max length of patterns (& possibly extra)
                - pattern length determined by 1st '~' tilde
                - start displacement within area & length of all pattern entries
                - op3 length could be longer than op4 to store counts beside patterns
           op4  - defines the max length of table patterns
                - displacment same as op3
                - max length for each pattern (usually same as op3)
                  (length for any 1 pattern is determined by 1st tilde)
                - end of table marked by entry of all '~' tildes

       tts   b0(200),b0(200),p0(50),p0(50)  search data table for match to pattern table
       ===================================
       skp=  match                          (cc set = if criteria met)
condition code
  • will be '=' if a match is found
  • will be '<' if no match is found
register x
  • will point to the 1st data table entry with match in pattern table
  • or end of op1 data table if nomatch
register y
  • will point to 1st pattern table entry with match in data table
  • or end of pattern table if nomatch
counter $ci1
  • count pattern table entery matches
counter $ci2
  • count data record table entry matches
option i0
  • sensetive to case
option i1
  • insensetive to case

We will demonstrate using the pre-programmed job 'selectlgfd1' which uses the 'tts' instruction to determine if the SYSIN group of lines (from '//SYSIN DD *' to '/*') matches the patterns entered on arg3=... We need to inspect SORT INCLUDE/OMIT CONDitions with both "AND"s & "OR"s which may need manual corrections.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

tts Example#1 - search JCL for SORTs with AND or OR CONDitions

Here is the comamnd line, followed by the report created in subdir selects/...


 uvcopy selectlgfd1,fild1=mf/jcl2,arg1=//SYSIN,arg2=/*,arg3=1@COND:2@AND:1@COND:2@OR
 ===================================================================================
 # Report: selects/mf_jcl2_1@_SYSIN_1@COND:2@AND:1@COND:2@OR%
 # ---> uvcopy selectlgfd1,fild1=mf/jcl2,arg1=1@//SYSIN,arg2=/*,arg3=1@COND:2@AND:1@COND:2@OR%
 #      =========================================================================
 # format: uvcopy selectlgfd1,fild1=directory,arg1=...,arg2=...,arg3=...,arg4=...,uop=abcdgi
 # arg1 patterns identify begin-group line, arg2 patterns identify end-group line
 # arg3 patterns qualify group selection, arg4 patterns qualify lines to output/print
 #  - code '^' circumflex for ' ' spaces and '%' percent for ',' commas in patterns
 #  - may prefix patterns: '-' for absence, '+' for presence (default)
 #  - may restrict search area: arg2=@0[2]/*  <-- "/*" must be in 1st 2 bytes
 #  - multiple-condition-series: arg3=1@SORT:2@COND:3@AND:4@OR <-- ALL patterns must match
 # Date=2019/05/29_10:26:54, Site=UV_Software, Host=uvsoft5, User=uvadm, Options=
 #===============================================================================
 //SYSIN    DD *
 SORT FIELDS=(31,6,CH,A,1,6,CH,A)
 OMIT COND=((11,2,CH,EQ,C'65'),OR,(COND=(11,2,CH,EQ,C'85'))
 /*
                          EOG: #1, 2 lines selected from mf/jcl2/jar200
                          EOF:     2 selected from 23 in mf/jcl2/jar200
 //SYSIN    DD *
 SORT FIELDS=(1,8,CH,A,69,12,CH,A)
 INCLUDE COND=((9,1,CH,EQ,C'T'),AND,(COND=(56,2,CH,EQ,C'BC'))
 /*
                          EOG: #1, 2 lines selected from mf/jcl2/jgl230
                          EOF:     2 selected from 34 in mf/jcl2/jgl230
 //SYSIN    DD *
 SORT FIELDS=(1,8,CH,A,69,12,CH,A)
 INCLUDE COND=(((9,1,CH,EQ,C'T'),OR,(COND=(9,1,CH,EQ,C'X'))),
                                 AND,(COND=(56,2,CH,EQ,C'AB')))
 /*
                          EOG: #1, 3 lines selected from mf/jcl2/jgl232
                          EOF:     3 selected from 35 in mf/jcl2/jgl232
 EOD: 8 files, 181 lines, selected 3 groups, 7 lines to selects/mf_jcl2_1@_SYSIN_1@COND:2@AND:1@COND:2@OR%

Notes re tts & selectlgfd1 demo

  1. Directory $UV/mf/jcl2/* contains 8 demo JCLs with 5 SYSINs (3 of them sorts). 'arg1=//SYSIN' defines the group starting line & arg2=/*' defines the group ending line.
  2. 'arg3=1@COND:2@AND:1@COND:2@OR' defines the select group conditions. This arg3 selects groups with lines that contain ("COND" & "AND") OR ("COND" & "OR"). The pattern rules are the same as for the 'sst' instruction (preceding).
  3. Better if we could select ONLY the groups with BOTH AND & OR, since it is only those that need correction, But 'selectlgfd1' (using 'tts' instruction) can not do this, Because its multi conditions apply to single lines & not to all lines in the group
  4. See 'selectlgfd2 (using the 'ttx' instruction), which searches for all lines in the group to satisfy multi condition series patterns (1,2,3,etc).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,"ttx",rpt,sta,sts,stt,rts,rtt

`ttx` - scan data table groups for matches to pattern table

'ttx' is similar to 'tts', except the series matching conditions apply to all lines in the data table, rather than applying to single lines within the data table.


      ttx  datatable(entrylth),dt(el),patterntable(entrylth),pt(patternlth)
      =====================================================================
               op1             op2              op3              op4

      ttx  b0(200),b0(200),p0(50),p0(50)   <-- example
      ==================================
      - scan data table in area 'b' with pattern table in area 'p'
           op1  - defines the 1st entry of the data table to be scanned
                - start displacement within area & length of all data entries
           op2  - same as op1 (format compatible with other table instructions)
           op3  - defines the 1st entry of the pattern table
                - max length of patterns (& possibly extra)
                - pattern length determined by 1st '~' tilde
                - start displacement within area & length of all pattern entries
                - op3 length could be longer than op4 to store counts beside patterns
           op4  - defines the max length of table patterns
                - displacment same as op3
                - max length for each pattern (usually same as op3)
                  (length for any 1 pattern is determined by 1st tilde)
                - end of table marked by entry of all '~' tildes

       ttx   b0(200),b0(200),p0(50),p0(50)  search data table for match to pattern table
       ===================================
       skp=  match                          (cc set = if criteria met)
condition code
  • will be '=' if a match is found
  • will be '<' if no match is found
register x
  • dsplcmnt to 1st record in data table with match in pattern table
  • or end of op1 data table if nomatch
register y
  • dsplcmnt to 1st entry in pattern table with match in data table
  • or end of pattern table if nomatch
register u
  • dsplcmnt to matching data within the matched record
  • or 0 if nomatch
register v
  • total dsplcmnt to matching data in the data table ($rx+$rv)
  • or end of op1 data table if nomatch
counter $ci1
  • count pattern table entery matches
counter $ci2
  • count data record table entry matches
option i0
  • sensetive to case
option i1
  • insensetive to case
Note
  • 'i1' on prior instructions ssti1 & ttsi1 lowercase both patterns & data before matching, but 'ttxi1' lowercases only the patterns, but not the data because the original data table is searched & not each line in a work area.
  • But select jobs using 'ttx' have option 's1' to lowercase the data when read

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

ttx Example#1 - search JCL for SORTs with AND or OR CONDitions

We will demonstrate using the pre-programmed job 'selectlgfd2' which uses the 'ttx' instruction to determine if the SYSIN group of lines (from '//SYSIN DD *' to '/*') matches the patterns entered on arg3=... We need to inspect SORT INCLUDE/OMIT CONDitions with both "AND"s & "OR"s which may need manual corrections.

Here is the comamnd line, followed by the report created in subdir selects/...


 uvcopy selectlgfd2,fild1=mf/jcl2,arg1=1@//SYSIN,arg2=/*,arg3=1@COND:2@AND:3@OR%
 ================================================================================
 # Report: selects/mf_jcl2_1@_SYSIN_1@COND:2@AND:3@OR%
 # ---> uvcopy selectlgfd2,fild1=mf/jcl2,arg1=1@//SYSIN,arg2=/*,arg3=1@COND:2@AND:3@OR%
 #      ===============================================================================
 # format: uvcopy selectlgfd2,fild1=directory,arg1=...,arg2=...,arg3=...,arg4=...,uop=abcdgi
 # arg1 patterns identify begin-group line, arg2 patterns identify end-group line
 # arg3 patterns qualify group selection, arg4 patterns qualify lines to output/print
 #  - code '^' circumflex for ' ' spaces and '%' percent for ',' commas in patterns
 #  - may prefix patterns: '-' for absence, '+' for presence (default)
 #  - may restrict search area: arg2=@0[2]/*  <-- "/*" must be in 1st 2 bytes
 #  - multiple-condition-series: arg3=1@SORT:2@COND:3@AND:4@OR <-- ALL patterns must match
 # Date=2019/05/29_10:27:05, Site=UV_Software, Host=uvsoft5, User=uvadm, Options=
 #===============================================================================
 //SYSIN    DD *
 SORT FIELDS=(1,8,CH,A,69,12,CH,A)
 INCLUDE COND=(((9,1,CH,EQ,C'T'),OR,(COND=(9,1,CH,EQ,C'X'))),
                                 AND,(COND=(56,2,CH,EQ,C'AB')))
 /*
                          EOG: #1, 3 lines selected from mf/jcl2/jgl232
                          EOF:     3 selected from 35 in mf/jcl2/jgl232
 EOD: 8 files, 181 lines, selected 1 groups, 3 lines to selects/mf_jcl2_1@_SYSIN_1@COND:2@AND:3@OR%

Notes re ttx vs tts & selectlgfd2 vs selectlgfd1

  1. Compare this selectlgfd2 (using the 'ttx' instruction) search result to the previous selectlgfd1 (using the 'tts' instruction).
  2. selectlgfd1/tts selection was 'arg3=1@COND:2@AND:1@COND:2@OR', which selected groups with (COND & AND) or (COND & OR). The result would include extra groups that do not need corection - ONLY groups with BOTH (AND & OR) may need correction.
  3. selectlgfd2/ttx selection is 'arg3=1@COND:2@AND:3@OR', which selects ONLY groups with BOTH ("AND" & "OR"), ie only those that may need correction.
  4. The 'tts' instruction), bases multi condition series patterns (1,2,3,etc) only on patterns found on any 1 line in the group.
  5. The 'ttx' instruction), bases multi condition series patterns (1,2,3,etc) on patterns found on any line in the group.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

Notes re select jobs & reports

  1. There are several SELECT jobs (selectlf1,selectlfd1,selectlgf1,etc), based on the 'sst', 'tts', 'ttx' instructions.
  2. By default, the SELECT jobs create their output reports in ./selects/... (subdir in the current directory).
  3. The output report filename defaults to a concatenation of the input directory, and the arg1/2/3 patterns, with '/'s converted to '_' underscores. For example: 'selects/mf_jcl2_SYSIN_1@COND:2@AND:3@OR'.
  4. If desired, you could specify an alterate output report filename, but the default is very convenient & creates unique filenames identifying the directory searched & the search patterns used.
  5. Note the 13 line report prefix which includes the Report: filename, the uvcopy command that created it, several lines of "help" information, and the current date=..., Site=..., Host=..., User=...,& Options=...

    summary of SELECT jobs based on sst,tts,ttx instructions

 See 'https://uvsoftware.ca/selectjobs.htm' documenting several uvcopy utility jobs
 based on  the 'sst', 'tts',& 'ttx' instructions. Here is a brief summary:

 #1. uvcopy selectlf1,fili1=infile,arg1=pattern1:pattern2:etc (max 9)
     ================================================================
     - select Lines from 1 File depending on arg1=... +matches & -nomatches

 #2. uvcopy selectlfd1,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     ================================================================
     - select Lines from all Files in a Directory depending on arg1=...

 #3. uvcopy selectlgfd1,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     =================================================================
     - select Line Groups from all Files in a Directory depending on:
       arg1/arg2 define begin/end group & arg3 selection patterns
     - multi condition series 1,2,3,etc based on patterns within each line

 #4. uvcopy selectlgfd2,fild1=indir,arg1=pattern1:pattern2:etc (max 9)
     =================================================================
     - select Line Groups from all Files in a Directory depending on:
       arg1/arg2 define begin/end group & arg3 selection patterns
     - multi condition series based on patterns on any line in the group

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,"rpt",sta,sts,stt,rts,rtt

`rpt` - replace by table

rpt area(lth),tablestart(entrylth),entryoffset(patternlth),'EOT char'

    rpt  b0(256),m0(80),m0(30),'~'
           op1  - defines the data area to be scanned
           op2  - defines the table start address & table entry length
           op3  - offset to the pattern within each entry (usually 0)
                  & max length for each pattern (usually 1/2 of op2 length)
                  (length for any 1 pattern is determined by 1st tilde)
                - the replacement data always follows the search pattern
                  & is the same maximum length as the search pattern
                  (length for any 1 replacement is determined by 1st tilde)
           op4  - end-of-table (EOT) character (2 of which are required)
                - default is tilde '~' (2 tildes '~~' in columns 1 & 2)
Note
  • entries with only 1 tilde '~' in col 1 & non-tilde in col 2 will be automatically bypassed
    rpt   b0(80),m0(20),m0(10)   - replace patterns in area b matching
                                   any entry on left side of table
                                   with corresponding entry from right side
    skp=  match                  - set cc = if any match found
    lod=m0(20)                   - load table (prior to @run)
    Mr ~~~~~~~Mr.~~~~~~~
    Mrs ~~~~~~Ms.~~~~~~~
    Doctor~~~~Dr.~~~~~~~
    ~~~~~~~~~~~~~~~~~~~~           '~~' in col 1&2 marks end of table
      rpti1 b0(80),m0(20),m0(10) - might need option 'i1' case insensetive
condition code
  • will be '=' if any replacements were made
  • will be '<' if no replacements were made

instruction counter #1 ($ci1) - will hold the count of re palcements made

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rpt" - replace by table (continued)

options for rpt

a1
  • ignore 1 leading blank in search pattern if we are testing at the 1st byte of the op1 data area (otherwise we might need 2 reps)
a2
  • allow for adjacent patterns with 1 leading blank & 1 trailing blank (otherwise we would get nomatches after the 1st match)
c1
  • perform replacements only on matches that begin in the 1st column of the op1 data field
b
  • inhibit multi-blank bypass (use when pattern has > 1 leading blank)
Warning
  • you must specify option 'b' when scanning for 1 or more blanks or when the pattern is preceded by more than 1 blank
d
  • ';' in search pattern match: blank,period,comma,semicolon,right-paren
  • ';' in replacement patterns will be replaced by actual character
  • prevents unintended matches to a parts of longer words.
  • normally used in last byte of search & replace patterns for cobol programs where periods & commas are common
i1
  • case insensetive, translates to lower case before search/replace
p
  • activates special pattern match characters
q1
  • inhibit matches within single quotes
q2
  • inhibit matches within double quotes
m1
  • replace the 1st match only (& ignore subsequent matches in the op1 area)
s
  • allow special pattern match characters within the replacement data as well as within the search data (use with option p)
  • allows constants to be inserted within the found data pattern example1: @#@#@#~~~~~~~~~~~~~~@#@ - #@#~~~~~~~~~~~ would insert ' - ' in CDN postal codes 'V5P3V8' to 'V5P - 3V8' example2: ###-###-####~~~~~~~~(###) ###-####~~~~~~ would convert tel#s from 'AAA-XXX-NNNN' to '(AAA) XXX-NNNN'

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rpt" - replace by table (continued)

registers stored by rpt

register 'x'
  • will hold the displacement of the 1st byte of the *1st* replacement made in the data (or the end of op1+1 if none)
register 'y'
  • will hold the displacement of the 1st byte of the *1st* matching entry in the table (or table end marker if nomatch)
register 'u'
  • will hold the displacement of the 1st byte of the *last* replacement made in the data (or the end of op1+1 if none)
register 'v'
  • will hold the displacement of the 1st byte of the *last* matching entry in the table (or table end marker if nomatch)
Note
  • As of May 2007, register 'v' is no longer stored by the rpt instruction
  • since $rv is stored by get & passes varlth recsize to following put
register 'w'
  • will hold the length of the *last* replacement data (else 0)
  • $ru + $rw = dsplcmnt of 1st byte beyond rep data

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

rptdemo - demo 'rpt' instrn

 # rptdemo - demo the uvcopy 'rpt' instrn
 #         - search/replace data via table of search/replace patterns
 #         - by Owen Townsend, UV Software, November 2009
 # - read search/replace table into area 'b' (reserved word fixes)
 # - read COBOL program line by line into area 'a' until EOF
 # - execute 'rpt' to apply search/replace table to each line
 # - write COBOL program lines to the output file
 rop=r1     # Run OPtion r1 for outfile disposition prompt at EOF (vi, more,cat)
 was=b8000  # increase areas b
 fili1=?tf/cobol2.cbl,typ=LST,rcs=128
 fili2=?tf/cnvcob9.tbl,typ=LST,rcs=128
 filo1=?tmp/$fili1,typ=LSTt,rcs=128
 @run
        opn    all                     open files
        rtbc1  fili2,b0(80),b0(80)     read search/replace table into area 'b'
 #      ===    option 'c1' bypasses any '# ' comment lines
 # begin loop to get/process/put each line of COBOL progm until EOF
 man20  get    fili1,a0                get next line of COBOL prgm
        skp>   eof
 #
        rptd   a7(65),b0(80),b0(30)    apply s/r table
 #      ===    option 'd' allows search table words ending w blank,comma,period
        put    filo1,a0                write out modified program
        skp    man20
 # EOF - close files & end job
 eof    cls    all                     close files
        eoj                            end job

 uvcopy rptdemo,fili1=tf/cobol2.cbl,fili2=tf/cnvcob9.tbl,filo1=tmp/cobol2.cbl
 ============================================================================
 uvcopy rptdemo   <-- same as above (files default as shown above)
 ==============

demo search/replace table

 # cnv/cnvcob9.tbl - search/replace table to test rptdemo,rtsdemo,rttdemo
 #      - modify old COBOL prgms to allow for new compiler reserved words
  printer;~~~~~~~~~~~~~~~~~~~~~ printer1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  name;~~~~~~~~~~~~~~~~~~~~~~~~ name1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  row;~~~~~~~~~~~~~~~~~~~~~~~~~ row1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  col;~~~~~~~~~~~~~~~~~~~~~~~~~ col1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test data output file (dummy COBOL program)

 ******* cobol2.cbl - dummy program to test uvcopy rptdemo,rtsdemo,rttdemo
 ******* modify old COBOL programs to allow for new compiler reserved words
 ******* - via search/replace table ctl/cnvcob9.tbl
         printer should be changed to printer1
         name should be changed to name1
         row, should be changed to row1,
         col. should be changed to col1.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,rpt,"sta",sts,stt,rts,rtt

`sta` - search data tables & count matches in a pattern table

sta data-table-entry,data-search-area,pattern-1st-entry,pattern-max-length

    sta   a0(80),a7(65),b0(60),b0(30)  <-- search data table in area 'a'
    skp=  match                            with pattern/count table in area 'b'
          op1 - defines first entry in table
              - starting position & length of each entry
              - table must be ended by '~~' 1st 2 bytes or null 1st byte
          op2 - defines dsplcmnt & length of each entry to scan
          op3 - defines search pattern table area & total entry length
                (max length of match pattern & count area)
              - each search pattern length determined by 1st tilde '~'
          op4 - defines search pattern dsplcmnt 0 max length
              - actual match pattern length determined by 1st tilde '~'
              - 10 byte count field follows search pattern max lth
              - op3 length must be at least 10 bytes > op4 length

     sta   a0(100),a0(100),p0(40),p0(30)   <-- example (from stademo1 next paage)
 #======================================
       op1 a0(100) - defines 1st entry in the data table (ended by '~~' col 1-2)
       op2 a0(100) - usually same, but could restrict to part of data entry
       op3 p0(40)  - defines 1st entry in the pattern/count table
       op4 p0(30)  - defines the search portion of the pattern/count table
                   - at least 10 bytes less than op4 to leave room for count

sample pattern/count table

 # pattern/count table used for the 'stademo1' job (on the next page)
 # - embedded within the stademo1 job, but could be read from a file at begin job
 lod=p0(50)
 * count DFSORT unsupported functions
 JOINKEYS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 JOIN~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 REFORMAT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *Total
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # - each entry must have a '~' in the last byte
 # - table ended with an all tildes entry
 # - '*' in col 1 identifies comments for headings & total lines
condition code
  • set equal if any match counted
  • set greater than if matches counted for all patterns
  • set less than if no matches counted for any pattern
 option c1 - clear *Total before this sta
        c0 - default allows multi files in directory)
 option j1 - inhibit scan if cols 1-2 "/*" (JCL comments)
 option s1 - inhibit scan if col 1 '#' (script comments)
 option s3 - allow scan of #= if col2 '=' (script instream)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

sta - scan a table of data for any match to table of search patterns

 # keywordstat1 - accumulate table of keyword counts in any 1 file
 #              - by Owen Townsend, UV Software, Dec17/2017
 # keywordstat2 - alternate job to count keywords in all files in any directory
 #              - general purpose job to assist problem analysis
 #
 # Uses 'sta' to search a data table & count matches in a pattern table
 # 1. 'rtb' to read a data file (JCL/script) into memory
 # 2. could use a 2nd rtb to load the pattern/count table
 #    - but this demo has the pattern/count table coded within the job
 # 3. 'sta' to scan for matches in the data & count in the pattern table
 # 4. dumps the pattern/count table to a file & prompts to display
 #
 # uvcopy keywordstat1,fili1=jcl3/sortjoin.ksh,filo1=tmp/sortops.rpt
 # =================================================================
 # - read JCL/script, search for patterns (see pattern table below)
 #   (patterns were DFSORT functions that need changes for uvsort)
 # - accumulate counts on the right side of the pattern table
 # - dump the pattern/count table to the output file
 # - prompts to display output file (option r1, reply vi,cat,more,etc)
 #
 # Also see keywordstat2 - reads all files in a directory
 # - counts matches for all files & dumps the pattern/count table at EOD
 # - intended as a general purpose job to assist problem analysis
 #
 rop=r1  # at EOF - prompt for oufile disposition (vi,cat,more,lp,etc)
 was=a1000000p10000   #increase area 'a' allow 10,000 lines of 100 bytes = 1 meg
 #                    #increase area 'p' allow 200 lines of 50 bytes = 10,000
 fili1=?mvstest/testlibs/jcl3/sortjoin.ksh,rcs=128,typ=LST
 filo1=stats/sortops.rpt,rcs=128,typ=LSTt
 #
 # load table of search patterns (max40) & count area(10)
 lod=p0(50)
 * count DFSORT unsupported functions
 JOINKEYS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 JOIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 REFORMAT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *Totals
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 @run
         opn     all                    open files
 #
 # read JCL/script file into memory table
        rtbc1   fili1,a0(100),a0(100)
 #
 # search script table & count matches in pattern table
        stab3c1 a0(100),a0(100),p0(50),p0(40)
 #  option b3   - ignore #comments & /*comments
 #    option c1 - clear *Total before this sta
 #
 # dump pattern/counts table to output file
        wtbe    filo1,p0(50),p0(50)
 #
 # close files & end job
        cls     all
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,rpt,sta,"sts",stt,rts,rtt

`sts` - scan a table for a character string

sts will scan a specified portion of each entry in a table, for a specified pattern. The table must be terminated by an entry with '~~' in cols 1-2.

    sts   1st-tbl-entry,scan-area,scan-pattern    - instrn format
    skp=                                          - cc = if pattern found
    sts   h0(80),h7(65),' accept '     - scan a table (COBOL program in memory)
    sts   hh0(80),hj7(65),' display '  - scan table entries using rgstrs
                                         loaded with start/stop displacements
          op1 - defines the first entry in the table
              - starting position & length of each entry
              - table must be ended by '~~' in 1st 2 bytes of an entry
              - op1 may specify a register with a start displacement
          op2 - defines the scan area in each entry
                using the displacement & length
              - op2 may specify a register with a stop displacement
          op3 - the search pattern (constant or data address)
condition code
  • set equal if pattern found, else unequal
 $ci1 - match count (instruction counter#1) usually 1 when match made
      - could be used with option n99 to count total matches
 $ci2 - entry# of matching table entry (zero relative)

registers - if op1 register NOT coded

rgstr 'u'
  • displacement to base of entry with matching pattern from the base of the op1 table area (different than other instrns)
  • Other instrn index rgstr values would be from starting dsplcmnt
  • irrelevant if your op1 starts at byte 0 (a0, b0, etc)
  • dsplcmnt to the '~~' EOT entry if no match found
rgstr 'w'
  • dsplcmnt to matching data within matching entry (zero if nomatch)
rgstr 'x'
  • total dsplcmnt to matching pattern from 1st entry scanned (rgstr 'u' + rgstr 'w')

registers - if op1 register IS coded

op1 rgstr
  • will be incremented by dsplcmnt to the base of matching entry (dsplcmnt within entire area, may differ from sts instrn begin)
  • allows for repeated scans down a memory table
  • use option 'z1' to ensure rgstr is cleared before 1st scan
  • see example on next page

rgstr 'u' & 'w' - same as above (when op1 rgstr not coded)

rgstr 'x'
  • will also be incremented by the op1 rgstr value (rgstr 'u' + rgstr 'w' + op1 rgstr value)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"sts" - scan a table for a character string (continued)

options - for sts instruction

b
  • multi-blank bypass (use when you need > 1 leading blank)
d
  • allows ';' to match blank, period, comma, semicolon,or right paren
g
  • option 'g' modifies the fixed op3 length specified or implied
g1
  • length of op3 search pattern determined by first NULL
g2
  • length of op3 search pattern determined by first TILDE
g4
  • length of op3 search pattern determined LAST NON-BLANK
g7
  • 'g7' (1+2+4) searches for all 3 situations in that order
Note
  • any option 'g' with blank op3 will be NoMatch
h1
  • inhibit scan if 1st char of pattern = '~' & set cc >
h2
  • inhibit scan if 1st char of pattern = '~' & set cc =
h4
  • inhibit scan if op2 pattern blank - return cc >
h8
  • inhibit scan if op2 pattern blank - return cc =
i1
  • case insensetive (not yet implemented)
n#
  • scan for specified occurrence#
n99
  • can use to count total matches in instrn ctr#1 $ci1
p
  • activates special pattern match characters
q1
  • inhibit replacements within single quotes
q2
  • inhibit replacements within double quotes
w#
  • match on specified word# on line
z1
  • clear op1 register before scan

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

sts - application example

 # ststest - test the 'sts' instrn
 #         - scan COBOL program for all ' accept 's
 was=b200000
 fili1=?in,typ=LST,rcs=100
 @run
        opn    fili1
        rtb    fili1,b0(100),b0(100)   read file into memory table
        mvn    $rb,0                   init rgstr b
 # begin loop to search for each occurrence of pattern - until no more
 loop   sts    bb0(100),b0(80),' accept '
        skp!   eoj
 # match found - calc ttl dsplcmnt from bgn table, display,& repeat search
        msg    bb0(72)                 display matching entry
        add    $rb,100                 bypass matching entry to next
        skp    loop
 eoj    cls    fili1
        eoj
Note
  • 'sts' is much faster than 'scn', which would search only 1 line at a time & you would repeat the loop for every line.
  • 'sts' searches multiple lines down the table until it finds a match or reaches the end of the table.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,rpt,sta,sts,"stt",rts,rtt

`stt` - search data tables for any match to a pattern table

stt data-table-entry,data-search-area,search-entry,search-length

    stt   a0(80),a7(65),b0(60),b0(30)  <-- search data table in area 'a'
    skp=  match                            with pattern table in area 'b'
          op1 - defines first entry in table
              - starting position & length of each entry
              - table must be ended by '~~' 1st 2 bytes or null 1st byte
              - op1 may specify a register to hold the starting displacement
          op2 - defines portion of each entry to scan
              - op2 may specify a register to hold the ending displacement
          op3 - defines search pattern table area & total entry length
                (max length of match pattern + nomatch pattern)
              - search pattern length determined by 1st tilde '~'
          op4 - defines search pattern max length
              - search nomatch pattern follows & assumed equal length
              - nomatch pattern length determined by 1st tilde '~'
condition code
  • set equal if any match made (else unequal)

registers - if op1 register NOT coded

rgstr 'u'
  • dsplcmnt to base of data table entry with matching pattern from the base of the data table area
  • dsplcmnt to the '~~' EOT entry if no match found
rgstr 'w'
  • dsplcmnt to matching data within matching entry
  • zero if nomatch found
rgstr 'x'
  • total dsplcmnt to matching pattern from 1st entry scanned (rgstr 'u' + rgstr 'w')
rgstr 'y'
  • dsplcmnt to the matching entry in the pattern table

registers - if op1 register IS coded

op1 rgstr
  • will be incremented by the dsplcmnt to the base of matching entry so op1 rgstr will point to matching entry within entire area (not just from begining of last stt instruction)
  • allows for repeated scans down a memory table (ensure rgstr is cleared before 1st scan)

rgstr 'u' & 'w' - same as above (op1 rgstr not coded)

 rgstr 'x' = (rgstr 'u' + rgstr 'w' + op1 rgstr initial value)
           - so rgstr x will point to matching entry within entire area
rgstr 'y'
  • dsplcmnt to the matching entry in the pattern table

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"stt" - scan a table of data for any match to table of search patterns

options - for stt instruction

a1
  • ignore lead blank in search pattern if at 1st byte of op1
a2
  • allow for adjacent patterns with leading & trailing blank
  • following adjacent patterns would otherwise be missed
b
  • multi-blank bypass (use when you need > 1 leading blank)
c1
  • match only if in 1st column of op1 data
d
  • allows ';' to match blank,period,comma,semicolon,or right paren
h1
  • inhibit scan if 1st char of pattern = '~' & set cc >
h2
  • inhibit scan if 1st char of pattern = '~' & set cc =
p
  • activates special pattern match characters
q1
  • inhibit matches within single quotes
q2
  • inhibit matches within double quotes
v1
  • expand uvcopy internal $symbols
  • op1 area must be large enough to hold the expanded values of $symbols
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,stt,sys instructions if option v2 present (option v2 no longer required).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

sample application of 'stt' instruction

See $UV/pf/selectbytbl general purpose uvcopy job to read all files in a directory and select files with any match to a table of patterns (created with editor). See sample application in 'https://uvsoftware.ca/jclcnv5items.htm'

We wanted to find any mainframe SORT parms using uncommon DFSORT/SYNCSORT functions that uvsort might not handle. We could scan the parms directory to select parms with uncommon fnctions (such as JOIN,PARSE,EDIT,etc) as follows:


 uvcopy selectbytbl,fild1=parms,fili2=ctl/dfsort3a.tbl,fild2=tmp1
 ================================================================
 - read all files in the parms/... directory, selecting parms with matches
   to table FILE of DFSORT patterns not handled by uvsort
 - writing to 1 output file with a blank line between selected parms
 - output file will be in the fild2=tmp1/dfsort3a.rpt

      stt   a0(100),a0(100),k0(40),k0(20)
 ========================================
 - 'stt' instrn from $UV/pf/IBM/selectbytbl
 - searching parms/... files for matches to patterns in ctl/dfsort3a.tbl
 # ctl/dfsort3a.tbl - table file of DFSORT patterns not handled by uvsort
 #  - sample search file for $UV/pf/selectbytbl
 lod=0(40)
 JOIN~~~~~~~~~~~~~~~~BUILD~~~~~~~~~~~~~~~
 PARSE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 EDIT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Note - the nomatch feature not yet implemented as of Dec2017

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,rpt,sta,sts,stt,"rts",rtt

`rts` - scan a table for a pattern & replace with an alternate

rts will search/replace in the specified portion of each entry in a table. For example, assuming you have a COBOL program loaded into memory (with ttb) you can perform search/replace within columns 8-72 of each entry.

rts 1st-tbl-entry,scan-area,pattern,replacement - format

    rts   b0(80),b7(65),'sysswch','switch'   - example
    skp=  match                                set cc = if found
          op1 - defines first entry in table
              - starting position & length of each entry
              - table must be ended by '~~' 1st 2 bytes or null 1st byte
              - op1 may specify a register to hold the starting displacement
          op2 - defines portion of each entry to scan
              - op2 may specify a register to hold the ending displacement
          op3 - defines search pattern (constant or adrs of data)
          op4 - defines replacement pattern (constant or adrs of data)
condition code
  • set equal if match found (else unequal)

instruction ctr#1 ($ci1) - will hold count of replacements made

registers - if op1 register NOT coded

rgstr 'u'
  • dsplcmnt to base of entry with matching pattern from the base of the table area
  • dsplcmnt to the '~~' EOT entry if no match found
rgstr 'w'
  • dsplcmnt to matching data within matching entry
  • zero if nomatch found
rgstr 'x'
  • total dsplcmnt to matching pattern from 1st entry scanned (rgstr 'u' + rgstr 'w')

registers - if op1 register IS coded

op1 rgstr
  • will be incremented by the dsplcmnt to the base of matching entry so op1 rgstr will point to matching entry within entire area (not just from begining of last rts instruction)
  • allows for repeated scans down a memory table (ensure rgstr is cleared before 1st scan)

rgstr 'u' & 'w' - same as above (op1 rgstr not coded)

 rgstr 'x' = (rgstr 'u' + rgstr 'w' + op1 rgstr initial value)
           - so rgstr x will point to matching entry within entire area

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rts" - scan a table for a pattern & replace with an alternate (continued)

options - for rts instruction

a1
  • ignore lead blank in search pattern if at 1st byte of op1
a2
  • allow for adjacent patterns with leading & trailing blank
  • following adjacent patterns would otherwise be missed
  • backs up 1 after replacement if trailing blank on search pattern to allow trailing blank to match leading blank of next pattern
b
  • multi-blank bypass (use when you need > 1 leading blank)
c1
  • replace matches only if in 1st column of op1
d
  • allows ';' to match blank,period,comma,semicolon,or right paren if ';' in replacement, restore the actual char saved from match
f
  • modifies the fixed op4 length specified or implied by constant
f1
  • length of replacing data (op4) determined by first NULL
  • often used for filename replacements ($fili1, etc)
f2
  • length of replacing data (op4) determined by first TILDE
f4
  • length of replacing data (op4) determined LAST NON-BLANK
f7
  • (1+2+4) would test for all 3 in that order & use 1st match
g
  • modifies the fixed op3 length specified or implied by constant
g1
  • length of op3 search pattern determined by first NULL
g2
  • length of op3 search pattern determined by first TILDE
g4
  • length of op3 search pattern determined LAST NON-BLANK
g7
  • 'g7' (1+2+4) searches for all 3 situations in that order
k
  • set op2 area to specified constant (inhibits normal search/replace)
k1
  • set all bytes of op2 area to character specified by op4
k2
  • set op2 to op4 constant, tilde fill on right if op4 lth < op2 lth
k4
  • set op2 to op4 constant, blank fill on right if op4 lth < op2 lth
p
  • activates special pattern match characters
q1
  • inhibit replacements within single quotes
q2
  • inhibit replacements within double quotes
r#
  • replace occurrence# in op1 area (ignore other matches in op1 area)
r0
  • replace all matches in op1 area
r1
  • replace only the 1st match, r2 replace only the 2nd match, etc
v1
  • expand uvcopy internal $symbols
  • op1 area must be large enough to hold the expanded values of $symbols
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rts" - scan a table for a pattern & replace with an alternate (continued)

rtsdemo - 'rts' replace patterns

 # rtsdemo - demo the 'rts' instrn (search/replace all entries in a table)
 #         - convert COBOL program reserved word 'name' to 'name1'
 #         - read COBOL program into a table, search/replace,& write table out
 #           (faster than using get/rep/put line by line)
 rop=r1     # Run OPtion r1 for outfile disposition prompt at EOF (vi, more,cat)
 was=a200000
 fili1=?tf/cobol1.cbl,typ=LST,rcs=128
 filo1=?tmp/$fili1,typ=LSTt,rcs=128
 @run
        opn    all                     open files
        rtbc1  fili1,a0(100),a0(100)   read file into memory table
 #      ===    option 'c1' bypasses any '# ' comment lines
 #
        rtsd   a0(100),a7(65),' name;',' name1;'  search/replace
 #      ===    option 'd' allows search table words ending w blank,comma,period
        wtbe   filo1,a0(100),a0(100)   write out modified program
        cls    all                     close files
        eoj                            end job

test file to demo rtsdemo

 ******* cobol1.cbl - dummy program to test uvcopy rptdemo,rtsdemo,rttdemo
 ******* modify old COBOL programs to allow for new compiler reserved words
 ******* Example - 'name' used in old COBOLs, reserved word in ANSI85
 ******* - our solution is to append '1' on such words
         name should be changed to name1
         name, should be changed to name1,
         name. should be changed to name1.
Note
  • you can run the demo job as follows:
 #1. Login as uvadm --> /home/uvadm

 #2. uvcopy rtsdemo,fili1=tf/cobol1.cbl,filo1=tmp/cobol1.cbl
     =======================================================

 #2a. uvcopy rtsdemo     <-- same as above (files default as shown above)
      ==============

 #3. cat tmp/cobol1.cbl  <-- display output file
     ==================    - observe search/replacements

output file AFTER rtsdemo

 ******* cobol1.cbl - dummy program to test uvcopy rptdemo,rtsdemo,rttdemo
 ******* modify old COBOL programs to allow for new compiler reserved words
 ******* Example - 'name' used in old COBOLs, reserved word in ANSI85
 ******* - our solution is to append '1' on such words
         name1 should be changed to name1
         name1, should be changed to name1,
         name1. should be changed to name1.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 8 (scan/replace) - scn,rep,mvu,sct,sst,tts,ttx,rpt,sta,sts,stt,rts,"rtt"

`rtt` - replace patterns in data table via search/replace table

rtt will search/replace in the specified portion of each entry in a table. For example, assuming you have a COBOL program loaded into memory (with rtb) you can perform search/replace within columns 8-72 of each entry via a 2nd table of search/replace patterns.

rtt data-table-entry,scan-area,search/replace-entry,search-length

    rtt   a0(80),a7(65),b0(60),b0(30)  <-- search/replace data table in area 'a'
    skp=  match                            with search/replace tbale in area 'b'
          op1 - defines first entry in table
              - starting position & length of each entry
              - table must be ended by '~~' 1st 2 bytes or null 1st byte
              - op1 may specify a register to hold the starting displacement
          op2 - defines portion of each entry to scan
              - op2 may specify a register to hold the ending displacement
          op3 - defines search/replace table area & total entry length
                (length of search pattern + replace pattern + possible extra)
              - search pattern length determined by 1st tilde '~'
          op4 - defines search pattern length,
              - replace pattern assumed to follow & equal length
              - replacement pattern length determined by 1st tilde '~'
condition code
  • set equal if any replacement made (else unequal)

instruction ctr#1 ($ci1) - will hold count of replacements made

registers - if op1 register NOT coded

rgstr 'u'
  • dsplcmnt to base of entry with matching pattern from the base of the table area
  • dsplcmnt to the '~~' EOT entry if no match found
rgstr 'w'
  • dsplcmnt to matching data within matching entry
  • zero if nomatch found
rgstr 'x'
  • total dsplcmnt to matching pattern from 1st entry scanned (rgstr 'u' + rgstr 'w')

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rtt" - scan a table for a pattern & replace with an alternate (continued)

registers - if op1 register IS coded

op1 rgstr
  • will be incremented by the dsplcmnt to the base of matching entry so op1 rgstr will point to matching entry within entire area (not just from begining of last rtt instruction)
  • allows for repeated scans down a memory table (ensure rgstr is cleared before 1st scan)

rgstr 'u' & 'w' - same as above (op1 rgstr not coded)

 rgstr 'x' = (rgstr 'u' + rgstr 'w' + op1 rgstr initial value)
           - so rgstr x will point to matching entry within entire area

options - for rtt instruction

a1
  • ignore lead blank in search pattern if at 1st byte of op1
a2
  • allow for adjacent patterns with leading & trailing blank
  • following adjacent patterns would otherwise be missed
  • backs up 1 after replacement if trailing blank on search pattern to allow trailing blank to match leading blank of next pattern
b
  • multi-blank bypass (use when you need > 1 leading blank)
c1
  • replace matches only if in 1st column of op1
d
  • allows ';' to match blank,period,comma,semicolon,or right paren if ';' in replacement, restore the actual char saved from match
p
  • activates special pattern match characters
q1
  • inhibit replacements within single quotes
q2
  • inhibit replacements within double quotes
r1
  • replace 1st match only (ignore subsequent matches)
v1
  • expand uvcopy internal $symbols
  • op1 area must be large enough to hold the expanded values of $symbols
Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rtt,sys instructions if option v2 present (option v2 no longer required).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"rtt" - scan a table for a pattern & replace with an alternate (continued)

rttdemo - demo 'rtt' instrn

 # rttdemo - demo the uvcopy 'rtt' instrn
 #         - search/replace data table via 2nd table of search/replace patterns
 #         - by Owen Townsend, UV Software, November 2009
 # - read COBOL program into a table in area 'a'
 # - read search/replace table into area 'b' (reserved word fixes)
 # - execute 'rtt' to apply search/replace table
 # - write COBOL program table to the output file
 rop=r1     # Run OPtion r1 for outfile disposition prompt at EOF (vi, more,cat)
 was=a200000b8000   # increase areas a & b
 fili1=?tf/cobol2.cbl,typ=LST,rcs=128
 fili2=?tf/cnvcob9.tbl,typ=LST,rcs=128
 filo1=?tmp/$fili1,typ=LSTt,rcs=128
 @run
        opn    all                     open files
        rtb    fili1,a0(100),a0(100)   read COBOL prgm into table in area 'a'
        rtbc1  fili2,b0(80),b0(80)     read search/replace table into area 'b'
 #      ===    option 'c1' bypasses any '# ' comment lines
 #
        rttd   a0(100),a7(65),b0(80),b0(30)  apply s/r table
 #      ===    option 'd' allows search table words ending w blank,comma,period
        wtbe   filo1,a0(100),a0(80)    write out modified program
        cls    all                     close files
        eoj                            end job

 uvcopy rttdemo,fili1=tf/cobol2.cbl,fili2=tf/cnvcob9.tbl,filo1=tmp/cobol2.cbl
 ============================================================================

 uvcopy rttdemo   <-- same as above (files default as shown above)
 ==============

demo search/replace table

 # cnv/cnvcob9.tbl - search/replace table to test rptdemo,rtsdemo,rttdemo
 #      - modify old COBOL prgms to allow for new compiler reserved words
  printer;~~~~~~~~~~~~~~~~~~~~~ printer1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  name;~~~~~~~~~~~~~~~~~~~~~~~~ name1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  row;~~~~~~~~~~~~~~~~~~~~~~~~~ row1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  col;~~~~~~~~~~~~~~~~~~~~~~~~~ col1;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test data file (dummy COBOL program)

 ******* cobol2.cbl - dummy program to test uvcopy rptdemo,rtsdemo,rttdemo
 ******* modify old COBOL programs to allow for new compiler reserved words
 ******* - via search/replace table ctl/cnvcob9.tbl
         printer1 should be changed to printer1
         name1 should be changed to name1
         row1, should be changed to row1,
         col1. should be changed to col1.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - "sqz", sqf, jus, cnt, ins, ctr

`sqz` - squeeze out occurrences of the op2 character from op1

    sqz    b0(80),' '       - squeeze all blanks in op1
    sqzc1  b0(80),' '       - squeeze multi-blanks to 1 blank
                              (option c1 leaves 1 between words)
    sqzc2l2  h0(80),' '     - squeeze to 2 blanks between words
                              & also leave 2 blanks at begin op1
    sqzr   f40(20),' ','0'  - squeeze right (vs default left)
                            - replaces blanks on right with zeros on left
                            - the op3 fill character defaults to blank
                              when not specified (as on above examples)
                            - the 'mvn' might be better for converting
                              character fields to numeric since mvn would
                              also strip out all nonnumeric characters

sqz options

c#
  • specifies the no of fill chars to leave between words (fill char is op3 which defaults to blank when unspecified)
c0
  • default is none (squeeze all)
c1
  • would leave 1 (normal)
l#
  • the no of fill chars to leave on the left side of op1
l0
  • default is none (squeeze flush left)
l1
  • would leave 1 blank at the begining of the op1 area
l2
  • would leave 2 blanks, etc
 l99- special meaning
    - leave the number of left hand fill characters as is
      & squeeze only the right hand remainder of the op1 area
      (from the existing left hand non-fill character)
r
  • squeeze right (vs default left)
a1
  • If the byte preceding the op1 area is non-blank then copy data up to the next blank+1 & squeeze from that point on (this option ignored if the area displacement is 0)
  • for example if area b is:
      b0123456789012345678901234567890
       abcd efg hijkl   mnop    qrstu   <-- area 'b' before sqzc1a1
       sqzc1a1 b10(60),' '              <-- squeeze a1 example
       abcd efg hijkl mnop qrstu        <-- area 'b' after sqzc1a1
     Since prior byte b9(1) is nonblank, we copy up to next blank before
     squeezing multiple blanks to 1 (due to option 'c1')

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - "sqz", sqf, jus, cnt, ins, ctr

register x (set by sqz)

condition code (set by sqz)

Condition Code set '=' if op1 all blank

Condition Code set '>' if ny data present

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - sqz, "sqf", jus, cnt, ins, ctr

`sqf` - squeeze multiple contiguous fields & blank fill at the end

     sqf   b0(30),6            - squeeze out any blank fields from the
                                 six 30 byte fields in area b (b0-b180)
                               - might be multi-line name & address
     sqf   b0(30),6,'*'        - would squeeze out any all '*' fields
                                 replacing with blank fields at end
     sqf   c0(10),'-- void --' - squeeze out any '-- void --' fields
condition code
  • set equal if all fields are blank (or match op3)
register 'x'
  • set to the 1st blank field (or match field) in result
counter $ci1
  • will hold the no of significant fields in the result
option 'r'
  • squeeze fields right (vs default left)
option 'd1'
  • remove duplicate (non-blank) fields
  • duplicate fields are 1st set to op3 (usually blanks) which are then squeezed out & non-op3 fields moved up

sqf example

     sqfd1 d0(10),5            - squeeze out any blank fields from the
                                 from the 6 10 byte fields in area 'd'
                               - option 'd1' removes duplicated field3
             111111111122222222223333333333444444444455555555556666666666
 before sqf: <-field1->          <-field3->          <-field5-><-field3->
 after  sqf: <-field1-><-field3-><-field5->

sqfr example

     sqfr  d0(10),5            - squeeze right (vs default left)
             111111111122222222223333333333444444444455555555556666666666
 before sqf: <-field1->          <-field3->          <-field5->
 after  sqf:                               <-field1-><-field3-><-field5->
Note
  • the sqf instruction is often used to process Name & Address fields.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - sqz, sqf, jus, "cnt", ins, ctr

`cnt` - count the number of op2 patterns in the op1 area

The count will be stored in instruction counter #1 ($ci1)

     cnt   a0(80),','           count number of ',' commas
     cmn   $ci1,10              at least 10 ','s for valid record ?
     skp<  err1
     cnt   a0(80),'cats'        count no of cats in area a (alley)
     skp=  dogs                 cc set = if 1 match or > if 2 or more
     skp=> dogs                 (use => to test for 1 or more matches)
     cntp  b0(100),'@#@'        count alpha+number+alpha patterns
     cnt   b0(80),<x'20'        count no of bytes < a space
                                (allowed if no option 'p' & op2 lth = 1)
 Sets cc = if exactly 1 occurrence found
         > if more than 1 found
         < if none found
 register x - holds the displacement in op1 of the 1st match to op2
          y - holds the displacement in op1 of the last match to op2
          u - holds the displacement in op1 of the 1st non-blank
          v - holds the displacement in op1 of the last non-blank
option 'c2'
  • counts various character types in counters 2 thru 13
  • ONLY if option 'c2' specified
        $ci1  = the count of op2 patterns
        $ci2  = alpha
        $ci3  = lower case alpha
        $ci4  = upper case alpha
        $ci5  = numeric
        $ci6  = alphanumeric
        $ci7  = printable
        $ci8  = printable but not blank
        $ci9  = punctuation
        $ci10 = control < x'20' & > x'7e'
        $ci11 = single quotes
        $ci12 = double quotes
        $ci13 = words

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"cnt" options continued

 option 'g' - option 'g' modifies the fixed op2 length specified
         g1 - length of op2 search pattern determined by first NULL
         g2 - length of op2 search pattern determined by first TILDE
         g4 - length of op2 search pattern determined LAST NON-BLANK
         g7 - 'g7' (1+2+4) searches for all 3 situations in that order
option 'i'
  • case insensetive
  • translates op1 to all lower case (in working storage) so you should code your op2 (usually a constant) in lower case
option p
  • invokes the pattern match characters
option p1
  • inhibit pattern match for 1st byte (use direct compare)
option p2
  • inhibit pattern match for 1st 2 bytes, etc... p2,p3,...p99

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - sqz, sqf, jus, cnt, "ins"

`ins` - insert op2 data prior to op1 data

       ins    op1dsp(lth),op2dsp(lth)   - instruction format
       ins    b10(30),'19'              - insert '19' in cols 11-12
                                          & shift cols 11-38 over to 13-40
 abcd------961231--------------------wxyz  - before
 abcd------19961231--------------------wx  - after
Note
  • if the original record were 40 bytes long, the above instruction would truncate columns 39-40. To retain these columns you need make the length at least 32 bytes, but better the max field 40.

The 'ins' instruction is useful when used with a register, for example' suppose we wanted to insert 'pre-' in front of every occurrence of the word 'processing' (note leading/trailing blanks below)

       scn    b0(80),' processing '
       skp!   1
       ins    bx1(80),'pre-'         - insert 'pre-' 1 higher than rgstr x

The above illustrates the 'ins' instruction, but is not the best way to perform the task of converting all 'processing' to pre-processing.

        rep   b0(80),' processing ',' pre-processing '

The 'rep' instruction would be better because it would convert multiple occurrences on the same line (& only requires 1 instrucit on).

options for 'ins'

option g1
  • insert length determined by 1st null
option g2
  • insert length determined by 1st tilde
option g4
  • insert length determined by 1st blank

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 9 (squeeze-insert) - sqz, sqf, jus, cnt, ins, "ctr"

`ctr` - center data within the op1 area

    ctr  op1start(op1length)    <-- instruction format
    ctr  h0(80),' '             <-- center data in 1st 80 bytes of area h

Current data start & end is determined by scanning for 1st byte > space from the left & from the right of the op1 area.

Op2 is the new fill character, normally a space, but could be other characters such as '-'.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - "fix", var, ,dlm, und, swp, dat

`fix` - convert variable field format to fixed length fields

fix 1st-out-field,input,#fields,delimiter[,fillchar] - format

    fix   b0(20),a0(80),6,'","'
  • converts the variable fields in area a to fixed fields in b
  • input fields are separated by "," delimiters
  • output will be 6 x 20 byte fields, blank filled on right
  • the fill-character (op5 not specified) defaults to a blank
    fix   c0(50),a0(100),8,'|','~'    <-- '|' pipe delims & '~' tilde fill
  • convert 8 '|' pipe delimited fields from a0(100) to 8 * 50 byte fields in c0(50),C100(50),etc to c350(50)
  • '~' tilde fill on right side of each 50 byte data field

condition code will be set = if at least 1 sepstring found

instrn ctr $ci1
  • count number of separators found
instrn ctr $ci2
  • count number of data (non-blank) fields
instrn ctr $ci3
  • field# of blank field following last data (nonblank) field
register 'x'
  • points to 1st blank field following last nonblank field
  • points to 1st byte beyond op1 if all fields non-blank
option b1
  • store 1 blank prior to the data in each field
option b2
  • store 1 blank after the data in each field
option b3
  • store 1 blank before & after the data in each field
option q1
  • inhibit recognizing separator pattern within single quotes
option q2
  • inhibit recognizing separator pattern within single quotes
option q3
  • inhibit separator patterns within single &/or double quotes
option p1
  • inhibit recognizing separator pattern within (parens)
option s1
  • squeeze ALL leading blanks prior to the data in each field
option t1
  • clear fields+1 to all '~' tildes
 option r1/r2 - for 3 byte delimiters formatted with double or single quotes
              - 2nd byte could be any character (comma, semicolon, pipe, etc)
 option r1 - 1st & 3rd byte single quotes (ex: ',' ';' '|' etc)
 option r2 - 1st & 3rd byte double quotes (ex: "," ";" "|" etc)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"fix" - convert variable field format to fixed length fields (continued)

'fix' Example#1 - var2fix1

 # var2fix1 - uvcopy Parameter File from UVSI stored in: /home/uvadm/pf/demo/...
 # var2fix1 - convert spreadsheet export format to fixed field length records
 #          - to transfer data from spreadsheets to mainframe/cobol jobs
 #
 # uvcopy var2fix1,fili1=tf/datavar2,filo1=tmp/datafix2  <-- execute demo var2fix1
 # ====================================================
 # uvcopy var2fix1  <-- same, default files on fili1=... & filo1=... below
 #
 #                 ** sample I/O - tf/datavar **
 #
 # 24595,"Bill Gates","INV2273",000000100,"000245.00","0000024,500.00"
 # 25669,"Thomas Watson","INV4000",000000200,"000801.50","0000160,300.00"
 # 30144,"Presper Eckert","CR8002",-00000100,"000149.00","-000014,900.00"
 #
 # 24595     Bill Gates          INV2273   000000100 000024500 00000002450000
 # 25669     Thomas Watson       INV4000   000000200 000080150 00000016030000
 # 30144     Presper Eckert      CR8002    -00000100 000014900 -0000001490000
 #
 #Jun23/2019 - using option r2 on 'fixr2' to demo "," delimited fields
 opr='$jobname - convert spreadsheet export format to fixed field length records'
 fili1=?tf/datavar2,rcs=80,typ=LST
 filo1=?tmp/datafix2,rcs=80,typ=LST
 @run
       opn   all
 loop  get   fili1,a0
       skp>  eof
 #
       fixr2 b0(20),a0(80),6,'","'        convert to fixed via '","' delims
 #     ===========================        output fields 20 bytes apart in b
       mvc   c0(5),b0                     cust# to output cols 1-5
       mvc   c10(20),b20                  cust name to cols 11-30
       mvc   c30(10),b40                  inv# to 31-40
 # use mvn instrn for the $amt fields to ensure rt adjust & zero left fill
       mvn   c40(-9z),b60(-12z)           quantity to 41-49
       mvn   c50(-9z),b80(-12z)           unit price to 51-59
       mvn   c60(-14z),b100(-16z)         extended amount to 61-69
       put   filo1,c0                     write out the fixed lth record
       skp   loop
 eof   cls   all
       eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"fix" - convert variable field format to fixed length fields (continued)

fix Example#2 - test delimiters within fields

This example illustrates that option r1/r2 allow delimiters within fields:

  1. Quotes (single or double depending on options r1/r2) can occur within character or numeric fields since end of field determined by 2nd character.
  2. The 2nd character can occur within character fields since end of field determined by 1st & 2nd chars ", or '; in our sample jobs testfixr1 & testfixr2
 # testfixr2 - test fix instrn, option r2 ","  Jun22/2019
 # option r2 - op4 1st & 3rd chars must be double quote
 #           - 2nd char could be anything else "|" ";" etc
 #           - see separate job testfixr1 option r1 for ';' etc
 rop=r1x8
 filo1=tmp/$jobname,rcs=100,typ=LSTt
 lod=b0(100)
 "ABCD",1234,"EFGH",6789,"MNOP"
 "ABCD",1234,"EFG"H",678"9,"MNO,P"
 #----- 2 inputs records above, outputs will be stored below -----
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 @run
        opn     filo1
        fixr2   b300(10),b000(80),8,'","'
        fixr2   b400(10),b100(80),8,'","'
        wtbx1   filo1,b0(100),b0(100)
        cls     filo1
        eoj
 #------------ messages displayed at EOJ (by wtbx1) ------------------
 # "ABCD",1234,"EFGH",6789,"MNOP"
 # "ABCD",1234,"EFG"H",678"9,"MNO,P"
 #------- 2 inputs records above, outputs will be stored below -------
 # ABCD      1234      EFGH      6789      MNOP
 # ABCD      1234      EFG"H     678"9     MNO,P
 #----------------------------------------------------------------------------
 # 2nd input illustrates delimiters can occur within fields:
 # - "EFG"H", - quotes OK in "character fields" - since charfields ended by ",
 # -   123"4, - quotes OK in   numeric fields   - since numfields  ended by ,
 # - "MNO,P", - commas OK in "character fields" - since charfields ended by ",

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"fix" - convert variable field format to fixed length fields (continued)

'fix' Example#2 using op5 fill char

        fix    h0(20),$reply,6,':','~'   - convert msg reply to a table

If the input were: filename1:file2:thirdfile;etc The output would be suitable for searching with sct (search table):

 filename1~~~~~~~~~~~
 file2~~~~~~~~~~~~~~~
 thirdfile~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~

Example#2a - fill char with option b3

        fixb3  h0(20),$reply,6,':','~'   - convert msg reply to a table
  filename1 ~~~~~~~~~
  file2 ~~~~~~~~~~~~~
  thirdfile ~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, "var", dlm, und, swp, dat

`var` - convert multi fixed length fields to a variable length string

     var   c1(79),a0(20),6,'","'

Please see demo job 'fix2var1' listed on next page to convert fixed field records to the variable format required to import to a spreadsheet. Here 1st record I/O:

 24595     Bill Gates          INV2273   000000100 000024500 00000002450000 <-- Input
 "24595","Bill Gates","INV2273","000000100","000245.00","0000024,500.00"   <-- Output

options

f2
  • remove any leading blanks in each field
b1
  • leave 1 blank if field is all blank (no data)
  • prevents a 'null' field which might not be desired if data loaded into a database table
b2
  • inhibit removal of trailing blanks in each field
  • default is to leave any leading blanks & remove any trailing blanks
r1
  • replace any existing delimiters (op4) with op5 (blank default)
r2
  • remove any trailing separators (after last field with data)

counters

$ci1 - count of significant fields

$ci2 - count of null fields (not yet implemented)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, "var", dlm, und, swp, dat

'var' Example#1 - fix2var1

 # fix2var1 - uvcopy Parameter File from UVSI stored in: /home/uvadm/pf/demo/
 # fix2var1 - convert fixed field length records to spreadsheet import format
 #          - transfer data from mainframe/cobol applications to spreadsheets
 #
 # uvcopy fix2var1,fili1=tf/datavar2,filo1=tmp/datafix2  <-- execute demo job
 # ====================================================
 # uvcopy fix2var1  <-- same, default files on fili1=... & filo1=... below
 #
 #               **  sample I/O - tf/datafix2 **
 #
 # 24595     Bill Gates          INV2273   000000100 000024500 00000002450000
 # 25669     Thomas Watson       INV4000   000000200 000080150 00000016030000
 # 30144     Presper Eckert      CR8002    -00000100 000014900 -0000001490000
 #
 # "24595","Bill Gates","INV2273","000000100","000245.00","0000024,500.00"
 # "25669","Thomas Watson","INV4000","000000200","000801.50","0000160,300.00"
 # "30144","Presper Eckert","CR8002","-00000100","000149.00","-000149,000.00"
 #
 #Jun23/2019 - create file for var2fix1 demo 'fixr2' option r2 for "," delimiters
 opr='$jobname - convert fixed field length records to spreadsheet import format'
 fili1=?tf/datafix2,rcs=80,typ=LST
 filo1=?tmp/datavar2,rcs=80,typ=LST
 @run
       opn   all
 loop  get   fili1,a0                    get next record
       skp>  eof                         (cc set > at EOF)
       clr   b0(120),' '                 init area b to all blanks
 # spread out fields into area 'b' 20 bytes apart - preparation for 'var'
       mvc   b0(5),a0                    1 cust#
       mvc   b20(20),a10                 3 cust name
       mvc   b40(10),a30                 4 inv# to
       mvc   b60(9),a40                  5 quantity
       mvc   b80(9),a50                  6 unit price
       mvc   b100(14),a60                7 extended amount
 # convert fixed fields to variable delimited fields
       var   c1(79),b0(20),6,'","'       convert to variable format
 #     ===========================
 # now insert opening '"' on 1st field & remove extra ',"' from last field
       mvc   c0(1),'"'                   insert opening quote for 1st field
       rep   c0(80),'," ',' '            remove extra ," form last field
       put   filo1,c0                    write out the variable lth record
       skp   loop
 eof   cls   all
       eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, var, "dlm", und, swp, dat

`dlm` - convert Fixed-Field to "delimited","format"


      dlm   b0(80),a0(20),4
      =====================
      - converts 4 20 byte fields a0(20), a20(20), a40(20), a60(20),
        to b0(80), inserting delimiters & removing trailing blanks.

      dlmn1 c0(100),b0(100),5  <-- option 'n1' inhibits '"'s on numeric fields
      =======================

You usually need to move the component fields to a contiguous set of maximum length same size fields, before executing the 'dlm' instruction. Here is a sample job taken from 'SQLdemo.doc#9A3'

 # delimcust1 - "delimit", customer name & address for SQL demo examples
 #            - by Owen Townsend, UV Software, November 2008
 #            - see www.uvsoftware.ca/sqldemo.htm
 #
 # uvcopy delimcust1  <-- execute this job (files default as shown below)
 # =================    - sample I/O for 1st record in file below:
 #
 # cust# 01-06, name 08-29, address 31-52, city 54-69, province 71-72
 #          1         2         3         4         5         6         7
 # 123456789012345678901234567890123456789012345678901234567890123456789012
 #
 # 130140 EVERGREEN MOTORS LTD.  1815 BOWEN ROAD        NANAIMO          BC
 #
 # 130140,"EVERGREEN MOTORS LTD.","1815 BOWEN ROAD","NANAIMO","BC"
 #
 fili1=?dat1/customers,rcs=80,typ=LST
 filo1=?dat1/customers.txt,rcs=80,typ=LSTt
 @run
        opn     all
 #
 # begin loop to process each record - until EOF
 man20  get     fili1,a0            get next record
        skp>    eof                 (cc set > at EOF)
 # store fields 100 bytes apart for 'dlm' insert ","
        mvc     b0(6),a0            cust#
        mvc     b100(22),a7         name
        mvc     b200(22),a30        address
        mvc     b300(16),a53        city
        mvc     b400(2),a70         province
        dlmn1 c0(100),b0(100),5     delimit 5*100 fields from area b to c
 #      =======================
        put     filo1,c0            write output record
        skp     man20               repeat loop
 #
 # EOF - close files & end job
 eof    cls     all
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, var, dlm, "und", swp, dat

`und` - convert "delimited","format" to Fixed-Field


      und   c0(20),b0(80),4
      =====================
      - converts "delimited","fields", in b0(80) to 4 * 20 byte fields
        c0(20), c20(20), c40(20), c60(20)
        removing delimiters & blank filling on the right side of each field

sample undelimit job

 # undlmsales1 - undelimit "customer","sales" test/demo file
 #             - by Owen Townsend, UV Software, November 2008
 #             - see www.uvsoftware.ca/sqldemo.htm
 #
 # uvcopy undlmsales1  <-- execute this job (files default as shown below)
 # ==================
 #
 # 130140,21,2004-08-02,"INV1120","HAM001",000010,00012.00,0000120.00 <-- input
 #
 # 130140 21 2004-08-02 INV11201 HAM001 000010 00012.00 0000120.00    <-- output
 #
 # cust# 01-06, salesman 08-09, date 11-20, inv# 22-29, product 31-36 <-- layout
 # quantity 38-43, unit price 45-52, extended amount 54-63
 #
 fili1=?dat1/sales.txt,rcs=80,typ=LST
 filo1=?tmp/sales.fix,rcs=64,typ=RST
 @run
        opn     all
 #
 # begin loop to process each record - until EOF
 man20  get     fili1,a0            get next record
        skp>    eof                 (cc set > at EOF)
 #
        und     b0(100),a0(100),8   undelimit 8 fields from area a to b (8*100)
 #      =========================
 # move data from fixed max lth fields to desired output layout (from b to c)
        mvc     c0(6),b0            cust#
        mvc     c7(2),b100          salesman
        mvc     c10(10),b200        date
        mvc     c21(8),b300         invoice#
        mvc     c30(6),b400         product code
        mvc     c37(6),b500         quantity
        mvc     c44(8),b600         unit price
        mvc     c53(10),b700        extended amount
        put     filo1,c0            write output record
        skp     man20               repeat loop
 #
 # EOF - close files & end job
 eof    cls     all
        eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, var, dlm, und, "swp", dat

`swp` - swap left & right sides of data in op1 based on op2 separator

    swp  b20(30),','           - swap left & right sides of data in 21-50
                                 based on a comma separator
                                 sample input:  Townsend, Owen
                                       output:  Owen Townsend
    swp  b20(30),'","',' / '   - swap left & right sides based on ","
                                 & insert a ' / ' as the new separator
                                 sample input:  Townsend","Owen
                                       output:  Owen / Townsend
    swpp  c0(40),'%'           - swap left & right sides of c0(40)
                                 based on the 1st punctuation character
                               - the '%' represents any punctuation
                               - option 'p' (4th byte of 'swpp')
                                 is required to activate special patterns
    swp    b0(80),<=' '        - swap on the 1st byte < or = to a space
                                 (allowed if no option 'p' & op2 lth = 1)
option p
  • invokes pattern match characters
  • allowing @=any alpha, #=any numeric, etc
option p1
  • inhibit pattern match for 1st byte (use direct compare)
option p2
  • inhibit pattern match for 1st 2 bytes, etc... p2,p3,...p99
        l1 - inhibit the automatic left justify of the original right
             hand data into the new left hand side of op1

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 10 (conversion) - fix, var, dlm, und, swp, "dat"

`dat` - convert dates between: calendar,julian,& days-since-1900

  1. calendar ccyymmdd - cc will default to system date century if not present (00 or only 6 digits)
  2. Julian ccyyjjj - cc will default to system date century if not present
  3. days since 1900 nnnnn - number of days since 1900

Days since 1900 most useful for adding to, subtracting from,or comparing calendar dates. Convert to days since 1900, perform the addition or subtraction,& then convert back.

The operand types are determined by options appended to the 'dat' instrn The types are coded as c=calendar, j=Julian, n=days since 1900. the input type (operand2) is coded in the 4th byte and the output type (operand1) is coded in the 5th byte.

datcj
  • calendar to julian
datcn
  • calendar to days since 1900
datjc
  • julian to calendar
datjn
  • julian to days since 1900
datnc
  • days since 1900 to calendar
datnj
  • days since 1900 to julian

dat stores alpha date at $adate y350(17)

The 'dat' instruction also stores the alphanumeric date in uvcopy working storage area 'y' at y350(17) or symbolic date $adate.

 $adate y350(17) - # Day Mth dd yyyy
                   1 Mon Nov 27 1995  - for example
        y350(1)  - day# of week coded 0-6 for Sunday-Saturday
        y352(3)  - day of week (Sun,Mon,Tue,Wed,Thu,Fri,Sat)
        y356(3)  - month (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)
        y310(2)  - day of month '01'-'31'
        y313(4)  - year 1900-9999

'dat' instruction examples


 #1. datcj  b20(7),a20(6)
     =====================
            - convert calendar date (yymmdd) from cols 21-26 of area a
              to julian (ccyyjjj) in cols 21-27 of area b
            - the century will be supplied from the system date

 #2. datcc  b20(5p),a20(6)
     =====================
            - convert calendar date (yymmdd) from cols 21-26 of area a
              to calendar (ccyymmdd) PACKED in cols 21-25 of area b

 #3. datcc  b20(4b),a20(6)
     =====================
            - convert calendar date (yymmdd) from cols 21-26 of area a
              to calendar (ccyymmdd) BINARY in cols 21-24 of area b

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"dat" - convert dates between any 2 of: calendar, julian,& days since 1900

'dat' examples (continued)

 4a. datcn   $ca1,a20(8)    - convert calendar date to days since 1900
 4b. add     $ca1,180       - add 180 days
 4c. datnc   a20(8),$ca1    - convert back to calendar date
 5a. datcn   $ca1,a20(8)    - convert calendar date to days since 1900
 5b. datcn   $ca2,$date1(8) - convert system date to days since 1900
 5c. sub     $ca2,$ca1      - subtract to get age in days
 5d. datnc   c0(8),$ca2     - convert back to calendar format
 5e. mvc     a30(6),c2(6)   - move age in yrs/mths/days back to record

dat ex#6 - store alpha date in page heading

Suppose we want to move the current date into a page heading in area h cols 61-71 'Mth dd yyyy' (drop day# of week)

      -----   ---------------
      datcc   c0(8),$date1(8)
      mvc     h0(11),$adate+6
      -----   ---------------
  1. op1 of 1st instrn (1st 8 bytes of area c) is not used. We are depending on the fact that all 'dat' instructions store the alpha date in $adate y350(17).
  2. The 2nd instruction op2 '$adate+6' addresses the 'Mth Day ##' since the '+6' bypasses the day# & alpha day of week

    dat ex#7 - determine weekend from date

Some applications need to know whether dates fall on a week-end or not. For example, suppose we are reading records into area 'a' that have a date (yyyymmdd) in bytes 80-87 & we wish to store a flag 'W' in byte 88 if weekend.

      -----  ----------
      datcn  $ca0,a80(8)       convert calendar date to days since 1900
      tst    $adate(1),'06'    Sat or Sun ?
      skp!   1
      mvc    a88(1),'W'        yes - store 'W'eekend flag
      -----  ----------
  1. op1 ($ca0) of the 'datcn' instruction is not used.
  2. 'datcn' always stores additional info in $adate (y350(17). See layout above.
  3. 1st byte of $adate is coded '0'-'6' for Sunday-Saturday
  4. the 'tst' instruction sets the condition code = if there is a match in op2

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

"dat" - convert dates between any 2 of: calendar, julian,& days since 1900

calcdate1 - example of 'dat' instruction

 # calcdate1 - add or subtract specified no of days to/from calendar date yyyymmdd
 #             & write result to subdir tmp/date1_$uops2 ($uops2 is 'b1' below)
 #          - by Owen Townsend, UV Software, Dec20/2017
 #
 # uvcopy calcdate1,arg1=20171220,uop=b1,filo1=tmp/date1_b1
 # ========================================================
 # example#1 - subtract 1 from Dec 20/2017 (arg1=20171220)
 #
 # uvcopy calcdate1,uop=b1,filo1=tmp/date1_b1
 # =========================================
 # example#2 - subtract 1 from the current date (default if arg1 unspecified)
 #  - if current date is 20171220, result would be 20171219
 #  - if current date is 20180101, result would be 20171231
 #
 # Also appends date in other formats, for example:
 #          1         2         3
 # 123456789012345678901234567890
 # 20171231  1 Mon Jan 31 2017
 #
 opr='$jobname - add/subtract days to/from calendar date yyyymmdd (default current)'
 opr='uop=q1a00b00 - option defaults'
 opr='      a99    - would Add 99 days & convert back to yyyymmdd'
 opr='         b99 - would suBtract 99 days & convert back to yyyymmdd'
 uop=q1a0b0        # option defaults
 rop=r1            # prompt for outfile disposition (vi, more, cat, etc, or null)
 filo1=tmp/date1_$uops2,rcs=80,typ=LSTt
 @run
         opn     filo1                  open output file
         mvn     a0(8),$arg1(8)         presume arg1 spcfd ?
         skp>    1
         mvc     a0(8),$date1           no - use current date
         datcn   $ca1,a0(8)             convert Calendar date to Number of days since 1900
 # if option a - Add days, if option b - suBtract daye
         cmn     $uopba,1               option 'a' specified ?
         skp<    1
         add     $ca1,$uopba            add days
         cmn     $uopbb,1               option 'a' specified ?
         skp<    1
         sub     $ca1,$uopbb            subtract days
 # convert back to calendar & write out
         datnc   b0(8),$ca1
         mvc     b10(17),$adate
         put     filo1,b0(80)
         cls     filo1
         eoj

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

calendar1 - print calendar between 2 dates


 uvcopy calendar1,uop=b20180101e20180131 <-- create calendar for Jan 2018
 =======================================   - options b/e = begin/end dates

 uvcopy calendar1   <-- defaults to printing calendar for current month
 ================     - sample shown below

 Calendar, Julian,   DaysSince1900,  Alpha-date
 ===============================================
 20180101  2018001   043100    1 Mon Jan 01 2018
 20180102  2018002   043101    2 Tue Jan 02 2018
 20180103  2018003   043102    3 Wed Jan 03 2018
         ----- 26 lines omitted -----
 20180130  2018030   043129    2 Tue Jan 30 2018
 20180131  2018031   043130    3 Wed Jan 31 2018

 vi $UV/pf/demo/calendar1   <-- see coding for calendar1
 ========================     - only 25 instructions

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 11 (special) - "sys", lok, pop, fxt, env, evs, evt, evs

`sys` - issue system commands - call the shell to execute op1 string

     sys    '----shell command----'    - op1 may be a constant
     sys    op1dsp(lth)                  or an address
     sysv1  'lp -onobanner $filo1'     - call the spooler to print
                                         the physical file indicated
                                         by the logical file '$filo1'
condition code
  • set to the return status of the UNIX command executed
  • zero usually success, non-zero is failure
RULES
  • op1 specifies the command arguments as they would be entered for the shell on the unix command line
  • any logical filenames ($fili1-8,$filo1-8,$filr1-8,$fild1-8) will be replaced by the corresponding physical filenames if option 'v1' is specified (see below)
  • Prior to June/99 sys expected just 'filo1' not '$filo1'

option 'v'

 option v1  - replace any $symbols with data using $symtbl & area q
        v2  - replace any ${symbols} with data from env-vars
        v4  - disable stop replace on 1st space, enable endrep on tilde
        v8  - inhibit stop on '.' period
        v16 - override stop replace options v4 (1st space) or v8 ('.' period)
            - use replace length from $symbol table
            - see 'uvsoftware.ca/uvcopy2.htm#B7'
 Note - options are binary, you must code v1 + v4 or v8 as desired (v5 or v9)
      - 'v13' would end $SYMBOL on '~' & replacement would not stop on '.'

option v expansion examples

filo1=tmp/xref.report

    sysv1   'lp $filo1'
    sysv1   'lp tmp/xref.report'      <-- '$filo1' replaced with actual
    sys     'echo "user=${LOGNAME}"'  <-- ${...} always expanded on all instrns
                                          (no options required)

Option 'v' was implemented in June/99 on: msg, mvf, rep, rts,& sys to control expansion of uvcopy $symbols & UNIX env-var ${symbols}

Note
  • ${symbols} are expanded on all functions and instructions as of Nov2002.
  • Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 11 (special) - "sys", lok, pop, fxt, env, evs, evt, evs

sys option 'w'

Option 'w' allows you to capture output from 'sys' into work area w1000-w9000, making it easier for you to examine the output (vs having to code your own .redirect to a file & read-back from the file).

Here is code to capture output of 'wc -l /etc/passwd' WITHOUT option 'w':

 fili2=/tmp/passwd_lines,typ=LSTt,rcs=128
     ...
     sys   'wc -l /etc/passwd >/tmp/passwd_lines'
     opn   fili2
     get   fili2,a0
     mvn   $ca1,a0(6)

Here is code to capture output of 'wc -l /etc/passwd' WITH option 'w':

     sysw3 'wc -l /etc/passwd'
     mvn  $ca1,$ci1
Note
  • sysw3 has options w1+w2=w3
option w1
  • redirect sys output to file for readback to workareas
  • store 9 lines max in w1000(100),w2000(100),...,w9000(100)
  • 9 words max from first line in w1100(100),w1200(100),...,w1900(100)
  • 9 words max from 2nd line in w2100(100),w2200(100),...,w2900(100) - - - - - etc - - - - -
  • 9 words max from 9th line in w9100(100),w9200(100),...,w9900(100)
option w3
  • also convert 1st line words w1100-w1900 to counters $ci1-$ci9
  • numerics in line1 word1 w1100(100) converted to ctr $ci1
  • numerics in line1 word2 w1200(100) converted to ctr $ci2, etc

work areas used by option w1

Option 'w1' stores up to 9 lines from sys output & isolates up to 9 words for each line. Here are the areas used:

w1000(100)
  • line1 as read (before word sep)
w1100(100)
  • line1 word1 - - - etc for word2-word8 of line1
w1900(100)
  • line1 word9
   - - - etc for line2-line8 - - -
w9100(100)
  • line9 word1 - - - etc for word2-word8 of line9
w9900(100)
  • line9 word9
 Option 'w2' converts numerics from words on 1st line to counters $ci1-$ci9:
 $ci1 - binary value of numerics in 1st word w1100(100) of 1st line w1000(100)
 $ci2 - binary value of numerics in 2nd word w1200(100) of 1st line w1000(100)
     - - - etc - - -
 $ci9 - binary value of numerics in 9th word w1900(100) of 1st line w1000(100)

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 11 (special) - "sys", lok, pop, fxt, env, evs, evt, evs

job to test sys instrn option 'w'

 # testsysw3 - test uvcopy sys instrn option w3 redirect output to w1000+'
 #           - by Owen Townsend, UV Software, Aug 24/2008
 #           - see sys instrn doc at www.uvsoftware.ca/uvcopy3.htm#sys
 #           - run as follows, no input files required
 #
 # uvcopy testsysw3
 # ================
 #
 @run
 man10  msg     '$jobname - test option w3 redirect sys output to w1000+'
        sysv1w3 'wc pf/adm/testsysw3'
        msg     'w1000(100)->',w1000(66)
        msg     'w1100(30)-->',w1100(30)
        msg     'w1200(30)-->',w1200(30)
        msg     'w1300(30)-->',w1300(30)
        msg     'w1400(30)-->',w1400(30)
        msgv1   'ci1=$ci1,ci2=$ci2,ci3=$ci3,ci4=$ci4,ci5=$ci5,ci6=$ci6'
        eoj

console output from testsysw3

 080824:182556:testsysw3: uvcopy ver=20080824 pf=/home/uvadm/pf/adm/testsysw3
 uvcopy DISAM ext=dat LNX L64  license=20080824V site=UV_Software
 $jobname - test option w3 redirect sys output to w1000+
 w1000(100)-> 19  76 697 pf/adm/testsysw3......................................
 w1100(30)-->19............................
 w1200(30)-->76............................
 w1300(30)-->697...........................
 w1400(30)-->pf/adm/testsysw3..............
 ci1=19,ci2=76,ci3=697,ci4=0,ci5=0,ci6=0

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

group 11 (special) - sys, "lok", pop, fxt, env, evs, evt, evs

`lok` - look-up a table of data (op1) for match to argument (op2)

    lok  table-entry,table-key,search-key,EOT-marker   - instrn format
    skp=                                               - cc = if found
op1 table-entry
  • length must define length of each table entry
op2 table-key
  • dsplcmnt(lth) may define just part of a table entry
op3 search-key
  • dsplcmnt(lth) defines the search argument
  • op3 length overrides op2 length (but op2 dsplcmnt important)
op4 EOT marker
  • optional, default is 2 '~' or 2 x'FF' in 1st 2 bytes but if op4 is specified it will be used (not restricted to 2 bytes)

The default lookup condition (when no option specified on the lok instruction) is to look for a match (same as lok=). Don't confuse with the = or ! conditions that might be coded on the skp_ instruction to test success/fail of the lookup.

 Option 'm' conditions (m1-m7) should be used on the lokm_ instruction to avoid
 this confusion. See option 'm' codes discussed on the next page --->

The data table might have been loaded by the 'lod' function, or by the 'rtb' (read table) instruction, or any other means.

example: 'lod' a table & 'lok' it up

 lod=m0(20)                     load table of 20 byte items
 T1:aaa=aardvarks
 T1:bbb=bumblebees
 T1:ccc=cats
 ~~~~~~~~~~~~~~~~~~~~
       ---
       lok   m0(20),m3(3),a0(3)   - look-up via 3 byte arg
       skp=  ok                   - condition code set = if found

registers

register 'x'
  • set to the displacement of the found entry (from search begin) or to the end of the table ('~~') if nofind
op1 register
  • if any register is coded in op1, the table search length is ADDED to that register

Option 'z1' may be used to clear the register on the 1st 'lok' & might be omitted on subsequent 'lok's down the same table. The following example will use register 'g' (vs default rgstr 'x'):

    lokz1  mg0(20),mg0(3),r0(3)   <-- 1st lok (option z1 clears rgstr g)
    skp=   xxx
    lok    mg0(20),mg0(3),r0(3)   <-- 2nd lok (w/o z1) continues search
    skp=   xxx

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'lok' - lookup conditions allowed

You may specify the type of lookup desired via symbols < = <= > or => or by option 'm' & digits 1,2,3,4,5,6,7.

  lok    lok    - default is to look for an exact match (=)
  lok=   lokm2    (may be coded but this is the default)
  skp=   skp=   - don't confuse the lok condition with the skp? test condition
  skp!   skp!   - can test for match found (=) or match NOT-found (!)

lok> lokm4 - looks down table for the 1st entry > than the argument lok=> lokm6 - looks down table for the 1st entry = or > than the argument

  lok<   lokm1  - looks down table for the 1st entry > than the argument
                  & then backs up to the preceding entry (except if 1st)
  lok<=  lokm3  - looks down table for the 1st entry > or = to the argument
                - if = entry found, register 'x' will point to it
                - if > entry found, register 'x' will be decremented to the
                  preceding entry (except if 1st)

Option m1-m7 is recommended since lok is usually followed by skp with a condition code & it is confusing if lok also carries a condition code.

       lokm4 m0(20),m3(3),a0(3)   - look for 1st entry > op3
       skp=  ok                   - condition code set = if desired entry found

'lok' resulting condition code (for skp?)

 cc set '=' (equal) if desired entry found,
            regardless of lookup mode (lok, lok=, lok=>, lok<, lok<=)
 cc set '!' (not equal) if desired entry not found
            the not equal could be '<' or '>' as follows:
            (usually do not need to make a distinction)
 cc set '<' if nofind due to end tbl marker '~~' reached
            or if op3 end tbl marker was specified & reached
 cc set '>' if nofind due to end tbl marker x'0000' reached
            might be used to distinguish max table area when looking up
            & adding entries to an area filled with tildes '~'s

table termination character

Normally the end of the table is signalled by the 1st entry found whose 1st 2 bytes are '~~' or whose 1st 2 bytes are null x'00' If operand 4 is specified, then the end of the table will be signalled by the 1st entry that matches op3 on the number of bytes specified by the length of op3.

         lok   m0(20),m0(3),a0(3),'~EOT'

This table lookup will be ended by the 1st entry encountered whose 1st 4 bytes match '~EOT'. This feature might be used when looking up binary tables where x'00' could occur, in Big Endian machines vs little Endian (Intel) machines.

Return to first page of:   this document    this library (librefs)    UV Software Home-Page

'lok' example in uvcopy jobs

 # uvhtm25 - copy HTML code (generated from UVSI text doc)
 #         - correcting excess space at end ordered lists - ID by </OL>
 #         - by Owen Townsend, UV Software, November 2009
 #         - called by script 'uvhtm2X' (see doc there)
 #
 # uvcopy uvhtm25,fili1=tmp1/htmlfile,filo1=tmp2/htmlfile
 # ======================================================
 # - search for  replacing 

on prior line with just 1
# #
  • --- documentation text ---

    <-- reduce to just 1
    # </OL> # # read HTML file into a table in area 'a' # - begin loop to search for </OL> # - search prior line for

    & replace with
    # - repeat search until no more </OL> found # write memory table to the output file # was=a8000000 # increase area 'a' to 8 meg, allowing 40,000 lines of 200 bytes fili1=?tmp1/html,typ=LST,rcs=256 filo1=?tmp2/$fili1,typ=LSTt,rcs=256 @run opn all open files rtb fili1,a0(200),a0(200) read HTML file into table in area 'a' mvn $ra,0 init register to base of table # # begin loop to search for replacing

    on prior line with
    # === man20 lok aa0(200),aa0(5),'</OL>' # === skp! man80 man22 mvn $rb,$ra save ptr to </OL> sub $rb,200 backup to prior line rep ab0(180),'

    ','
    ' add $ra,200 bypass </OL> line skp man20 repeat loop til no more </OL> # # No more </OL> found - write table to output file & close files man80 wtbe filo1,a0(200),a0(200) write out modified program cls all close files eoj end job
  • This job also illustrates 'rtb' (read file into memory table) & 'wtb' (write memory table out to a file).

    Note that register 'a' on the 'lok' instrn (2nd 'a' of aa0(200) captures the table displacement to next occurrence of '</OL>'. We then transfer to register 'B' & subtract 200 (1 table entry) to modify the preceding line.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 11 (special) - sys, lok, "pop", fxt, env, evs, evt, evs

    `pop` - process option string into process/user option storage

         pop   a80(20)             - process options in 81-100 of area a
                                     into $popca-$popcz & $popba-$popbz
         popu  'abcd1e25f12345z9'  - process options from constant string
                                     into $uopca-$uopcz & $uopba-$uopbz
         cmc   $popcx,'x'          - test option x character specified ?
         skp=  opx
         cmn   $popbx,100          - test option x integer value
         skp=  opx

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 11 (special) - sys, lok, pop, "fxt", env, evs, evt, evs

    `fxt` - add a uvcopy instruction to the execution table

         fxt   a0(80)              - add the instruction in area a to the table
         fxt   $reply              - add the instruction in $reply to the table

    A good example of using this instruction is the 'copyvq' job in uvjobs6 which solicits uvcopy instructions from the operator via 'msgw' prompts & adds the instructions to the end of the prmfile.

    "copyvq" is a skeleton job which would simply copy a file unchanged if no instructions were keyed in at the prompt.

    This job is very handy when you only want to perform 1 or 2 or a few instructions since it saves you from having to create a new prmfile

    Jobs using the fxt instruction must be coded with a 'bal' subroutine at the end of the prmfile & must supply the 'ret' instruction after all other instructions have been added

    Most of the copyvq job is shown below. Note the following:

     1 - solicitation of instructions via msgw & storing via 'fxt'
           (the job supplies the 'ret' when the operator keys a period to end)
     2 - the 'bal' to the skeleton subroutine from the record get/put loop
     3 - the skeleton subroutine coded at the end of the prmfile
     fxt1  msgwn   'enter a uvcopy instruction (period "." terminates entries)'
           cmc   $reply(1),'.'            end of instrn entries ?
           skp=  fxt2
           mvc   f1(80),$reply            move to area f leaving col 1 blank
           fxt   f0(80)                   add instrn to end of execution table
           skp   fxt1                     repeat loop
     fxt2  mvc   c0(10),'  ret  #'        setup 'return' instrn for end of table
           fxt   c0(10)                   add return instrn to end of table
     #
     loop  get   fili1,a0(256)            get each record into area 'a'
           skp>  eof
           mvc   b0(256),a0               move record to output area 'b'
           bal   mod                      execute the users instrns in subrtn
           put   filo1,b0(256)            write record to output file
           skp   loop
     #
     eof   cls   all
           eoj
     #
     # subroutine for user entered instructions (must be at end of job)
     mod   nop
     #     ---   ----,----               user entered instrns built here
     #     ret   #                       return added after last user instrn

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 11 (special) - sys, lok, pop, fxt, "env", evs, evt, evs

    `env` - get value for any specified environmental variable

         env    areadsp(lth),'symbol'  - instruction format
         env    e0(200),'PATH'         - get the value of PATH into area 'e'
         skp!   nofind                   (cc set = if found, unequal if not)

    "env" searches the environment for the variable specified by op2 (usually a constant, but could be stored in an area).

    If found, the value will be stored in op1 & blank filled by default.

    option 't1'
    • will null terminate the value stored in op1
    condition code
    • set equal '=' if found, unequal '!' if not found
    register 'x'
    • will hold the length of the value stored

    alternative ${symbols} expansion

    ${symbols} are expanded on all functions and instructions as of Nov2002. Prior to Nov2002 ${symbols} were expanded only on msg,mvf,mrep,rts,sys instructions if option v2 present (option v2 no longer required).

         mvf    h0(20),'${LOGNAME}'   <-- no option required to expand
                                          ${...} symbols on any instruction
     The 'lod' function requires the 'v2' option to expand ${...} symbols
     on the data lines following the 'lod' up to the '~~' end of data marker.
     Use option 'v3' (v1+v2=v3) for both $symbols & ${symbols}, for example:
     lodv3=h0(80)
     ABC Company    Expense Report
     For user: ${LOGNAME}         Date: $datetime
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Expansion controlled by option v1/v2/v4/v8/v16 as follows:

     option v1  - replace any $symbols with data using $symtbl & area q
            v2  - replace any ${symbols} with data from env-vars
            v4  - disable stop replace on 1st space, enable endrep on tilde
            v8  - inhibit stop on '.' period
            v16 - override stop replace options v4 (1st space) or v8 ('.' period)
                - use replace length from $symbol table
                - see 'uvsoftware.ca/uvcopy2.htm#B7'

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 11 (special) - sys, lok, pop, fxt, env, evs, "evt", evs

    `evt` - get & table the values for all environmental variables

         evt   1stentry,no of entries - instruction format
         evt   e0(80),200             - store all env vars in area 'e'
                                        each entry 80 bytes, max 200 allowed
    operand 1
    • defines 1st table entry (table base & length of 1st entry)
    operand 2
    • defines the maximum number of entries allowed
    option 't1'
    • will null terminate each entry stored in the table
    option 't2'
    • will follow the last entry stored with an entry of all tildes '~'s (end tbl marker for other instrns)
    counter $ci1
    • will hold count of entries stored

    example of table format

     PATH=/bin:/usr/bin:.:/home/uvadm/bin:/home/uvadm/sf
     LOGNAME=uvadm
     MAIL=/usr/spool/mail/uvadm
     PS1=uv>
     PFPATH=/home/userxx/pf:/home/uvadm/pf
     SHELL=/bin/ksh
     HOME=/home/uv
     TERM=ansi
     PWD=/home/uv
     TZ=PST8PDT
    Note1
    • the above was captured by the 'uvenv' job which is 1 of the supplied pre-programmed jobs for uvcopy & you can run as follows:
    
             uvcopy uvenv       - writes a file with all env values
             ============       - displays the file on the screen
                                - leaves the file in cwd as 'uvenv.tmp'
                                  (in case you want to use in any way)
    Note2
    • See the complete 'uvenv' job presented with the 'srt' instruction which sorts the table of environmental variables.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 11 (special) - sys, lok, pop, fxt, env, evt, "evs"

    `evs` - copy text, expanding any environmental variables

    evs
    • copy text, expanding environmental variables - allow $SYMBOL or ${SYMBOL}
    • symbols ended by any non-alphanum except '_'
    
          evs   b0(100),a0   <-- copy 1st 100 bytes from area 'a' to area 'b'
          ================       expanding $SYMBOLs
    option t1
    • insert LineFeed after last non-blank
    option t2
    • null terminate after LF &/or last non-blank
     cc        - condition code set '=' if any replacements, else '<'
     $ci1      - replacement count
     $rx       - dsplcmnt to 1st replacement
     $ry       - length of 1st replacement

    testevs1 - uvcopy job supplied to test 'evs'

     # testevs1 - test uvcopy instruction 'evs' (test job in $UV/pf/adm/testevs1)
     #          - copy a string expanding environmental-variables
     #          - this job includes a hard-coded string with $HOME,$LOGNAME,etc
     # testevs2 - also see alternate job testevs2, that prompts you to enter any string
     #
     # uvcopy testevs1    <-- execute this job to test the "evs" instruction
     # ===============      - with hard-coded $Variables (see testevs2 prompts for entry)
     @run
             msg     '  --- test uvcopy instruction "evs" copy text expanding $VARIABLES ---'
             mvf     a0(100),'homedir=$HOME, user=$LOGNAME, machine=$HOSTNAME, datetime=$datetime'
             msg     a0(100)                show string BEFORE expanding variables
             evs     b0(100),a0(100)        copy from area 'a' to area 'b' expanding $variables
             msg     b0(100)                show string AFTER expanding variables
             eoj
     #                      ** sample output **
     # test uvcopy instruction "evs" - copy a string expanding $VARIABLES
     # homedir=$HOME, user=$LOGNAME, machine=$HOSTNAME, datetime=2020/03/28_08:00:29
     # homedir=/home/uvadm, user=uvadm, machine=uvsoft5, datetime=2020/03/28_08:00:29

    testevs2 - uvcopy job supplied to test 'evs'

     # testevs2 - test uvcopy instruction 'evs' (test job in $UV/pf/adm/testevs2)
     #          - copy a string expanding environmental-variables
     #          - this job prompts you to enter a string containing any environment variables
     # testevs1 - alternate job with hard-coded $VARIABLES ($HOME,$LOGNAME,$HOSTNAME)
     #
     # uvcopy testevs2    <-- execute this job to test the "evs" instruction
     # ===============      - prompting to enter string with $VARIABLEs
     @run
             msg     '    --- test "evs" - copy YOUR string expanding $VARIABLES ---'
     man10   msga1w  '    ---> enter text containing $VARIABLEs (ex: $HOME, $PWD, $datetime, etc)'
             skp<    man99                  goto end job if null entry
             mvfv3   a0(100),$arg1
             evs     b0(100),a0(100)        copy from area 'a' to area 'b' expanding $variables
             msg     b0(100)                show string AFTER expanding variables
             msg     '    --- may enter another string OR null entry to end job'
             skp     man10
     man99   eoj

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    `expandevs1` - using "evs" to expand $VARIABLEs in DB2 scripts

     # expandevs1 - copy a text file expanding unix ENVIRONMENTAL $VARIABLEs
     #            - by Owen Townsend, UV Software, Jan 2018
     # Example below used by db2 script dsntiaul to expand $SYSRTMP
     #  - JCL converter uses this technique to load/unload DB2 tables
     #
     # uvcopy expandevs1,fili1=$SYSIN,filo1=$SYSINTMP
     # ==============================================
     # - copy $SYSIN to $SYSINTMP, expanding $VARIABLEs ($SYSRTMP, possible others)
     # - used by db2 script dsntiaul to expand variables such as $SYSRTMP
     #   since input on db2 -txf $SYSIN does not expand
     # - may run this demo job with supplied test file $UV/tf/expandevs1_data
     rop=r1      # prompt for output file disposition at EOJ
     fili1=?tf/expandevs1_data,rcs=256,typ=LST
     filo1=?tmp/$fili1,rcs=256,typ=LSTt
     @run
             opn    all
     # begin loop to copy expanding $variables
     man20   get    fili1,a0                get next line
             skp>   man90                   (cc set > at EOF)
             evs    b0(200),a0(100)         copy expanding any $variables
             put    filo1,b0                write to output file
             skp    man20                   repeat loop until EOF
     # EOF - close files & end job
     man90   cls    all
             eoj
     #
     #             ** dsntiaul - script to unload DB2 tables **
     # JCL converter uses this script when converting DSNTIAUL steps to unload tables
     # This script is followed by uvcopy (in the calling JCL/script), to convert the
     # exported delimited format to fixed-field copybook format, while copying from a
     # $SYSRTMP file to the $SYSREC00 defined in the calling JCL/script
     # Here is the critical code extracted from $UV/sf/IBM/dsntiaul (as #cooments)
     #
     # # --> exportfile SYSRTMP  $JTMP/${JSTEP}_SYSREC00 #<-- SYSRTMP  def in JCL/script
     # # --> exportfile SYSREC00 data1/northvan.citytax2 #<-- SYSREC00 def in JCL/script
     # #
     # rm -f $SYSRTMP            # remove any existing $SYSRTMP
     # touch $SYSRTMP            # recreate empty file
     # export SYSREC00=$SYSRTMP  #<-- redef SYSREC00 as $SYSRTMP (only in this script)
     # #=======================
     # # Redefine SYSREC00 as $SYSRTMP, since DB2 UDB outputs delimited (vs mainframe fixed)
     # # On return to the JCL/script, uvcopy will convert the delimited format (from $SYSRTMP)
     # # to the fixed-field format (in $SYSREC00) expected by some following step.
     # #
     # uvcopy expandevs1,fili1=$SYSIN,filo1=$SYSINTMP,uop=q0i7,rop=r0
     # #=============================================================
     # # - copy $SYSIN to $SYSINTMP, expanding $VARIABLEs ($SYSRTMP, possible others)
     # #   since input on db2 -txf $SYSIN does not expand
     # #-------------------------------------------------------------------------------
     # export DB2CLP=**$$**
     # echo "db2 script begin: dsntiaul - UNLOAD SELECT with delimiter via export chardel"
     # db2 "CONNECT TO $DBNAME USER $DBUSR USING $DBPWD"
     # db2 "SET SCHEMA = $DBUSR"

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 12 (sort) - "srt" (internal); sxo, sxp, sxs, sxg, sxc (external)

    `srt` - internal sort (tables, record arrays, etc)

    The 'srt' instruction is intended for sorting fixed size items in memory (tables, record arrays, etc). This instruction is completely unrelated to the external sort instructions (sxo,sxp,sxs,sxg,sxc).

          srt   entry,key,number         - instruction format
          srt   b0(80),b0(20),100        - sort 80 byte entries in area 'b'
                                         - key is 1st 20 bytes of each entry
                                         - 100 max entries (see option n1).

    options

    d1
    • drop entries with duplicate keys - except for the FIRST.
    d2
    • drop entries with duplicate keys - except for the LAST.
    d4
    • insert duplicate count in last 5 bytes of remaining entry
    n0
    • (default) number of entries determined only by the op3 count
    n1
    • number of entries determined by the 1st entry encountered with '~~' in 1st 2 bytes. option 'n1' is often used with srt since tables are often initialized to all tildes.
    n2
    • tilde fill the entry at the end of the table (before sorting)
    • use with option 'n1' (ie n3) when the sort key does not begin in the 1st byte of each entry & when option 'b' is used to sort blanks high
    r1
    • reverse sort (descending keys vs ascending by default)
    b_
    • controls treatment of blank keys & end of table recognition
    b1
    • sort blank key entries high
    • temporarily inserts a '~' tilde (x'7E') into the 1st byte of blank keys which forces them to sort high (in the ASCII collating sequence)
    • after the sort is completed, these tildes will be removed
    b2
    • inhibit removal of '~' tilde from 1st byte of keys at end of sort (probably resulting from b1 option to insert '~' in blank keys)
    • code as 'b3' for both b1 & b2 actions, BUT 'b3' would be unusual
    • The only codes that make normal sense are 'b1' or 'b7'
    b4
    • at the end of the sort, this option will '~' tilde fill the entire entry of any entry with 1 tilde in the 1st byte of the key.
    • this has the effect of shortening the table, since 2 tildes '~~' are recognized by several instructions as end-of-table.
    • code as 'b7' since b4 would be used in conjunction with b1 & b2.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    "srt" - internal sort for tables, record arrays, etc (continued)

    registers

    rgstr x
    • set to the end of the table
    • 1st entry beyond the table if option 'n1' present
    • 1st entry with '~~' in 1st 2 bytes of the key if 'n1' not present
    rgstr y
    • set to the 1st blank entry
    • option 'b1' may have been used to sort blank keys high

    instruction counters

     $ci1  - total entries in the table
           - prior to the 1st '~~' entry unless overridden by option 'n1'
     $ci2  - number of non-blank entries
     $ci3  - number of blank entries
     $ci4  - no of passes required (for the internal bubble sort)
     $ci5  - no of field swaps required (for the internal bubble sort)

    example of use

    Please see the 'uvenv' job documented in UVjobs1.doc. This job reads all environmental variables, sorts them,& displays on the screen. The entire uvcopy job (interpretive parameter file) is listed below:

     # uvenv  - display UNIX environment variables = values (SORTED)
     opr='$jobname - display UNIX environment variables=values (SORTED)'
     opr='demo powerful table handling instructions:'
     opr='evt - read environmental variables into a table'
     opr='srt - sort table in memory'
     opr='wtb - write table to a file'
     rop=r1x2  #Run OPtion EOJ prompt report disposition(vi,more,etc), default more
     was=a100000     # allow 200 entries of 500 bytes each = 100K
     filo1=tmp/uvenv,rcs=512,typ=LSTt    # writes to a file for user use ?
     @run
           opn     filo1
           evtt2   a0(500),200            table all env-vars & '~' terminate
           srtb7   a0(500),a0(30),200     sort table
           wtbe    filo1,a0(500),a0(500)  dump table to file
           cls     filo1
           eoj
    Note
    • this job also writes out a file 'uvenv.tmp' in case you wanted to do something with the results.
    • Also see the 'evt' instruction that reads the environmental variables.
    • op1 area must be large enough to hold the expanded values of $symbols

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 12 sort external (vs srt internal) sxo, sxp, sxs, sxg, sxc

    `sort` (external) - sxo, sxp, sxs, sxg, sxc

    sxo rcsz,'key1,key2,etc','sortwork dir' - open the sort

        sxo   256,'228(3pd),59(15ca),0(8)'         - open sort for 3 keys
                                                 1 - 229:231 packed descending
                                                 2 - 60:74 character ascending
                                                 3 - 1-8 char ascend (default)
        sxo   c0(4),'59(15)','tmp'    - op1 may be an address containing
                                        the record size to be sorted
                                      - op3 may specify the sort workfile
                                        directory (default tmp in cur dir)
        sxo   $rn,'0(8)'              - op1 may be a register, or counter
                                        or user option ($uopbn)
        sxp   a0(256)                 - put record to the sort
        sxs                           - perform the sort
        sxg   b0(256)                 - get a record from the sort
        skp>  eof                     - cc set > at end of all records
                                      - also stores '~EOS' in 1st 4 bytes
                                        of the get area
        sxc                           - close the sort
                                      - not required unless you want to do
                                        2 sorts in 1 job

    sort field data types

    a
    • alphabetic (case insensetive, lower & upper treated equally)
    b
    • binary (bit for bit) - same as character (see below)
    c
    • character ASCII (the default)
    e
    • EBCDIC collating sequence (for ASCII data sort fields)
    f
    • first blank high (as if it were a tilde x'7E')
    h
    • sort all blanks high regardless of field location
    i
    • integer (2 or 4 bytes) Intel reversed byte architecture
    p
    • packed decimal
    u
    • unsigned integer (length must be 2 or 4)
    y
    • special field type for the Year2000 windowed date field compares
    • assumes 1st 2 characters of field is the 2 digit year (no century)
    • default window '50' meaning: years 50-99=1950-1999,& 00-49=2000-2049
    • window may be modified by run option 'y__' value & 'z1' sliding window
    z
    • zoned decimal

    sort field sequence codes

    a
    • ascending sequence (the default)
    d
    • descending sequence

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    options for the sort instructions

    sxo option m
    • define max memory to be used in megabytes
    • changed May2003 from kilobytes to megabytes
    sxom64
    • default 64 megs, no need to increase for files up to 6.4 gig
    sxom256
    • would request 256 meg to be used
    • may also be requested via run option 'm' on command line

    uvcopy jobxxx,rop=m256 <-- run option m overrides sxom64 & internal default

    sxo option w
    • declares the max no of work files to be used
    sxow100
    • default is 100 files, which is the maximum allowed so this would not normally be used unless you wanted to experiment with its influence
    • the work files will not be used at all if the file is smaller than the memory assigned (option m, default 64 meg)
    Note
    • by default work files are created in sub-directory 'tmp' within the current directory
    • tmp subdir will be created if required & it does not already exist
    • the work files are automatically scratched at the end of any normal termination of the sort
    sxo option v0
    • verbose inhibit
    sxov1
    • default will display sort status msgs (% complete) during multiple intermediate merge passes

    run options 'y__' & 'z1' for field type 'y'

          sxo  64,'44(6y)'  <--- field type y for windowed date field sort
    rop=y70
    • run option 'y' to set Y2K window for field type 'y'
    • run option 'y' assumes 1st 2 bytes of field is the year (no century)
    • 'rop=y70' means years 70-99 = 1970-1999 & 00-69 = 2000-2069
    rop=y70z1
    • option 'z1' specifies sliding windows, for example in 1998 rop=y70z1 window value would be 98+70 = 168-100 = 68 meaning years 68-99 = 1968-1999 & 00-67 = 2000-2067

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    sxg options d1k# to drop duplicates

          sxgd1   b0(80)        <-- option d1 will drop dup recs on all keys spcfd
                                  - when no k# option spcfd on sxo & no op2 spcfd
          sxgd1k2 b0(80)        <-- option d1k2 drops dup recs matching on 1st 2 keys
                                  - see demo job 'sort1' on the next page
          sxgd1   b0(80),b30(6) <-- op2 overrides keys spcfd on sxo
                                  - this would drop recs matching on cols 31-36
                                  - dangerous if overriding higher sort keys

    demo option d1k2 - drop records with dup keys

    The next page lists a complete uvcopy job with an external sort. The 'sort1' demo job sorts dat1/sales2 on key1=slsmn,key2=customer,& key3=product.

    Here we have extracted the essential sort instructions to demo options 'd1k2' (on sxgd1k2) to drop records with dups on 1st 2 keys (salesman & customer).

            sxo     80,'10(2),0(6),30(6)'  open sort, specify rcsz & sort fields
     #                                     sort key1=slsmn,key2=customer,key3=product
     fget   get     fili1,a0(80)           get record from input file
            skp>    eof                    (cc set > at EOF)
            mvc     b0(80),a0              copy input area to work area b
            sxp     b0(80)                 put to the sort
            skp     fget                   return to get next record
     #
     eof    sxs                            sort created records
     #
     sget   sxgd1k2 g0(80)                 getrec, drop if match on 1st 2 keys
     #      =======                                ===========================
            skp>    eos                    (cc set >  at end sortrecs)
            put     filo1,g0(80)           write to output file
            skp     sget
     #
     eos    cls     all
            eoj
    Note
    • see input data file (20 records) listed following the sort1 job listing
    • also lists the output file (10 records dropped)

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    "sort" (external) - sxo, sxp, sxs, sxg, sxc - template job

    The following job is provided as a template to copy, rename,& modify whenever you need to create a new job using the sort feature of uvcopy.

    
     #1. cp /home/uvadm/pf/sort1 pf/mysort   - copy & rename to your pf directory
         =================================
     #2. vi pf/mysort                          - modify as required
         ============

    uvcopy sample sort for copy,rename,modify

     # sort1 - uvcopy Parameter File from UVSI stored in: /home/uvadm/pf/demo/
     # sort1 - sample/skeleton uvcopy job to illustrate sort capability in uvcopy
     #       - template for creating new uvcopy/sortjobs (copy/rename/modify)
     #       - sorts demo file /home/uvadm/dat1/sales2 on slsmn,customer,product
     # sort1  - this job demos option 'sxgd1k2' drop recs with dups on 1st 2 keys
     # sort1a - alternate job to drop if dup on product# only (op2 on sxg)
     #
     opr='$jobname - sample/template uvcopy job to illustrate sort capability'
     fili1=?dat1/sales2,rcs=80,typ=LST
     filo1=?tmp/$fili1,rcs=80,typ=LSTt
     @run
            opn     all
            sxo     80,'10(2),0(6),30(6)'  open sort, specify rcsz & sort fields
     #                                     sort key1=slsmn,key2=customer,key3=product
     # input phase - get records & put to the sort
     fget   get     fili1,a0(80)           get record from input file
            skp>    eof                    (cc set > at EOF)
     #--------------------------------------------------------------------
            mvc     b0(80),a0              copy input area to work area b
     #      ---     -----,-----            process input records here
     #--------------------------------------------------------------------
            sxp     b0(80)                 put to the sort
            skp     fget                   return to get next record
     #
     # end of input file - sort the created records
     eof    sxs                           sort created records
     #
     # get records from the sort & write to the output file
     sget   sxgd1k2 g0(80)                 getrec, drop if match on 1st 2 keys
            skp>    eos                    (cc set >  at end sortrecs)
     #--------------------------------------------------------------------
     #      ---     -----,-----            process output records here
     #--------------------------------------------------------------------
            put     filo1,g0(80)           write to output file
            skp     sget
     #
     # end sort records - close files & end job
     eos    cls     all
            eoj

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    data file to demo d1k2 drop dups

    
     #1. cd /home/uvadm
         ==============
    
     #2. cat dat1/sales2   <-- display input file (for sort1 demo sxgd1k2)
         ===============
                    1         2         3         4         5         6
          0123456789012345678901234567890123456789012345678901234567890123
           cust# slsm#  date  invoice# product#    qty   price    amount
          ================================================================
          130140    21 940802 IN111001  HAM001  000020 0000001 000000020
          130140    21 940802 IN111001  SCR012  000021 0001001 000021021
          130140    21 940802 IN111001  CHR001  000022 0002001 000044022
          139923    35 950802 IN111002  TAB013  000023 0003001 000069023
          139923    35 950807 IN111002  TAB013  000024 0004001 000096024
          150825    44 960804 IN1122    HAM001  000025 0005001 000125025
          150825    44 960804 IN1122    HAX129  000026 0006001 000156026
          201120    44 970807 CR5234    WHIP75  000027 0007001 000189027
          223240    65 980816 CR955     HAM001  000028 0008001 000224028
          223240    65 980816 IN441     BBQ001  000029 0009001 000261029
          308685    21 990812 IN6605    SAW051  00001p 0000001 00000001p
          308685    21 990812 IN6605    WHIP75  00001q 0001001 00001101q
          308685    21 990812 CR8835    TAB013  00001r 0002001 00002401r
          315512    44 000805 IN2251    HAM001  00001s 0003001 00003901s
          315512    44 000805 IN2251    SAW051  00001t 0004001 00005601t
          315512    44 000805 IN2255    WHIP75  00001u 0005001 00007501u
          400002    85 010812 CR245     HAX129  00001v 0006001 00009601v
          406082    35 020815 IN33001   BBQ001  00001w 0007001 00011901w
          406082    35 020815 IN33001   TAB013  00001x 0008001 00014401x
          406082    65 020816 IN441     HAM001  00001y 0009001 00017101y
    
     #3. uvcopy sort1    <-- execute demo job to illustrate sxgd1k2
         ============
    
     #4. cat tmp/sales2  <-- display output file
         ==============

    sorted output dups dropped on cust# & slsmn# matches

                    1         2         3         4         5         6
          0123456789012345678901234567890123456789012345678901234567890123
           cust# slsm#  date  invoice# product#    qty   price    amount
          ================================================================
          130140    21 940802 IN111001  CHR001  000022 0002001 000044022
          308685    21 990812 IN6605    SAW051  00001p 0000001 00000001p
          139923    35 950802 IN111002  TAB013  000023 0003001 000069023
          406082    35 020815 IN33001   BBQ001  00001w 0007001 00011901w
          150825    44 960804 IN1122    HAM001  000025 0005001 000125025
          201120    44 970807 CR5234    WHIP75  000027 0007001 000189027
          315512    44 000805 IN2251    HAM001  00001s 0003001 00003901s
          223240    65 980816 IN441     BBQ001  000029 0009001 000261029
          406082    65 020816 IN441     HAM001  00001y 0009001 00017101y
          400002    85 010812 CR245     HAX129  00001v 0006001 00009601v

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    "sort" (external) - sxo, sxp, sxs, sxg, sxc - continued

    more sample jobs using the sort instructions of uvcopy

    sort1
    • template job for you to copy, rename,& modify lt;------------------ see listing on the previous page
    pswsort1
    • demo sort using the /etc/passwd file (see uvcopy4.doc #9)
    • converts variable format to fixed fields via the ':' delimiters
    • drops UNIX system entries (any user# < 100)
    • sorts on the comment field (often used for user name)
    • creates report on output (with field headings & date/time)
    
                try this ---> uvcopy pswsort1
                              ===============
    index
    • in section TEXTjobs.doc
    • extracts keywords from documentation & sorts on page# to create and index
    • illustrates record processing at input & output times
    sort2
    • in section uvcopy4.doc
    • illustrates multi-file sort input
    cmreport
    • in section uvsort.doc
    • illustrates extensive record processing while putting records to the sort & getting records from the sort
    cmsplit
    • in section uvsort.doc
    • illustrates multi-record output from each record at output time

    sort times

    Most sort times are determined by input & output times. Intermediate sort merges are required only for files larger than 6.4 gigabytes, assuming the default sort memory of 64 megs & 100 sort work files. As the input file is read, each 64 meg portion is sorted & written to up to 100 work files in the tmp subdir. These are then merged during the output phase.

    sort time examples

     #1. sort 100 meg file of 300,000 * 350 byte records
         - requires 25 seconds (10 seconds input & 15 seconds output)
     #2. sort 1 gig file of 3,000,000 * 350 byte records
         - requires 7 minutes (3 input & 4 output)

    The tests above were run using 64 megs & 100 work files max. For test#2 about 18 work files are created in tmp during the input phase which are merged during the output phase. (18 * 64 meg = 1 gig file approx). There is no advantage increasing the memory unless the file is > 6.4 gig.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - tbl, tbf, tbh, tbp, tbd

    `table overview` - build tables in memory to dump at EOJ

    tbl
    • build tables in memory (probably executed for each detail record)
    tbf
    • declare format for print editing when written to output file
    tbh
    • declare table field headings to be used when edited to output file
    tbp
    • print (edit) table(s) to output file (probably at end of job)
    tbd
    • dump (unedited) table(s) to output file (probably at end of job)

    "tbl" will build tables in memory to be printed at the end of the job.

    Each table may have an argument up to 48 bytes which could be composed in a work area from several subfields before the 'tbl' instruction is executed. Up to 6 accumulators may be specified for each table.

    An entry count is provided automatically so you don't have to waste 1 of the 6 accumulators for this purpose.

    Percentages of the 100% total at the bottom, may be automatically calculated, for the entry count & for each of the 6 accumulators.

    Several 'tbl' instructions could be executed for each record of the input file, with several different arguments & accumulators. The tables are built & dumped in sequence by their argument fields.

    The tables are normally dumped to an output file at the end of the job by the 'tbp' &/or 'tbd' instructions.

    "tbp" edits (prints) the tbl entries into a file which may be subsequently printed via 'lp'.

    "tbd" writes the the tbl entries (unedited) into a file for additional processing, collection,or storage.

    There is no limit on the number of tables or on the number of entries in any 1 table (other than available system memory), but there are defaults which may be increased via 'run' options 'u' & 'v'.

    rop=u12
    • run option 'u' to specify max tables allowed (default 12)
    • each table requires about 500 bytes before entries are accumulated
    rop=v2000
    • run option 'v' to specify max table entries (default 2000)
    • shared by all tables
    • each entry only 8 bytes until required, then 112 more

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - "tbl", tbf, tbh, tbp, tbd

    `tbl` - build tables in memory to be dumped at end of job

    tbl argument,heading,acum1,acum2,acum3,acum4,acum5,acum6

    tbl example

        tblt1f2 a100(16),'city-name;sales;costs;profit',a40(8z),a48(6p),a54(4b)

    tbl example #2

        tbhh1   '-dummy-;sales;costs;profit'
        ----
        tblt1f2h1 a100(16),'city-name',a40(8z),a48(6p),a54(4b)
        tblt1f2h1 a120(6),'postal-code',a40(8z),a48(6p),a54(4b)

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    tbl options

    t#
    • specifies the table# (t1 - t999)
    • it is unusual, but the same table# could be specified on 2 or more tbl instructions, which would accumulate into the same table.
    f#
    • specifies the editing format to be used when the table is subsequently dumped (written to the output file), via the 'tbp' instruction.
    • 12 pre-programmed formats are supplied (f1-f12) & you may respecify any or all of these to your own desired formats. 'f1' is the default.
    • See the table formats documented a few pages ahead.
    • The format is specified on the tbl instruction (vs the tbp instruction) because there is usually only 1 tbp instruction to edit all tables.
    h#
    • may specify the column headings to be used when the table is later edited by the tbp instruction.
    • the headings are usually specified via op2 of the tbl instruction, but if desired they may be specified separately via the 'tbh' instruction, in which case the op2 of the tbl may be left blank (,,).
    • You might specify the headings on the tbh instruction when you want to shorten the tbl instruction because you are using all 6 accumulators.
    • 9 separate headings are provided (h1-h9).
    m#
    • maximum entries to be tabled before limiting new entries to lower/higher than any existing entries & removal of a mid-point entry.
    • used for sampling data fields
    • see gentbl1 job that generates a job with a tbl for all fields
    • gentbl1 generates tblt001d3f7m030v10 (you can then modify as desired)
    v#
    • number of invalid entries (unprintable chars, invalid digits/signs)
    • after this limit, invalid entries are counted for the ~Invalid Total line
    d_
    • for Invalid digits in Numeric fields
    d0
    • drop invalid digits
    d1
    • convert invalid digits to '0's in zoned (unpacked) fields
    d2
    • convert invalid digits to '0's in packed fields

    condition code (after tbl executed)

    "=" if the table already contained the current argument

    "<" if a new table entry was created for the current argument.

     ">" if the entry pointer table is full (area 'w')
           - stops with an error message
           - may continue bypassing the current entry
           - you could test the condition ">" & branch to dump the table ?
             (or better kill, increase area w,& rerun the job)

    instruction counters

    $ci21 - will be set to the number of table entries present

    $ci22 - will be set to the number of matches for current argument

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - tbl, "tbf", tbh, tbp, tbd

    `tbf` - declare formats to be used when editing tables to output files

    tbf argument-location(length),accumulator editing formats

    tbf example

        tbff2  p31(32),'zzz,zzz,zzz.99- %%%- zzz,zzz,zzz.99- %%%-  .etc.'
    Note
    • If you are reading this documentation as printed by 'uvlist' or 1 of the uvlist scripts such as uvlp12D (Duplex) any 2 conseccutive '%'s will print as '%@'
    • IE, the 2nd '%' is converted to '@' by uvlist because 2 consecutive '%'s is a postscript command which mucks up printing even though I use PCL5 (vs postscript)

    tbf options

    f#
    • the format#, (f1-f12), must be present
    • see detailed formats 9 pages ahead under table formats
    d#
    • the no of decimal places for the count percentage
    • the decimal places for acum %'s are specified by the edit patterns

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - tbl, tbf, "tbh", tbp, tbd

    `tbh` - declare table column (field) headings

    tbhh1 'province;This Year Sales;Last Year sales;'

    tbh + tbl + tbp

    tbhh1 'Province;ThisYearSales;LastYearSales;

        tblt1h1 a77(2),'province:TYsales;LYsales;',$ca1,$ca2
        tbhh1  'province;SalesThisyear;SalesLastYear;     <-- tbh at EOF

    tbpt1h1 filo1,'sales by province (thisyr & lastyr)'

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - tbl, tbf, tbh, "tbp", tbd

    `tbp` - print (edit) the table entries into a file (usually at eoj)

    tbp file,table-title-heading

    tbp example

    tbpt1e3 filo1,'sales analysis'

    options

    t#
    • tbp may specify a specific table# to be printed via the 't' option (tbpt1 would print table #1).
    • if omitted tbp will print all tables that have been declared.
    e#
    • option 'e' may be used to specify the 'end' table# in order to print groups of tables (tbpt10e5 will print tables 10-15).
    c
    • clear the table as it is being dump, in order to re-accumulate, for example, 'tbpt1c' would clear table#1 as it is being dumped.
    • only required when program is building & dumping on control breaks.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    tbp options (continued)

    h#
    • use the specified table field headings (h1-h19)
    • normally you don't need the 'h' option on the 'tbp' since the field headings declared on the 'tbl' are automatically printed by tbp.
    • table field headings are stored in special areas $tbh1 - $tbh19
    • you may have modified these with mvf instructions prior to dumping the table at EOF time, for example:
           mvf   $tbh1,'product#;quantity;amount'
           tbp   filo1,'Sales by Product#'
    i0
    • (default) page headings on 1st page only
    i1
    • inhibit all page headings
    i2
    • inhibit accumulator field headings headings if accumultor totals all zero
    • so tables with counts only not cluttered with unused acum headings on right side
    l##
    • specify lines per page, before generating space or formfeed (default l55) For jobs with multi tables, a space or formfeed is generated as follows: - formfeed generated if prior table lines > option l(55) - formfeed generated if (lines since last FF + next table lines) > 55 - space generated if (lines since last FF + next table lines) < 55 (lines in next table known to program from table control structure)
    j1
    • inhibit total lines
    j2
    • insert blank line between data lines & total line
    s1
    • space before next table dumped (vs default FormFeed)
    • use with multiple tables (tbpt1, tbpt2s1, tbpt3s1, etc)
    x1
    • convert any unprintable characters in table data to '.' periods
    x2
    • show hexadecimal for any table entry with unprintable characters
    • shown on rihtside allowing 20 bytes for table argument
    z1
    • inhibit writing lines with all accumulators = zero
    • regardless of the automatic entry 'count' (the counts would then not add up to the total count)
    • breaks in the line sequence#'s would indicate dropped entries
    z2
    • re-sequence the line#'s
    • to not indicate dropped entries due to all accumulators = zero
    • this option would be meaningless without z1
    z3
    • inhibit writing lines with all acums zero & re-sequence line#'s (z3 = z1 + z2)

    $ci1 - no of table entries written (not yet implemented)

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 (table) - tbl, tbf, tbh, tbp, "tbd"

    `tbd` - dump (unedited) the table entries into a file (usually at eoj)

    tbd file,constant-data (to be appended to table entries)

    tbd example

    tbdt1e3 filo2,'19940430'

    options

    t#
    • a table# must be specified via option 't' to dump a specific table.
    e#
    • option "e" may specify an "end" table# to dump groups of tables (tbdt5e7 will dump tables 5,6,7).
    c
    • clear the table as it is being dump, in order to re-accumulate, for example, 'tbdt1c' would clear table#1 as it is being dumped.
    • only required when program is building & dumping on control breaks.
    j1
    • inhibit total record output
    z1
    • inhibit writing records with all accumulators = zero
    z2
    • re-sequence the sequence#'s in bytes 36-39 of the record to not leave gaps where entries dropped due to all acums = zero

    $ci1 - no of table entries written (not yet implemented)

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    `tbl examples` - sample problem & solution

    given
    • sales file dat1/custmas1 containing the following relevant fields: 061-076 - province code 121-180 - this year sales - 12 x 5 byte packed decimal fields 181-240 - last year sales - 12 x 5 byte packed decimal fields
    required
    • create a report which summarizes this year & last year sales by province code, also calculating percentages of the total sales
    • Note that the input file may be in any sequence, but the table entries will be printed in province code sorted sequence.

    output report

     testtbl11  2019/05/26_12:19:19  testtbl11 - field hdngs via op2 of tbl (default)
     tbl#0001  tblt1f2   a77(2)       argument            -acum#1-    %        -acum#2-    %
     line#   1strec#  %      count  province          thisyr sales         lastyr sales
         1        15   9         3  AB                      323.13    0        1,534.06    3
         2        13  34        11  AL                   29,530.35   29       35,979.84   79
         3         1  53        17  BC                   64,943.24   65        7,926.94   17
         4        20   3         1  NW                    4,901.21    4
                     100        32*  *TOTAL*             99,697.93 *100       45,440.84 *100

    testbl11 - code to create report above

     # testtbl11 - table summary of customer sales by province
     #           - uvcopy Parameter File stored at pf/demo/testtbl11
     #
     # uvcopy testtbl11  <-- execute uvcopy to interpret this parameter file
     # ================    - files default as coded below on fili1=... & filo1=...
     #
     opr='$jobname - summarize sales (thisyr&lastyr) by province'
     rop=r1x8   #EOF options to display output file (cat $filo1)
     fili1=dat1/custmas1,rcs=256,typ=RSF
     filo1=tmp1/$jobname,rcs=80,typ=LSTt
     @run
            opn       all
     # begin loop to read all customer master sales history records
     # - crossfooting & accumulating (tabling) thisyr & lastyr totals
     loop   get       fili1,a0(256)
            skp>      eof
            xft       $ca1,a120(5p),12
            xft       $ca2,a180(5p),12
            tblt1f2   a77(2),'province;thisyr sales;lastyr sales',$ca1,$ca2
            skp       loop
     # EOF - print/edit table to file for: cat $filo1 (options rop=r1x8 above)
     eof    tbpt1     filo1,'testtbl11 - field hdngs via op2 of tbl (default)'
            cls       all
            eoj
     #1. Login uvadm --> /home/uvadm (I/O files in dat1/ & tmp1/)
    
     #2. uvcopy testtbl11 <-- execute job I/O files coded in job
         ================   - writes report to tmp1/testtbl11 & displays on screen

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    tbh/tbp Alternative #2 specify argument & accum field headings

     # testtbl12 - table summary customer sales by province
     #           - uvcopy Parameter File stored at pf/demo/testtbl11
     #           - Alternative ways to specify argument & accumulator field headings
     #             stored by tbl op2, tbh at setup, tbh at EOF, or mvf $tbh1,'....'
     # testtbl11 - field hdngs from tbl op2
     #*testtbl12 - field hdngs from tbh setup time, option h1 on tbl
     # testtbl13 - field hdngs from tbh execution time, option h1 on tbp
     # testtbl14 - field hdngs from mvft1, h1 on tbp
     #
     # uvcopy testtbl12  <-- execute uvcopy to interpret this parameter file
     # ================    - files default as coded below on fili1=... & filo1=...
     #
     opr='$jobname - summarize sales (thisyr&lastyr) by province'
     rop=r1x8   #EOF options to display output file (cat $filo1)
     fili1=dat1/custmas1,rcs=256,typ=RSF
     filo1=tmp1/$jobname,rcs=80,typ=LSTt
     @run
            opn       all
            tbhh1     'Province;Thisyr Sales;Lastyr Sales'
     # begin loop to read all customer master sales history records
     # - crossfooting & accumulating (tabling) thisyr & lastyr totals
     loop   get       fili1,a0(256)
            skp>      eof
            xft       $ca1,a120(5p),12
            xft       $ca2,a180(5p),12
            tblt1f2h1 a77(2),' ',$ca1,$ca2    #<-- field hdngs via tbhh1 at setup above
            skp       loop
     # EOF - print/edit table to file for: cat $filo1 (options rop=r1x8 above)
     eof    tbpt1s1   filo1,'testtbl12 - field hdngs via setup tbhh1 & tblt1h1 option'
            cls       all
            eoj
     #
     # testtbl12  2019/05/26_12:19:40  testtbl12 - field hdngs via setup tbhh1 & tblt1h1 option
     # tbl#0001  tblt1f2h1 a77(2)       argument            -acum#1-    %        -acum#2-    %
     # line#   1strec#  %      count  Province          Thisyr Sales         Lastyr Sales
     #     1        15   9         3  AB                      323.13    0        1,534.06    3
     #     2        13  34        11  AL                   29,530.35   29       35,979.84   79
     #     3         1  53        17  BC                   64,943.24   65        7,926.94   17
     #     4        20   3         1  NW                    4,901.21    4
     #                 100        32*  *TOTAL*             99,697.93 *100       45,440.84 *100

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    tbh/tbp Alternative #3 specify argument & accum field headings

     # testtbl13 - table summary customer sales by province
     #           - uvcopy Parameter File stored at pf/demo/testtbl11
     #           - Alternative ways to specify argument & accumulator field headings
     #             stored by tbl op2, tbh at setup, tbh at EOF, or mvf $tbh1,'....'
     # testtbl11 - field hdngs from tbl op2
     # testtbl12 - field hdngs from tbh setup time, option h1 on tbl
     #*testtbl13 - field hdngs from tbh execution time, option h1 on tbp
     # testtbl14 - field hdngs from mvft1, h1 on tbp
     #
     # uvcopy testtbl13  <-- execute uvcopy to interpret this parameter file
     # ================    - files default as coded below on fili1=... & filo1=...
     #
     opr='$jobname - summarize sales (thisyr&lastyr) by province'
     rop=r1x8   #EOF options to display output file (cat $filo1)
     fili1=dat1/custmas1,rcs=256,typ=RSF
     filo1=tmp1/$jobname,rcs=80,typ=LSTt
     @run
            opn       all
     # begin loop to read all customer master sales history records
     # - crossfooting & accumulating (tabling) thisyr & lastyr totals
     loop   get       fili1,a0(256)
            skp>      eof
            xft       $ca1,a120(5p),12
            xft       $ca2,a180(5p),12
            tblt1f2   a77(2),' ',$ca1,$ca2   #<-- omit op2 hdngs, use tbhh1 at EOF
            skp       loop
     # EOF - print/edit table to file for: cat $filo1 (options rop=r1x8 above)
     eof    tbhh1     'Province;ThisYear Sales;LastYear Sales'
            tbpt1h1   filo1,'testtbl13 - field hdngs via tbhh1 at EOF & tbpt1h1 option'
            cls       all
            eoj
     #
     # testtbl13  2019/05/26_12:35:01  testtbl13 - field hdngs via tbhh1 at EOF & tbpt1h1 option
     # tbl#0001  tblt1f2   a77(2)       argument            -acum#1-    %        -acum#2-    %
     # line#   1strec#  %      count  Province        ThisYear Sales       LastYear Sales
     #     1        15   9         3  AB                      323.13    0        1,534.06    3
     #     2        13  34        11  AL                   29,530.35   29       35,979.84   79
     #     3         1  53        17  BC                   64,943.24   65        7,926.94   17
     #     4        20   3         1  NW                    4,901.21    4
     #                 100        32*  *TOTAL*             99,697.93 *100       45,440.84 *100

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    mvf/tbp Alternative #4 specify argument & accum field headings

     # testtbl14 - table summary customer sales by province
     #           - uvcopy Parameter File stored at pf/demo/testtbl11
     #           - Alternative ways to specify argument & accumulator field headings
     #             stored by tbl op2, tbh at setup, tbh at EOF, or mvf $tbh1,'....'
     # testtbl11 - field hdngs from tbl op2
     # testtbl12 - field hdngs from tbh setup time, option h1 on tbl
     # testtbl13 - field hdngs from tbh execution time, option h1 on tbp
     #*testtbl14 - field hdngs from mvft1, h1 on tbp
     #
     # uvcopy testtbl14  <-- execute uvcopy to interpret this parameter file
     # ================    - files default as coded below on fili1=... & filo1=...
     #
     opr='$jobname - summarize sales (thisyr&lastyr) by province'
     rop=r1x8   #EOF options to display output file (cat $filo1)
     fili1=dat1/custmas1,rcs=256,typ=RSF
     filo1=tmp1/$jobname,rcs=80,typ=LSTt
     @run
            opn       all
     # begin loop to read all customer master sales history records
     # - crossfooting & accumulating (tabling) thisyr & lastyr totals
     loop   get       fili1,a0(256)
            skp>      eof
            xft       $ca1,a120(5p),12
            xft       $ca2,a180(5p),12
            tblt1f2   a77(2),' ',$ca1,$ca2   #<-- hdngs via mvft1 $tbh1,'...' at EOF
            skp       loop
     # EOF - print/edit table to file for: cat $filo1 (options rop=r1x8 above)
     eof    mvft1      $tbh1,'Province;This Year Sales;Last Year Sales'
            tbpt1h1   filo1,'testtbl14 - field hdngs via: mvft1h1 $tbh1,...'
            cls       all
            eoj
     #
     # testtbl14  2019/05/26_12:35:04  testtbl14 - field hdngs via: mvft1h1 Province;This,
     # tbl#0001  tblt1f2   a77(2)       argument            -acum#1-    %        -acum#2-    %
     # line#   1strec#  %      count  Province       This Year Sales      Last Year Sales
     #     1        15   9         3  AB                      323.13    0        1,534.06    3
     #     2        13  34        11  AL                   29,530.35   29       35,979.84   79
     #     3         1  53        17  BC                   64,943.24   65        7,926.94   17
     #     4        20   3         1  NW                    4,901.21    4
     #                 100        32*  *TOTAL*             99,697.93 *100       45,440.84 *100

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    `table formats` - supplied formats available (f1-f12)

     tbff1  p31(32),'zz,zzz,zzz,zz9- %%9- zz,zzz,zzz,zz9- %%9-      .etc.' DEFAULT
     tbff2  p31(32),'zzz,zzz,zzz.99- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff3  p31(32),'zz,zzz,zzz,zz9- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff4  p31(48),'zz,zzz,zzz,zz9- %%9- zz,zzz,zzz,zz9- %%9-      .etc.'
     tbff5  p31(48),'zzz,zzz,zzz.99- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff6  p31(48),'zz,zzz,zzz,zz9- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff7  p31(64),'zz,zzz,zzz,zz9- %%9- zz,zzz,zzz,zz9- %%9-      .etc.'
     tbff8  p31(64),'zzz,zzz,zzz.99- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff9  p31(64),'zz,zzz,zzz,zz9- %%9- zzz,zzz,zzz.z9- %%9-      .etc.'
     tbff10 p31(32),'zzz,zzz,zzz.99- %%9.%%- zzz,zzz,zzz.99- %%9.%%-.etc.'
     tbff11 p31(32),'zz,zzz,zzz,zz9- zz,zzz,zzz,zz9-                .etc.'
     tbff12 p31(32),'zzz,zzz,zzz.99- zzz,zzz,zzz.z9-                .etc.'
          count%        ---acum#1---  ----acum#2----       max-print max-print
     fmt# dcmls arg-lth dcmls %dcmls  dcmls %dcmls acum3-6  2 acums   6 acums
     f1     0     32       0      0      0      0  same as     78      149  DFLT
     f2     0     32       2      0      2      0  acum #2     78      149
     f3     0     32       0      0      2      0     "        78      149
     f4     0     48       0      0      0      0     "        94      181
     f5     0     48       2      0      2      0     "        94      181
     f6     0     48       0      0      2      0     "        94      181
     f7     0     64       0      0      0      0     "       110      197
     f8     0     64       2      0      2      0     "       110      197
     f9     0     64       0      0      2      0     "       110      197
     f10    2     32       2      2      2      2     "        84      171
     f11    0     32       0      -      0      -     "        68      115
     f12    0     32       2      -      2      -     "        68      115

    description of pre-programmed formats

    f1
    • arg 32 bytes, acums all 0 dcmls (qtys), percentages all 0 dcmls
    • 'f1' is the DEFAULT format if unspecified on the 'tbl' instruction
    f2
    • arg 32 bytes, cums all 2 dcmls ($ & cents), percentages all 0 dcmls
    f3
    • arg 32 bytes, acum#1 0 dcmls (qty), acums2-6 2 dcmls, %'s all 0 dcmls
    f4
    • arg 48 bytes, acums all 0 dcmls (qtys), percentages all 0 dcmls
    f5
    • arg 48 bytes, acums all 2 dcmls ($ & cents), percentages all 0 dcmls
    f6
    • arg 48 bytes, acum#1 0 dcmls (qty), acums2-6 2 dcmls, %'s all 0 dcmls
    f7
    • arg 64 bytes, acums all 0 dcmls (qtys), percentages all 0 dcmls
    f8
    • arg 64 bytes, acums all 2 dcmls ($ & cents), percentages all 0 dcmls
    f9
    • arg 64 bytes, acum#1 0 dcmls (qty), acums2-6 2 dcmls, %'s all 0 dcmls
    f10
    • arg 32 bytes, acums all 2 dcmls ($ & cents), percentages all 2 dcmls
    f11
    • arg 32 bytes, acums all 0 dcmls (qtys), no percentages
    f12
    • arg 32 bytes, acums all 2 dcmls ($ & cents), no percentages

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    Notes re the pre-programmed table formats shown on the preceding page

    The edit patterns are shown only for the 1st 2 sets of (acum & %) on each line because acums 3-6 are always the same as acum #2 (for these pre-programmed formats).

          tbff3  p31(32),'zz,zzz,zzz,zzz- %%%- zz,zzzz,zzz.zz- %%%-  ..etc..'

    Accumulator digit positions are indicated with 'z's & percentage digit positions are indicated with '%' symbols.

    There must be 1 space between the edit patterns. On the total line, the space following the acum will be set to an "*" to identify the total line.

    Percentage edit patterns should always be at least 3 long.

    You can use 9's in trailing positions of either accumulator or percentage edit patterns to stop zero suppress.

          tbff3  p31(32),'zz,zzz,zzz,zz9- %%9- zzz,zzz,zz9.99- %%9.99-  ..etc..'

    The maximum print position assumes that all 6 acums are present which is rarely the case.

    All acums are 10 digits max & are either 0 decimals (quantity) or 2 decimals (dollars & cents).

    If none of these pre-programmed formats fits your requirements, you can re-specify any or all of these to your desired format via the 'tbf' instruction.

    Note
    • If you are reading this documentation as printed by 'uvlist' or 1 of the uvlist scripts such as uvlp12D (Duplex) any 2 conseccutive '%'s will print as '%.'
    • IE, the 2nd '%' is converted to '.' by uvlist because 2 consecutive '%'s is a postscript command which mucks up printing even though I use PCL5 (vs postscript)

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    sample report - for pre-programmed format discussion

     testtbl11  2019/05/26_12:19:19  testtbl11 - field hdngs via op2 of tbl (default)
     tbl#0001  tblt1f2   a77(2)       argument            -acum#1-    %        -acum#2-    %
     line#   1strec#  %      count  province          thisyr sales         lastyr sales
         1        15   9         3  AB                      323.13    0        1,534.06    3
         2        13  34        11  AL                   29,530.35   29       35,979.84   79
         3         1  53        17  BC                   64,943.24   65        7,926.94   17
         4        20   3         1  NW                    4,901.21    4
                     100        32*  *TOTAL*             99,697.93 *100       45,440.84 *100
           tbff1  p31(32),'zz,zzz,zzz,zzz- %%%- zz,zzz,zzz,zzz- %%%-  ..etc..'

    All pre-programmed formats allow for line#, count,& % of count in the 1st 17 print positions & this is why the pre-programmed formats all specify the argument field as p31(xx).

    If you wanted count % edited to 2 decimals, you could specify option 'd2' & specify the argument operand as p20(32) or whatever.

           tbff1d2  p20(32),'zz,zzz,zzz,zzz- %%%- zz,zzz,zzz,zzz- %%%-  ..etc..'

    If you did not want any count percentage, you could specify option 'd9' & then specify the argument operand as low as p14(xx)

    The actual argument data length is specified on the tbl instruction & would usually be less than & left justified within the tbf specification.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    `table entry layout` - dumped by tbd (unedited)

     000-000 (character) - 'T' to identify a valid table entry
     001-003 (character) - table# zoned numeric 000-999
     004-051 (character) - table argument, 48 bytes max, blank filled on right
                           ^G*TOTAL* in 1st 8 bytes for table Total record
     052-055 (binary)    - sequence# of entry when written to output file
     056-059 (binary)    - hit count, no of matches/adds to this entry
     060-063 (binary)    - table#

    accumulators for 32 bit versions

     064-067 (binary)    - accumulator #1
     068-071 (binary)    - accumulator #2
     072-075 (binary)    - accumulator #3
     076-079 (binary)    - accumulator #4
     080-083 (binary)    - accumulator #5
     084-087 (binary)    - accumulator #6
     088-111             - not used

    accumulators for 64 bit versions

     064-071 (binary)    - accumulator #1
     072-079 (binary)    - accumulator #2
     080-087 (binary)    - accumulator #3
     088-095 (binary)    - accumulator #4
     096-103 (binary)    - accumulator #5
     104-111 (binary)    - accumulator #6
     112-115 (binary)    - record# of 1st record with this argument
     116-119             - unused

    optional fields at end of dumped entries

     120-135 - jobname (of uvcopy job creating the table)
     136-149 - date & time created, 14 characters yyyymmddhhmmss
     150-xxx - operand 2 (if any) from the 'tbd' instruction
             - max length would depend on the rcsz declared on the output file

    sample 'tbd' (table dump) & notes

        tbd   filo1,'x---appended to dumped entries---x'

    The record size written by 'tbd' depends on the rcs= declared on the "filo1" declaration, for example:

     filo1=tmp/tablexxx,rcs=160,typ=RSF

    This example (rcs=160) include space for the optional items (jobname, datetime,operand 2), and the 1st 16 bytes from op2 of the tbd instruction. "rcs=72" will include the 1st 2 acums if 32 bit & only the 1st acum if 64 bit.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    32 bit vs 64 bit

    Note that 64 bit versions (of uvcopy & uvqrpg) are available on some machines & architectures, as documented in doc/install.doc. As of May 2000 these are:

    1. Dec Alpha - 64 bit hardware & software (DEC C long = 64 bits).
    2. UnixWare 7+ on Intel 32 bit hardware. You may compile uvcopy for 32 bit or 64 bit acums (via software).
    3. UW 7+ on Intel 64 bit hardware (Itanium chip available in 2001).

      more notes re tbd - table dump

    The table total control record would be written out first & it has the same format as the table entry detail records shown above.

    It can be identified by the x'07' in the 1st byte of the argument. or possibly '*TOTAL' in bytes 2-7 of the argument if you know you cannot have this in your data.

    The control record carries the totals on which the 100% calcs are based. The sequence# would carry the total no of entries in the table.

    You would only need to know the table entry layout when & if you are using the 'tbd' instruction to dump the tables (unedited) into a file for subsequent processing.

    For example, you could collect table records for each day, week,or month & then re-table them for summaries at the end of the week, month,or year.

    The records will be written out with the length specified by the 'rcs' parameter on the output file. The records will have no linefeeds since they contain binary fields.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    run options to increase number of tables & entries

    Table entries are 88 bytes each & storage is assigned dynamically as required via memory requests from the operating system.

    However the number of table control structures & the pointers to the table entries are assigned within fixed areas within the uvcopy program.

    The defaults allow for 12 tables & 1000 total entries for all tables.

    If you exceed 12 tables or 1000 total table entries, you will get an error message. You would then increase the maximums via run options "u" &/or "v" and rerun your job.

    rop=u10
    • the default number of tables (these entries are 184 bytes each)
    rop=v4000
    • the default no of entries for all tables (these entries are 8 bytes each)
    rop=u20
    • would increase no of tables allowed to 20
    rop=v8000
    • would increase no of entries to 8000 (for all tables)
    
     uvcopy tbljob,rop=u20v8000  - u & v may be coded on command line
     ==========================
     # tbljob
     rop=u20v8000                - better to code within the parameter file
     fili1=xxxx,rcs=999,typ=RSF
     filo1=yyyy,rcs=80,typ=LSTt
     @run
              opn    all
          --- etc ---

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    tbl sample #2 problem & solution

    given
    • a payroll master file with the following relevant fields 11-13 - department# 14-17 - job class 21-24 - year of birth 51-55 - ytd hours regular (packed) 56-60 - ytd hours overtime (packed) 61-65 - ytd gross pay (packed) 66-70 - ytd tax (packed) 71-75 - ytd pension (packed) 76-80 - ytd insurance (packed)
    required
    • accumulate 6 values (ytd reghrs,othrs,gross,tax,pension,insur) into 3 tables: by dept, by job class, by birth year

    solution

     # tblprm - table analysis of the payroll master file
     # - accumulating ytd reghrs,othrs,gross,tax,pension,& insurance
     #   by dept, job class, birth yr,& dept + birth yr
     opr='$jobname - table analysis of the payroll master file'
     fili1=paymaster,rcs=256,typ=RSF
     filo1=$jobname.tmp,rcs=132,typ=LSTt
     @run
           opn    all
      # declare tbl format: acums 1&2 1 dcml, acums 3-6 2 dcmls (4-6 duplicated)
           tbff1  p17(10),'zz,zzz.z- %%%- zz,zzz.z- %%%- zzz,zzz.zz- %%%-'
     # declare tbl headings - for accumulators, argument modified by each tbl
           tbhh1  'Dept;reg hrs; over hrs; gross; tax; pension; insurance'
           tbhh2  'Class;reg hrs; over hrs; gross; tax; pension; insurance'
           tbhh3  'BirthYear';reg hrs; over hrs; gross; tax; pension; insurance'
     #
     # begin loop to get records & build tables until EOF
     loop  get    fili1,a0(256)             get a record
           skp>   eof                       ( cc set > at EOF)
        tblt1f1h1 a10(3),'dept',a50(5p),a55(5p),a60(5p),a65(5p),a70(5p),a75(5p)
        tblt2f1h2 a13(4),'class',a50(5p),a55(5p),a60(5p),a65(5p),a70(5p),a75(5p)
        tblt3f1h3 a20(4),'birth',a50(5p),a55(5p),a60(5p),a65(5p),a70(5p),a75(5p)
     #Note - field headings on 'tbl' ignored when option 'h' on tbl
           skp    loop                      repeat loop until EOF
     #
     # EOF - dump (print/edit) tables to output file & then print via 'lp'
     eof   tbhh1  'dept;reg hrs; over hrs; gross; tax; pension; insurance'
           tbhh2  'class;reg hrs; over hrs; gross; tax; pension; insurance'
           tbhh3  'birthyear';reg hrs; over hrs; gross; tax; pension; insurance'
     #Note - Alternative, could declare fileld headings at EOF time vs setup time (above)
           tbpt1h1  filo1,'payroll stats by Dept'
           tbpt2h2  filo1,'payroll stats by Class'     <-- Print the tables
           tbpt3h3  filo1,'payroll stats by BirthYear'     (write to file for lp)
           cls    all
           eoj                              end job

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    notes re tblprm sample job on the previous page

    The tblprm sample job illustrates several important points & to facilitate discussion, the relevant tbl instructions are reproduced below.

                    ----- setup (file open time) -----
     1.  tbff1  p17(10),'zz,zzz.z- %%%- zz,zzz.z- %%%- zzz,zzz.zz- %%%-'
     2.  tbhh1  'Dept;reg hrs; over hrs; gross; tax; pension; insurance'
                       ----- program loop -----
     3. tblt1f1h1 a10(3),'dept',a50(5p),a55(5p),a60(5p),a65(5p),a70(5p),a75(5p)
                         ----- EOF/EOJ -----
     2a.   tbhh1  'dept;reg hrs; over hrs; gross; tax; pension; insurance'
    1. tbpt1h1 filo1,'payroll stats by Dept'
     1 - The 'tbff1' stores the table format 'f1' to be used when the tables
         are printed out at the end of the job by the 'tbp'.
       - Op1 p17(10) defines the print area for the argument (dept,class,birth)
       - Op2 defines the edit patterns for the 6 accumulators & their percentages
       - Note that we had to define this custom tbf because none of the standard
         12 formats fit our requirements (acums 1 & 2 with 1 decimal for hours
         & acums 3-6 edited to 2 decimals for dollars & cents).
       - We did not have to code the edit patterns for acums 4-6, because the
         right most edit patterns are duplicated to the remaining sets.
     2 - tbhh1 - tbhh3 stores the headings to be used when the tables are printed
         out at the end of the job by the 'tbp'.
     3 - The above logic is possible because the 'tbl' instruction (at setup
         time) also creates a control structure for each unique tbl#.
         The control structure holds the headings integrated from the tbl &
         the tbh. The control structure also holds the totals for all accumulators
         to allow percentage calculations of 100% before we reach the total line.

    2a. Alternatively, we could declare the field headings at EOF (vs setup time)

     4 - tbpt1h1 - tbpt3h3 prints (edits) all tables into a file which is then
         actually printed via the UNIX 'lp' command.
       - The proper headings will be associated with each table.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 13 "table" - tbl, tbf, tbh, tbp, tbd

    Alternate ways to specify argument & acum field headings

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 14 Delimit/Undelimit - "ftd"' & dtf

    `ftd` - Fixed-field To Delimited

     The 'ftd' instruction converts Fixed-fields (defined by COBOL copyboks)
     to Delimited format for loading DataBase Tables. See documentaion at
     'DATAcnv1.doc#4M3' or 'https://uvsoftware.ca/datacnv1.htm#4M3'.

    The 'ftd' built-in instruction added in Oct 2014 to allow fields > 100 bytes, a limitation of the previously used combination of 'mvc's & 'edt's to store fields 100 bytes apart, followed by a 'var' instruction to insert delimiters.

    'ftd' appends the data from each field to area 'c', controlled by register 'c'. The 'get' instruction clears register 'c' & area 'c' must be cleared after outputting each record & before repeating the loop.

    Here are a few of the 'ftd' instructions (used in the demo job 'citytax1' at 'DATAcnv1.doc#4M3'), followed by the corresponding COBOL copybook field definitions, 1st record of the demo data file,& the 1st 3 records in the delimited output file.

     loop   get    fili1,a0                <-- get resets register 'c'
            ftd    b0(10c)                            #1 folio
            ftd    b10(25c)                <-- 'ftd' appends to area c + '|'
            ftd    a88(4bs),'+zzzzzz9'                #7 post-date
            ftd    a92(5p),'+zzzzzzzz9'               #8 land-value
            ftd    b107(9z),'+zzzzzzz.99'             #11 maint-tax
            put    filo1,c0                <-- write out current record
            clr    c0($rc64000),' '        <-- clear area 'c' for next record
            skp    loop
     cpys/citytax1                  citytax1           RCSZ=00128  bgn  end  lth typ
          10 folio                 pic  x(00010).                 0000 0009  010
          10 name                  pic  x(00025).                 0010 0034  025
          10 post-date             pic s9(00007) comp-4.          0088 0091  004bns 7
          10 land-value            pic s9(00009) comp-3.          0092 0096  005pns 9
          10 maint-tax             pic s9(00007)v99.              0107 0115  009 ns 9
     uvhd d2asc/citytax1 r128
     records=10 rsize=128 fsize=1280
                          10        20        30        40        50        60
     r#        1 0123456789012345678901234567890123456789012345678901234567890123
               0 10130140  JOHN HENRY               1815 BOWEN ROAD          VANC
                 3333333322444424445522222222222222233332445442544422222222225444
                 1013014000AF8E085E29000000000000000181502F75E02F14000000000061E3
              64 OUVER           BCV9S1H1..C...W.........qq.000149061970530
                 455452222222222244535343004D005880008000770333333333333333222222
                 F5652000000000002369318101320072C0047C0111C000149061970530000000
     10130140|JOHN HENRY|1815 BOWEN ROAD|VANCOUVER|BC|V9S1H1|+82898|+57828|+4870|+171710|+1490.61|970530| |
     10139923|GEORGE BROWN|1250 EAST PENDER ST.|VANCOUVER|BC|V5L1W1|+82898|+57828|+4878|+178524|-1462.61|980601| |
     10147615|BONNIE SMITH|44430 YALE ROAD WEST|VANCOUVER|BC|V2P6J1|+121395|+39623|+0|+51914|+376.92|950601| |

    See the corresponding 'dtf' instruction at 'uvcopy3.doc#dtf'.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 14 Delimit/Undelimit - ftd & "dtf"

    `dtf` - Delimited To Fixed-field

    The 'dtf' instruction converts Delimited format To Fixed-fields (usually defined by a COBOL copybok). See documentaion at 'DATAcnv1.doc#4N3' or 'https://uvsoftware.ca/datacnv1.htm#4N3'.

    The 'dtf' built-in instruction added in Oct 2014 to allow fields > 100 bytes, a limitation of the previously used combination of a 'fix' instruction to store fields 100 bytes apart, followed by a series of mvc's or mvn's to store the fields in the output record as defined by the COBOL copybook.

    Each 'dtf' extracts data from area 'c', controlled by register 'c', until the next delimiter is reached. The 'get' instruction resets register 'c'.

    Here are a few of the 'dtf' instructions (used in the demo job 'citytax1' at 'DATAcnv1.doc#4N3'), followed by the corresponding COBOL copybook field definitions, the 1st 3 records of the delimited input file,& the 1st record of the output fixed-field record.

     loop   get    fili1,a0
            dtf    d0(10c),c0,'folio'
            dtf    d10(25c),c0,'name'
            dtf    d88(4b),c0,'post-date'
            dtf    d92(5p),c0,'land-value'
            dtf    d107(9z),c0,'maint-tax'
            put    filo1,d0
            skp    loop
     cpys/citytax1                  citytax1           RCSZ=00128  bgn  end  lth typ
          10 folio                 pic  x(00010).                 0000 0009  010
          10 name                  pic  x(00025).                 0010 0034  025
          10 post-date             pic s9(00007) comp-4.          0088 0091  004bns 7
          10 land-value            pic s9(00009) comp-3.          0092 0096  005pns 9
          10 maint-tax             pic s9(00007)v99.              0107 0115  009 ns 9
     10130140|JOHN HENRY|1815 BOWEN ROAD|VANCOUVER|BC|V9S1H1|+82898|+57828|+4870|+171710|+1490.61|970530| |
     10139923|GEORGE BROWN|1250 EAST PENDER ST.|VANCOUVER|BC|V5L1W1|+82898|+57828|+4878|+178524|-1462.61|980601| |
     10147615|BONNIE SMITH|44430 YALE ROAD WEST|VANCOUVER|BC|V2P6J1|+121395|+39623|+0|+51914|+376.92|950601| |
    
     uvhd d2asc/citytax1 r128
     ========================
     records=10 rsize=128 fsize=1280
                          10        20        30        40        50        60
     r#        1 0123456789012345678901234567890123456789012345678901234567890123
               0 10130140  JOHN HENRY               1815 BOWEN ROAD          VANC
                 3333333322444424445522222222222222233332445442544422222222225444
                 1013014000AF8E085E29000000000000000181502F75E02F14000000000061E3
              64 OUVER           BCV9S1H1..C...W.........qq.000149061970530
                 455452222222222244535343004D005880008000770333333333333333222222
                 F5652000000000002369318101320072C0047C0111C000149061970530000000

    See the corresponding 'ftd' instruction at 'uvcopy3.doc#ftd'.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 15 (misc) - "ran", vnf, xxa,xxb,xxc

    `ran` - generate random numbers

    
           ran   number,low,high    <-- generate a random# in op1
           =====================        in a range from op2 to op3
    
           ran   $ca10,1000,2000    <-- generate random# in $ca10
           =====================        between 1000 & 2000
    
           ran   $ca10,$ca11,$ca12  <-- generate random# in $ca10
           =======================      between $ca11 & $ca12

    Here is uvcopy job to test the 'ran' instruction, run as follows:

    
           uvcopy testrandom1   <-- run uvcopy job to test 'ran'
           ==================     - supplied in $UV/pf/adm/testrandom1
     # testrandom1 - uvcopy job to test the 'ran' random# generator
     #             - by Owen Townsend, UV Software, March 2020
     #             - testjob stored at $UV/pf/adm/testrandom1
     #
     # uvcopy testrandom1  <-- start random# generator
     # ==================    - will prompt for number,low,high ranges
     # enter: number of random#s desired, low range, high range
     # --> 5,100,200  <-- example, gen 5 random#s between 100 & 200
     # random# 1 = 127
     # random# 2 = 176
     # random# 3 = 106
     # random# 4 = 123
     # random# 5 = 133
     @run
     man10   msg    'enter: number of random#s desired, low range, high range'
             msgwa1 '--> 5,100,200  <-- example, gen 5 random#s between 100 & 200'
             fix    a0(20),$arg1,3,','      separate to a0(20),a20(20),a40(20)
             mvnx3  $ca1,a0(20)             convert to binary in $ca1,$ca2,$ca3
             cmn    $ca3,0                  errchk high range entered ?
             skp<=  man90
     #
     # begin loop to generate $ca1 random#s between $ca2 & $ca3
     man20   add    $ca5,1                  count loops
     #       =====================
             ran    $ca4,$ca2,$ca3          gen current random# in $ca4
     #       =====================
             msgv1  'random# $ca5 = $ca4'   show current loop count & random#
             cmn    $ca5,$ca1               loop ctr = number requested ?
             skp=>  man80                   yes - goto End JOb
     #
             skp    man20                   no - repeat loop
     man80   eoj                            yes - End job
     # Error if high range not entered
     man90   msgl2  'ERROR - high range not entered, can retry'
             skp    man10

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 15 (misc) - ran, "vnf", xxa,xxb,xxc

    `vnf` - Verify Numeric Field

    'vnf' Verifies Numeric Field digits & sign (packed or zoned), and sets the condition code =/! to indicate OK/errors. vnf stores error counts (see below).

          vnf    field,count,'field name' <-- instruction format
          skp>   error                      - cc set > if any error
          skp=   good                       - cc set = if no error
          vnf    a0(6z)          <-- verify 1st 6 bytes area a (numeric zoned)
          vnft3  a0(6),1,'cust#' <-- may specify option 't1' on 1st vnf in job
                                     to init area t tabale of errors
                                   - option t2 acums errs in area t to dump at EOJ
                                   - op3 fieldname optional (will show in area t)
          vnft2  a120(5p),12,'monthly-sales' <-- verify 12*5 byte packed
                                   - op2 may specify a repeat count
                                     for multiple contiguous same size fields
     option x#  - repeat # times, incrementing op1 by its length
                 (also increment op2 if an address & not a constant)
            j#  - alternate length to increment op1 (vs op1 lth coded)
            k#  - alternate length to increment op2 (vs op2 lth coded)

    Error Counters stored by vnf

          cmn    $ce3,1      <-- test $ce3 for any errors (digits or signs)
          skp>   err

    $ce1,$ce2,$ce3 store error counts for digits,signs,total for last vnf. $ce11,$ce12,$ce13 accumulate error counts for digits,signs,total since vnft1 (ie for current record).

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 15 (misc) - ran, "vnf", xxa,xxb,xxc

    area 't' error report

    vnf also builds a table of field errors in area 't'. You may init the table by specifying option 't1' (of vnft3) on the 1st vnf in the job. Code option 't2' on subsequent vnf's to acumulate errors in area 't' to dump at EOJ. Then use 'wtb' to dump the table after the last vnft2 for each record.

               1         2         3         4         5         6
     01234567890123456789012345678901234567890123456789012345678901234567
     ##p-<--------packed-hex----------> <---numeric---> 999 99 fieldname
     00-01 - field length in 2 digits
     02-02 - 'p' if packed, else ' ' blank
     03-03 - '-' neg sign if valid negative sign
     04-33 - hexrep of packed or numeric dat (15*2=30 bytes)
     35-49 - numeric zoned data (max 15)
     51-53 - current fili1 rec# (min 3 digits, will expand if reqd)
     55-56 - occurs# (if applicable, min 2 digits, will expand if reqd)
     55-80 or 58-80 - field dscrptn from vnf op3 (will shorten if reqd)
    Register 't'
    • points to (holds displacement of) next error entry to be stored
    • initialized by option t1 on 1st vnft3 in uvcopy job
    • incremented by 80 for each error detected & stored

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    uvcopy job to demo 'vnf' instruction

     # testvnf5 - test vnf (Verify Numeric Field) instrn
     #          - by Owen Townsend, UV Software, Jan 2009
     #          - test repeat option for multiple contiguous fields
     rop=r1
     was=t80000   #increase area t to 80,000 to allow 1000 * 80 byte entries
     fili1=dat1/cm1_testvnf,typ=RSF,rcs=256
     filo1=tmp/cm1vnferrs,typ=LSTt,rcs=80
     @run
            opn    all
     #
     # begin loop to test each record - until EOF
     man20  get    fili1,a0
            skp>   man90
            vnft3  a0(6),1,'customer#'
            vnft2  a120(5p),12,'this-year-sales'
            vnft2  a180(5p),12,'last-year-sales'
     #
     # End all vnf numeric field checks for current record
     # if any errs - dump area 't' table of vnf errors detected
     #             - write out cust# & name with err counts
     man50  cmn    $rt,0                any errs ?
            skp<=  man20
            wtbe   filo1,t0(80),t0(80)  dump table of errs detected
            mvf    b0(80),a0(35)        store cust# & name
            mvfv1  b36(44),'ERRs: $ce11 digits, $ce12 signs, $ce13 total'
            put    filo1,b0
            put    filo1,' '            space between records
            skp    man20
     #
     # EOF - close files & end job
     man90  cls    all
            eoj

    You can run the demo job as follows:

    
     #1. cd /home/uvadm
         ==============
    
     #2. uvcopy testvnf5
         ===============

    report generated by testvnf5

     06                    313358313430          13X140 001 customer#
     05p                     EE1234567C                 001 01 this-year-sales
     05p-                    EF0001669D                 001 12 last-year-sales
     13X140    EVERGREEN MOTORS LTD.     ERRs: 3 digits, 0 signs, 3 total
     05p                     0E3456789C                 003 12 last-year-sales
     139923    JOHNSTONE BOILER & TANKS  ERRs: 1 digits, 0 signs, 1 total
     06                    333135583132          315X12 026 customer#
     05p                     000123456E                 026 03 this-year-sales
     05p-                    EE0203040D                 026 04 last-year-sales
     315X12    PARTS PLUS                ERRs: 2 digits, 1 signs, 3 total

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    input file for testvnf5

    The test/demo file for testvnf5 is /home/uvadm/dat1/cm1_testvnf. It has 32 records of 256 bytes. We purposely created errors in rec#s 1,3,& 26. We will show you the uvhd display for record #1 only.

    
     uvhd dat1/cm1_testvnf    <-- use 'uvhd' for files with packed fields
     =====================
                          10        20        30        40        50        60
     r#        1 0123456789012345678901234567890123456789012345678901234567890123
               0 13X140    EVERGREEN MOTORS LTD.    1815 BOWEN ROAD          NANA
                 3353332222454545444244545524542222233332445442544422222222224444
                 138140000056527255E0DF4F230C44E0000181502F75E02F140000000000E1E1
              64 IMO          BC V9S1H1    250-754-5531 LARRY WRENCH     ..4V|...
                 44422222222224425353432222333233323333244555255444422222E1357000
                 9DF00000000002306931810000250D754D55310C12290725E3800000E246C000
             128 .........W0....`........)X}..f3.....\.................4V}...f...
                 0000000005300016000000002570063100095000000000000000013570016000
                 0C0000C0270D0540C0000C0098D0263C0444C0000C0000C0000C0246D0056C00
             192 .E|...V}.......................f.....<........f.C 19950531
                 0470005700000000880000000018000680001300000E00694233333333222222
                 35C0046D0000C0023C0000C0083C0056D0012C0000CF016D3019950531000000

    errors created in rec#1

    000-005 - '13X140', 'X' in numeric zoned field (customer#)

     120-124 - x'EE1234567C', x'EE' in 1st byte of 1st 5 byte packed field
             - in 2nd segment (starting at byte 64 on left)
             - x'EE' under byte 56 (on top scale) + 64 (begin segment) = 120
     235-239 - x'EF0001669D', x'EF' in 1st byte of 24th 5 byte packed field
             - in 4th segment (starting at byte 192 on left)
             - x'EF' under byte 43 (on top scale) + 192 (begin segment) = 235

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    group 15 (misc) - ran, vnf, "xxa", xxb, xxc

    `xxa` - call user subfunction (written in C & linked to uvcopy)

    xxa,xxb,& xxc instructions are provided to call user subfunctions. These subfunctions must have been compiled & archived to /home/uvadm/lib/uvlib.a so they can be linked to uvcopy.

    uvsubxxa.c, uvsubxxb.c,& uvsubxxc.c are 3 dummy subfunctions provided in subdir /home/uvadm/srcf/... that you may modify with your desired C code. Here is uvsubxxa.c, which includes the procedure required:

    NOTE
    • see instructions embedded in the uvsubxxa.c source code below:

    uvsubxxa.c subfunction for uvcopy instruction 'xxa'

     /* uvsubxxa.c - dummy subfunction for uvcopy&uvqrpg user instrn xxa       */
     /*            - also see uvsubxxb.c for xxb & uvsubxxc.c for xxc          */
     /*                                                                        */
     /* /home/uvadm/srcf/uvsubxxa.c  <-- this code stored in subdir 'srcf'     */
     /* /home/uvadm/lib/uvlib.a      <-- for link & archive to uvlib.a         */
     /*                                                                        */
     /* 1. cd /home/uvadm                                                      */
     /* 2. vi srcf/uvsubxxa.c           <-- modify dummy instrn with yours     */
     /* 3. ccf uvsubxxa INT I32 NOISAM  <-- compile & archive to lib/uvlib.a   */
     /* 4. ccc uvcopy INT I32 DISAM     <-- recompile&link uvcopy with subrtns */
     /*                                                                        */
     /* uvcopy instructions xxa, xxb, xxc have no operands                     */
     /* - areas i,j,k must be stored for subrtn arg1,2,3 (see area1,2,3 below) */
     /* - instrn ctrs 21,22,23 must be stored for arg4,5,6 (see ctr1,2,3 below)*/
     /* - ctrs are defined here as long, but in uvcopy/uvqrpg as UVi64         */
     /*   which is long if I32 but long long if I64 (modify here if I64)       */
     /* - ctrs are pointers so you can store them as well as reference them    */
     /*                                                                        */
     #include <stdio.h>
     int uvsubxxa(char *area1, char *area2, char *area3,
                     long *ctr1, long *ctr2,  long *ctr3)
     {
     int ii;
     /* ............ user would code his desired function here .............. */
     /* - this dummy function will copy area2 to area1 for length in ctr1     */
     /*   & store the actual length in ctr2                                   */
     memcpy(area1, area2, *ctr1);
     for (ii=80; ii > 0; ii--)
       { if (area1[ii] > ' ')
            break;
       }
     *ctr2 = ii;
     return(ii);
     }
     See sample job to test 'xxa' & 'uvsubxxa.c' on the next page --->

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    'testxxa' - sample job to test xxa & ubsubxxa.c

     # testxxa - test user instrn June 29/00
     #         - see srcf/uvsubxxa.c & uvcopy instrn xxa
     # - uvsubxxa.c copies area 'j' to area 'i' for length in $ci21
     # - stores actual lth in $ci22, & returns lth (to set cc in uvcopy)
     # - instrns xxa,xxb,xxc pass character pointers to areas i,j,& k, and
     #   long pointers to instruction counters $ci21, $ci22,& $ci23
     @run
            msgwa1 'test user instrn xxa - enter something to copy via xxa'
            mvc    j0(80),$arg1             store data in area j
            mvn    $ci21,30                 store lth to copy
     #-----------------------------------------------------------------------
            xxa                             # xxa copies j to i for lth $ci21
     #-----------------------------------------------------------------------
            mvn    $ci24,$cc                save condition code for msg below
            msg    i0(80)                   display output data
            msgv1  'max lth = $ci21, actual lth $ci22, cc = $ci24    '
            eoj

    This job is supplied in /home/uvadm/pf/testxxa & you can run as follows:

    
     uvcopy testxxa
     ==============

    test xxa, enter some text: --> how long is this ? how long is this ? max lth 30, actual lth 17

    This test stores input for the uvsubxxa.c subrtn in area 'j', calls the 'xxa' instruction, and displays area 'i' (output of uvsubxxa.c).

    You can modify uvsubxxa.c with your own desired code, recompile uvsubxxxa, and recompile uvcopy (to link new uvsubxxa from archive lib/uvlib.a)

    1. cd /home/uvadm
    2. vi srcf/uvsubxxa.c <-- modify dummy instrn with yours
    3. ccf uvsubxxa INT I32 NOISAM <-- compile & archive to lib/uvlib.a
    4. ccc uvcopy INT I32 DISAM <-- recompile&link uvcopy with subrtns
     If desired, you can add more 'own code' instructions to uvcopy.c.
     I suggest you use vi to search for 'xxa'. You will easily see where you
     can add more instructions (xxd,xxe,xxf,etc). Then add the corresponding
     uvsubxxd.c, etc to /home/uvadm/srcf/, compile them with 'ccf',& recompile/
     relink uvcopy (as shown above).

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J0. uvcopy DEBUGGER - rop=d

    `debug` - uvcopy DEBUGGER - Contents

    Note
    • this is the same as 'uvcopy2.htm#J0' - J13 & 'UVdemos1.doc#Part_8'
    • links J1-J13 don't work here since links in uvcopy3 based on instruction codes

    J1. Debugging uvcopy jobs - Run OPtion rop=d
    Listing of $UV/pf/demo/fixUSstates1.csv uvcopy job to demo debugging <

    J2. Debug demo session#1 - using uvcopy fixUSstates1 & testfile USstates.csv
    uvcopy fixUSstates.csv,rop=d - USstates.csv to fixed-field

    J3. Debug Command Summary (group1) - Display Data-Areas, Counters, Registers
    'd' (or 'p') to Display (or Print) Data Areas (a,b,c...x,y,z)
    'a' (or 'c') to display Accumulators (or Counters)

    J4. Debug Command Summary (group2) - Breakpoints & Gotos
    b# tag - store break-point tags b1,b2,b3 for gotos g1,g2,g3,g4,g5
    b1/b2/b3/b4/b5 tag - set breakpoint tags for corresponding gotos g1/g2/g3/g4/g5
    b1/b2/b3/b4/b5 - - clear breakpoint if tag spcfd as '-'
    g# - execute until reaching an instruction with label matching b#
    g1/g2/g3/g4/g5 - executes until finding a label matching stored b1/b2/b3/b4/b5
    g - executes until finding a label matching any 1 of b1/b2/b3/b4/b5
    g1/g2/g3/g4/g5 tag - store this tag in b1/b2/b3/b4/b5 & execute until we find it
    g tag - ERROR: tag Allowed only with g1/g2/g3/g4/g5
    G - executes until the end of the job, close files,& exit uvcopy
    s1 - set Subrtn display mode, shows instructions between bal & ret
    s0 - set Subrtn suppression, don't show instructions between bal & ret (default)

    J5. Debug demo session#2 - uvcopy extendsales1,rop=d

    J6. I/O files for extendsales1 uvcopy job (to demo debugging).
    dat1/productmaster - tabled in memory
    dat1/salesitems - INPUT file
    dat1/salesextended - OUTPUT extended with product price & dscrptn **

    J7. debug session#2 --> uvcopy extendsales1,rop=d
    - null entries to step thru instructions for 1st record cycle
    - d (or p) to Display (or Print) Data Areas (a,b,c...x,y,z)
    - a (or c) to display Accumulators or Counters (after 1st record)

    J8. p8 p0(50) - to display 1st 8 records in table area 'p' (50 bytes each)
    r - to display Registers

    J9. g3 man90 - to store label 'man90' in brkpt g3 & go to it
    c - to display counters (total for all records)
    G - to Goto EOJ (close files & end job)

    J10. Debug session#3 to demo Breakpoints & Gotos
    - see J4 above for summary of Breakpoint & Goto commands

    J11. debug session#4 - demo using only 'goto's without setting breakpoints
    J12. debug session#4 - Why product# ERRORs cause description '~~~~~~~~~'

    J13. Debug Command 'x' to Display Hexadecimal data

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J1. 'DEBUGGING' uvcopy parameter files - run option 'd'

    Most uvcopy programs will not require the debug option, but it can be useful for for larger complex programs especially if using index registers and program loops.

    Debug mode is invoked by appending ',rop=d' to the command line. You may also set debug mode via 'export UVCOPYROP=d' (for uvcopy jobs within scripts). In debug mode, uvcopy will display each instruction before execution & wait for an operator command. See the "Command Summary" on pages 'J3' & 'J4'.

    But first we will present a sample debug session to give you a good idea of debugging. We will demo the debug option using $UV/pf/demo/fixUSstates.csv listed below, & then executed with the debug option on the next page.

     # fixUSstates.csv - convert dat1/USstates.csv to tmp1/USstates.fix
     #                 - convert csv fields to space-filled 20 byte fixed-fields
     #
     #     ----- sample INPUT 1st 3 records -----
     # abr,state,state-pop,capital,capital-pop
     # AL,Alabama,4908620,Montgomery,205764,
     # AK,Alaska,734002,Juneau,31275,
     #
     #     ----- sample OUTPUT 1st 3 records -----
     # abr                 state               state-pop           capital             capital-pop
     # AL                  Alabama             4908620             Montgomery          205764
     # AK                  Alaska              734002              Juneau              31275
     #
     rop=r1    # EOF option prompt to view output file (vi,cat,more,head,etc)
     fili1=?dat1/USstates.csv,typ=LST,rcs=4096
     filo1=?tmp1/USstates.fix,typ=LST,rcs=4096
     @run
             opn     all                     open files
     # begin loop to get & put records until EOF
     getrec  get     fili1,a0                get record into area 'a'
             skp>    EOF                     (cc set > at EOF)
             mvc     b0(4096),a0             move in-area 'a' to out-area 'b'
     #-----------------------------------
             fix     b0(20),a0(100),6,','    convert csv to fixed-fields 20 apart
     #-----------------------------------
     putrec  put     filo1,b0                write to out-file from area 'b'
             add     $ca1,1                  count records for EOF msg
     return  skp     getrec                  return to get next record
     #
     EOF     cls     all                     close files
             msgv1   '$ca1 records converted to fixed-field from $fili1 to $filo1'
             eoj                             end job
    
     uvcopy fixUSstates.csv  <-- run demo job to convert USstares.csv to fixed-field
     ======================    - without debugging (omitting ',rop=d' from uvcopy command)
                               - see below to run with debugging (by appending ",rop=d")
    Note
    • You can run these demos, enter suggested debug commands,& match your results
    • login as uvadm OR yourself if you have copied $UV/demo/* to your $HOME/demo/...

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J2. Debugging uvcopy jobs - Run OPtion rop=d

    Debug session#1 - prior to command summary

    
     uvcopy fixUSstates.csv,rop=d   - run demo job to convert USstares.csv to fixed-field
     ============================   - 'rop=d' causes uvcopy to display each instruction
                                       & wait for operator command
                                    - 'null entry' executes next instruction
          0         opn    all                     open files
     debug>
        152 getrec  get    fili1,a0                get record into area 'a'
     debug>
        352         skp>   EOF                     (cc set > at EOF)
     debug>
        504         mvc    b0(4096),a0             move in-area 'a' to out-area
     debug>
        656         fix    b0(20),a0(100),6,','    convert csv to fixed-fields 2
     debug>
        880 putrec  put    filo1,b0                write to out-file from area '
     debug>
       1080         add    $ca1,1                  count records for EOF msg
     debug>
       1232         skp    getrec                  return to get next record
     debug> p a0
                            1         2         3         4         5         6         7         8         9       100
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->abr,state,state-pop,capital,capital-pop
     debug> p b0
                            1         2         3         4         5         6         7         8         9       100
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->abr                 state               state-pop           capital             capital-pop
     debug> a                                     <-- 'a' to display accumulators
            accumulators: ca1=1,
     debug> r                                     <-- 'r' to display registers
            registers: u=4096,v=39,x=100,z=92,
     debug> G                                     <-- 'G' to Goto EOJ
     20201109:472804:fixUSstates.: EOF fili01 rds=51 size=1916: dat1/USstates.csv
     20201109:472804:fixUSstates.: EOF filo01 wrts=51 size=4423: tmp1/USstates.fix
     51 records converted to fixed-field from dat1/USstates to tmp1/USstates
     uvcopy fixUSstates.csv start 2020/11/09_11:46:08 end 11:47:28 elapsed 001_19_700
     EOJ, Output File written to: tmp1/USstates.fix
     ----- enter: vi,cat,more,lp,uvlp13,etc (default null) --> head -3
     abr                 state               state-pop           capital             capital-pop
     AL                  Alabama             4908620             Montgomery          205764
     AK                  Alaska              734002              Juneau              31275

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J3. Debug Command Summary (group1) - Display Data

    Here is the Debug Command Summary, in 2 groups (Display DATA & Breakpoints/Gotos). You can try these out using the demo jobs listed on the preceding & following pages.

    Display data areas, accumulators, registers

    d/p
    • 'd' Display data area, or 'p' Print a data area
    p a0(100)
    • print(display) area 'a' from byte 0 - 99 (100) bytes default
    • print area may be any 1 of 'a' - 'z'
    p a
    • same as above since displacement defaaults to 0 & length to 100
    p b100(100)
    • print area 'b' bytes 100-199 (max line width 100 bytes)
    p5 c0(100)
    • print 5 lines c0(100,c100(100),c200(100),c300(100),c400(100)
    pe e0
    • Display area e0(100) translating Ebcdic to ascii
    px4 x0
    • Display area x0(100),x100(100),x200(100),x300(100) in hexadecimal
    • 3 line groups: line1 character, line2 hex zones, line3 hex digits
    • characters on line1 with unprintable bytes replaced by periods
    a/c
    • 'a' display Accumulators, or 'c' Counters (synonym)
    c
    • display counters, non-zero acums in bank 'a' $ca0-$ca24 (default) Example: counters: ca1=100,ca2=25,ca4=4,
    c b
    • display non-zero acums in bank 'b' $cb0-$cb24 example: ----- etc - 9 banks (a-i) of 25 acums -----
    c i
    • display non-zero acums in bank 'i' $ci0-$ci24 example: Example: cb1=300,cb2=2300000,
    • Note: 9 banks (a-i) of 25 acums each
    r
    • display Registers (in decimal, only non-zero registers) Example: registers: a=20000,b=84,d=20,s=1,u=50,v=200,x=50,z=80,
          ------- Display Data,Counters,Registers EXAMPLEs based on fixUSstates.csv (page 'J1') -------
     p a0
                     1         2         3         4         5         6         7         8         9       100
            1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
      ----->abr,state,state-pop,capital,capital-pop
     p b0
                     1         2         3         4         5         6         7         8         9       100
            1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
      ----->abr                 state               state-pop           capital             capital-pop
     a                                     <-- 'a' to display accumulators
     accumulators: ca1=1,
     r                                     <-- 'r' to display registers
     registers: u=4096,v=39,x=100,z=92,

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J4. Debug Command Summary (group2) - Breakpoints & Gotos

    Breakpoints

    null entry
    • single step, execute the instruction on display, then
    • then display the next instruction & prompt for a command or null to continue executing 1 at a time.
     b# tag             - store break-point tags b1,b2,b3,b4,b5 for gotos g1,g2,g3,g4,g5
     b1/b2/b3/b4/b5 tag - store breakpoint tags for gotos g1/g2/g3/g4/g5
     b1/b2/b3/b4/b5 -   - clear breakpoint if tag spcfd as '  -'
          ------- Breakpoint examples based on fixUSstates.csv (page 'J1') -------
     b1 getrec   - set Breakpoint#1 on the instruction with label 'getrec'
     b2 putrec   - set Breakpoint#2 on the instruction with label 'putrec'
     b3 EOF      - set Breakpoint#3 on the instruction with label 'EOF'

    Breakpoints are set using the labels on uvcopy instructions. The examples above are based on the uvcopy job listed on page 'J1' & the debug session on page 'J2'. Max 5 breakpoints at any 1 time, but you may redefine.

    Gotos

     g#                 - execute until reaching an instruction with label matching b#
     g1/g2/g3/g4/g5     - executes until finding a label matching stored b1/b2/b3/b4/b5
     g                  - executes until finding a label matching any 1 of b1/b2/b3/b4/b5
     g1/g2/g3.g4/g5 tag - store this tag in b1/b2/b3/b4/b5 & execute until we find it
     g tag              - ERROR: tag Allowed only with g1/g2/g3/g4/g5
     G                  - executes until the end of the job, close files,& exit uvcopy
          ------- Goto examples based on fixUSstates.csv (page 'J1') -------
     g2         <-- execute until reaching label 'putrec' (stored in b2 above)
     g          <-- execute until label matching any 1 of tags stored in b1/b2/b3/b4/b5
     g3 EOF     <-- replaces any existing b3 tag with 'EOF'
                    & executes until we find it

    Sub-Routine display instructions or Suppress

    s1
    • set Subrtn display mode, shows instructions between bal & ret
    s0
    • set Subrtn suppression, will not show instructions between bal & ret
    • the default is 's0' to inhibit showing subroutine instructions

    Display Data-Areas, Counters, Registers

    At any breakpoint, you may display areas,counters,registers as shown on prior page

    p a0
    • display areas relevant to current breakpoint 1 2 3 4 5 6 7 8 9 100 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 abr,state,state-pop,capital,capital-pop
    c a
    • display counters, non-zero acums in bank 'a' $ca0-$ca24 (default) counters: ca1=100,ca2=25,ca4=4,
    r
    • display Registers (in decimal, only non-zero registers) registers: a=20000,b=84,d=20,s=1,u=50,v=200,x=50,z=80,

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J5. Debug demo#2 - uvcopy extendsales1

    $UV/pf/demo/extendsales1 - 2nd job to demo debugging

     # extendsales1 - demo uvcopy table load (rtb) & table lookup (lok)
     #              - load product master file into memory table at begin job
     #              - extend sales items by looking up product master for price & dscrptn
     #              - see documentation at 'https://uvsoftware.ca/uvcopy3.htm#rtb'
     #Note - also used to demo uvcopy debugging, see 'https://uvsoftware.ca/uvcopy2.htm#J1'
     #
     # uvcopy extendsales1,fili1=dat1/salesitems,fili2=dat1/productmaster,filo1=tmp1/salesextended
     # ===========================================================================================
     # uvcopy extendsales1,rop=d  - same as above (files default as shown)
     # =========================  - ',rop=d' to debug, displays instructions before executing
     #  ** sample 1st record from input salesitems,productmaster,& output salesextended **
     #          1         2         3         4         5         6         7         8
     # 12345678901234567890123456789012345678901234567890123456789012345678901234567890
     # cust#    date   invoice# product qty
     # 130140 20200802 IN001001 BBQ010 000010
     #          1         2         3         4
     # 1234567890123456789012345678901234567890
     # Product#  Description      unit-price
     # BBQ010    BAR-B-Q             0019500
     #        1         2         3         4         5         6         7         8
     # 12345678901234567890123456789012345678901234567890123456789012345678901234567890
     # cust#    date   invoice# product qty     price   extended product description
     # 130140 20200802 IN001001 BBQ010 000010  0019500 000195000 BAR-B-Q
     #
     rop=r1       # EOF option prompt to view output file (vi,cat,more,etc)
     fili1=?dat1/salesitems,rcs=80,typ=LST      # sales item file
     fili2=?dat1/productmaster,rcs=80,typ=LST   # product master file
     filo1=tmp1/salesextended,rcs=100,typ=LST   # output items extended w price/dscrptn
     @run
            opn    all                      open all files
            rtb    fili2,p0(50),p0(50)      read product master into memory area 'p'
     #      ===
     # begin loop: read sales items, extending with price & dscrptn from table lookup
     man20  get    fili1,a0                 read next sales item record
            skp>   man90                    (cc set > at EOF)
     man22  mvc    b0(80),a0                copy input to output area
            lokz1  pp0(50),pp0(6),a25(6)    lookup table by product code
     #      ===
            skp=   man26                    (cc unequal if nomatch)
     man24  msg    'ERROR - product code not found',a25(6)
     man26  mvn    b40(7),pp30(7)           price from table
            mvn    b48(9),pp30(7)           price to amount for extension
            mpy    b48(9),b32(6)            master price * item qty = amount
     man28  mvc    b58(16),pp10             product dscrptn from table
            add    $ca1,b48(9)              accumulate total sales for EOF msg
     man30  put    filo1,b0                 write output
            skp    man20                    return to get next record
     # EOF - close files & end job (rop=r1 prompts to show output file)
     man90  cls    all
            msgv1  'Total sales = $ca1 in $filo1'
            eoj

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J6. Debug demo#2 - uvcopy extendsales1

    Here are the I/O files for the above extendsales1 uvcopy job (to demo debugging). This job was used to demo the 'rtb' instruction (documented at 'uvcopy3.htm#rtb'), by tabling a product master file, then looking it up by product# to extend a sales item file using the product master price & description.

    dat1/productmaster - to be tabled in memory

     Product#  Description      unit-price
              1         2         3         4
     1234567890123456789012345678901234567890
     ========================================
     BBQ010    BAR-B-Q             0019500
     HAM010    CLAW HAMMER         0000950
     HAM020    BALL HAMMER         0001200
     HAM035    JACK HAMMER         0029500
     SAW011    HAND SAW            0001975
     SAW012    RIP SAW             0002500
     SAW051    POWER SAW           0008500

    dat1/salesitems - INPUT file

     cust#  slsmn  date  invoice#  product quantity
              1         2         3         4
     1234567890123456789012345678901234567890
     ========================================
     cust#    date   invoice# product qty
     130140 20200802 IN001001 HAM035 000010
     139923 20200802 IN001002 SAW011 000020
     139923 20200802 IN001003 HAM020 000030
     250825 20200804 IN001104 BBQ010 000040
     250825 20200804 IN001004 SAW099 000050
     401210 20200816 IN001005 SAW051 000060

    dat1/salesextended - OUTPUT extended with product price & dscrptn

     cust#  slsmn  date  invoice#  product quantity  price   amount  product-dscrptn
              1         2         3         4         5         6         7         8
     12345678901234567890123456789012345678901234567890123456789012345678901234567890
     ================================================================================
     cust#    date   invoice# product qty     price   extended product description
     130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
     139923 20200802 IN001002 SAW011 000020  0001975 000039500 HAND SAW
     139923 20200802 IN001003 HAM020 000030  0001200 000036000 BALL HAMMER
     250825 20200804 IN001104 BBQ010 000040  0019500 000780000 BAR-B-Q
     250825 20200804 IN001004 SAW099 000050  0000000 000000000 ~~~~~~~~~~~~~~~~
     401210 20200816 IN001005 SAW051 000060  0008500 000510000 POWER SAW
    
     uvcopy salesextend,rop=d  <-- execute uvcopy job to demo 'rtb' & 'lok'
     ========================    - ',rop=d' to debug (display instructions before executing)
     - see the uvcopy job listed on the previous page.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J7. Debugging uvcopy jobs (rop=d)

    debug session#2 using $UV/pf/demo/extendsales1

    Please refer to uvcopy job listing on page 'J5' & the I/O files on 'J6' above. We will single step (null entries) to end of 1st loop processing 1st instruction. Then display the relevant I/O data areas, registers & accumulators.

    
     uvcopy extendsales1,rop=d
     =========================
            0000         opn    all                      open all files
     debug> 0152         rtb    fili2,p0(50),p0(50)      read product master into memory
     debug> 0376 man20   get    fili1,a0                 read next sales item record
     debug> 0576         skp>   man90                    (cc set > at EOF)
     debug> 0728 man22   mvc    b0(80),a0                copy input to output area
     debug> 0880         lokz1  pp0(50),pp0(6),a25(6)    lookup table by product code
     debug> 1056         skp=   man26                    (cc unequal if nomatch)
     debug> 1360 man26   mvn    b40(7),pp30(7)           price from table
     debug> 1512         mvn    b48(9),pp30(7)           price to amount for extension
     debug> 1664         mpy    b48(9),b32(6)            master price * item qty = am
     debug> 1816 man28   mvc    b58(16),pp10             product dscrptn from table
     debug> 1968         add    $ca1,b48(9)              accumulate total sales for EO
     debug> 2120 man30   put    filo1,b0                 write output
     debug> 2320         skp    man20                    return to get next record
     debug> p a0        <-- display the 1st INPUT record (in area 'a')
                            1         2         3         4         5         6         7         8
                   123456789012345678901234567890123456789012345678901234567890123456789012345678901
             ----->130140 20200802 IN001001 HAM035 000010
     debug> p b0        <-- display the 1st OUTPUT record (in area 'b')
                            1         2         3         4         5         6         7         8         9        1
                   12345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
     debug> c
            counters: ca1=295000,
    
          130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
          ================================================<-48(9)->==============
    
            add    $ca1,b48(9)              accumulate total sales for EOF msg
            ==================

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J8. Debugging uvcopy jobs (rop=d)

    debug session#2 (extendsales1) - continued

     debug> p8 p0(50)   <-- display the product lookup file (tabled in memory by rtb)
                          - 'rtb' tabled 40 byte records as 50 byte entries to simplify addresses
                          - 'lok' looks-up the table by product# key to get description & price
                             1         2         3         4
                   12345678901234567890123456789012345678901234567890
            0000-->BBQ010    BAR-B-Q             0019500
            0050-->HAM010    CLAW HAMMER         0000950
            0100-->HAM020    BALL HAMMER         0001200
            0150-->HAM035    JACK HAMMER         0029500
            0200-->SAW011    HAND SAW            0001975
            0250-->SAW012    RIP SAW             0002500
            0300-->SAW051    POWER SAW           0008500
            0350-->~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     debug> r
            registers: p=150,u=100,v=38,x=150,z=70,
    
            lokz1  pp0(50),pp0(6),a25(6)    lookup table by product code
            ============================
            mvn    b40(7),pp30(7)           price from table
            mpy    b48(9),b32(6)            master price * item qty = am
     man28  mvc    b58(16),pp10             product dscrptn from table
            ===================

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J9. Debugging uvcopy jobs (rop=d)

    debug session#2 (extendsales1) - continued

     debug> g3 man90                    <-- goto man90 (label at EOF)
            2472 man90   cls    all
     debug> c                           <-- display counters at EOF
            counters: ca1=1785500,
     debug> G
            ERROR - product code not found SAW099
     20201119:044903:extendsales1: EOF fili01 rds=6 size=234: dat1/salesitems
     20201119:044903:extendsales1: EOF fili02 rds=7 size=266: dat1/productmaster
     20201119:044903:extendsales1: EOF filo01 wrts=6 size=416: tmp1/salesextended

    Total sales = 1660500 in tmp1/salesextended

     uvcopy extendsales1 start 2020/11/19_11:04:35 end 11:04:49 elapsed 000_14_125
     EOJ, Output File written to: tmp1/salesextended
     ----- enter: vi,cat,more,lp,uvlp13,etc (default null) --> cat
     130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
     139923 20200802 IN001002 SAW011 000020  0001975 000039500 HAND SAW
     139923 20200802 IN001003 HAM020 000030  0001200 000036000 BALL HAMMER
     250825 20200804 IN001104 BBQ010 000040  0019500 000780000 BAR-B-Q
     250825 20200804 IN001004 SAW099 000050  0000000 000000000 ~~~~~~~~~~~~~~~~
     401210 20200816 IN001005 SAW051 000060  0008500 000510000 POWER SAW

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J10. debug session#3 to demo Breakpoints & Gotos

    The previous Debug session on page 'J7' illustrated stepping thru the job & displaying Data-Areas, Counters,& Registers, but did not illustrate Breakpoints & Gotos. Please also refer backto page 'J5' which listed all instructions in extendsales1 (vs just those executed in the debug session on page 'J7').

    
     uvcopy extendsales1,rop=d
     =========================
          0         opn    all                      open all files
     debug> b1 man20
     debug> b2 man24
     debug> b3 man30
     debug> g1    <-- goto tag 'man20' (breakpoint 'b2 man20' above)
        376 man20   get    fili1,a0                 read next sales item record
     debug> g3
       2120 man30   put    filo1,b0                 write output
     debug> p a0  <-- display 1st INPUT record (in area 'a')
                             1         2         3         4         5         6         7         8         9        1
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->130140 20200802 IN001001 HAM035 000010
     debug> p b0  <-- display 1st OUTPUT record (in area 'b')
                             1         2         3         4         5         6         7         8         9        1
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->130140 20200802 IN001001 HAM035 000010  0029500 000295000 JACK HAMMER
    Note
    • We are now at the end of the 1st record cycle at tag 'man30' please see tag 'man30' on the listing of extendsales1 on page 'J5'
    • We now want to investigate the "ERROR - product code not found" caused by product code 'SAW099' on record #6 in dat1/salesitems listed on 'J6'
     debug> g2    <-- goto tag 'man24' (breakpoint 'b2 man24' above)
       1208 man24   msg    'ERROR - product code not found',a25(6)
     debug> g3    <-- goto tag 'man30', which will be the end of the ERROR record#6
                  ERROR - product code not found SAW099
       2120 man30   put    filo1,b0                 write output
     debug> p a0  <-- display INPUT record#6 causing the ERROR
                    - product code SAW099 not found in the productmaster (tabled in memory)
                             1         2         3         4         5         6         7         8         9        1
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->250825 20200804 IN001004 SAW099 000050
     debug> p b0  <-- display OUTPUT record#6 (ERROR will omit price, amopunt, description)
                             1         2         3         4         5         6         7         8         9        1
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->250825 20200804 IN001004 SAW099 000050  0000000 000000000 ~~~~~~~~~~~~~~~~
     debug> c     <-- display accums at end of ERROR record#6
            counters: ca1=1150500,   <-- total of 1st 5 good records

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J11. debug session#3 demo Breakpoints & Gotos - Continued

     debug> g5 man90                 <-- goto man90 (tag at EOJ to close files)
                                       - did not setup 'b5 man90' at begin debug
       2472 man90   cls    all
     debug> c     <-- display accums at EOF (total missing $amt of ERROR record#6)
            counters: ca1=1660500,   <-- total of 1st 5 & 7th records
     debug> G     <-- Goto EOJ (end of program)
     20201119:244201:extendsales1: EOF fili01 rds=6 size=234: dat1/salesitems
     20201119:244201:extendsales1: EOF fili02 rds=7 size=266: dat1/productmaster
     20201119:244201:extendsales1: EOF filo01 wrts=6 size=416: tmp1/salesextended
     Total sales = 1660500 in tmp1/salesextended
     uvcopy extendsales1 start 2020/11/19_17:22:33 end 17:24:42 elapsed 002_09_013
     EOJ, Output File written to: tmp1/salesextended

    debug session#4 - demo using only 'goto's without breakpoints

    Session#4 will show you do not need to set brkpts with 'b# tagxx'; you can use goto for both setting brkpts & going to them. You must code 'g# tagxx' on 1st use but can subsequently code just the 'g#' to goto that tagxx. Use 'b#' brkpts when you want to plan ahead on big programs, use 'g# brkpts' for more specific bugs.

     Question - Why did invalid product code 'SAW099' cause description '~~~~~~~~~~~~~~~~' ?
     Session#2 on page 'J8' explained how the 'lok' (table lookup instruction)
     sets register 'p' to the matching entry in the productmaster tabled in memory.
     Here are just the relevant instrns.
            lokz1  pp0(50),pp0(6),a25(6)    lookup table by product code
            skp=   man26                    (cc unequal if nomatch)
     man24  msg    'ERROR - product code not found',a25(6)
     man26  ...                             - omitting less relevant instrns
            mvc    b58(16),pp10             product dscrptn from table
     man30  put    filo1,b0                 write output

    We know the bad product code is record#6, which causes the 'lok' instrn to set condition code unequal & executes the 'man24 msg ERROR...' instrn. So we can use 'g1 man24' to go directly to the problem record#6, bypassing the 1st 5 good records that do not execute the 'man24 msg ERROR' instrn.

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J12. debug session#4 - Why product# ERRORs cause description '~~~...'

    debug session#4 - investigate '~~~' description if bad product#

    
     uvcopy extendsales1,rop=d
     =========================
          0         opn    all                      open all files
     debug> g1 man24           <-- go directly to man24 where ERROR detected
                                 - bypasses 1st 5 records that have no ERROR
       1208 man24   msg    'ERROR - product code not found',a25(6)
     debug> g2 man28
                   ERROR - product code not found SAW099
       1816 man28   mvc    b58(16),pp10             product dscrptn from table
     debug>                  <-- null entry to execute 'mvc b58(16),pp10' (description)
                               - so we can examine the output record & the registers
       1968         add    $ca1,b48(9)              accumulate total sales for EOJ
     debug> p b0             <-- display output record#6 with bad product code 'SAW099'
                             1         2         3         4         5         6         7         8         9        1
                   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
             ----->250825 20200804 IN001004 SAW099 000050  0000000 000000000 ~~~~~~~~~~~~~~~~
     debug> r                <-- display the Registers to see WHY description '~~~~~~~~~~~~~~~~' ?
            registers: p=350,u=100,v=38,x=350,z=38,
            0000-->BBQ010    BAR-B-Q             0019500
            0050-->HAM010    CLAW HAMMER         0000950
            0100-->HAM020    BALL HAMMER         0001200
            0150-->HAM035    JACK HAMMER         0029500
            0200-->SAW011    HAND SAW            0001975
            0250-->SAW012    RIP SAW             0002500
            0300-->SAW051    POWER SAW           0008500
            0350-->~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     debug> g1          <-- could search for any more ERRORs (at tag man24)
                          - do not need to code 'g1 man24' (already assigned)
                          - will goto EOF/EOJ since only the 1 ERROR in this file
     20201120:150104:extendsales1: EOF fili01 rds=6 size=234: dat1/salesitems
     20201120:150104:extendsales1: EOF fili02 rds=7 size=266: dat1/productmaster
     20201120:150104:extendsales1: EOF filo01 wrts=6 size=416: tmp1/salesextended
     Total sales = 1660500 in tmp1/salesextended

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    J13. Debug Command 'x' to Display Hexadecimal data

    Display area 'x' Reserved for Registers, Counters, etc

    You can skip this page if not interested in the binary bits of how stuff works. You don't really need to know this sicne you can address registers by their symbolic name example: $ra for register 'a' vs x0(4b) where actually stored. And you can address counters by thier symbolic names example, for example: $ca1 vs x208(8b) where actually stored.

    You can see the detailed layout of area 'x' at 'uvcopy2.htm#A1'. Here is just the 1st few Registers & Counters:

     absolute    | symbolic |     item
     address     | address  | description
     x0(4b)        $ra       index register 'a'
     x4(4b)        $rb       index register 'b'
     x8(4b)        $rc       index register 'c'
      ...          ...              ...
     x100(4b)      $rz       index register 'z'
     x200(8b)      $ca0      user counter set 'a' counter# 0
     x208(8b)      $ca1      user counter set 'a' counter# 1
      ...          ...           ...
     x392(8b)      $ca24     user counter set 'a' counter# 24
     x1800(8b)     $ci0      instruction counter i0
      ...          ...           ...

    But, you can display area 'x' if desired, for example, here is the 1st 300 bytes of area 'x' at label 'man90' (EOF) from 'extendsales1' shown on page 'J5'.

     px3 x0(100)  - display area 'x' in hexadecimal - area 'x' reserved for Registers, Accumulators, etc
                          1         2         3         4         5         6         7         8         9      100
                0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
         0000-->................................................................................d...&...............
                0000000000000000000000000000000000000000000000000000000000009000000000000000000060002000000090000000
                0000000000000000000000000000000000000000000000000000000000006000000000000000000040006000000060000000
         0100-->F...........X.......G...:...................................(................................L......
                40000000000058000000410031001000000000000000E10001000F00E0002000900000000000000000000000000004000000
                600000000000804000007B00AB001000000000000000C30009000A008300810000000000000000000000000000000C000000
         0200-->........X...........................................................................................
                0000000058000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                0000000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     debug> r
            registers: p=150,u=100,v=38,x=150,z=70,
     debug> c
            counters: ca1=295000,

    Return to first page of:   this document    this library (librefs)    UV Software Home-Page

    Visitor Counters for ThisYear and LastYear