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
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
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
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
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
 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
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)
translations, edited reports, sorts, table lookups, convert tabs to blanks
convert fixed length fields to delimited (comma,pipe,etc), split files, Indexed file random access to update sequential files.
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 - 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
When you want to make a new job, the following steps are recommended:
      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)
      #-----------------------------
            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.
Return to first page of: this document this library (librefs) UV Software Home-Page
| given | 
  | 
| required | 
  | 
| solution | 
  | 
       #-----------------------------
       #     ---   -----,-----         ** 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
       #-----------------------------
 # 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
    mvc  tobyte(lth),frombyte      - instruction format
    mvc  op1dsp(op1lth),op2dsp     - op2 may be an area address
    mvc  op1dsp(op1lth),'constant'   or a constant
                     
    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
                  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
            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
    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 | 
  | 
| option 't' | 
  | 
| option 't1' | 
  | 
    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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
"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.   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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
      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 | 
  | 
| condition code | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
  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
                  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
      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 | 
  | 
 option a  - inserts after op2 data appended (at end of op2 data)
        a1,a2,a4,a8 - same as above
| register 'x' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
    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
     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 | 
  | 
| register 'w' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| option 'a1' | 
  | 
         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)
                
     edt   b60(10),$date1(8),'9999/99/99'       edit system date
     edt   b72(5),$date1+8(4),'99:99'           edit system time
  | 
     edt   p30(13),$ca1,'z,zzz,zzz.99-'
     edt   p30(13),x200(4b),'z,zzz,zzz.99-'
  | 
     edt   p50(9),a20(7z),'zzzzz.99-'
     edt   p50(9),a20(7z),'z.99-'
  | 
     edt   p50(9),a20(7z),'-z.99'
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
"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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
"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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| Example | 
  | 
     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
     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
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 types & signs may be coded within the (length), for example:
      mvn   b100(-9za),a20(5p)
1st alpha letter defines the data type
| z | 
  | 
| p | 
  | 
| b | 
  | 
| k | 
  | 
| f | 
  | 
2nd alpha letter defines the codeset (or indicates binary switch)
| a | 
  | 
| e | 
  | 
| s | 
  | 
| x | 
  | 
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' 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 | 
  | 
| condition code | 
  | 
    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
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 | 
  | 
                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
  | 
| option i2 | 
  | 
| option i3 | 
  | 
| note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| option q1 | 
  | 
| option s | 
  | 
        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# | 
  | 
        mvnv2w2  a10(8),a0(8)
        =====================
           12345     00012345   - no dcml with optn w2 (dflt 2 if no '.')
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
       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
       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
       mvn   a20(-7),a10(7)        - leading sign if '-' leading in (..)
           1234567   1234567
           123456w   -234567
              1234   0001234
           1234-     -001234
           -1234     -001234
       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   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 | 
  | 
       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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
       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 | 
  | 
      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
'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 | 
  | 
 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
 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
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 | 
  | 
 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
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 | 
  | 
      div   c50(9),24            divide hours by hrs/day
      cmn   $rem,12              remainder > or < 12 hrs ?
| condition code | 
  | 
 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
    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
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
  | 
      xft   d0(4b),a100(5p),12
      skp=  allzero
  | 
      xft   $ca1,a100(5p),12
  | 
 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
       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' | 
  | 
       cmcp    b70(6),'@#@#@#'  - validate the Canadian postal code
       skp=    ok
| option 'p1' | 
  | 
| option 'p9' | 
  | 
       cmcp1   a0(2),'##'   <-- compare '#' in 1st byte + any digit 0-9 in 2nd
| option 'i1' | 
  | 
       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
| register 'w' | 
  | 
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
       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
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 | 
  | 
      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
 # 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
    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' | 
  | 
| option 'i' | 
  | 
 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' 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 - 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
     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)
