Пример #1
0
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;
}
Пример #2
0
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;
}