void op_zprint(mval *rtn, mval *start_label, int start_int_exp, mval *end_label, int end_int_exp) /* contains label to be located or null string */ /* contains label offset or line number to reference */ /* contains routine to look in or null string */ /* NOTE: If only the first label is specified, the */ /* parser makes the second label the duplicate */ /* of the first. (not so vice versa) */ { mval print_line, null_str; mstr *src1, *src2; uint4 stat1, stat2; rhdtyp *rtn_vector; error_def(ERR_FILENOTFND); error_def(ERR_TXTSRCMAT); error_def(ERR_ZPRTLABNOTFND); error_def(ERR_ZLINKFILE); error_def(ERR_ZLMODULE); MV_FORCE_STR(start_label); MV_FORCE_STR(end_label); MV_FORCE_STR(rtn); if (NULL == (rtn_vector = find_rtn_hdr(&rtn->str))) { op_zlink(rtn, NULL); rtn_vector = find_rtn_hdr(&rtn->str); if (NULL == rtn_vector) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, rtn->str.len, rtn->str.addr, ERR_ZLMODULE, 2, mid_len(&zlink_mname), &zlink_mname.c[0]); } stat1 = get_src_line(rtn, start_label, start_int_exp, &src1); if (stat1 & LABELNOTFOUND) rts_error(VARLSTCNT(1) ERR_ZPRTLABNOTFND); if (stat1 & SRCNOTFND) rts_error(VARLSTCNT(4) ERR_FILENOTFND, 2, rtn_vector->src_full_name.len, rtn_vector->src_full_name.addr); if (stat1 & (SRCNOTAVAIL | AFTERLASTLINE)) return; if (stat1 & (ZEROLINE | NEGATIVELINE)) { null_str.mvtype = MV_STR; null_str.str.len = 0; stat1 = get_src_line(rtn, &null_str, 1, &src1); if (stat1 & AFTERLASTLINE) /* the "null" file */ return; } if (end_int_exp == 0 && (end_label->str.len == 0 || *end_label->str.addr == 0)) stat2 = AFTERLASTLINE; else if ((stat2 = get_src_line(rtn, end_label, end_int_exp, &src2)) & LABELNOTFOUND) rts_error(VARLSTCNT(1) ERR_ZPRTLABNOTFND); if (stat2 & (ZEROLINE | NEGATIVELINE)) return; if (stat2 & AFTERLASTLINE) { null_str.mvtype = MV_STR; null_str.str.len = 0; stat2 = get_src_line(rtn, &null_str, 1, &src2); /* number of lines less one for duplicated zero'th line and one due to termination condition being <= */ assert((INTPTR_T)src2 > 0); src2 += rtn_vector->lnrtab_len - 2; } if (stat1 & CHECKSUMFAIL) { rts_error(VARLSTCNT(1) INFO_MSK(ERR_TXTSRCMAT)); op_wteol(1); } print_line.mvtype = MV_STR; for ( ; src1 <= src2 ; src1++) { if (outofband) outofband_action(FALSE); print_line.str.addr = src1->addr; print_line.str.len = src1->len; op_write(&print_line); op_wteol(1); } return; }
void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret) /* label contains label to be located or null string */ /* int_exp contains label offset or line number to reference */ /* ret is used to return the correct string to caller */ { char *cp, *ctop; int i, lbl, letter; mval *temp_rtn, temp_mval; mstr *sld; uint4 stat; rhdtyp *rtn_vector; error_def(ERR_TXTNEGLIN); error_def(ERR_TXTSRCMAT); error_def(ERR_ZLINKFILE); error_def(ERR_ZLMODULE); MV_FORCE_STR(label); MV_FORCE_STR(rtn); temp_rtn = &temp_mval; *temp_rtn = *rtn; /* make a copy of the routine in case the caller used the same mval for rtn and ret */ ret->str.len = 0; /* make ret an emptystring in case the return is by way of the condition handler */ ret->mvtype = MV_STR; sld = (mstr *)NULL; ESTABLISH(fntext_ch); /* to swallow errors and permit an emptystring result */ if ((int_exp == 0) && ((label->str.len == 0) || (*label->str.addr == 0))) stat = ZEROLINE; else stat = get_src_line(temp_rtn, label, int_exp, &sld); if ((FALSE == (stat & CHECKSUMFAIL)) && (FALSE == (stat & NEGATIVELINE))) { if (stat & ZEROLINE) { if (NULL == (rtn_vector = find_rtn_hdr(&temp_rtn->str))) { /* not here, so try to bring it in */ op_zlink(temp_rtn, 0); rtn_vector = find_rtn_hdr(&temp_rtn->str); } if (NULL != rtn_vector) { ret->str.addr = cp = (char *)&rtn_vector->routine_name; for (ctop = cp + sizeof(mident); *cp && cp < ctop; cp++) ; ret->str.len = cp - ret->str.addr; } } else if (NULL != sld) ret->str = *sld; } REVERT; /* If non-empty, copy result to stringpool and * convert any tabs in linestart to spaces */ if (ret->str.len) { if (stringpool.free + ret->str.len > stringpool.top) stp_gcol(ret->str.len); cp = stringpool.free; for (i = 0, lbl = 1; i < ret->str.len; i++) { letter = ret->str.addr[i]; if (lbl) { if ((' ' == letter) || ('\t' == letter)) { letter = ' '; lbl = 0; } *cp++ = letter; } else { if ((' ' != letter) && ('\t' != letter)) { memcpy(cp, &ret->str.addr[i], ret->str.len - i); break; } else *cp++ = ' '; } } ret->str.addr=stringpool.free; stringpool.free += ret->str.len; } return; }