Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Got an update for this. A Bug Fix, as the original FINDREP has no ENDPOS (so could get false hits if counting numerics). And a simplification, to use a binary count value instead of the character one.
The binary method can count up to 255 simply, and beyond would not be onerous.
Code: |
//HUMPHREY EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYMNAMES DD *
*
* The character or string to be counted
*
SEARCH-CHAR-OR-STRING,C'1'
*
* Contents of ARBITRARY-STRING are irrelevant, as long as one byte
* shorter than SEARCH-CHAR-OR-STRING.
*
ARBITRARY-STRING,C''
*
* In binary, from zero to the maximum to be counted. If line is filled,
* multiple constants will be needed.
*
COUNTS-18,X'000102030405060708090A0B0C0D0E0F101112'
*
* Important - define the entire input record here.
*
INPUT-RECORD,*,80,CH
* Define DUMMY... imemdiately after the record, it is "POSITION'ed" to
* later.
*
DUMMY-FOR-FIRST-BYTE-AFTER-RECORD,*,1,CH
*
* Fields prefixed OUTPUT- are just for the example, not part
* of the solution.
*
OUTPUT-SEPARATOR,25,1,CH
OUTPUT-COUNT,26,2,ZD
OUTPUT-LAST-BYTE,80,1,CH
*
* To locate to first byte after end of record.
*
POSITION,DUMMY-FOR-FIRST-BYTE-AFTER-RECORD
*
* The following must be have the length of count constant(s), else some
* danger of a false hit.
*
EXTENSION-FOR-COUNTS-UNDERFLOW,*,19,CH
*
* If the constant for the count required splitting (see above)
* then each part of the constant requires a unique starting position
* immediately after then end of the previous one.
*
EXTENSION-FOR-COUNTS,*,=,CH
*
* This will hold the count, in binary of length one, starting from zero
* and going up to maximum needed, to a maximum of 255.
*
EXTENSION-FOR-COUNTS-1ST-BYTE,=,1,BI
//SYMNOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
* IFOUTLEN is just for the example, not part of the solution.
*
INREC IFOUTLEN=80,
* Establishes the count contant(s) in the extention to the input record.
*
IFTHEN=(WHEN=INIT,
OVERLAY=(EXTENSION-FOR-COUNTS:COUNTS-18)),
* Does the required search, in the example from position 7 to position
* 80, change these to what is needed.
*
IFTHEN=(WHEN=INIT,
FINDREP=(IN=SEARCH-CHAR-OR-STRING,
OUT=ARBITRARY-STRING,
STARTPOS=7,
ENDPOS=80)),
* The appended constant has been shifted left by the FINDREP for each
* instance of the character/string found, so that the first byte of the
* extended counts points to the count of times shifted.
* The leading part of the appended count constant has "underflowed"
* into the place established for it. The count of successful searches
* is just sitting there in a one-byte binary field.
*
IFTHEN=(WHEN=INIT,
OVERLAY=(OUTPUT-COUNT:
EXTENSION-FOR-COUNTS-1ST-BYTE,
TO=ZD,
LENGTH=2)),
* Just formatting for the output example.
*
IFTHEN=(WHEN=INIT,
OVERLAY=(OUTPUT-SEPARATOR:
X,
OUTPUT-LAST-BYTE:
X))
//SORTIN DD *
ABC000111111111111111111
ABC00111111111111111111
ABC0021111111111111111
ABC003111111111111111
ABC00411111111111111
ABC0051111111111111
ABC006111111111111
ABC00711111111111
ABC0081111111111
ABC009111111111
ABC01011111111
ABC0111111111
ABC012111111
ABC01311111
ABC0141111
ABC015111
ABC01611
ABC0171
ABC018
|
|
|