ironwork 0.6.0
Summary
ironwork 0.6.0 runs more of what a batch job's utility steps do. A job whose SORT step reformats and edits records with DFSORT IFTHEN, or whose IDCAMS steps list the catalog, print data sets or define alternate indexes, runs instead of being refused or ending with condition code 12.
- IFTHEN: INREC, OUTREC and OUTFIL IFTHEN with WHEN=INIT, a condition (HIT=NEXT), NONE and GROUP (BEGIN, KEYBEGIN, END, RECORDS, PUSH), applied in DFSORT's order.
- Editing and conversion: edit masks M0 to M26, EDIT and EDxy with SIGNS and LENGTH, and TO= conversions between ZD, PD, BI, FI and the other formats, with Table 12's lengths.
- Symbols: SYMNAMES, with each statement substituting symbols by its own context and the table written to SYMNOUT.
- Bad data: an invalid ZD or PD digit abends the step S0C7. FINDREP, PARSE, arithmetic, dates and SEQNUM are refused by name before any step runs.
- LISTCAT: lists the catalog in IBM's layouts, with ENTRIES, LEVEL, generic names, type selections and ALL.
- PRINT: lists a key-sequenced, entry-sequenced or relative record cluster, an alternate index, a path or a sequential data set in DUMP, HEX or CHARACTER format, with SKIP, COUNT, FROMKEY and TOKEY.
- Alternate indexes: DEFINE ALTERNATEINDEX and PATH, BLDINDEX, and a DD that names a path reads the base cluster in alternate-key order. A step that changes a base cluster rebuilds its alternate indexes.
- Catalog: DEFINE CLUSTER takes KEYS, RECORDSIZE, the organization and RECATALOG. A command that ends at condition code 12 or more closes with IDC3003I.
- Messages: IDCAMS writes its messages to SYSPRINT, not into the OUTFILE data set.
- Fuzzing: a loop that runs on every input is no longer reported as a hang the input caused.
Limit: a program's ALTERNATE RECORD KEY reads use the base cluster as it stands, and the base-ddname+N path DDs are not opened (C350).
Added
- DFSORT IFTHEN in INREC, OUTREC and OUTFIL, as the z/OS 3.1 DFSORT Application Programming Guide describes it. WHEN=GROUP carries fields, identifiers and sequence numbers from record to record. Conditions take HIT=NEXT, and IFOUTLEN is read. Assumptions C340 to C343 record the choices the manual leaves open.
- Edit masks M0 to M26 (Tables 8 to 11), EDIT and EDxy patterns, and TO= conversions.
- SYMNAMES, with the symbol table written to SYMNOUT.
- IDCAMS LISTCAT. With no selection it nests each cluster's and alternate index's components and paths beneath it. ENTRIES keeps the order given and reports a missing name with IDC3012I and condition code 4. LEVEL, generic names and type selections list entries flat in name order. ALL adds the attributes the catalog entries keep. Components take the names DATA(NAME()) and INDEX(NAME()) give, or ones VSAM generates.
- IDCAMS PRINT, laid out as the Access Method Services samples show. Each record comes under its key, RBA, relative record number or record sequence number, and IDC0005I gives the count. SKIP and COUNT select by position. FROMKEY starts at its key or the next higher one and TOKEY stops at its key or the next lower one; a key that ends in an asterisk or is shorter than the data set's is generic. A key longer than the data set's ends the command with IDC3310I, a key on a data set without keys with IDC3311I, and a start past the last record with IDC3006I. An empty cluster fails to open with VSAM OPEN return code 160. Each gives condition code 12, and a listing with no records gives 4.
- IDCAMS DEFINE CLUSTER with KEYS, RECORDSIZE and the organization, DEFINE ALTERNATEINDEX and PATH, and BLDINDEX, which takes a path as its output, refuses an empty base cluster or a built alternate index without REUSE, and reports with IBM's messages. Each is recorded as a
NAME.catalog-entryfile beside the data set. - DEFINE CLUSTER with RECATALOG catalogs a data set already in the directory and keeps its records.
- A DD that names a path reads the base cluster's records in alternate-key order, and what a program writes there goes back to the base cluster. DELETE of a cluster removes its alternate indexes, paths and components, and lists each component it removes.
- Assumptions C350 to C356, C358 and C359 record what ironwork chose where IBM is silent.
Changed
- IDCAMS writes its messages to SYSPRINT. A LISTCAT or PRINT with OUTFILE used to write them into the OUTFILE data set with the listing.
- A command that ends with condition code 12 or more closes with IDC3003I FUNCTION TERMINATED, where it used to close with IDC0001I FUNCTION COMPLETED.
- A duplicate name on DEFINE is condition code 8.
- PRINT lists a key-sequenced cluster in key order, as VSAM reads one, even when REPRO loaded its records out of order. An empty slot of a relative record cluster held as text stays empty and PRINT leaves it out.
ironwork runandjobplace an S322 at the first statement of the loop the run is in once the statement limit is spent, not where the count ran out, and the message names the loop's lines (C241). The place no longer depends on how many statements ran before the loop.ironwork fuzzcompares a hang with the empty input's S322 by loop and keeps each loop once. A loop that runs on every input is not kept. A kept run records the statement limit it ran under inruns[].limit, an optional key in theironwork-fuzz/v1schema, and in the journal's argv. A kept S322 or S806 is not run again at OPTIMIZE(2), which cannot change either. A run that timed out while ACCEPT kept finding SYSIN at its end is not run again, and ACCEPT says so once per statement. Standard error is read at most 1 MiB from each end.fuzz --jobfeeds a generation data group's base through its newest generation and never writes the base, and feeds a relative generation by the generation it names. No SYSIN card it generates starts with/*or//, which end in-stream data on z/OS. The summary counts kept hangs and CALLs the input named apart from the outcomes.fuzz --cicsrefuses--hang-limit.job --coveragekeeps programs of two sources apart when they share a PROGRAM-ID, and names each one's source.
Fixed
- PRINT was parsed but listed nothing and ended with condition code 12, which failed any job that checked a data set with it.
- Jobs that defined an alternate index, built it or read a cluster through a path were refused before any step ran.
- A SORT step that used IFTHEN, edit masks, TO= conversions or SYMNAMES was refused before any step ran.
Upgrading
- Load modules from 0.5.0 run unchanged; the format is still 0.5.
- 0.6.0's code is 0.5.0's: only the version commit sits between the two tags. The jobs work above was already in the 0.5.0 tag, so a 0.5.0 build runs the DFSORT and IDCAMS features here.
- A script that read an IDCAMS LISTCAT or PRINT message from the OUTFILE data set now finds it on SYSPRINT.
- PRINT now lists the data set. A step that ended with condition code 12 because PRINT listed nothing now ends with the listing's own code, and 4 where the listing has no records.
- An S322 reported by
runorjobis placed at the loop's first statement. A script or finding keyed on the old line should be rekeyed. - A fuzz manifest written before this release has no
runs[].limit; readers treat the key as optional.
Install
ironwork for COBOL 0.6.0. Builds for Linux (static), macOS and Windows, and the npm package @portll/ironwork. The ironwork-tls archives are the same builds with TLS for --sql-db (rustls, sslmode=verify-full). The Python package is on PyPI as ironwork, and the crates are on crates.io. Each file carries SLSA build provenance: gh attestation verify -R Portll/ironwork.