776 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			776 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *	nreq.c - cawf(1) processing of nroff requests
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 *	Copyright (c) 1991 Purdue University Research Foundation,
 | 
						|
 *	West Lafayette, Indiana 47907.  All rights reserved.
 | 
						|
 *
 | 
						|
 *	Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
 | 
						|
 *	University Computing Center.  Not derived from licensed software;
 | 
						|
 *	derived from awf(1) by Henry Spencer of the University of Toronto.
 | 
						|
 *
 | 
						|
 *	Permission is granted to anyone to use this software for any
 | 
						|
 *	purpose on any computer system, and to alter it and redistribute
 | 
						|
 *	it freely, subject to the following restrictions:
 | 
						|
 *
 | 
						|
 *	1. The author is not responsible for any consequences of use of
 | 
						|
 *	   this software, even if they arise from flaws in it.
 | 
						|
 *
 | 
						|
 *	2. The origin of this software must not be misrepresented, either
 | 
						|
 *	   by explicit claim or by omission.  Credits must appear in the
 | 
						|
 *	   documentation.
 | 
						|
 *
 | 
						|
 *	3. Altered versions must be plainly marked as such, and must not
 | 
						|
 *	   be misrepresented as being the original software.  Credits must
 | 
						|
 *	   appear in the documentation.
 | 
						|
 *
 | 
						|
 *	4. This notice may not be removed or altered.
 | 
						|
 */
 | 
						|
 | 
						|
#include "cawf.h"
 | 
						|
#include <ctype.h>
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Prototypes for request processing functions.
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_UL(unsigned char *line, int brk);
 | 
						|
static void nr_Ub(unsigned char *line, int brk);
 | 
						|
static void nr_Uc(unsigned char *line, int brk);
 | 
						|
static void nr_Uf(unsigned char *line, int brk);
 | 
						|
static void nr_Ur(unsigned char *line, int brk);
 | 
						|
static void nr_ad(unsigned char *line, int brk);
 | 
						|
static void nr_bp(unsigned char *line, int brk);
 | 
						|
static void nr_br(unsigned char *line, int brk);
 | 
						|
static void nr_ce(unsigned char *line, int brk);
 | 
						|
static void nr_di(unsigned char *line, int brk);
 | 
						|
static void nr_ds(unsigned char *line, int brk);
 | 
						|
static void nr_fi(unsigned char *line, int brk);
 | 
						|
static void nr_fl(unsigned char *line, int brk);
 | 
						|
static void nr_ft(unsigned char *line, int brk);
 | 
						|
static void nr_it(unsigned char *line, int brk);
 | 
						|
static void nr_na(unsigned char *line, int brk);
 | 
						|
static void nr_nf(unsigned char *line, int brk);
 | 
						|
static void nr_ns(unsigned char *line, int brk);
 | 
						|
static void nr_rm(unsigned char *line, int brk);
 | 
						|
static void nr_rn(unsigned char *line, int brk);
 | 
						|
static void nr_rr(unsigned char *line, int brk);
 | 
						|
static void nr_rs(unsigned char *line, int brk);
 | 
						|
static void nr_tm(unsigned char *line, int brk);
 | 
						|
static void nr_tr(unsigned char *line, int brk);
 | 
						|
 | 
						|
static void nr_nil(unsigned char *line, int brk);
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * NrReqt[] - nroff request processing table
 | 
						|
 *
 | 
						|
 * CAUTION: place new entries in their proper alphabetical order, since
 | 
						|
 *	    this table is processed with a binary search.
 | 
						|
 */
 | 
						|
 | 
						|