"=" (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
Return to first page of: this document this library (librefs) UV Software Home-Page
      opn  fili1               - open a specific file
      opn  all                 - open all files that have been declared
                                 via the fil__, rcs,& typ functions
| register z | 
  | 
| register u | 
  | 
  | 
| register v | 
  | 
 $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 | 
  | 
      opne1  fili1              - open file & test if present ?
      skp<   nofile
Return to first page of: this document this library (librefs) UV Software Home-Page
"opn" - open file (continued)
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' - 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
     | LST | 
  | 
| RSF/RST | 
  | 
| ISF | 
  | 
| DIR | 
  | 
| IDX | 
  | 
| RSV | 
  | 
| STL | 
  | 
| fillchar | 
  | 
| altstopchar | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
              fili1=dat1/custmast,typ=ISFl4,rcs=256 #<-- must code option l4 on typ=ISFl4 =====================================
| l4 (typ=ISFl4) | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| c2 | 
  | 
| c4 | 
  | 
| c8 | 
  | 
| c16 | 
  | 
| c32 | 
  | 
| c64 | 
  | 
| c128 | 
  | 
| d1 | 
  | 
| e1 | 
  | 
| s1 | 
  | 
| s2 | 
  | 
| s4 | 
  | 
| s8 | 
  | 
| t1 | 
  | 
| t2 | 
  | 
| t4 | 
  | 
| t8 | 
  | 
  | |
| m1 | 
  | 
| m2 | 
  | 
| m4 | 
  | 
| m8 | 
  | 
| n1 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| typ=RSFu | 
  | 
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' 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).
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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
  
 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
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'
                 ^^^^^
                    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.
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
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 | 
  | 
| b1 | 
  | 
| b2 | 
  | 
| c1 | 
  | 
| c2 | 
  | 
| c4 | 
  | 
| c8 | 
  | 
| c16 | 
  | 
| c32 | 
  | 
| c64 | 
  | 
| c128 | 
  | 
| d1 | 
  | 
| e1 | 
  | 
| s1 | 
  | 
| s2 | 
  | 
| s4 | 
  | 
| s8 | 
  | 
| t1 | 
  | 
| t2 | 
  | 
| t4 | 
  | 
| t8 | 
  | 
| x1 | 
  | 
  | |
| m1 | 
  | 
| m2 | 
  | 
| m4 | 
  | 
| m8 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| RSF | 
  | 
| RST | 
  | 
| LST | 
  | 
| ISF | 
  | 
| IDX | 
  | 
| RSV | 
  | 
| STL | 
  | 
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 | 
  | 
| typ=LSTw2 | 
  | 
| typ=LSTt1 | 
  | 
| typ=LSTt2 | 
  | 
| typ=LSTt3 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| Note | 
  | 
| IDXf1 | 
  | 
| IDXf3 | 
  | 
| IDXf8 | 
  | 
| v9999 | 
  | 
| x | 
  | 
| x1 | 
  | 
| x2 | 
  | 
| y | 
  | 
| y1 | 
  | 
| y2 | 
  | 
| y4 | 
  | 
| y8 | 
  | 
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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
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.
 # 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
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
           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
      
 # 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
"rtb" reads a table of data into the op2 area from the op1 file
| Note | 
  | 
    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 | 
  | 
| op2 | 
  | 
| op3 | 
  | 
| op4 | 
  | 
| op5 | 
  | 
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
 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 | 
  | 
| option c2 | 
  | 
| option c4 | 
  | 
| option e | 
  | 
     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 | 
  | 
| option t1 | 
  | 
| option x1 | 
  | 
instrn counter $ci1 - counts lines loaded into the op1 area
Return to first page of: this document this library (librefs) UV Software Home-Page
| registers | 
  | 
  | 
     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'
  | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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.
 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
           
 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
 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
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 | 
  | 
| op2 | 
  | 
| op3 | 
  | 
| op4 | 
  | 
| op5 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| e2 | 
  | 
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 | 
  | 
| x1 | 
  | 
| Instrn ctr $ci1 | 
  | 
                                --- 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)
    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
    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
    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
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 | 
  | 
| Note | 
  | 
read redm5l4w1r8 filr1,c0 ==========================
| option l4 | 
  | 
| option w# | 
  | 
| option r# | 
  | 
updt updl4 filr1,c0 <-- update record read by prior redm5l4 ===================== - and release the lock
| option l4 | 
  | 
| Note | 
  | 
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
 # 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
 # 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
     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
    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' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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.
| produpISF1 | 
  | 
| produpIDX2 | 
  | 
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 | 
  | 
| ISFlock2 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
    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
    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
    lck   fili1                   - lock a D-ISAM file
    lck   filr1                     (for input or random files)
| Note | 
  | 
    ulk   fili1                   - unlock a D-ISAM input/random file
Return to first page of: this document this library (librefs) UV Software Home-Page
    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 | 
  | 
 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 | 
  | 
| option y | 
  | 
| option n | 
  | 
| option b | 
  | 
| option j1 | 
  | 
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 | 
  | 
| register x | 
  | 
 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
 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 | 
  | 
