def levta(self, node: KeyValue) -> str: level = node.get_value("LEVEL") in_use = node.get_value("INUSE") if node.get_value( "INUSE") else node.fall_down not_used = node.get_value("NOTUSED") if node.get_value( "NOTUSED") else node.fall_down return in_use if self._is_level_present(level) else not_used
def error_check(self, node: KeyValue) -> str: if self.is_error(node.label): field_name = node.get_value("FIELD") reg = Register(node.get_value("BASE")) address = self.regs.get_unsigned_value(reg) + self.seg.evaluate( field_name) byte_array = DataType("X", input=node.get_value("XVALUE")).to_bytes() self.vm.set_bytes(byte_array, address, len(byte_array)) return node.fall_down
def sysra(self, node: KeyValue) -> Optional[str]: return_code = node.get_value("P1") dump = node.get_value("P2") self.dumps.append(dump) if return_code == "R": return node.fall_down elif return_code == "E": return None else: raise DumpExecutionError
def mhinf(self, node: KeyValue) -> str: if node.keys[0] != "ECB": raise MhinfExecutionError reg = Register(node.get_value("REG")) if not reg.is_valid(): raise MhinfExecutionError option = node.get_value("INPTR") if option == "NAME": airline_code = self.vm.get_bytes(self.regs.get_value(reg), 2) self.set_partition(DataType("X", bytes=airline_code).decode) else: raise MhinfExecutionError return node.fall_down
def dbifb(self, node: KeyValue) -> str: self._base_sw00sr() error_label = node.get_value("ERRORA") if node.get_value("FILE") == "PR001W": if error_label and self.is_error(node.label): self.regs.R3 = 0 return error_label return node.fall_down if node.get_value("REF") not in self.tpfdf_ref: self.regs.R3 = 0 if error_label: return error_label return node.fall_down
def dbred(self, node: KeyValue) -> str: self._base_sw00sr() # Setup KEY1 Primary key pky = node.get_sub_value("KEY1", "PKY") if pky is not None: key = f"{self.seg.evaluate(pky):02X}" else: key = f"{self.seg.evaluate(node.get_sub_value('KEY1', 'S')):02X}" # Set up KEY2 to KEY6 other_keys = dict() for key_number in range(2, 7): key_n = f"KEY{key_number}" if node.get_value(key_n) is None: break df_field_name = node.get_sub_value(key_n, "R") condition = node.get_sub_value(key_n, "C") sign = self.C[condition] if condition is not None else "==" field: FieldBaseDsp = node.get_sub_value(key_n, "S") if field is None: # TODO For M, D, L types raise DbredError base_address = self.regs.get_value(field.base) length = self.seg.lookup(df_field_name).length byte_array = self.vm.get_bytes(base_address + field.dsp, length) other_keys[df_field_name] = (f"{sign} {byte_array}", length) # Get the lrec ref_name = node.get_value("REF") item_number = 0 if node.get_value( "BEGIN") else self.tpfdf_ref[ref_name] item_number += 1 lrec, item_number = Tpfdf.get_lrec(ref_name, key, item_number, other_keys) self.tpfdf_ref[ref_name] = item_number # Update error_code and REG= if lrec is None or self.is_error(node.label): error_code = self.seg.evaluate("#TPFDBER") else: error_code = self.seg.evaluate("#TPFDBOK") data_address = self.regs.R3 + self.seg.evaluate("SW00KL1") self.vm.set_bytes(lrec, data_address, len(lrec)) reg = Register(node.get_value("REG")) if reg.is_valid(): self.regs.set_value(data_address, reg) self.vm.set_byte(error_code, self.regs.R3 + self.seg.evaluate("SW00RTN")) # ERROR= error_label = node.get_value("ERRORA") if error_label and self.is_error(node.label): return error_label return node.fall_down
def dbcls(self, node: KeyValue) -> str: if any(key not in ["FILE", "REF"] for key in node.keys): raise TpfdfExecutionError(node) file_value = node.get_value("FILE") ref_value = node.get_value("REF") if file_value and file_value != "PR001W": raise TpfdfExecutionError(node) if file_value == "PR001W": return node.fall_down if ref_value not in self.tpfdf_ref and ref_value != "ALL": raise TpfdfExecutionError(node) if ref_value == "ALL": self.tpfdf_ref.clear() else: del self.tpfdf_ref[ref_value] return node.fall_down
def aaget(self, node: KeyValue) -> str: address = self.vm.allocate() ecb_address = self.get_ecb_address("D1", "CE1CR") self.vm.set_value(address, ecb_address) reg = Register(node.get_value("BASEREG")) if reg.is_valid(): self.regs.set_value(address, reg) return node.fall_down
def crusa(self, node: KeyValue) -> str: for index in range(16): level = node.get_value(f"S{index}") if level is None: break control_address = self.get_ecb_address(f"D{level}", "CE1CT") size_address = self.get_ecb_address(f"D{level}", "CE1CC") self.vm.set_value(0x01, control_address, 2) self.vm.set_value(0, size_address, 2) return node.fall_down
def senda(self, node: KeyValue) -> str: message: str = node.get_value("MSG") if message: self.messages.append(message.replace("'", "")) return node.fall_down can: str = node.get_value("CAN") if not can: raise UserDefinedMacroExecutionError(node) canned_number = macros["UI2PF"].evaluate(can) if node.get_value("SEC") == "YES": canned_number += 256 message_string = next( (canned["message"] for canned in UI2CNN if int(canned["number"]) == canned_number), None) if not message_string: raise UserDefinedMacroExecutionError(node) self.messages.append(message_string) return node.fall_down
def aacpy(self, node: KeyValue) -> str: to_level = node.get_value("TO") if to_level not in config.ECB_LEVELS or to_level == "1": raise UserDefinedMacroExecutionError(node) core_reference = self.get_ecb_address(f"D{to_level}", "CE1CR") aaa_copy = self.vm.allocate() self.vm.set_value(aaa_copy, core_reference) aaa_bytes = copy(self.vm.frames[self.vm.base_key(config.AAA)]) self.vm.set_bytes(aaa_bytes, aaa_copy, len(aaa_bytes)) return node.fall_down
def pnrcc(self, node: KeyValue) -> str: action = node.get_value("ACTION") reg = Register(node.get_value("REG")) if not reg.is_valid(): raise RegisterInvalidError pnrcm_base = self.regs.get_value(reg) self.seg.load_macro("PNRCM") if self.is_error(node.label): error_code = self.seg.evaluate("#PM1ER5") self.vm.set_value(error_code, pnrcm_base + self.seg.evaluate("PM1ERR"), 1) return node.fall_down if action in ["CRLON"]: pnr_locator_bytes = self.vm.get_bytes( pnrcm_base + self.seg.evaluate("PM1LOC"), 6) pnr_locator = DataType("X", bytes=pnr_locator_bytes).decode ordinal = PnrLocator.to_ordinal(pnr_locator) self.vm.set_value(ordinal, pnrcm_base + self.seg.evaluate("PM1ORN")) self.vm.set_value(ordinal, pnrcm_base + self.seg.evaluate("PM1FAD")) return node.fall_down
def heapa(self, node: KeyValue) -> str: # REG, REF and SREF reg = Register(node.get_value("REG")) ref = node.get_value("REF") if ref is None: sref = node.get_value("SREF") if sref is None: raise HeapaExecutionError ref_bytes = self.seg.get_constant_bytes(sref, 8) ref = DataType("X", bytes=ref_bytes).decode # ERROR= for forced errors error_label = node.get_value("ERROR") if error_label and self.is_error(node.label): if reg.is_valid(): self.regs.set_value(0, reg) return error_label # HEAPA / CFCMA / EHEAPA command types command = node.keys[0] heap = self.heap["new"] if node.command == "EHEAPA" else self.heap[ "old"] if command == "ALLOCATE": address = self.vm.allocate() heap[ref] = address if reg.is_valid(): self.regs.set_value(address, reg) elif command == "LOADADD": address = heap[ref] if ref in heap else 0 if reg.is_valid(): self.regs.set_value(address, reg) if address == 0 and error_label: return error_label elif command == "FREE": heap.pop(ref, None) else: raise HeapaExecutionError return node.fall_down
def mcpck(self, node: KeyValue) -> str: match_label = node.get_value("YES") if node.get_value( "YES") else node.fall_down not_match_label = node.get_value("NO") if node.get_value( "NO") else node.fall_down if node.get_value("GROUP") == "LAN": return match_label if self.get_partition() in { "LA", "4M", "XL" } else not_match_label if node.get_value("PP"): not_mcp_label = node.get_value("NOTMCP") if not_mcp_label and self.get_partition() not in { "LA", "4M", "XL" }: return not_mcp_label return match_label if self.get_partition() in { "LA" } else not_match_label raise McpckExecutionError
def _pd0_base(self, node: KeyValue) -> Optional[int]: workarea = node.get_value("WORKAREA") if workarea is None: raise Pd0BaseError if workarea[0] == "LEV": lev_parameter = workarea[1] level = lev_parameter[1] if len( lev_parameter ) == 2 and lev_parameter[0] == "D" else lev_parameter if not self._is_level_present(level): self._core_block(self.vm.allocate(), level) level = f"D{level}" level_address = self.get_ecb_address(level, "CE1CR") pd0_base = self.vm.get_value(level_address) elif workarea[0] == "REG": reg = Register(workarea[1]) if not reg.is_valid(): raise RegisterInvalidError pd0_base = self.regs.get_value(reg) else: raise Pd0BaseError return pd0_base
def prima(self, node: KeyValue) -> str: if "PNR" not in node.keys and "AAA" not in node.keys: raise PrimaExecutionError if node.get_value("MODE") != "CHECK": raise PrimaExecutionError if node.get_value("PNRLEV") or node.get_value("PRDATA"): raise PrimaExecutionError match_label = node.get_value("YES") if node.get_value( "YES") else node.fall_down not_match_label = node.get_value("NO") if node.get_value( "NO") else node.fall_down prime_host = self.vm.get_value( config.AAA + macros["WA0AA"].evaluate("WA0PHA"), 1) & 0x0F input_type = node.get_value("PH") if prime_host == 0: return not_match_label elif prime_host == 2: return match_label if input_type in ("1F", "ANY") else not_match_label elif prime_host == 3: return match_label if input_type in ("1B", "ANY") else not_match_label else: raise PrimaExecutionError
def pdred(self, node: KeyValue) -> str: # Get the key from FIELD= or INDEX= self.seg.load_macro("PDEQU") self.seg.load_macro("PD0WRK") key_label = f"#PD_{node.get_value('FIELD')}_K" try: key_number = self.seg.evaluate(key_label) key = f"{key_number:2X}" except KeyError: # TODO Code for INDEX= Not in ETA5 raise PdredFieldError # ERROR= error_label = node.get_value("ERROR") if error_label and self.is_error(node.label): return error_label # ACTION=VERIFY if node.get_value("ACTION") == "VERIFY": not_found_label = node.get_value("NOTFOUND") if node.get_value( "NOTFOUND") else node.fall_down found_label = node.get_value("FOUND") if node.get_value( "FOUND") else node.fall_down data, _ = Pnr.get_pnr_data(self._get_pnr_locator(), key, item_number=1) return not_found_label if data is None else found_label # Get the base of PD0WRK pd0_base = self._pd0_base(node) if pd0_base == 0: raise TPFServerMemoryError # Get the item number to read (Item numbers start from 1) pd0_ctl_key: LabelReference = self.seg.lookup("PD0_CTL_KEY") pd0_mc_cin: LabelReference = self.seg.lookup("PD0_MC_CIN") last_key = self.vm.get_unsigned_value(pd0_base + pd0_ctl_key.dsp, pd0_ctl_key.length) item_number = self.vm.get_value(pd0_base + pd0_mc_cin.dsp, pd0_mc_cin.length) + 1 \ if last_key == key_number else 1 self.vm.set_value(key_number, pd0_base + pd0_ctl_key.dsp, pd0_ctl_key.length) # SEARCH-n parameters starts_with: Optional[str] = None for index in range(1, 7): search = node.get_value(f"SEARCH{index}") if search is None: break if search[0] == "START": if len(search) != 2: raise PdredSearchError if search[1].startswith("'") and search[1].endswith("'"): starts_with = search[1][1:-1] elif search[1].startswith("(") and search[1].endswith(")"): reg = search[1][1:-1] base_address = self.regs.get_unsigned_value(reg) length = self.vm.get_unsigned_value(base_address, 1) char_bytes = self.vm.get_bytes(base_address + 1, length) starts_with = DataType("X", bytes=char_bytes).decode # Get the data pnr_locator = self._get_pnr_locator() packed = node.get_value("FORMATOUT") == "PACKED" if key == "20": # PNR Header data, item_number = Pnr.get_pnr_data(pnr_locator, "20", 1, packed=True) else: data, item_number = Pnr.get_pnr_data(pnr_locator, key, item_number, packed=packed, starts_with=starts_with) self.vm.set_value(item_number, pd0_base + pd0_mc_cin.dsp, pd0_mc_cin.length) # NOTFOUND & last item if data is None: not_found = node.get_value("NOTFOUND") if not_found is None: raise PdredNotFoundError return not_found elif item_number == Pnr.get_len(pnr_locator, key): last_item_bit: int = self.seg.evaluate("#PD0_RT_LST") pd0_rt_id1: LabelReference = self.seg.lookup("PD0_RT_ID1") self.vm.or_bit(pd0_base + pd0_rt_id1.dsp, last_item_bit) # Update the data in PD0WRK pd0_itm: LabelReference = self.seg.lookup( "PD0_P_DATA") if packed else self.seg.lookup("PD0_C_ITM") pd0_rt_adr: LabelReference = self.seg.lookup("PD0_RT_ADR") if len(data) > pd0_itm.length: raise PdredPd0Error self.vm.set_bytes(data, pd0_base + pd0_itm.dsp, len(data)) pd0_rt_adr_value = pd0_base + pd0_itm.dsp if node.get_value("POINT") == "YES": attribute = Pnr.get_attribute_by_key(key) if packed: pd0_rt_adr_value += (len(Pnr.STD_PREFIX_BYTES) + len(attribute.std_fix)) pd0_rt_adr_value += len(attribute.std_var) self.vm.set_value(pd0_rt_adr_value, pd0_base + pd0_rt_adr.dsp, pd0_rt_adr.length) return node.fall_down
def realtima(self, node: KeyValue) -> str: realtime_label = node.get_value("YES") if node.get_value( "YES") else node.fall_down return realtime_label
def dbopn(self, node: KeyValue) -> str: self.tpfdf_ref[node.get_value("REF")] = 0 return node.fall_down
def nmsea(node: KeyValue) -> str: # TODO Finish NMSEA when data on NM0ID or WGL1 is available error = node.get_value("ERROR") return error if error else node.fall_down
def tkdna(node: KeyValue) -> str: error = node.get_value("ERROR") if not error: raise NotImplementedExecutionError return error
def pnamc(self, node: KeyValue) -> str: field: FieldBaseDsp = node.get_value("FIELD") self.vm.set_bytes(self.fields["CE3ENTPGM"], self.regs.get_value(field.base) + field.dsp, 4) return node.fall_down