static struct nr_req {
 | 
						|
	char *nm;			/* nroff request */
 | 
						|
	void (*fun)();			/* processing function */
 | 
						|
} NrReqt[] = {
 | 
						|
	{ "\\\"",	nr_nil },	/* backslash-quote */
 | 
						|
	{ "^#",		nr_UL  },
 | 
						|
	{ "^=",		nr_UL  },
 | 
						|
	{ "^b",		nr_Ub  },
 | 
						|
	{ "^c",		nr_Uc  },
 | 
						|
	{ "^d",		nr_nil },
 | 
						|
	{ "^e",		nr_nil },
 | 
						|
	{ "^f",		nr_Uf  },
 | 
						|
	{ "^r",		nr_Ur  },
 | 
						|
	{ "^x",		nr_nil },
 | 
						|
	{ "ad",		nr_ad  },
 | 
						|
	{ "bp",		nr_bp  },
 | 
						|
	{ "br",		nr_br  },
 | 
						|
	{ "ce",		nr_ce  },
 | 
						|
	{ "di",		nr_di  },
 | 
						|
	{ "ds",		nr_ds  },
 | 
						|
	{ "fi",		nr_fi  },
 | 
						|
	{ "fl",		nr_fl  },
 | 
						|
	{ "ft",		nr_ft  },
 | 
						|
	{ "hy",		nr_nil },
 | 
						|
	{ "i0",		nr_nil },
 | 
						|
	{ "it",		nr_it  },
 | 
						|
	{ "lg",		nr_nil },
 | 
						|
	{ "li",		nr_nil },
 | 
						|
	{ "na",		nr_na  },
 | 
						|
	{ "nf",		nr_nf  },
 | 
						|
	{ "ns",		nr_ns  },
 | 
						|
	{ "ps",		nr_nil },
 | 
						|
	{ "rm",		nr_rm  },
 | 
						|
	{ "rn",		nr_rn  },
 | 
						|
	{ "rr",		nr_rr  },
 | 
						|
	{ "rs",		nr_rs  },
 | 
						|
	{ "tm",		nr_tm  },
 | 
						|
	{ "tr",		nr_tr  },
 | 
						|
	{ "vs",		nr_nil },
 | 
						|
};
 | 
						|
/*
 | 
						|
 * Nreq(line, brk) - process miscellaneous nroff requests from line
 | 
						|
 *		     buffer with request status of (brk)
 | 
						|
 */
 | 
						|
 | 
						|