| Note | 
  | 
      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' | 
  | 
      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
 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 - 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)
            
 # 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
       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
               Return to first page of: this document this library (librefs) UV Software Home-Page
     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 | 
  | 
| option v1 | 
  | 
| Note | 
  | 
'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
      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 | 
  | 
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   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
        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 | 
  | 
      bal    g0(8)     <-- may specify the subrtn label in any area
                         - max 8 blank filled
| Note | 
  | 
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
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 | 
  | 
| Your assignment | 
  | 
| NOTE | 
  | 
        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
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
'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)
  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 | 
  | 
| op4 data | 
  | 
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
 # 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
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 | 
  | 
| t1 | 
  | 
| t2 | 
  | 
| t3 | 
  | 
| t4 | 
  | 
| t5 | 
  | 
| t6 | 
  | 
| t7 | 
  | 
| t8 | 
  | 
| t9 | 
  | 
| t10 | 
  | 
| t11 | 
  | 
    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
    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.
    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 | 
  | 
    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
      trt   b0(80),c0            - translate area b
                                   using the translate table in area c
| Note | 
  | 
| example | 
  | 
        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
         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
     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 | 
  | 
     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 | 
  | 
| op2 | 
  | 
 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
    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  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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
     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 | 
  | 
| op2 | 
  | 
| op3 | 
  | 
| op4 | 
  | 
| option a1 | 
  | 
| option b1 | 
  | 
| option b2 | 
  | 
| option b4 | 
  | 
Please see the 'vhx' example on the next page --->
Return to first page of: this document this library (librefs) UV Software Home-Page
# 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
    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 | 
  | 
| condition code | 
  | 
| register 'x' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 'b' - inhibit multi-blank-bypass
     - would slow the instruction down
       but would allow more than 1 leading blank in search data
| Warning | 
  | 
 '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 | 
  | 
| Note | 
  | 
 '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
'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
| problem | 
  | 
            =========================================================
                  05 gross-pay          pic  s9(5)v99    comp-3.
            =========================================================
                    
        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.
        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.
        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')
       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
             continuing the scan for a 2nd following pattern
             -----------------------------------------------
| problem | 
  | 
            ==========================================================
                   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
| problem | 
  | 
              =============================================
   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
| Note | 
  | 
@ - 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' | 
  | 
| option 'p2' | 
  | 
      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
     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 | 
  | 
instruction counter #1 ($ci1) will hold a count of total replcmnts made
| rgstr 'x' | 
  | 
| rgstr 'u' | 
  | 
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) < <= => >
| a1 | 
  | 
| a2 | 
  | 
| b | 
  | 
| Warning | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| c1 | 
  | 
| d | 
  | 
| f | 
  | 
| f1 | 
  | 
| f2 | 
  | 
| f4 | 
  | 
| f7 | 
  | 
    Example - replacing patterns with filenames which are null terminated
            mvc   b0(50),'file = fff'
            repf  b0(50),'fff',$fili1
| g | 
  | 
| g1 | 
  | 
| g2 | 
  | 
| g4 | 
  | 
| g7 | 
  | 
| i1 | 
  | 
       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 | 
  | 
| q2 | 
  | 
| m | 
  | 
| n# | 
  | 
| p | 
  | 
| r# | 
  | 
| r1 | 
  | 
| r# | 
  | 
| r2n3 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| s | 
  | 
| v1 | 
  | 
| Note | 
  | 
| x1 | 
  | 
      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
    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 | 
  | 
| register 'x' | 
  | 
| register 'y' | 
  | 
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.
Options may be appended following the 3 character instruction code. Options are lower case alphas (a-z) & may have a following numeric value.
| b1 | 
  | 
| t1 | 
  | 
| m | 
  | 
| p | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| d | 
  | 
| g | 
  | 
| g1 | 
  | 
| g2 | 
  | 
| g4 | 
  | 
| g7 | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| q3 | 
  | 
| a4 | 
  | 
| a2 | 
  | 
| a1 | 
  | 
| e2 | 
  | 
| e1 | 
  | 
| register 'x' | 
  | 
| register 'y' | 
  | 
| Note | 
  | 
| Note | 
  | 
| Note | 
  | 
| z1 | 
  | 
| z2 | 
  | 
| z3 | 
  | 
| u1 | 
  | 
| u2 | 
  | 
| u3 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| given | 
  | 
| required | 
  | 
            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
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
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
     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
| condition code | 
  | 
| register 'x' | 
  | 
