Skip to main content

ironwork_syntax/
system.rs

1//! The copy members IBM's translators and products supply, as ironwork's own declarations of the
2//! layouts and names IBM documents: Db2 13 for z/OS SQL Reference ("The included SQLCA", "The
3//! included SQLDA"), CICS TS Data Areas ("EIB - EXEC interface block") and CICS TS Application
4//! Programming Reference, "BMS-related constants" (DFHAID, DFHBMSCA). A library member of the same
5//! name is found first, as it would be ahead of the system library on z/OS.
6
7/// The EXEC interface block the CICS translator adds to a program's LINKAGE SECTION, in IBM's
8/// order: EIBCALEN at X'18', EIBFN at X'1B', EIBRCODE at X'1D', EIBRESP at X'4C'. IBM names neither
9/// the halfword at X'14' nor the byte at X'3E'.
10pub const EIB: &[(&str, &str)] = &[
11    ("EIBTIME", "S9(7) COMP-3"),
12    ("EIBDATE", "S9(7) COMP-3"),
13    ("EIBTRNID", "X(4)"),
14    ("EIBTASKN", "S9(7) COMP-3"),
15    ("EIBTRMID", "X(4)"),
16    ("FILLER", "S9(4) COMP"),
17    ("EIBCPOSN", "S9(4) COMP"),
18    ("EIBCALEN", "S9(4) COMP"),
19    ("EIBAID", "X(1)"),
20    ("EIBFN", "X(2)"),
21    ("EIBRCODE", "X(6)"),
22    ("EIBDS", "X(8)"),
23    ("EIBREQID", "X(8)"),
24    ("EIBRSRCE", "X(8)"),
25    ("EIBSYNC", "X(1)"),
26    ("EIBFREE", "X(1)"),
27    ("EIBRECV", "X(1)"),
28    ("FILLER", "X(1)"),
29    ("EIBATT", "X(1)"),
30    ("EIBEOC", "X(1)"),
31    ("EIBFMH", "X(1)"),
32    ("EIBCOMPL", "X(1)"),
33    ("EIBSIG", "X(1)"),
34    ("EIBCONF", "X(1)"),
35    ("EIBERR", "X(1)"),
36    ("EIBERRCD", "X(4)"),
37    ("EIBSYNRB", "X(1)"),
38    ("EIBNODAT", "X(1)"),
39    ("EIBRESP", "S9(8) COMP"),
40    ("EIBRESP2", "S9(8) COMP"),
41    ("EIBRLDBK", "X(1)"),
42];
43
44const DFHAID: &[(&str, Option<&str>)] = &[
45    ("DFHNULL", Some("00")), ("DFHENTER", Some("7D")), ("DFHCLEAR", Some("6D")), ("DFHCLRP", Some("6A")), ("DFHPEN", Some("7E")),
46    ("DFHOPID", Some("E6")), ("DFHMSRE", Some("E7")), ("DFHSTRF", Some("88")), ("DFHTRIG", Some("7F")), ("DFHPA1", Some("6C")),
47    ("DFHPA2", Some("6E")), ("DFHPA3", Some("6B")), ("DFHPF1", Some("F1")), ("DFHPF2", Some("F2")), ("DFHPF3", Some("F3")),
48    ("DFHPF4", Some("F4")), ("DFHPF5", Some("F5")), ("DFHPF6", Some("F6")), ("DFHPF7", Some("F7")), ("DFHPF8", Some("F8")),
49    ("DFHPF9", Some("F9")), ("DFHPF10", Some("7A")), ("DFHPF11", Some("7B")), ("DFHPF12", Some("7C")), ("DFHPF13", Some("C1")),
50    ("DFHPF14", Some("C2")), ("DFHPF15", Some("C3")), ("DFHPF16", Some("C4")), ("DFHPF17", Some("C5")), ("DFHPF18", Some("C6")),
51    ("DFHPF19", Some("C7")), ("DFHPF20", Some("C8")), ("DFHPF21", Some("C9")), ("DFHPF22", Some("4A")), ("DFHPF23", Some("4B")),
52    ("DFHPF24", Some("4C")),
53];
54
55/// IBM's "BMS-related constants", each with its byte where one is known here. DFHBMFLG carries the
56/// conditions DFHERASE and DFHCURSR instead of a value.
57const DFHBMSCA: &[(&str, Option<&str>)] = &[
58    ("DFHBMPEM", Some("19")), ("DFHBMPNL", Some("15")), ("DFHBMPFF", Some("0C")), ("DFHBMPCR", Some("0D")), ("DFHBMASK", Some("F0")),
59    ("DFHBMUNP", Some("40")), ("DFHBMUNN", Some("50")), ("DFHBMPRO", Some("60")), ("DFHBMBRY", Some("C8")), ("DFHBMDAR", Some("4C")),
60    ("DFHBMFSE", Some("C1")), ("DFHBMPRF", Some("61")), ("DFHBMASF", Some("F1")), ("DFHBMASB", Some("F8")), ("DFHBMPSO", Some("0E")),
61    ("DFHBMPSI", Some("0F")), ("DFHBMEOF", Some("80")), ("DFHBMCUR", Some("02")), ("DFHBMEC", Some("82")), ("DFHBMFLG", None),
62    ("DFHBMDET", None), ("DFHSA", Some("28")), ("DFHERROR", None), ("DFHCOLOR", Some("42")), ("DFHPS", Some("43")), ("DFHHLT", Some("41")),
63    ("DFH3270", Some("C0")), ("DFHVAL", Some("C1")), ("DFHOUTLN", Some("C2")), ("DFHBKTRN", Some("46")), ("DFHALL", None),
64    ("DFHDFT", Some("FF")), ("DFHDFCOL", None), ("DFHBLUE", Some("F1")), ("DFHRED", Some("F2")), ("DFHPINK", Some("F3")),
65    ("DFHGREEN", Some("F4")), ("DFHTURQ", Some("F5")), ("DFHYELLO", Some("F6")), ("DFHNEUTR", Some("F7")), ("DFHBASE", None),
66    ("DFHDFHI", None), ("DFHBLINK", Some("F1")), ("DFHREVRS", Some("F2")), ("DFHUNDLN", Some("F4")), ("DFHMFIL", None),
67    ("DFHMENT", None), ("DFHMFE", None), ("DFHMT", None), ("DFHMFT", None), ("DFHMET", None), ("DFHMFET", None), ("DFHUNNOD", None),
68    ("DFHUNIMD", None), ("DFHUNNUM", None), ("DFHUNNUB", None), ("DFHUNINT", None), ("DFHUNNON", None), ("DFHPROTI", None),
69    ("DFHPROTN", None), ("DFHDFFR", None), ("DFHUNDER", None), ("DFHRIGHT", None), ("DFHOVER", None), ("DFHLEFT", None), ("DFHBOX", None),
70    ("DFHSOSI", None), ("DFHTRANS", None), ("DFHOPAQ", None),
71];
72
73fn constants(group: &str, names: &[(&str, Option<&str>)]) -> String {
74    let mut out = format!("       01  {group}.\n");
75    for (n, value) in names {
76        match value {
77            Some(v) => out.push_str(&format!("           02 {n} PIC X VALUE X'{v}'.\n")),
78            None => out.push_str(&format!("           02 {n} PIC X.\n")),
79        }
80        if *n == "DFHBMFLG" {
81            out.push_str("              88 DFHERASE VALUES X'80' X'82'.\n              88 DFHCURSR VALUES X'02' X'82'.\n");
82        }
83    }
84    out
85}
86
87/// The text of a system member, for a COPY or EXEC SQL INCLUDE no library answers.
88pub fn member(name: &str) -> Option<String> {
89    Some(match name.to_ascii_uppercase().as_str() {
90        "SQLCA" => [
91            "       01  SQLCA.",
92            "           05 SQLCAID PIC X(8).",
93            "           05 SQLCABC PIC S9(9) COMP-5.",
94            "           05 SQLCODE PIC S9(9) COMP-5.",
95            "           05 SQLCADE REDEFINES SQLCODE PIC S9(9) COMP-5.",
96            "           05 SQLERRM.",
97            "              49 SQLERRML PIC S9(4) COMP-5.",
98            "              49 SQLERRMC PIC X(70).",
99            "           05 SQLERRP PIC X(8).",
100            "           05 SQLERRD PIC S9(9) COMP-5 OCCURS 6.",
101            "           05 SQLWARN.",
102            "              10 SQLWARN0 PIC X.",
103            "              10 SQLWARN1 PIC X.",
104            "              10 SQLWARN2 PIC X.",
105            "              10 SQLWARN3 PIC X.",
106            "              10 SQLWARN4 PIC X.",
107            "              10 SQLWARN5 PIC X.",
108            "              10 SQLWARN6 PIC X.",
109            "              10 SQLWARN7 PIC X.",
110            "           05 SQLEXT.",
111            "              10 SQLWARN8 PIC X.",
112            "              10 SQLWARN9 PIC X.",
113            "              10 SQLWARNA PIC X.",
114            "              10 SQLSTATE PIC X(5).",
115            "              10 SQLSTAT REDEFINES SQLSTATE PIC X(5).",
116            "",
117        ]
118        .join("\n"),
119        "SQLDA" => [
120            "       01  SQLDA.",
121            "           05 SQLDAID PIC X(8).",
122            "           05 SQLDABC PIC S9(9) BINARY.",
123            "           05 SQLN PIC S9(4) BINARY.",
124            "           05 SQLD PIC S9(4) BINARY.",
125            "           05 SQLVAR OCCURS 0 TO 750 TIMES DEPENDING ON SQLN.",
126            "              10 SQLVAR1.",
127            "                 15 SQLTYPE PIC S9(4) BINARY.",
128            "                 15 SQLLEN PIC S9(4) BINARY.",
129            "                 15 FILLER REDEFINES SQLLEN.",
130            "                    20 SQLPRECISION PIC X.",
131            "                    20 SQLSCALE PIC X.",
132            "                 15 SQLDATA POINTER.",
133            "                 15 SQLIND POINTER.",
134            "                 15 SQLNAME.",
135            "                    49 SQLNAMEL PIC S9(4) BINARY.",
136            "                    49 SQLNAMEC PIC X(30).",
137            "",
138        ]
139        .join("\n"),
140        "DFHEIBLK" => {
141            let mut out = "       01  DFHEIBLK.\n".to_owned();
142            for (n, p) in EIB {
143                out.push_str(&format!("           02 {n} PIC {p}.\n"));
144            }
145            out
146        }
147        "DFHAID" => constants("DFHAID", DFHAID),
148        "DFHBMSCA" => constants("DFHBMSCA", DFHBMSCA),
149        _ => return None,
150    })
151}
152
153/// EIBRESP values by condition name, as the CICS Application Programming Reference lists them, for
154/// DFHRESP(condition), which the translator replaces with the number.
155const RESP: &[(&str, i32)] = &[
156    ("NORMAL", 0), ("ERROR", 1), ("RDATT", 2), ("WRBRK", 3), ("EOF", 4), ("EODS", 5), ("EOC", 6), ("INBFMH", 7), ("ENDINPT", 8),
157    ("NONVAL", 9), ("NOSTART", 10), ("TERMIDERR", 11), ("FILENOTFOUND", 12), ("DSIDERR", 12), ("NOTFND", 13), ("DUPREC", 14),
158    ("DUPKEY", 15), ("INVREQ", 16), ("IOERR", 17), ("NOSPACE", 18), ("NOTOPEN", 19), ("ENDFILE", 20), ("ILLOGIC", 21), ("LENGERR", 22),
159    ("QZERO", 23), ("SIGNAL", 24), ("QBUSY", 25), ("ITEMERR", 26), ("PGMIDERR", 27), ("TRANSIDERR", 28), ("ENDDATA", 29),
160    ("INVTSREQ", 30), ("EXPIRED", 31), ("RETPAGE", 32), ("RTEFAIL", 33), ("RTESOME", 34), ("TSIOERR", 35), ("MAPFAIL", 36),
161    ("INVERRTERM", 37), ("INVMPSZ", 38), ("IGREQID", 39), ("OVERFLOW", 40), ("INVLDC", 41), ("NOSTG", 42), ("JIDERR", 43),
162    ("QIDERR", 44), ("NOJBUFSP", 45), ("DSSTAT", 46), ("SELNERR", 47), ("FUNCERR", 48), ("UNEXPIN", 49), ("NOPASSBKRD", 50),
163    ("NOPASSBKWR", 51), ("SEGIDERR", 52), ("SYSIDERR", 53), ("ISCINVREQ", 54), ("ENQBUSY", 55), ("ENVDEFERR", 56), ("IGREQCD", 57),
164    ("SESSIONERR", 58), ("SYSBUSY", 59), ("SESSBUSY", 60), ("NOTALLOC", 61), ("CBIDERR", 62), ("INVEXITREQ", 63), ("INVPARTNSET", 64),
165    ("INVPARTN", 65), ("PARTNFAIL", 66), ("USERIDERR", 69), ("NOTAUTH", 70), ("VOLIDERR", 71), ("SUPPRESSED", 72), ("END", 83),
166    ("DISABLED", 84), ("TASKIDERR", 91), ("TCIDERR", 92), ("DSNNOTFOUND", 93), ("LOADING", 94), ("MODELIDERR", 95), ("PARTNERIDERR", 97),
167    ("PROFILEIDERR", 98), ("LOCKED", 100), ("RECORDBUSY", 101), ("UOWNOTFOUND", 102), ("CONTAINERERR", 110), ("TOKENERR", 112),
168    ("CSDERR", 119), ("DUPRES", 120), ("CHANNELERR", 122), ("CCSIDERR", 123), ("TIMEDOUT", 124), ("CODEPAGEERR", 125), ("INCOMPLETE", 126),
169    ("BUSY", 128),
170];
171
172pub fn resp_code(condition: &str) -> Option<i32> {
173    RESP.iter().find(|(n, _)| n.eq_ignore_ascii_case(condition)).map(|&(_, v)| v)
174}
175
176/// CICS commands whose second word is part of the command, not an option.
177pub fn cics_two_word(first: &str, second: &str) -> bool {
178    matches!(
179        (first, second),
180        ("SEND" | "RECEIVE", "MAP" | "TEXT" | "CONTROL" | "PAGE" | "PARTNSET")
181            | ("HANDLE", "CONDITION" | "AID" | "ABEND")
182            | ("IGNORE", "CONDITION")
183            | ("PUSH" | "POP", "HANDLE")
184            | ("READQ" | "WRITEQ" | "DELETEQ", "TS" | "TD")
185            | ("GET" | "PUT" | "DELETE" | "MOVE", "CONTAINER")
186            | ("WEB", _)
187            | ("INQUIRE" | "SET" | "CREATE" | "DISCARD", _)
188            | ("START", "BROWSE" | "TRANSID")
189            | ("GETNEXT", _)
190            | ("ENDBROWSE", _)
191    )
192}
193