void Nreq(unsigned char *line, int brk) {
 | 
						|
	unsigned char c[3];		/* command buffer */
 | 
						|
	int cmp, hi, low, mid;		/* binary search indixes */
 | 
						|
 | 
						|
	c[0] = c[1] = c[2] = '\0';
 | 
						|
	if ((c[0] = line[1]) != '\0')
 | 
						|
		c[1] = line[2];
 | 
						|
 | 
						|
	low = mid = 0;
 | 
						|
	hi = sizeof(NrReqt) / sizeof(struct nr_req);
 | 
						|
	while (low <= hi) {
 | 
						|
		mid = (low + hi) / 2;
 | 
						|
		if ((cmp = strcmp((char *)c, NrReqt[mid].nm)) < 0)
 | 
						|
			hi = mid - 1;
 | 
						|
		else if (cmp > 0)
 | 
						|
			low = mid + 1;
 | 
						|
		else {
 | 
						|
			(void) (*NrReqt[mid].fun)(line, brk);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
	}
 | 
						|
    /*
 | 
						|
     * Unknown request starting with a '.' or '\''..
 | 
						|
     */
 | 
						|
	Error(WARN, LINE, " unknown request", NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Adjust - "^[.']ad"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_ad(unsigned char *line, int brk) {
 | 
						|
	Pass3(NOBREAK, (unsigned char *)"both", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
* Begin new page - "^[.']bp"
 | 
						|
*/
 | 
						|
 | 
						|
static void nr_bp(unsigned char *line, int brk) {
 | 
						|
	Pass3(brk, (unsigned char *)"need", NULL, 999);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
* Break - "^[.']br"
 | 
						|
*/
 | 
						|
 | 
						|
static void nr_br(unsigned char *line, int brk) {
 | 
						|
	Pass3(brk, (unsigned char *)"flush", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Center - "^[.']ce"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_ce(unsigned char *line, int brk) {
 | 
						|
	unsigned char *s;			/* string poiner */
 | 
						|
 | 
						|
	if ((s = Field(2, line, 0)) != NULL)
 | 
						|
		Centering = atoi((char *)s);
 | 
						|
	else
 | 
						|
		Centering = 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Diversion on and off - "^[.']di"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_di(unsigned char *line, int brk) {
 | 
						|
	Pass3(DOBREAK, (unsigned char *)"flush", NULL, 0);
 | 
						|
	Divert ^= 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Define string - "^[.']ds"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_ds(unsigned char *line, int brk) {
 | 
						|
	unsigned char buf[MAXLINE];	/* temporary buffer */
 | 
						|
	unsigned char nm[4], nm1[4];	/* name buffers */
 | 
						|
	unsigned char *s1, *s2, *s3,	/* temporary string pointers */
 | 
						|
		       *s4;
 | 
						|
 | 
						|
	if (Asmname(&line[3], nm) == 0) {
 | 
						|
		Error(WARN, LINE, " no name", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	s1 = Field(3, line, 0);
 | 
						|
	s2 = Findstr(nm, s1, 1);
 | 
						|
	while (*s2 == '\\' && *(s2 + 1) == '*') {
 | 
						|
		s2++;
 | 
						|
		s3 = Asmcode(&s2, nm1);
 | 
						|
		s2 = Findstr(nm1, NULL, 0);
 | 
						|
	}
 | 
						|
	if (Hdft) {
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Look for names LH, LF, CH, CF, RH, RF.
 | 
						|
	 */
 | 
						|
		if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
 | 
						|
		&&  (nm[1]=='F' || nm[1]=='H')) {
 | 
						|
			(void) sprintf((char *)buf, "%s", (char *)nm);
 | 
						|
			Pass3(NOBREAK, buf, s2, 0);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Fill - "^[.']fi"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_fi(unsigned char *line, int brk) {
 | 
						|
	Fill = 1;
 | 
						|
	Pass3(brk, (unsigned char *)"flush", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Flush - "^[.']fl"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_fl(unsigned char *line, int brk) {
 | 
						|
	Pass3(brk, (unsigned char *)"flush", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Font - "^[.']ft <font_name>"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_ft(unsigned char *line, int brk) {
 | 
						|
	int i;				/* temporary index */
 | 
						|
 | 
						|
	if (line[3] == '\0' || line[4] == '\0')
 | 
						|
		line[4] = 'P';
 | 
						|
	if (line[4] == 'P') {
 | 
						|
		Font[0] = Prevfont;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	for (i = 0; Fcode[i].nm; i++) {
 | 
						|
		if (Fcode[i].nm == line[4])
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	if (Fcode[i].status == '\0') {
 | 
						|
		Error(WARN, LINE, " bad font code", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	Prevfont = Font[0];
 | 
						|
	Font[0] = line[4];
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Input trap - "^[.']it [1 <request>]"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_it(unsigned char *line, int brk) {
 | 
						|
	unsigned char buf[MAXLINE];	/* temporary buffer */
 | 
						|
	int i;				/* temporary index */
 | 
						|
	unsigned char *s1, *s2;		/* temporary string pointers */
 | 
						|
 | 
						|
	if ((s1 = Field(2, line, 0)) == NULL) {
 | 
						|
		Free(&Aftnxt);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((i = atoi((char *)s1)) != 1) {
 | 
						|
		Error(WARN, LINE, " first .it arg must be 1", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((s2 = Field(3, line, 0)) == NULL)
 | 
						|
		Free(&Aftnxt);
 | 
						|
	else {
 | 
						|
		(void) sprintf((char *)buf, "%s,%s",
 | 
						|
			(Aftnxt == NULL) ? "" : (char *)Aftnxt,
 | 
						|
			(char *)s2);
 | 
						|
		Free(&Aftnxt);
 | 
						|
		Aftnxt = Newstr(buf);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Comment - "^[.']\\" - do nothing
 | 
						|
 *
 | 
						|
 * Debug - "^[.']\^d" - do nothing
 | 
						|
 *
 | 
						|
 * Finalization - "[.']\^e" - do nothing
 | 
						|
 *
 | 
						|
 * Error file - "^[.']\^x <name>" - do nothing
 | 
						|
 *
 | 
						|
 * "^[.']i0", "^[.']lg" and "^[.']li" - do nothing
 | 
						|
 *
 | 
						|
 * Point size - "^[.']ps" - do nothing
 | 
						|
 *
 | 
						|
 * Vertical spacing - "^[.']vs" - do nothing
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_nil(unsigned char *line, int brk) {
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * No adjust "^[.']na"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_na(unsigned char *line, int brk) {
 | 
						|
	Pass3(NOBREAK, (unsigned char *)"left", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * No fill - "^[.']nf"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_nf(unsigned char *line, int brk) {
 | 
						|
	Fill = 0;
 | 
						|
	Pass3(brk, (unsigned char *)"flush", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * No space - "^[.']ns"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_ns(unsigned char *line, int brk) {
 | 
						|
	Pass3(NOBREAK, (unsigned char *)"nospace", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Remove macro or string - "^[.']rm"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_rm(unsigned char *line, int brk) {
 | 
						|
	int i;				/* temporary index */
 | 
						|
	unsigned char nm[4];		/* name buffer */
 | 
						|
 | 
						|
	if (Asmname(&line[3], nm) == 0) {
 | 
						|
		Error(WARN, LINE, " no name", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((i = Findmacro(nm, 0)) >= 0) {
 | 
						|
		Delmacro(i);
 | 
						|
		return;
 | 
						|
			}
 | 
						|
	(void) Findstr(nm, NULL, 0);
 | 
						|
		if (Sx >= 0) {
 | 
						|
			Delstr(Sx);
 | 
						|
			return;
 | 
						|
	}
 | 
						|
	Error(WARN, LINE, " no macro/string", NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Rename macro or string - "^[.']rn"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_rn(unsigned char *line, int brk) {
 | 
						|
	int i, j;			/* temporary indexes */
 | 
						|
	unsigned char nm[4], nm1[4];	/* name buffers */
 | 
						|
	unsigned char *s1;		/* temporary string pointer */
 | 
						|
 | 
						|
	if ((s1 = Field(2, line, 0)) == NULL ||  Asmname(s1, nm) == 0) {
 | 
						|
		Error(WARN, LINE, " no name", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((s1 = Field(3, line, 0)) == NULL ||  Asmname(s1, nm1) == 0) {
 | 
						|
		Error(WARN, LINE, " no new name", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((i = Findmacro(nm, 0)) >= 0) {
 | 
						|
		if ((j = Findmacro(nm1, 0)) >= 0)
 | 
						|
			Delmacro(j);
 | 
						|
		j = Findmacro(nm1, 1);
 | 
						|
		Macrotab[j].bx = Macrotab[i].bx;
 | 
						|
		Macrotab[i].bx = -1;
 | 
						|
		Macrotab[j].ct = Macrotab[i].ct;
 | 
						|
		Macrotab[i].ct = 0;
 | 
						|
		Delmacro(i);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	(void) Findstr(nm, NULL, 0);
 | 
						|
	if ((i = Sx) >= 0) {
 | 
						|
		(void) Findstr(nm1, Str[i].str, 1);
 | 
						|
		Delstr(i);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if (Findmacro(nm1, 0) < 0)
 | 
						|
		(void) Findmacro(nm1, 1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Remove register - "^[.']rr"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_rr(unsigned char *line, int brk) {
 | 
						|
	int i;				/* temporary index */
 | 
						|
	unsigned char nm[4];		/* name buffer */
 | 
						|
 | 
						|
	if (Asmname(&line[3], nm) == 0) {
 | 
						|
		Error(WARN, LINE, " no name", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if ((i = Findnum(nm, 0, 0)) < 0) {
 | 
						|
		Error(WARN, LINE, " no register", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	Delnum(i);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Resume space - "^[.']rs"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_rs(unsigned char *line, int brk) {
 | 
						|
	Pass3(NOBREAK, (unsigned char *)"yesspace", NULL, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Message - "^[.']tm"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_tm(unsigned char *line, int brk) {
 | 
						|
	Pass3(MESSAGE, Inname, (line[3] == ' ') ? &line[4] : &line[3], NR);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Translate - "^[.']tr abcd..."
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_tr(unsigned char *line, int brk) {
 | 
						|
	unsigned char buf[MAXLINE];	/* temporary buffer */
 | 
						|
	int i, j;			/* temporary indexes */
 | 
						|
	unsigned char nm[4], nm1[4];	/* name buffers */
 | 
						|
	unsigned char *s1, *s2;		/* temporary string pointers */
 | 
						|
	int trin, trout;		/* types: 0 = char; 1 = named char */
 | 
						|
	unsigned char xbuf[MAXLINE];	/* temporary buffer */
 | 
						|
 | 
						|
	if (line[3] != ' ') {
 | 
						|
		Error(WARN, LINE, " unknown translation", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	for (s1 = &line[4]; *s1;) {
 | 
						|
	    nm[1] = nm[2] = '\0';
 | 
						|
	    s2 = s1 + 1;
 | 
						|
	/*
 | 
						|
	 * Assemble the input value.
 | 
						|
	 */
 | 
						|
	    if (*s1 == '\\' && (*s2 == '*' || *s2 == '(')) {
 | 
						|
		if (*s2 == '(') {
 | 
						|
	    /*
 | 
						|
	     * Input is named character -- "\(xx".
 | 
						|
	     */
 | 
						|
		    trin = 1;
 | 
						|
		    s1 = s2 + 1;
 | 
						|
		    if ((nm[0] = *s1) != '\0') {
 | 
						|
			s1++;
 | 
						|
			if ((nm[1] = *s1) != '\0')
 | 
						|
			    s1++;
 | 
						|
		    }
 | 
						|
		} else {
 | 
						|
	    /*
 | 
						|
	     * Input is interpolated string -- "\*x" or "\*(xx".
 | 
						|
	     */
 | 
						|
		    s1 = Asmcode(&s2, nm);
 | 
						|
		    if (*s1)
 | 
						|
			s1++;
 | 
						|
		    s2 = Findstr(nm, NULL, 0);
 | 
						|
		    if (*s2 != '\0') {
 | 
						|
			if ((strlen((char *)s2) + strlen((char *)s1) + 1)
 | 
						|
			>= MAXLINE)
 | 
						|
			    Error(WARN, LINE, " string too long: ", (char *)nm);
 | 
						|
			else {
 | 
						|
			    (void) sprintf((char *)buf, "%s%s",
 | 
						|
				(char *)s2, (char *)s1);
 | 
						|
			    (void) strcpy((char *)xbuf, (char *)buf);
 | 
						|
			    s1 = xbuf;
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		    continue;
 | 
						|
		}
 | 
						|
	    } else {
 | 
						|
 | 
						|
	    /*
 | 
						|
	     * Input is a simple character.
 | 
						|
	     */
 | 
						|
		trin = 0;
 | 
						|
		if ((nm[0] = *s1) != '\0')
 | 
						|
		    s1++;
 | 
						|
	    }
 | 
						|
	/*
 | 
						|
	 * Assemble the output value.
 | 
						|
	 */
 | 
						|
 | 
						|
assemble_output:
 | 
						|
	    nm1[1] = nm1[2] = '\0';
 | 
						|
	    if (*s1 == '\0') {
 | 
						|
 | 
						|
	    /*
 | 
						|
	     * Supply a space if there is no output character.
 | 
						|
	     */
 | 
						|
		trout = 0;
 | 
						|
		nm1[0] = ' ';
 | 
						|
	    } else {
 | 
						|
		s2 = s1 + 1;
 | 
						|
		if (*s1 == '\\' && (*s2 == '(' || *s2 == '*')) {
 | 
						|
		    if (*s2 == '(') {
 | 
						|
		/*
 | 
						|
		 * The output is a named character -- "\(xx".
 | 
						|
		 */
 | 
						|
			trout = 1;
 | 
						|
			s1 = s2 + 1;
 | 
						|
			if ((nm1[0] = *s1) != '\0') {
 | 
						|
			    s1++;
 | 
						|
			    if ((nm1[1] = *s1) != '\0')
 | 
						|
				s1++;
 | 
						|
			}
 | 
						|
		    } else {
 | 
						|
		/*
 | 
						|
		 * The output is an interpolated string -- * "\*x" or "\*(xx".
 | 
						|
		 */
 | 
						|
			s1 = Asmcode(&s2, nm1);
 | 
						|
			if (*s1)
 | 
						|
			    s1++;
 | 
						|
			s2 = Findstr(nm1, NULL, 0);
 | 
						|
			if (*s2 != '\0') {
 | 
						|
		    /*
 | 
						|
		     * Interpolate a string value.
 | 
						|
		     */
 | 
						|
			    if ((strlen((char *)s2) + strlen((char *)s1) + 1)
 | 
						|
			    >= MAXLINE)
 | 
						|
				Error(WARN, LINE, " string too long: ",
 | 
						|
				    (char *)nm);
 | 
						|
			    else {
 | 
						|
				(void) sprintf((char *)buf, "%s%s", (char *)s2,
 | 
						|
				    (char *)s1);
 | 
						|
				(void) strcpy((char *)xbuf, (char *)buf);
 | 
						|
			        s1 = xbuf;
 | 
						|
			    }
 | 
						|
			}
 | 
						|
			goto assemble_output;
 | 
						|
		    }
 | 
						|
		} else {
 | 
						|
		    trout = 0;
 | 
						|
		    if ((nm1[0] = *s1) != '0')
 | 
						|
			s1++;
 | 
						|
		    else
 | 
						|
			nm1[0] = ' ';
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	/*
 | 
						|
	 * Do the translation.
 | 
						|
	 */
 | 
						|
	    switch (trin) {
 | 
						|
 | 
						|
	    case 0:			/* simple char */
 | 
						|
		switch (trout) {
 | 
						|
 | 
						|
		case 0:			/* to simple char */
 | 
						|
		    Trtbl[(int)nm[0]] = nm1[0];
 | 
						|
		    break;
 | 
						|
		case 1:			/* to named char */
 | 
						|
		    if ((i = Findchar(nm1, 0, NULL, 0)) < 0
 | 
						|
		    ||  strlen((char *)Schar[i].str) != 1)
 | 
						|
			Error(WARN, LINE, " bad named character: ",
 | 
						|
			    (char *)nm1);
 | 
						|
		    else
 | 
						|
			Trtbl[(int)nm[0]] = *(Schar[i].str);
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case 1:			/* named char */
 | 
						|
		if ((i = Findchar(nm, 0, NULL, 0)) < 0)
 | 
						|
		    Error(WARN, LINE, " unknown named character: ", (char *)nm);
 | 
						|
		else {
 | 
						|
		    switch (trout) {
 | 
						|
 | 
						|
		    case 0:		/* to simple char */
 | 
						|
			Free(&Schar[i].str);
 | 
						|
			Schar[i].str = Newstr(nm1);
 | 
						|
			Schar[i].len = 1;
 | 
						|
			break;
 | 
						|
		    case 1:		/* to named char */
 | 
						|
			if ((j = Findchar(nm1, 0, NULL, 0)) < 0)
 | 
						|
			    Error(WARN, LINE, " unknown named character: ",
 | 
						|
				(char *)nm1);
 | 
						|
			else
 | 
						|
			    (void) Findchar(nm, Schar[j].len, Schar[j].str, 1);
 | 
						|
			break;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Initialization - "^[.']\^b (fh|HF|NH) [01]"
 | 
						|
 *
 | 
						|
 * fh = first page header status
 | 
						|
 * HF = header/footer status
 | 
						|
 * NH = initialize number headers
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_Ub(unsigned char *line, int brk) {
 | 
						|
	int i;				/* temporary index */
 | 
						|
	unsigned char *s1, *s2;		/* temporary string pointers */
 | 
						|
 | 
						|
	if ((s1 = Field(2, line, 0)) == NULL)
 | 
						|
		return;
 | 
						|
	if ((s2 = Field(3, line, 0)) == NULL)
 | 
						|
		i = 0;
 | 
						|
	else
 | 
						|
		i = atoi((char *)s2);
 | 
						|
	if (s1[0] == 'f' && s1[1] == 'h')
 | 
						|
		Pass3(NOBREAK, (unsigned char *)"fph", NULL, i);
 | 
						|
	else if (s1[0] == 'H' && s1[1] == 'F')
 | 
						|
		Hdft = i;
 | 
						|
	else if (s1[0] == 'N' && s1[1] == 'H') {
 | 
						|
		for (i = 0; i < MAXNHNR; i++)
 | 
						|
			Nhnr[i] = 0;
 | 
						|
	} else
 | 
						|
		Error(WARN, LINE, " unknown initialization", NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Character definitions - "^[.']\^c"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_Uc(unsigned char *line, int brk) {
 | 
						|
	unsigned char buf[MAXLINE];	/* temporary buffer */
 | 
						|
	int i;				/* temporary index */
 | 
						|
	unsigned char *s1, *s2, *s3,	/* temporary string pointers */
 | 
						|
		      *s4, *s5;
 | 
						|
 | 
						|
	s2 = Field(2, line, 0);
 | 
						|
	i = atoi((char *)Field(3, line, 0));
 | 
						|
	s4 = Field(4, line, 0);
 | 
						|
	if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
 | 
						|
		Error(WARN, LINE, " bad character definition", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	if (s4 == NULL)
 | 
						|
		s4 = (unsigned char *)"";
 | 
						|
	else if (*s4 == '"')
 | 
						|
		s4++;
 | 
						|
	s1 = buf;
 | 
						|
	while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
 | 
						|
		while (s5 > s4)
 | 
						|
			*s1++ = *s4++;
 | 
						|
		s4 = ++s5;
 | 
						|
		if (*s5 == '\\')
 | 
						|
			*s1++ = '\\';
 | 
						|
		else if (*s5 == 'b')
 | 
						|
			*s1++ = '\b';
 | 
						|
		if (*s4)
 | 
						|
			s4++;
 | 
						|
	}
 | 
						|
	while ((*s1++ = *s4++))
 | 
						|
		;
 | 
						|
	if (*s2 == 'h' && *(s2+1) == 'y')
 | 
						|
		(void) Findhy(buf, i, 1);
 | 
						|
	else
 | 
						|
		(void) Findchar(s2, i, buf, 1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Font is OK - "[.']\^f <font_name_character>"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_Uf(unsigned char *line, int brk) {
 | 
						|
	int i;				/* temporary index */
 | 
						|
 | 
						|
	if (line[3] != '\0' && line[4] != '\0') {
 | 
						|
		for (i = 0; Fcode[i].nm; i++) {
 | 
						|
			if (line[4] == Fcode[i].nm) {
 | 
						|
				Fcode[i].status = '1';
 | 
						|
				return;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	Error(WARN, LINE, " unknown font", NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Resolutions - "[.']\^r cpi horizontal vertical"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_Ur(unsigned char *line, int brk) {
 | 
						|
	unsigned char buf[MAXLINE];	/* temporary buffer */
 | 
						|
	int i, j;			/* temporary indexes */
 | 
						|
	double tval;			/* temporary value */
 | 
						|
 | 
						|
	if ((i = atoi((char *)Field(3, line, 0))) <= 0
 | 
						|
	||  (j = atoi((char *)Field(4, line, 0))) <= 0) {
 | 
						|
		Error(WARN, LINE, " bad cpi resolutions", NULL);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	tval = (double) (240.0 / (double) i);
 | 
						|
	if (Findscale((int)'m', tval, 1) < 0)
 | 
						|
		Error(FATAL, LINE, " missing Scal['m']", NULL);
 | 
						|
	Scalen = tval;
 | 
						|
	if (Scalen <= 0.0) {
 | 
						|
		(void) sprintf((char *)buf, " bad Scale['n'] (%f)", Scalen);
 | 
						|
		Error(FATAL, LINE, (char *)buf, NULL);
 | 
						|
	}
 | 
						|
	if (Findscale((int)'n', tval, 1) < 0)
 | 
						|
		Error(FATAL, LINE, " missing Scale['n']", NULL);
 | 
						|
	Scalev = (double) (240.0 / (double) j);
 | 
						|
	if (Scalev <= 0.0) {
 | 
						|
		(void) sprintf((char *)buf, " bad Scale['v'] (%f)", Scalen);
 | 
						|
		Error(FATAL, LINE, (char *)buf, NULL);
 | 
						|
	}
 | 
						|
	if (Findscale((int)'v', Scalev, 1) < 0)
 | 
						|
		Error(FATAL, LINE, " missing Scale['v']", NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Set line number and file name - "^[.']\^# <number> <file>"
 | 
						|
 *
 | 
						|
 * Lock line number and file name - "^[.']\^= <number> <file>"
 | 
						|
 */
 | 
						|
 | 
						|
static void nr_UL(unsigned char *line, int brk) {
 | 
						|
	unsigned char *s1;		/* temporary string pointer */
 | 
						|
 | 
						|
	if ((s1 = Field(2, line, 0)) != NULL)
 | 
						|
		P2il = atoi((char *)s1) - 1;
 | 
						|
	else
 | 
						|
		P2il = 0;
 | 
						|
	Lockil = (line[2] == '#') ? 0 : 1;
 | 
						|
	Free(&P2name);
 | 
						|
	if (Field(3, line, 1) != NULL) {
 | 
						|
		P2name = F;
 | 
						|
		F = NULL;
 | 
						|
	} else
 | 
						|
		P2name = NULL;
 | 
						|
}
 |