| register 'y' | 
  | 
| register 'w' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| option b | 
  | 
| Warning | 
  | 
| option c1 | 
  | 
| option d | 
  | 
 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 | 
  | 
| option p | 
  | 
| option p1 | 
  | 
| option p2 | 
  | 
 option q1  - inhibit matches within single quotes
        q2  - inhibit matches within double quotes
| option w1 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
      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 | 
  | 
| register x | 
  | 
| register y | 
  | 
| counter $ci1 | 
  | 
| counter $ci2 | 
  | 
| option i0 | 
  | 
| option i1 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
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 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
 #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)
     ===============
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
      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 | 
  | 
| register x | 
  | 
| register y | 
  | 
| counter $ci1 | 
  | 
| counter $ci2 | 
  | 
| option i0 | 
  | 
| option i1 | 
  | 
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
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%
        Return to first page of: this document this library (librefs) UV Software Home-Page
'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 | 
  | 
| register x | 
  | 
| register y | 
  | 
| register u | 
  | 
| register v | 
  | 
| counter $ci1 | 
  | 
| counter $ci2 | 
  | 
| option i0 | 
  | 
| option i1 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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%
Return to first page of: this document this library (librefs) UV Software Home-Page
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
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 | 
  | 
    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 | 
  | 
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
| a1 | 
  | 
| a2 | 
  | 
| c1 | 
  | 
| b | 
  | 
| Warning | 
  | 
| d | 
  | 
| i1 | 
  | 
| p | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| m1 | 
  | 
| s | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| register 'x' | 
  | 
| register 'y' | 
  | 
| register 'u' | 
  | 
| register 'v' | 
  | 
| Note | 
  | 
| register 'w' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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) ==============
# 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;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ******* 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
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
            # 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 | 
  | 
 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
 # 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
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 | 
  | 
 $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)
       | rgstr 'u' | 
  | 
| rgstr 'w' | 
  | 
| rgstr 'x' | 
  | 
| op1 rgstr | 
  | 
rgstr 'u' & 'w' - same as above (when op1 rgstr not coded)
| rgstr 'x' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| b | 
  | 
| d | 
  | 
| g | 
  | 
| g1 | 
  | 
| g2 | 
  | 
| g4 | 
  | 
| g7 | 
  | 
| Note | 
  | 
| h1 | 
  | 
| h2 | 
  | 
| h4 | 
  | 
| h8 | 
  | 
| i1 | 
  | 
| n# | 
  | 
| n99 | 
  | 
| p | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| w# | 
  | 
| z1 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| rgstr 'u' | 
  | 
| rgstr 'w' | 
  | 
| rgstr 'x' | 
  | 
| rgstr 'y' | 
  | 
| op1 rgstr | 
  | 
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' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| a1 | 
  | 
| a2 | 
  | 
| b | 
  | 
| c1 | 
  | 
| d | 
  | 
| h1 | 
  | 
| h2 | 
  | 
| p | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| v1 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
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 | 
  | 
instruction ctr#1 ($ci1) - will hold count of replacements made
| rgstr 'u' | 
  | 
| rgstr 'w' | 
  | 
| rgstr 'x' | 
  | 
| op1 rgstr | 
  | 
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
| a1 | 
  | 
| a2 | 
  | 
| b | 
  | 
| c1 | 
  | 
| d | 
  | 
| f | 
  | 
| f1 | 
  | 
| f2 | 
  | 
| f4 | 
  | 
| f7 | 
  | 
| g | 
  | 
| g1 | 
  | 
| g2 | 
  | 
| g4 | 
  | 
| g7 | 
  | 
| k | 
  | 
| k1 | 
  | 
| k2 | 
  | 
| k4 | 
  | 
| p | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| r# | 
  | 
| r0 | 
  | 
| r1 | 
  | 
| v1 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
             
 ******* 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 | 
  | 
#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
             
 ******* 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
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 | 
  | 
instruction ctr#1 ($ci1) - will hold count of replacements made
| rgstr 'u' | 
  | 
| rgstr 'w' | 
  | 
| rgstr 'x' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| op1 rgstr | 
  | 
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
           | a1 | 
  | 
| a2 | 
  | 
| b | 
  | 
| c1 | 
  | 
| d | 
  | 
| p | 
  | 
| q1 | 
  | 
| q2 | 
  | 
| r1 | 
  | 
| v1 | 
  | 
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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) ==============
# 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;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ******* 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
    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
                    | c# | 
  | 
