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); and CEEIGZCT, Language
5//! Environment's symbolic feedback codes (`crate::feedback`). A library member of the same name is
6//! found first, as it would be ahead of the system library on z/OS.
7
8/// The EXEC interface block the CICS translator adds to a program's LINKAGE SECTION, in IBM's
9/// order: EIBCALEN at X'18', EIBFN at X'1B', EIBRCODE at X'1D', EIBRESP at X'4C'. IBM names neither
10/// the halfword at X'14' nor the byte at X'3E'.
11pub const EIB: &[(&str, &str)] = &[
12    ("EIBTIME", "S9(7) COMP-3"),
13    ("EIBDATE", "S9(7) COMP-3"),
14    ("EIBTRNID", "X(4)"),
15    ("EIBTASKN", "S9(7) COMP-3"),
16    ("EIBTRMID", "X(4)"),
17    ("FILLER", "S9(4) COMP"),
18    ("EIBCPOSN", "S9(4) COMP"),
19    ("EIBCALEN", "S9(4) COMP"),
20    ("EIBAID", "X(1)"),
21    ("EIBFN", "X(2)"),
22    ("EIBRCODE", "X(6)"),
23    ("EIBDS", "X(8)"),
24    ("EIBREQID", "X(8)"),
25    ("EIBRSRCE", "X(8)"),
26    ("EIBSYNC", "X(1)"),
27    ("EIBFREE", "X(1)"),
28    ("EIBRECV", "X(1)"),
29    ("FILLER", "X(1)"),
30    ("EIBATT", "X(1)"),
31    ("EIBEOC", "X(1)"),
32    ("EIBFMH", "X(1)"),
33    ("EIBCOMPL", "X(1)"),
34    ("EIBSIG", "X(1)"),
35    ("EIBCONF", "X(1)"),
36    ("EIBERR", "X(1)"),
37    ("EIBERRCD", "X(4)"),
38    ("EIBSYNRB", "X(1)"),
39    ("EIBNODAT", "X(1)"),
40    ("EIBRESP", "S9(8) COMP"),
41    ("EIBRESP2", "S9(8) COMP"),
42    ("EIBRLDBK", "X(1)"),
43];
44
45const DFHAID: &[(&str, Option<&str>)] = &[
46    ("DFHNULL", Some("00")), ("DFHENTER", Some("7D")), ("DFHCLEAR", Some("6D")), ("DFHCLRP", Some("6A")), ("DFHPEN", Some("7E")),
47    ("DFHOPID", Some("E6")), ("DFHMSRE", Some("E7")), ("DFHSTRF", Some("88")), ("DFHTRIG", Some("7F")), ("DFHPA1", Some("6C")),
48    ("DFHPA2", Some("6E")), ("DFHPA3", Some("6B")), ("DFHPF1", Some("F1")), ("DFHPF2", Some("F2")), ("DFHPF3", Some("F3")),
49    ("DFHPF4", Some("F4")), ("DFHPF5", Some("F5")), ("DFHPF6", Some("F6")), ("DFHPF7", Some("F7")), ("DFHPF8", Some("F8")),
50    ("DFHPF9", Some("F9")), ("DFHPF10", Some("7A")), ("DFHPF11", Some("7B")), ("DFHPF12", Some("7C")), ("DFHPF13", Some("C1")),
51    ("DFHPF14", Some("C2")), ("DFHPF15", Some("C3")), ("DFHPF16", Some("C4")), ("DFHPF17", Some("C5")), ("DFHPF18", Some("C6")),
52    ("DFHPF19", Some("C7")), ("DFHPF20", Some("C8")), ("DFHPF21", Some("C9")), ("DFHPF22", Some("4A")), ("DFHPF23", Some("4B")),
53    ("DFHPF24", Some("4C")),
54];
55
56/// IBM's "BMS-related constants", each with its byte where one is known here. DFHBMFLG carries the
57/// conditions DFHERASE and DFHCURSR instead of a value.
58const DFHBMSCA: &[(&str, Option<&str>)] = &[
59    ("DFHBMPEM", Some("19")), ("DFHBMPNL", Some("15")), ("DFHBMPFF", Some("0C")), ("DFHBMPCR", Some("0D")), ("DFHBMASK", Some("F0")),
60    ("DFHBMUNP", Some("40")), ("DFHBMUNN", Some("50")), ("DFHBMPRO", Some("60")), ("DFHBMBRY", Some("C8")), ("DFHBMDAR", Some("4C")),
61    ("DFHBMFSE", Some("C1")), ("DFHBMPRF", Some("61")), ("DFHBMASF", Some("F1")), ("DFHBMASB", Some("F8")), ("DFHBMPSO", Some("0E")),
62    ("DFHBMPSI", Some("0F")), ("DFHBMEOF", Some("80")), ("DFHBMCUR", Some("02")), ("DFHBMEC", Some("82")), ("DFHBMFLG", None),
63    ("DFHBMDET", None), ("DFHSA", Some("28")), ("DFHERROR", None), ("DFHCOLOR", Some("42")), ("DFHPS", Some("43")), ("DFHHLT", Some("41")),
64    ("DFH3270", Some("C0")), ("DFHVAL", Some("C1")), ("DFHOUTLN", Some("C2")), ("DFHBKTRN", Some("46")), ("DFHALL", None),
65    ("DFHDFT", Some("FF")), ("DFHDFCOL", None), ("DFHBLUE", Some("F1")), ("DFHRED", Some("F2")), ("DFHPINK", Some("F3")),
66    ("DFHGREEN", Some("F4")), ("DFHTURQ", Some("F5")), ("DFHYELLO", Some("F6")), ("DFHNEUTR", Some("F7")), ("DFHBASE", None),
67    ("DFHDFHI", None), ("DFHBLINK", Some("F1")), ("DFHREVRS", Some("F2")), ("DFHUNDLN", Some("F4")), ("DFHMFIL", None),
68    ("DFHMENT", None), ("DFHMFE", None), ("DFHMT", None), ("DFHMFT", None), ("DFHMET", None), ("DFHMFET", None), ("DFHUNNOD", None),
69    ("DFHUNIMD", None), ("DFHUNNUM", None), ("DFHUNNUB", None), ("DFHUNINT", None), ("DFHUNNON", None), ("DFHPROTI", None),
70    ("DFHPROTN", None), ("DFHDFFR", None), ("DFHUNDER", None), ("DFHRIGHT", None), ("DFHOVER", None), ("DFHLEFT", None), ("DFHBOX", None),
71    ("DFHSOSI", None), ("DFHTRANS", None), ("DFHOPAQ", None),
72];
73
74fn constants(group: &str, names: &[(&str, Option<&str>)]) -> String {
75    let mut out = format!("       01  {group}.\n");
76    for (n, value) in names {
77        match value {
78            Some(v) => out.push_str(&format!("           02 {n} PIC X VALUE X'{v}'.\n")),
79            None => out.push_str(&format!("           02 {n} PIC X.\n")),
80        }
81        if *n == "DFHBMFLG" {
82            out.push_str("              88 DFHERASE VALUES X'80' X'82'.\n              88 DFHCURSR VALUES X'02' X'82'.\n");
83        }
84    }
85    out
86}
87
88/// The text of a system member, for a COPY or EXEC SQL INCLUDE no library answers.
89pub fn member(name: &str) -> Option<String> {
90    Some(match name.to_ascii_uppercase().as_str() {
91        "SQLCA" => [
92            "       01  SQLCA.",
93            "           05 SQLCAID PIC X(8).",
94            "           05 SQLCABC PIC S9(9) COMP-5.",
95            "           05 SQLCODE PIC S9(9) COMP-5.",
96            "           05 SQLCADE REDEFINES SQLCODE PIC S9(9) COMP-5.",
97            "           05 SQLERRM.",
98            "              49 SQLERRML PIC S9(4) COMP-5.",
99            "              49 SQLERRMC PIC X(70).",
100            "           05 SQLERRP PIC X(8).",
101            "           05 SQLERRD PIC S9(9) COMP-5 OCCURS 6.",
102            "           05 SQLWARN.",
103            "              10 SQLWARN0 PIC X.",
104            "              10 SQLWARN1 PIC X.",
105            "              10 SQLWARN2 PIC X.",
106            "              10 SQLWARN3 PIC X.",
107            "              10 SQLWARN4 PIC X.",
108            "              10 SQLWARN5 PIC X.",
109            "              10 SQLWARN6 PIC X.",
110            "              10 SQLWARN7 PIC X.",
111            "           05 SQLEXT.",
112            "              10 SQLWARN8 PIC X.",
113            "              10 SQLWARN9 PIC X.",
114            "              10 SQLWARNA PIC X.",
115            "              10 SQLSTATE PIC X(5).",
116            "              10 SQLSTAT REDEFINES SQLSTATE PIC X(5).",
117            "",
118        ]
119        .join("\n"),
120        "SQLDA" => [
121            "       01  SQLDA.",
122            "           05 SQLDAID PIC X(8).",
123            "           05 SQLDABC PIC S9(9) BINARY.",
124            "           05 SQLN PIC S9(4) BINARY.",
125            "           05 SQLD PIC S9(4) BINARY.",
126            "           05 SQLVAR OCCURS 0 TO 750 TIMES DEPENDING ON SQLN.",
127            "              10 SQLVAR1.",
128            "                 15 SQLTYPE PIC S9(4) BINARY.",
129            "                 15 SQLLEN PIC S9(4) BINARY.",
130            "                 15 FILLER REDEFINES SQLLEN.",
131            "                    20 SQLPRECISION PIC X.",
132            "                    20 SQLSCALE PIC X.",
133            "                 15 SQLDATA POINTER.",
134            "                 15 SQLIND POINTER.",
135            "                 15 SQLNAME.",
136            "                    49 SQLNAMEL PIC S9(4) BINARY.",
137            "                    49 SQLNAMEC PIC X(30).",
138            "",
139        ]
140        .join("\n"),
141        "DFHEIBLK" => {
142            let mut out = "       01  DFHEIBLK.\n".to_owned();
143            for (n, p) in EIB {
144                out.push_str(&format!("           02 {n} PIC {p}.\n"));
145            }
146            out
147        }
148        "DFHAID" => constants("DFHAID", DFHAID),
149        "DFHBMSCA" => constants("DFHBMSCA", DFHBMSCA),
150        "JNI" => crate::jni::member(),
151        "CEEIGZCT" => crate::feedback::member(),
152        _ => return None,
153    })
154}
155
156/// The EIBRESP value for DFHRESP(condition), by any name the condition goes by.
157pub fn resp_code(condition: &str) -> Option<i32> {
158    rt::cics::Condition::from_name(condition).map(rt::cics::Condition::resp)
159}
160
161/// CICS commands whose second word is part of the command, not an option.
162pub fn cics_two_word(first: &str, second: &str) -> bool {
163    matches!(
164        (first, second),
165        ("SEND" | "RECEIVE", "MAP" | "TEXT" | "CONTROL" | "PAGE" | "PARTNSET")
166            | ("HANDLE", "CONDITION" | "AID" | "ABEND")
167            | ("IGNORE", "CONDITION")
168            | ("PUSH" | "POP", "HANDLE")
169            | ("READQ" | "WRITEQ" | "DELETEQ", "TS" | "TD")
170            | ("GET" | "PUT" | "DELETE" | "MOVE", "CONTAINER")
171            | ("WEB", _)
172            | ("INQUIRE" | "SET" | "CREATE" | "DISCARD", _)
173            | ("START", "BROWSE" | "TRANSID")
174            | ("GETNEXT", _)
175            | ("ENDBROWSE", _)
176    )
177}
178