xref: /csrg-svn/usr.bin/deroff/deroff.c (revision 9075)
1*9075Srrh #ifndef lint
2*9075Srrh static char sccsid[] = "@(#)deroff.c	4.1	(Berkeley)	82/11/06";
3*9075Srrh #endif not lint
4*9075Srrh 
5*9075Srrh char *xxxvers = "\nDeroff Version (Bell Labs) 2.0    29 December 1979\n";
6*9075Srrh 
7*9075Srrh 
8*9075Srrh #include <stdio.h>
9*9075Srrh 
10*9075Srrh /* Deroff command -- strip troff, eqn, and Tbl sequences from
11*9075Srrh a file.  Has two flags argument, -w, to cause output one word per line
12*9075Srrh rather than in the original format.
13*9075Srrh -ms (or -m) causes -ms macro's to be interpreted so that just
14*9075Srrh sentences are output, -mm does same for -mm macro's,
15*9075Srrh -ml in addition to interpreting -ms macros also gets rid of
16*9075Srrh lists.
17*9075Srrh Deroff follows .so and .nx commands, removes contents of macro
18*9075Srrh definitions, equations (both .EQ ... .EN and $...$),
19*9075Srrh Tbl command sequences, and Troff backslash constructions.
20*9075Srrh 
21*9075Srrh All input is through the C macro; the most recently read character is in c.
22*9075Srrh */
23*9075Srrh 
24*9075Srrh #define C ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
25*9075Srrh #define C1 ( (c=getc(infile)) == EOF ? eof() :  c)
26*9075Srrh #define SKIP while(C != '\n')
27*9075Srrh #define SKIP_TO_COM SKIP; SKIP; pc=c; while(C != '.' || pc != '\n' || C > 'Z')pc=c
28*9075Srrh 
29*9075Srrh #define YES 1
30*9075Srrh #define NO 0
31*9075Srrh #define MS 0
32*9075Srrh #define MM 1
33*9075Srrh #define ONE 1
34*9075Srrh #define TWO 2
35*9075Srrh 
36*9075Srrh #define NOCHAR -2
37*9075Srrh #define SPECIAL 0
38*9075Srrh #define APOS 1
39*9075Srrh #define DIGIT 2
40*9075Srrh #define LETTER 3
41*9075Srrh 
42*9075Srrh int wordflag = NO;
43*9075Srrh int msflag = NO;
44*9075Srrh int mac = MS;
45*9075Srrh int disp = 0;
46*9075Srrh int inmacro = NO;
47*9075Srrh int intable = NO;
48*9075Srrh 
49*9075Srrh char chars[128];  /* SPECIAL, APOS, DIGIT, or LETTER */
50*9075Srrh 
51*9075Srrh char line[512];
52*9075Srrh char *lp;
53*9075Srrh 
54*9075Srrh int c;
55*9075Srrh int pc;
56*9075Srrh int ldelim	= NOCHAR;
57*9075Srrh int rdelim	= NOCHAR;
58*9075Srrh 
59*9075Srrh 
60*9075Srrh int argc;
61*9075Srrh char **argv;
62*9075Srrh 
63*9075Srrh char fname[50];
64*9075Srrh FILE *files[15];
65*9075Srrh FILE **filesp;
66*9075Srrh FILE *infile;
67*9075Srrh 
68*9075Srrh char *calloc();
69*9075Srrh 
70*9075Srrh 
71*9075Srrh 
72*9075Srrh main(ac, av)
73*9075Srrh int ac;
74*9075Srrh char **av;
75*9075Srrh {
76*9075Srrh register int i;
77*9075Srrh register char *p;
78*9075Srrh static char onechar[2] = "X";
79*9075Srrh FILE *opn();
80*9075Srrh 
81*9075Srrh argc = ac - 1;
82*9075Srrh argv = av + 1;
83*9075Srrh 
84*9075Srrh while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0')
85*9075Srrh 	{
86*9075Srrh 	for(p=argv[0]+1; *p; ++p) switch(*p)
87*9075Srrh 		{
88*9075Srrh 		case 'w':
89*9075Srrh 			wordflag = YES;
90*9075Srrh 			break;
91*9075Srrh 		case 'm':
92*9075Srrh 			msflag = YES;
93*9075Srrh 			if(*(p+1) == 'm'){
94*9075Srrh 				mac=MM;
95*9075Srrh 				p++;
96*9075Srrh 			}
97*9075Srrh 			else if(*(p+1) == 's')
98*9075Srrh 				p++;
99*9075Srrh 			else if(*(p+1) == 'l'){
100*9075Srrh 				disp=1;
101*9075Srrh 				p++;
102*9075Srrh 			}
103*9075Srrh 			break;
104*9075Srrh 		default:
105*9075Srrh 			onechar[0] = *p;
106*9075Srrh 			fatal("Invalid flag %s\n", onechar);
107*9075Srrh 		}
108*9075Srrh 	--argc;
109*9075Srrh 	++argv;
110*9075Srrh 	}
111*9075Srrh 
112*9075Srrh if(argc == 0)
113*9075Srrh 	infile = stdin;
114*9075Srrh else	{
115*9075Srrh 	infile = opn(argv[0]);
116*9075Srrh 	--argc;
117*9075Srrh 	++argv;
118*9075Srrh 	}
119*9075Srrh 
120*9075Srrh files[0] = infile;
121*9075Srrh filesp = &files[0];
122*9075Srrh 
123*9075Srrh for(i='a'; i<='z' ; ++i)
124*9075Srrh 	chars[i] = LETTER;
125*9075Srrh for(i='A'; i<='Z'; ++i)
126*9075Srrh 	chars[i] = LETTER;
127*9075Srrh for(i='0'; i<='9'; ++i)
128*9075Srrh 	chars[i] = DIGIT;
129*9075Srrh chars['\''] = APOS;
130*9075Srrh chars['&'] = APOS;
131*9075Srrh 
132*9075Srrh work();
133*9075Srrh }
134*9075Srrh 
135*9075Srrh 
136*9075Srrh 
137*9075Srrh skeqn()
138*9075Srrh {
139*9075Srrh while((c = getc(infile)) != rdelim)
140*9075Srrh 	if(c == EOF)
141*9075Srrh 		c = eof();
142*9075Srrh 	else if(c == '"')
143*9075Srrh 		while( (c = getc(infile)) != '"')
144*9075Srrh 			if(c == EOF)
145*9075Srrh 				c = eof();
146*9075Srrh 			else if(c == '\\')
147*9075Srrh 				if((c = getc(infile)) == EOF)
148*9075Srrh 					c = eof();
149*9075Srrh if(msflag)return(c='x');
150*9075Srrh return(c = ' ');
151*9075Srrh }
152*9075Srrh 
153*9075Srrh 
154*9075Srrh FILE *opn(p)
155*9075Srrh register char *p;
156*9075Srrh {
157*9075Srrh FILE *fd;
158*9075Srrh 
159*9075Srrh if(p[0]=='-' && p[1]=='\0')
160*9075Srrh 	fd = stdin;
161*9075Srrh else if( (fd = fopen(p, "r")) == NULL)
162*9075Srrh 	fatal("Cannot open file %s\n", p);
163*9075Srrh 
164*9075Srrh return(fd);
165*9075Srrh }
166*9075Srrh 
167*9075Srrh 
168*9075Srrh 
169*9075Srrh eof()
170*9075Srrh {
171*9075Srrh if(infile != stdin)
172*9075Srrh 	fclose(infile);
173*9075Srrh if(filesp > files)
174*9075Srrh 	infile = *--filesp;
175*9075Srrh else if(argc > 0)
176*9075Srrh 	{
177*9075Srrh 	infile = opn(argv[0]);
178*9075Srrh 	--argc;
179*9075Srrh 	++argv;
180*9075Srrh 	}
181*9075Srrh else
182*9075Srrh 	exit(0);
183*9075Srrh 
184*9075Srrh return(C);
185*9075Srrh }
186*9075Srrh 
187*9075Srrh 
188*9075Srrh 
189*9075Srrh getfname()
190*9075Srrh {
191*9075Srrh register char *p;
192*9075Srrh struct chain { struct chain *nextp; char *datap; } *chainblock;
193*9075Srrh register struct chain *q;
194*9075Srrh static struct chain *namechain	= NULL;
195*9075Srrh char *copys();
196*9075Srrh 
197*9075Srrh while(C == ' ') ;
198*9075Srrh 
199*9075Srrh for(p = fname ; (*p=c)!= '\n' && c!=' ' && c!='\t' && c!='\\' ; ++p)
200*9075Srrh 	C;
201*9075Srrh *p = '\0';
202*9075Srrh while(c != '\n')
203*9075Srrh 	C;
204*9075Srrh 
205*9075Srrh /* see if this name has already been used */
206*9075Srrh 
207*9075Srrh for(q = namechain ; q; q = q->nextp)
208*9075Srrh 	if( ! strcmp(fname, q->datap))
209*9075Srrh 		{
210*9075Srrh 		fname[0] = '\0';
211*9075Srrh 		return;
212*9075Srrh 		}
213*9075Srrh 
214*9075Srrh q = (struct chain *) calloc(1, sizeof(*chainblock));
215*9075Srrh q->nextp = namechain;
216*9075Srrh q->datap = copys(fname);
217*9075Srrh namechain = q;
218*9075Srrh }
219*9075Srrh 
220*9075Srrh 
221*9075Srrh 
222*9075Srrh 
223*9075Srrh fatal(s,p)
224*9075Srrh char *s, *p;
225*9075Srrh {
226*9075Srrh fprintf(stderr, "Deroff: ");
227*9075Srrh fprintf(stderr, s, p);
228*9075Srrh exit(1);
229*9075Srrh }
230*9075Srrh 
231*9075Srrh work()
232*9075Srrh {
233*9075Srrh 
234*9075Srrh for( ;; )
235*9075Srrh 	{
236*9075Srrh 	if(C == '.'  ||  c == '\'')
237*9075Srrh 		comline();
238*9075Srrh 	else
239*9075Srrh 		regline(NO,TWO);
240*9075Srrh 	}
241*9075Srrh }
242*9075Srrh 
243*9075Srrh 
244*9075Srrh 
245*9075Srrh 
246*9075Srrh regline(macline,const)
247*9075Srrh int macline;
248*9075Srrh int const;
249*9075Srrh {
250*9075Srrh line[0] = c;
251*9075Srrh lp = line;
252*9075Srrh for( ; ; )
253*9075Srrh 	{
254*9075Srrh 	if(c == '\\')
255*9075Srrh 		{
256*9075Srrh 		*lp = ' ';
257*9075Srrh 		backsl();
258*9075Srrh 		}
259*9075Srrh 	if(c == '\n') break;
260*9075Srrh 	if(intable && c=='T')
261*9075Srrh 		{
262*9075Srrh 		*++lp = C;
263*9075Srrh 		if(c=='{' || c=='}')
264*9075Srrh 			{
265*9075Srrh 			lp[-1] = ' ';
266*9075Srrh 			*lp = C;
267*9075Srrh 			}
268*9075Srrh 		}
269*9075Srrh 	else	*++lp = C;
270*9075Srrh 	}
271*9075Srrh 
272*9075Srrh *lp = '\0';
273*9075Srrh 
274*9075Srrh if(line[0] != '\0')
275*9075Srrh 	if(wordflag)
276*9075Srrh 		putwords(macline);
277*9075Srrh 	else if(macline)
278*9075Srrh 		putmac(line,const);
279*9075Srrh 	else
280*9075Srrh 		puts(line);
281*9075Srrh }
282*9075Srrh 
283*9075Srrh 
284*9075Srrh 
285*9075Srrh 
286*9075Srrh putmac(s,const)
287*9075Srrh register char *s;
288*9075Srrh int const;
289*9075Srrh {
290*9075Srrh register char *t;
291*9075Srrh 
292*9075Srrh while(*s)
293*9075Srrh 	{
294*9075Srrh 	while(*s==' ' || *s=='\t')
295*9075Srrh 		putchar(*s++);
296*9075Srrh 	for(t = s ; *t!=' ' && *t!='\t' && *t!='\0' ; ++t)
297*9075Srrh 		;
298*9075Srrh 	if(*s == '\"')s++;
299*9075Srrh 	if(t>s+const && chars[ s[0] ]==LETTER && chars[ s[1] ]==LETTER)
300*9075Srrh 		while(s < t)
301*9075Srrh 			if(*s == '\"')s++;
302*9075Srrh 			else
303*9075Srrh 				putchar(*s++);
304*9075Srrh 	else
305*9075Srrh 		s = t;
306*9075Srrh 	}
307*9075Srrh putchar('\n');
308*9075Srrh }
309*9075Srrh 
310*9075Srrh 
311*9075Srrh 
312*9075Srrh putwords(macline)	/* break into words for -w option */
313*9075Srrh int macline;
314*9075Srrh {
315*9075Srrh register char *p, *p1;
316*9075Srrh int i, nlet;
317*9075Srrh 
318*9075Srrh 
319*9075Srrh for(p1 = line ; ;)
320*9075Srrh 	{
321*9075Srrh 	/* skip initial specials ampersands and apostrophes */
322*9075Srrh 	while( chars[*p1] < DIGIT)
323*9075Srrh 		if(*p1++ == '\0') return;
324*9075Srrh 	nlet = 0;
325*9075Srrh 	for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p)
326*9075Srrh 		if(i == LETTER) ++nlet;
327*9075Srrh 
328*9075Srrh 	if( (!macline && nlet>1)   /* MDM definition of word */
329*9075Srrh 	   || (macline && nlet>2 && chars[ p1[0] ]==LETTER && chars[ p1[1] ]==LETTER) )
330*9075Srrh 		{
331*9075Srrh 		/* delete trailing ampersands and apostrophes */
332*9075Srrh 		while(p[-1]=='\'' || p[-1]=='&')
333*9075Srrh 			 --p;
334*9075Srrh 		while(p1 < p) putchar(*p1++);
335*9075Srrh 		putchar('\n');
336*9075Srrh 		}
337*9075Srrh 	else
338*9075Srrh 		p1 = p;
339*9075Srrh 	}
340*9075Srrh }
341*9075Srrh 
342*9075Srrh 
343*9075Srrh 
344*9075Srrh comline()
345*9075Srrh {
346*9075Srrh register int c1, c2;
347*9075Srrh 
348*9075Srrh com:
349*9075Srrh while(C==' ' || c=='\t')
350*9075Srrh 	;
351*9075Srrh comx:
352*9075Srrh if( (c1=c) == '\n')
353*9075Srrh 	return;
354*9075Srrh c2 = C;
355*9075Srrh if(c1=='.' && c2!='.')
356*9075Srrh 	inmacro = NO;
357*9075Srrh if(c2 == '\n')
358*9075Srrh 	return;
359*9075Srrh 
360*9075Srrh if(c1=='E' && c2=='Q' && filesp==files)
361*9075Srrh 	eqn();
362*9075Srrh else if(c1=='T' && (c2=='S' || c2=='C' || c2=='&') && filesp==files){
363*9075Srrh 	if(msflag){ stbl(); }
364*9075Srrh 	else tbl(); }
365*9075Srrh else if(c1=='T' && c2=='E')
366*9075Srrh 	intable = NO;
367*9075Srrh else if(c1=='G' && c2 == 'R')
368*9075Srrh 		sdis('G','E');
369*9075Srrh else if(!inmacro && c1=='d' && c2=='e')
370*9075Srrh 	macro();
371*9075Srrh else if(!inmacro && c1=='i' && c2=='g')
372*9075Srrh 	macro();
373*9075Srrh else if(!inmacro && c1=='a' && c2 == 'm')
374*9075Srrh 	macro();
375*9075Srrh else if(c1=='s' && c2=='o')
376*9075Srrh 	{
377*9075Srrh 	getfname();
378*9075Srrh 	if( fname[0] )
379*9075Srrh 		infile = *++filesp = opn( fname );
380*9075Srrh 	}
381*9075Srrh else if(c1=='n' && c2=='x')
382*9075Srrh 	{
383*9075Srrh 	getfname();
384*9075Srrh 	if(fname[0] == '\0') exit(0);
385*9075Srrh 	if(infile != stdin)
386*9075Srrh 		fclose(infile);
387*9075Srrh 	infile = *filesp = opn(fname);
388*9075Srrh 	}
389*9075Srrh else if(c1=='h' && c2=='w')
390*9075Srrh 	{ SKIP; }
391*9075Srrh else if(msflag && c1 == 'T' && c2 == 'L'){
392*9075Srrh 	SKIP_TO_COM;
393*9075Srrh 	goto comx; }
394*9075Srrh else if(msflag && c1=='N' && c2 == 'R')SKIP;
395*9075Srrh else if(msflag && c1 == 'A' && (c2 == 'U' || c2 == 'I')){
396*9075Srrh 	if(mac==MM)SKIP;
397*9075Srrh 	else {
398*9075Srrh 		SKIP_TO_COM;
399*9075Srrh 		goto comx; }
400*9075Srrh 	}
401*9075Srrh else if(msflag && c1 == 'F' && c2 == 'S'){
402*9075Srrh 	SKIP_TO_COM;
403*9075Srrh 	goto comx; }
404*9075Srrh else if(msflag && c1 == 'S' && c2 == 'H'){
405*9075Srrh 	SKIP_TO_COM;
406*9075Srrh 	goto comx; }
407*9075Srrh else if(msflag && c1 == 'N' && c2 == 'H'){
408*9075Srrh 	SKIP_TO_COM;
409*9075Srrh 	goto comx; }
410*9075Srrh else if(msflag && c1 == 'O' && c2 == 'K'){
411*9075Srrh 	SKIP_TO_COM;
412*9075Srrh 	goto comx; }
413*9075Srrh else if(msflag && c1 == 'N' && c2 == 'D')
414*9075Srrh 	SKIP;
415*9075Srrh else if(msflag && mac==MM && c1=='H' && (c2==' '||c2=='U'))
416*9075Srrh 	SKIP;
417*9075Srrh else if(msflag && mac==MM && c2=='L'){
418*9075Srrh 	if(disp || c1 == 'R')sdis('L','E');
419*9075Srrh 	else{
420*9075Srrh 		SKIP;
421*9075Srrh 		putchar('.');
422*9075Srrh 		}
423*9075Srrh 	}
424*9075Srrh else if(msflag && (c1 == 'D' || c1 == 'N' || c1 == 'K') && c2 == 'S')
425*9075Srrh 	{ sdis(c1,'E'); }		/* removed RS-RE */
426*9075Srrh else if(msflag && c1 == 'n' && c2 == 'f')
427*9075Srrh 	sdis('f','i');
428*9075Srrh else if(msflag && c1 == 'c' && c2 == 'e')
429*9075Srrh 	sce();
430*9075Srrh else
431*9075Srrh 	{
432*9075Srrh 	if(c1=='.' && c2=='.')
433*9075Srrh 		while(C == '.')
434*9075Srrh 			;
435*9075Srrh 	++inmacro;
436*9075Srrh 	if(c1 <= 'Z' && msflag)regline(YES,ONE);
437*9075Srrh 	else regline(YES,TWO);
438*9075Srrh 	--inmacro;
439*9075Srrh 	}
440*9075Srrh }
441*9075Srrh 
442*9075Srrh 
443*9075Srrh 
444*9075Srrh macro()
445*9075Srrh {
446*9075Srrh if(msflag){
447*9075Srrh 	do { SKIP; }
448*9075Srrh 		while(C!='.' || C!='.' || C=='.');	/* look for  .. */
449*9075Srrh 	if(c != '\n')SKIP;
450*9075Srrh 	return;
451*9075Srrh }
452*9075Srrh SKIP;
453*9075Srrh inmacro = YES;
454*9075Srrh }
455*9075Srrh 
456*9075Srrh 
457*9075Srrh 
458*9075Srrh 
459*9075Srrh sdis(a1,a2)
460*9075Srrh char a1,a2;
461*9075Srrh {
462*9075Srrh 	register int c1,c2;
463*9075Srrh 	register int eqnf;
464*9075Srrh 	eqnf=1;
465*9075Srrh 	SKIP;
466*9075Srrh 	while(1){
467*9075Srrh 		while(C != '.')SKIP;
468*9075Srrh 		if((c1=C) == '\n')continue;
469*9075Srrh 		if((c2=C) == '\n')continue;
470*9075Srrh 		if(c1==a1 && c2 == a2){
471*9075Srrh 			SKIP;
472*9075Srrh 			if(eqnf)putchar('.');
473*9075Srrh 			putchar('\n');
474*9075Srrh 			return;
475*9075Srrh 		}
476*9075Srrh 		else if(a1 == 'D' && c1 == 'E' && c2 == 'Q'){eqn(); eqnf=0;}
477*9075Srrh 		else SKIP;
478*9075Srrh 	}
479*9075Srrh }
480*9075Srrh tbl()
481*9075Srrh {
482*9075Srrh while(C != '.');
483*9075Srrh SKIP;
484*9075Srrh intable = YES;
485*9075Srrh }
486*9075Srrh stbl()
487*9075Srrh {
488*9075Srrh while(C != '.');
489*9075Srrh SKIP_TO_COM;
490*9075Srrh if(c != 'T' || C != 'E'){
491*9075Srrh 	SKIP;
492*9075Srrh 	pc=c;
493*9075Srrh 	while(C != '.' || pc != '\n' || C != 'T' || C != 'E')pc=c;
494*9075Srrh }
495*9075Srrh }
496*9075Srrh 
497*9075Srrh eqn()
498*9075Srrh {
499*9075Srrh register int c1, c2;
500*9075Srrh register int dflg;
501*9075Srrh int last;
502*9075Srrh 
503*9075Srrh last=0;
504*9075Srrh dflg = 1;
505*9075Srrh SKIP;
506*9075Srrh 
507*9075Srrh for( ;;)
508*9075Srrh 	{
509*9075Srrh 	if(C == '.'  || c == '\'')
510*9075Srrh 		{
511*9075Srrh 		while(C==' ' || c=='\t')
512*9075Srrh 			;
513*9075Srrh 		if(c=='E' && C=='N')
514*9075Srrh 			{
515*9075Srrh 			SKIP;
516*9075Srrh 			if(msflag && dflg){
517*9075Srrh 				putchar('x');
518*9075Srrh 				putchar(' ');
519*9075Srrh 				if(last){putchar('.'); putchar(' '); }
520*9075Srrh 			}
521*9075Srrh 			return;
522*9075Srrh 			}
523*9075Srrh 		}
524*9075Srrh 	else if(c == 'd')	/* look for delim */
525*9075Srrh 		{
526*9075Srrh 		if(C=='e' && C=='l')
527*9075Srrh 		    if( C=='i' && C=='m')
528*9075Srrh 			{
529*9075Srrh 			while(C1 == ' ');
530*9075Srrh 			if((c1=c)=='\n' || (c2=C1)=='\n'
531*9075Srrh 			    || (c1=='o' && c2=='f' && C1=='f') )
532*9075Srrh 				{
533*9075Srrh 				ldelim = NOCHAR;
534*9075Srrh 				rdelim = NOCHAR;
535*9075Srrh 				}
536*9075Srrh 			else	{
537*9075Srrh 				ldelim = c1;
538*9075Srrh 				rdelim = c2;
539*9075Srrh 				}
540*9075Srrh 			}
541*9075Srrh 			dflg = 0;
542*9075Srrh 		}
543*9075Srrh 
544*9075Srrh 	if(c != '\n') while(C != '\n'){ if(c == '.')last=1; else last=0; }
545*9075Srrh 	}
546*9075Srrh }
547*9075Srrh 
548*9075Srrh 
549*9075Srrh 
550*9075Srrh backsl()	/* skip over a complete backslash construction */
551*9075Srrh {
552*9075Srrh int bdelim;
553*9075Srrh 
554*9075Srrh sw:  switch(C)
555*9075Srrh 	{
556*9075Srrh 	case '"':
557*9075Srrh 		SKIP;
558*9075Srrh 		return;
559*9075Srrh 	case 's':
560*9075Srrh 		if(C == '\\') backsl();
561*9075Srrh 		else	{
562*9075Srrh 			while(C>='0' && c<='9') ;
563*9075Srrh 			ungetc(c,infile);
564*9075Srrh 			c = '0';
565*9075Srrh 			}
566*9075Srrh 		--lp;
567*9075Srrh 		return;
568*9075Srrh 
569*9075Srrh 	case 'f':
570*9075Srrh 	case 'n':
571*9075Srrh 	case 'k':
572*9075Srrh 	case '*':
573*9075Srrh 		if(C != '(')
574*9075Srrh 			return;
575*9075Srrh 
576*9075Srrh 	case '(':
577*9075Srrh 		if(C != '\n') C;
578*9075Srrh 		return;
579*9075Srrh 
580*9075Srrh 	case '$':
581*9075Srrh 		C;	/* discard argument number */
582*9075Srrh 		return;
583*9075Srrh 
584*9075Srrh 	case 'b':
585*9075Srrh 	case 'x':
586*9075Srrh 	case 'v':
587*9075Srrh 	case 'h':
588*9075Srrh 	case 'w':
589*9075Srrh 	case 'o':
590*9075Srrh 	case 'l':
591*9075Srrh 	case 'L':
592*9075Srrh 		if( (bdelim=C) == '\n')
593*9075Srrh 			return;
594*9075Srrh 		while(C!='\n' && c!=bdelim)
595*9075Srrh 			if(c == '\\') backsl();
596*9075Srrh 		return;
597*9075Srrh 
598*9075Srrh 	case '\\':
599*9075Srrh 		if(inmacro)
600*9075Srrh 			goto sw;
601*9075Srrh 	default:
602*9075Srrh 		return;
603*9075Srrh 	}
604*9075Srrh }
605*9075Srrh 
606*9075Srrh 
607*9075Srrh 
608*9075Srrh 
609*9075Srrh char *copys(s)
610*9075Srrh register char *s;
611*9075Srrh {
612*9075Srrh register char *t, *t0;
613*9075Srrh 
614*9075Srrh if( (t0 = t = calloc( strlen(s)+1, sizeof(*t) ) ) == NULL)
615*9075Srrh 	fatal("Cannot allocate memory", (char *) NULL);
616*9075Srrh 
617*9075Srrh while( *t++ = *s++ )
618*9075Srrh 	;
619*9075Srrh return(t0);
620*9075Srrh }
621*9075Srrh sce(){
622*9075Srrh register char *ap;
623*9075Srrh register int n, i;
624*9075Srrh char a[10];
625*9075Srrh 	for(ap=a;C != '\n';ap++){
626*9075Srrh 		*ap = c;
627*9075Srrh 		if(ap == &a[9]){
628*9075Srrh 			SKIP;
629*9075Srrh 			ap=a;
630*9075Srrh 			break;
631*9075Srrh 		}
632*9075Srrh 	}
633*9075Srrh 	if(ap != a)n = atoi(a);
634*9075Srrh 	else n = 1;
635*9075Srrh 	for(i=0;i<n;){
636*9075Srrh 		if(C == '.'){
637*9075Srrh 			if(C == 'c'){
638*9075Srrh 				if(C == 'e'){
639*9075Srrh 					while(C == ' ');
640*9075Srrh 					if(c == '0')break;
641*9075Srrh 					else SKIP;
642*9075Srrh 				}
643*9075Srrh 				else SKIP;
644*9075Srrh 			}
645*9075Srrh 			else SKIP;
646*9075Srrh 		}
647*9075Srrh 		else {
648*9075Srrh 			SKIP;
649*9075Srrh 			i++;
650*9075Srrh 		}
651*9075Srrh 	}
652*9075Srrh }
653