| c0 | 
  | 
| c1 | 
  | 
| l# | 
  | 
| l0 | 
  | 
| l1 | 
  | 
| l2 | 
  | 
 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 | 
  | 
| a1 | 
  | 
      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
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
     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 | 
  | 
| register 'x' | 
  | 
| counter $ci1 | 
  | 
| option 'r' | 
  | 
| option 'd1' | 
  | 
     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  d0(10),5            - squeeze right (vs default left)
             111111111122222222223333333333444444444455555555556666666666
 before sqf: <-field1->          <-field3->          <-field5->
after sqf: <-field1-><-field3-><-field5->
| Note | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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' | 
  | 
        $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
 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' | 
  | 
| option p | 
  | 
| option p1 | 
  | 
| option p2 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
       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 | 
  | 
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).
| option g1 | 
  | 
| option g2 | 
  | 
| option g4 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
    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
fix 1st-out-field,input,#fields,delimiter[,fillchar] - format
    fix   b0(20),a0(80),6,'","'
  | 
    fix   c0(50),a0(100),8,'|','~'    <-- '|' pipe delims & '~' tilde fill
  | 
condition code will be set = if at least 1 sepstring found
| instrn ctr $ci1 | 
  | 
| instrn ctr $ci2 | 
  | 
| instrn ctr $ci3 | 
  | 
| register 'x' | 
  | 
| option b1 | 
  | 
| option b2 | 
  | 
| option b3 | 
  | 
| option q1 | 
  | 
| option q2 | 
  | 
| option q3 | 
  | 
| option p1 | 
  | 
| option s1 | 
  | 
| option t1 | 
  | 
 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
 # 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
This example illustrates that option r1/r2 allow delimiters within fields:
# 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    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~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
        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
     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
| f2 | 
  | 
| b1 | 
  | 
| b2 | 
  | 
| r1 | 
  | 
| r2 | 
  | 
$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
 # 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
      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
      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
               
 # 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
    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 | 
  | 
| option p1 | 
  | 
| option p2 | 
  | 
        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
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 | 
  | 
| datcn | 
  | 
| datjc | 
  | 
| datjn | 
  | 
| datnc | 
  | 
| datnj | 
  | 
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
            
 #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
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
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
      -----   ---------------
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
      -----  ----------
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
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
     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 | 
  | 
| RULES | 
  | 
 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 '.'
            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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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 | 
  | 
| option w1 | 
  | 
| option w3 | 
  | 
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) | 
  | 
| w1100(100) | 
  | 
| w1900(100) | 
  | 
- - - etc for line2-line8 - - -
| w9100(100) | 
  | 
| w9900(100) | 
  | 
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
 # 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
           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
    lok  table-entry,table-key,search-key,EOT-marker   - instrn format
    skp=                                               - cc = if found
| op1 table-entry | 
  | 
| op2 table-key | 
  | 
| op3 search-key | 
  | 
| op4 EOT marker | 
  | 
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.
 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
                     | register 'x' | 
  | 
| op1 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
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
     
 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
            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
# 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
# #
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
     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
     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
     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' | 
  | 
| condition code | 
  | 
| register 'x' | 
  | 
${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
     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 | 
  | 
| operand 2 | 
  | 
| option 't1' | 
  | 
| option 't2' | 
  | 
| counter $ci1 | 
  | 
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 | 
  | 
         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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| evs | 
  | 
      evs   b0(100),a0   <-- copy 1st 100 bytes from area 'a' to area 'b'
      ================       expanding $SYMBOLs
| option t1 | 
  | 
| option t2 | 
  | 
cc - condition code set '=' if any replacements, else '<' $ci1 - replacement count $rx - dsplcmnt to 1st replacement $ry - length of 1st replacement
 # 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 - 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 - 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
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).
                      | d1 | 
  | 
| d2 | 
  | 
| d4 | 
  | 
| n0 | 
  | 
| n1 | 
  | 
| n2 | 
  | 
| r1 | 
  | 
| b_ | 
  | 
| b1 | 
  | 
| b2 | 
  | 
| b4 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| rgstr x | 
  | 
| rgstr y | 
  | 
 $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)
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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
               | a | 
  | 
| b | 
  | 
| c | 
  | 
| e | 
  | 
| f | 
  | 
| h | 
  | 
| i | 
  | 
| p | 
  | 
| u | 
  | 
| y | 
  | 
| z | 
  | 
| a | 
  | 
| d | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| sxo option m | 
  | 
| sxom64 | 
  | 
| sxom256 | 
  | 
uvcopy jobxxx,rop=m256 <-- run option m overrides sxom64 & internal default
| sxo option w | 
  | 
| sxow100 | 
  | 
| Note | 
  | 
| sxo option v0 | 
  | 
| sxov1 | 
  | 
      sxo  64,'44(6y)'  <--- field type y for windowed date field sort
| rop=y70 | 
  | 
| rop=y70z1 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
      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
   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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
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
     ============
     
 # 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
 #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
     ==============
                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
| sort1 | 
  | 
| pswsort1 | 
  | 
            try this ---> uvcopy pswsort1
                          ===============
| index | 
  | 
| sort2 | 
  | 
| cmreport | 
  | 
| cmsplit | 
  | 
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.
 #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
| tbl | 
  | 
| tbf | 
  | 
| tbh | 
  | 
| tbp | 
  | 
| tbd | 
  | 
"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 | 
  | 
| rop=v2000 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
tbl argument,heading,acum1,acum2,acum3,acum4,acum5,acum6
    tblt1f2 a100(16),'city-name;sales;costs;profit',a40(8z),a48(6p),a54(4b)
    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
| t# | 
  | 
| f# | 
  | 
| h# | 
  | 
| m# | 
  | 
| v# | 
  | 
| d_ | 
  | 
| d0 | 
  | 
| d1 | 
  | 
| d2 | 
  | 
"=" 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)
               $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
tbf argument-location(length),accumulator editing formats
    tbff2  p31(32),'zzz,zzz,zzz.99- %%%- zzz,zzz,zzz.99- %%%-  .etc.'
| Note | 
  | 
| f# | 
  | 
| d# | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
tbhh1 'province;This Year Sales;Last Year sales;'
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
tbp file,table-title-heading
tbpt1e3 filo1,'sales analysis'
| t# | 
  | 
| e# | 
  | 
| c | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
| h# | 
  | 
       mvf   $tbh1,'product#;quantity;amount'
       tbp   filo1,'Sales by Product#'
| i0 | 
  | 
| i1 | 
  | 
| i2 | 
  | 
| l## | 
  | 
| j1 | 
  | 
| j2 | 
  | 
| s1 | 
  | 
| x1 | 
  | 
| x2 | 
  | 
| z1 | 
  | 
| z2 | 
  | 
| z3 | 
  | 
$ci1 - no of table entries written (not yet implemented)
Return to first page of: this document this library (librefs) UV Software Home-Page
tbd file,constant-data (to be appended to table entries)
tbdt1e3 filo2,'19940430'
| t# | 
  | 
| e# | 
  | 
| c | 
  | 
| j1 | 
  | 
| 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
| given | 
  | 
| required | 
  | 
 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
      
 # 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
 # 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
 # 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
 # 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
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
| f1 | 
  | 
| f2 | 
  | 
| f3 | 
  | 
| f4 | 
  | 
| f5 | 
  | 
| f6 | 
  | 
| f7 | 
  | 
| f8 | 
  | 
| f9 | 
  | 
| f10 | 
  | 
| f11 | 
  | 
| f12 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 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
 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#
         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
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
 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
       
    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
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:
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
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 | 
  | 
| rop=v4000 | 
  | 
| rop=u20 | 
  | 
| rop=v8000 | 
  | 
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
| given | 
  | 
| required | 
  | 
 # 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
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 - 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
Return to first page of: this document this library (librefs) UV Software Home-Page
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
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
       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
'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)
           
      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
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' | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
     ===============
           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
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
              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
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 | 
  | 
 /* 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 - 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)
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
| Note | 
  | 
 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
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 | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 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
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.
| d/p | 
  | 
| p a0(100) | 
  | 
| p a | 
  | 
| p b100(100) | 
  | 
| p5 c0(100) | 
  | 
| pe e0 | 
  | 
| px4 x0 | 
  | 
| a/c | 
  | 
| c | 
  | 
| c b | 
  | 
| c i | 
  | 
| r | 
  | 
      ------- 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
| null entry | 
  | 
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.
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
   | s1 | 
  | 
| s0 | 
  | 
At any breakpoint, you may display areas,counters,registers as shown on prior page
| p a0 | 
  | 
| c a | 
  | 
| r | 
  | 
Return to first page of: this document this library (librefs) UV Software Home-Page
 # 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
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.
 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
           
 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
 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
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
 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
 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
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 | 
  | 
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
 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
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
 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
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