hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

sed1.c (16599B)


      1 /*	from Unix 7th Edition sed	*/
      2 /*	Sccsid @(#)sed1.c	1.42 (gritter) 2/6/05>	*/
      3 /*
      4  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *   Redistributions of source code and documentation must retain the
     10  *    above copyright notice, this list of conditions and the following
     11  *    disclaimer.
     12  *   Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *   All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed or owned by Caldera
     18  *      International, Inc.
     19  *   Neither the name of Caldera International, Inc. nor the names of
     20  *    other contributors may be used to endorse or promote products
     21  *    derived from this software without specific prior written permission.
     22  *
     23  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
     24  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
     25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
     28  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     34  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35  */
     36 
     37 #include	<sys/types.h>
     38 #include	<sys/stat.h>
     39 #include	<fcntl.h>
     40 #include	<unistd.h>
     41 #include	<stdlib.h>
     42 #include	<ctype.h>
     43 #include	<wchar.h>
     44 #include	<wctype.h>
     45 #include "sed.h"
     46 
     47 #if !defined (SUS) && !defined (SU3) && !defined(S42)
     48 #define	INIT		extern char *cp, *badp; \
     49 			register char *sp = cp;
     50 #define	GETC()		(*sp++)
     51 #define	PEEKC()		(*sp)
     52 #define	UNGETC(c)	(--sp)
     53 #define	RETURN(c)	{ cp = sp; return ep; }
     54 #define	ERROR(c)	{ cp = sp; return badp; }
     55 
     56 #define	regexp_h_malloc(n)	smalloc(n)
     57 #include <regexp.h>
     58 #endif	/* !SUS && !SU3 && !S42 */
     59 
     60 #ifndef	CCEOF
     61 #ifdef	CEOF
     62 #define	CCEOF	CEOF
     63 #else	/* !CEOF */
     64 #define	CCEOF	22
     65 #endif	/* !CEOF */
     66 #endif	/* !CCEOF */
     67 
     68 int ceof = CCEOF;
     69 
     70 #if !defined (SUS) && !defined (SU3)
     71 static const char	*trans[]  = {
     72 	"\\00",
     73 	"\\01",
     74 	"\\02",
     75 	"\\03",
     76 	"\\04",
     77 	"\\05",
     78 	"\\06",
     79 	"\\07",
     80 	"-<",
     81 	"->",
     82 	"\n",
     83 	"\\13",
     84 	"\\14",
     85 	"\\15",
     86 	"\\16",
     87 	"\\17",
     88 	"\\20",
     89 	"\\21",
     90 	"\\22",
     91 	"\\23",
     92 	"\\24",
     93 	"\\25",
     94 	"\\26",
     95 	"\\27",
     96 	"\\30",
     97 	"\\31",
     98 	"\\32",
     99 	"\\33",
    100 	"\\34",
    101 	"\\35",
    102 	"\\36",
    103 	"\\37"
    104 };
    105 #endif	/* !SUS, !SU3 */
    106 
    107 static char	*cbp;
    108 static char	*ebp;
    109 static int	dolflag;
    110 static int	sflag;
    111 static int	jflag;
    112 static int	delflag;
    113 static long long	lnum;
    114 static char	ibuf[512];
    115 static int	ibrd;
    116 static int	mflag;
    117 static int	f = -1;
    118 static int	spend;
    119 static int	genend;
    120 static int	hspend;
    121 
    122 static void command(struct reptr *);
    123 static int match(char *, int, int);
    124 static int substitute(struct reptr *);
    125 static void dosub(char *);
    126 static int place(int, int, int);
    127 static int gline(int);
    128 static void arout(void);
    129 static void lcom(wint_t, int);
    130 static void oout(int);
    131 static void mout(const char *);
    132 static void nout(wint_t);
    133 static void wout(wint_t);
    134 static void lout(int);
    135 
    136 #if defined (SUS) || defined (SU3) || defined (S42)
    137 #define	NBRA	9
    138 int	sed;
    139 int	nbra;
    140 int	circf;
    141 static char	*braslist[NBRA];
    142 static char	*braelist[NBRA];
    143 static char	*loc1, *loc2, *locs;
    144 
    145 static int
    146 step(char *line, char *pattern)
    147 {
    148 	struct re_emu	*re = (struct re_emu *)&pattern[-1];
    149 	regmatch_t bralist[NBRA+1];
    150 	int	eflag = 0;
    151 	int	res;
    152 	int	i, nsub;
    153 
    154 	if (circf == 2)	/* empty pattern */
    155 		return 0;
    156 	if (locs)
    157 		eflag |= REG_NOTBOL;
    158 	/*
    159 	 * Don't fetch more match locations than necessary since this
    160 	 * might prevent use of DFA.
    161 	 */
    162 	nsub = mflag;
    163 	if ((res = regexec(&re->r_preg, line, nsub, bralist, eflag)) == 0) {
    164 		if (nsub > 0) {
    165 			loc1 = line + bralist[0].rm_so;
    166 			loc2 = line + bralist[0].rm_eo;
    167 			for (i = 1; i < nsub; i++) {
    168 				if (bralist[i].rm_so != -1) {
    169 					braslist[i-1] = line + bralist[i].rm_so;
    170 					braelist[i-1] = line + bralist[i].rm_eo;
    171 				} else
    172 					braslist[i-1] = braelist[i-1] = NULL;
    173 			}
    174 		}
    175 	}
    176 	return res == 0;
    177 }
    178 #endif	/* SUS || SU3 || S42 */
    179 
    180 static int	lcomlen;
    181 static int	Braslist[NBRA];
    182 static int	Braelist[NBRA];
    183 static int	Loc1, Loc2;
    184 
    185 void
    186 execute(const char *file)
    187 {
    188 	register char *p1, *p2;
    189 	register struct reptr	*ipc;
    190 	int	c;
    191 	int	execc;
    192 
    193 	if (f >= 0)
    194 		close(f);
    195 	if (file) {
    196 		if ((f = open(file, O_RDONLY)) < 0) {
    197 			nonfatal("Can't open %s", file);
    198 			return;
    199 		}
    200 	} else
    201 		f = 0;
    202 
    203 	ebp = ibuf;
    204 	cbp = ibuf;
    205 
    206 	if(pending) {
    207 		ipc = pending;
    208 		pending = 0;
    209 		goto yes;
    210 	}
    211 
    212 	for(;;) {
    213 		if((execc = gline(0)) < 0) {
    214 			if (f >= 0) {
    215 				close(f);
    216 				f = -1;
    217 			}
    218 			return;
    219 		}
    220 		spend = execc;
    221 
    222 		for(ipc = ptrspace; ipc->command; ) {
    223 
    224 			p1 = ipc->ad1;
    225 			p2 = ipc->ad2;
    226 
    227 			if(p1) {
    228 
    229 				if(ipc->inar) {
    230 					if(*p2 == CEND) {
    231 						p1 = 0;
    232 					} else if(*p2 == CLNUM) {
    233 						c = glno(&p2[1]);
    234 						if(lnum > tlno[c]) {
    235 							ipc->inar = 0;
    236 							if(ipc->negfl)
    237 								goto yes;
    238 							ipc++;
    239 							continue;
    240 						}
    241 						if(lnum == tlno[c]) {
    242 							ipc->inar = 0;
    243 						}
    244 					} else if(match(p2, 0, 0)) {
    245 						ipc->inar = 0;
    246 					}
    247 				} else if(*p1 == CEND) {
    248 					if(!dolflag) {
    249 						if(ipc->negfl)
    250 							goto yes;
    251 						ipc++;
    252 						continue;
    253 					}
    254 
    255 				} else if(*p1 == CLNUM) {
    256 					c = glno(&p1[1]);
    257 					if(lnum != tlno[c]) {
    258 						if(ipc->negfl)
    259 							goto yes;
    260 						ipc++;
    261 						continue;
    262 					}
    263 					if(p2) {
    264 						ipc->inar = 1;
    265 #if defined (SUS) || defined (SU3)
    266 						goto ichk;
    267 #endif	/* SUS, SU3 */
    268 					}
    269 				} else if(match(p1, 0, 0)) {
    270 					if(p2) {
    271 						ipc->inar = 1;
    272 #if defined (SUS) || defined (SU3)
    273 					ichk:	if (*p2 == CLNUM) {
    274 							c = glno(&p2[1]);
    275 							if (lnum >= tlno[c])
    276 								ipc->inar = 0;
    277 						}
    278 #endif	/* SUS, SU3 */
    279 					}
    280 				} else {
    281 					if(ipc->negfl)
    282 						goto yes;
    283 					ipc++;
    284 					continue;
    285 				}
    286 			}
    287 
    288 			if(ipc->negfl) {
    289 				ipc++;
    290 				continue;
    291 			}
    292 	yes:
    293 			command(ipc);
    294 
    295 			if(delflag)
    296 				break;
    297 
    298 			if(jflag) {
    299 				jflag = 0;
    300 				if((ipc = P(ipc->bptr.lb1)) == 0) {
    301 					ipc = ptrspace;
    302 					break;
    303 				}
    304 			} else
    305 				ipc++;
    306 
    307 		}
    308 		if(!nflag && !delflag) {
    309 			for(p1 = linebuf; p1 < &linebuf[spend]; p1++)
    310 				putc(*p1&0377, stdout);
    311 			putc('\n', stdout);
    312 		}
    313 
    314 		if(A(aptr) > abuf) {
    315 			arout();
    316 		}
    317 
    318 		delflag = 0;
    319 
    320 	}
    321 }
    322 
    323 static int
    324 match(char *expbuf, int gf, int needloc)
    325 {
    326 	register char	*p1;
    327 	int	i, val;
    328 
    329 	if(gf) {
    330 		if(*expbuf)	return(0);
    331 #if defined (SUS) || defined (SU3) || defined (S42)
    332 		if (loc1 == loc2) {
    333 			int	n;
    334 			wchar_t	wc;
    335 			if (multibyte && (n = mbtowc(&wc, &linebuf[Loc2],
    336 							MB_LEN_MAX)) > 0)
    337 				Loc2 += n;
    338 			else
    339 				Loc2++;
    340 		}
    341 #endif
    342 		locs = p1 = loc2 = &linebuf[Loc2];
    343 	} else {
    344 		p1 = linebuf;
    345 		locs = 0;
    346 	}
    347 
    348 	mflag = needloc;
    349 	circf = *expbuf++;
    350 	val = step(p1, expbuf);
    351 	for (i = 0; i < NBRA; i++) {
    352 		Braslist[i] = braslist[i] - linebuf;
    353 		Braelist[i] = braelist[i] - linebuf;
    354 	}
    355 	Loc1 = loc1 - linebuf;
    356 	Loc2 = loc2 - linebuf;
    357 	return val;
    358 }
    359 
    360 static int
    361 substitute(struct reptr *ipc)
    362 {
    363 	int	matchcnt = 1;
    364 
    365 	if (match(ipc->bptr.re1, 0, ipc->nsub + 1) == 0)
    366 		return(0);
    367 
    368 	sflag = 0;
    369 	if (ipc->gfl >= -1 && ipc->gfl <= 1)
    370 		dosub(ipc->rhs);
    371 
    372 	if(ipc->gfl != 0) {
    373 		while(linebuf[Loc2]) {
    374 			if(match(ipc->bptr.re1, 1, ipc->nsub + 1) == 0)
    375 				break;
    376 			matchcnt++;
    377 			if (ipc->gfl == -1 || ipc->gfl == matchcnt)
    378 				dosub(ipc->rhs);
    379 		}
    380 	}
    381 	return(1);
    382 }
    383 
    384 static void
    385 dosub(char *rhsbuf)
    386 {
    387 	register int lc, sc;
    388 	register char	*rp;
    389 	int c;
    390 
    391 	sflag = 1;
    392 	lc = 0;	/*linebuf*/
    393 	sc = 0;	/*genbuf*/
    394 	rp = rhsbuf;
    395 	while (lc < Loc1)
    396 		genbuf[sc++] = linebuf[lc++];
    397 	while((c = *rp++) != 0) {
    398 		if (c == '&') {
    399 			sc = place(sc, Loc1, Loc2);
    400 			continue;
    401 		} else if (c == '\\') {
    402 			c = *rp++;
    403 			if (c >= '1' && c < NBRA+'1') {
    404 				sc = place(sc, Braslist[c-'1'],
    405 						Braelist[c-'1']);
    406 				continue;
    407 			}
    408 		}
    409 		if (sc >= gbend)
    410 			growsp("output line too long.");
    411 		genbuf[sc++] = (char)c;
    412 	}
    413 	lc = Loc2;
    414 	Loc2 = sc;
    415 	do {
    416 		if (sc >= gbend)
    417 			growsp("Output line too long.");
    418 	} while (genbuf[sc++] = linebuf[lc++], lc <= spend);
    419 	genend = sc-1;
    420 	lc = 0;	/*linebuf*/
    421 	sc = 0;	/*genbuf*/
    422 	while (linebuf[lc++] = genbuf[sc++], sc <= genend);
    423 	spend = lc-1;
    424 }
    425 
    426 static int
    427 place(int asc, int al1, int al2)
    428 {
    429 	register int sc;
    430 	register int l1, l2;
    431 
    432 	sc = asc;
    433 	l1 = al1;
    434 	l2 = al2;
    435 	while (l1 < l2) {
    436 		if (sc >= gbend)
    437 			growsp("Output line too long.");
    438 		genbuf[sc++] = linebuf[l1++];
    439 	}
    440 	return(sc);
    441 }
    442 
    443 static void
    444 command(struct reptr *ipc)
    445 {
    446 	register int	i;
    447 	wint_t	c;
    448 	register char	*p1, *p2;
    449 	int	k1, k2, k3;
    450 	char	*lp;
    451 	int	execc;
    452 
    453 
    454 	switch(ipc->command) {
    455 
    456 		case ACOM:
    457 			*A(aptr) = ipc;
    458 			aptr_inc();
    459 			*A(aptr) = 0;
    460 			break;
    461 
    462 		case CCOM:
    463 			delflag = 1;
    464 			if(!ipc->inar || dolflag) {
    465 				for(p1 = ipc->bptr.re1; *p1; ) {
    466 					putc(*p1&0377, stdout);
    467 					p1++;
    468 				}
    469 				putc('\n', stdout);
    470 			}
    471 			break;
    472 		case DCOM:
    473 			delflag++;
    474 			break;
    475 		case CDCOM:
    476 			p1 = p2 = linebuf;
    477 
    478 			while(*p1 != '\n') {
    479 				if(p1++ == &linebuf[spend]) {
    480 					delflag++;
    481 					return;
    482 				}
    483 			}
    484 
    485 			p1++;
    486 			while(*p2++ = *p1++, p1 <= &linebuf[spend]);
    487 			spend = p2-1 - linebuf;
    488 			jflag++;
    489 			break;
    490 
    491 		case EQCOM:
    492 			fprintf(stdout, "%lld\n", lnum);
    493 			break;
    494 
    495 		case GCOM:
    496 			p1 = linebuf;
    497 			p2 = holdsp;
    498 			while(*p1++ = *p2++, p2 <= &holdsp[hspend]);
    499 			spend = p1-1 - linebuf;
    500 			break;
    501 
    502 		case CGCOM:
    503 			linebuf[spend++] = '\n';
    504 			k1 = spend;
    505 			k2 = 0;	/*holdsp*/
    506 			do {
    507 				if(k1 >= lbend)
    508 					growsp(NULL);
    509 			} while(linebuf[k1++] = holdsp[k2++], k2 <= hspend);
    510 			spend = k1-1;
    511 			break;
    512 
    513 		case HCOM:
    514 			p1 = holdsp;
    515 			p2 = linebuf;
    516 			while(*p1++ = *p2++, p2 <= &linebuf[spend]);
    517 			hspend = p1-1 - holdsp;
    518 			break;
    519 
    520 		case CHCOM:
    521 			holdsp[hspend++] = '\n';
    522 			k1 = hspend;
    523 			k2 = 0;	/*linebuf*/
    524 			do {
    525 				if(k1 >= hend)
    526 					growsp("\1hold space overflow !");
    527 			} while(holdsp[k1++] = linebuf[k2++], k2 <= spend);
    528 			hspend = k1-1;
    529 			break;
    530 
    531 		case ICOM:
    532 			for(p1 = ipc->bptr.re1; *p1; ) {
    533 				putc(*p1&0377, stdout);
    534 				p1++;
    535 			}
    536 			putc('\n', stdout);
    537 			break;
    538 
    539 		case BCOM:
    540 			jflag = 1;
    541 			break;
    542 
    543 		case LCOM:
    544 			lp = linebuf;
    545 			lcomlen = 0;
    546 			while (lp < &linebuf[spend]) {
    547 				c = fetch(&lp);
    548 				lcom(c, invchar == 0);
    549 			}
    550 #if defined (SUS) || defined (SU3)
    551 			putc('$', stdout);
    552 #endif	/* SUS, SU3 */
    553 			putc('\n', stdout);
    554 			break;
    555 
    556 		case NCOM:
    557 			if(!nflag) {
    558 				for(p1 = linebuf; p1 < &linebuf[spend]; p1++)
    559 					putc(*p1&0377, stdout);
    560 				putc('\n', stdout);
    561 			}
    562 
    563 			if(A(aptr) > abuf)
    564 				arout();
    565 			if((execc = gline(0)) < 0) {
    566 				pending = ipc;
    567 				delflag = 1;
    568 				break;
    569 			}
    570 			spend = execc;
    571 
    572 			break;
    573 		case CNCOM:
    574 			if(A(aptr) > abuf)
    575 				arout();
    576 			linebuf[spend++] = '\n';
    577 			if((execc = gline(spend)) < 0) {
    578 				pending = ipc;
    579 				delflag = 1;
    580 				break;
    581 			}
    582 			spend = execc;
    583 			break;
    584 
    585 		case PCOM:
    586 			for(p1 = linebuf; p1 < &linebuf[spend]; p1++)
    587 				putc(*p1&0377, stdout);
    588 			putc('\n', stdout);
    589 			break;
    590 		case CPCOM:
    591 	cpcom:
    592 			for(p1 = linebuf; *p1 != '\n' && p1<&linebuf[spend]; ) {
    593 				putc(*p1&0377, stdout);
    594 				p1++;
    595 			}
    596 			putc('\n', stdout);
    597 			break;
    598 
    599 		case QCOM:
    600 			if(!nflag) {
    601 				for(p1 = linebuf; p1 < &linebuf[spend]; p1++)
    602 					putc(*p1&0377, stdout);
    603 				putc('\n', stdout);
    604 			}
    605 			if(A(aptr) > abuf)	arout();
    606 			fclose(stdout);
    607 			if (ibrd > 0)
    608 				lseek(f, -ibrd, SEEK_CUR);
    609 			exit(0);
    610 		case RCOM:
    611 
    612 			*A(aptr) = ipc;
    613 			aptr_inc();
    614 			*A(aptr) = 0;
    615 
    616 			break;
    617 
    618 		case SCOM:
    619 			i = substitute(ipc);
    620 			if(ipc->pfl && i)
    621 				if(ipc->pfl == 1) {
    622 					for(p1 = linebuf; p1 < &linebuf[spend];
    623 							p1++)
    624 						putc(*p1&0377, stdout);
    625 					putc('\n', stdout);
    626 				}
    627 				else
    628 					goto cpcom;
    629 			if(i && ipc->fcode)
    630 				goto wcom;
    631 			break;
    632 
    633 		case TCOM:
    634 			if(sflag == 0)	break;
    635 			sflag = 0;
    636 			jflag = 1;
    637 			break;
    638 
    639 		wcom:
    640 		case WCOM:
    641 			fprintf(ipc->fcode, "%s\n", linebuf);
    642 			break;
    643 		case XCOM:
    644 			p1 = linebuf;
    645 			p2 = genbuf;
    646 			while(*p2++ = *p1++, p1 <= &linebuf[spend]);
    647 			genend = p2-1 - genbuf;
    648 			p1 = holdsp;
    649 			p2 = linebuf;
    650 			while(*p2++ = *p1++, p1 <= &holdsp[hspend]);
    651 			spend = p2-1 - linebuf;
    652 			p1 = genbuf;
    653 			p2 = holdsp;
    654 			while(*p2++ = *p1++, p1 <= &genbuf[genend]);
    655 			hspend = p2-1 - holdsp;
    656 			break;
    657 
    658 		case YCOM:
    659 			if (multibyte) {
    660 				struct yitem	**yt, *yp;
    661 
    662 				yt = (struct yitem **)ipc->bptr.re1;
    663 				k1 = 0;	/*linebuf*/
    664 				k2 = 0;	/*genbuf*/
    665 				do {
    666 					k3 = k1;
    667 					lp = &linebuf[k1];
    668 					c = fetch(&lp);
    669 					k1 = lp - linebuf;
    670 					if (invchar == 0 &&
    671 					    (yp = ylook(c, yt, 0)) != NULL) {
    672 						k3 = 0;	/*yp->y_mc*/
    673 						do {
    674 							if (k2 >= gbend)
    675 								growsp("output "
    676 								"line too "
    677 								"long.");
    678 							genbuf[k2] =
    679 								yp->y_mc[k3++];
    680 						} while (genbuf[k2++] != '\0');
    681 						k2--;
    682 					} else {
    683 						while (k3 < k1) {
    684 							if (k2 >= gbend)
    685 								growsp("output "
    686 								"line too "
    687 								"long.");
    688 							genbuf[k2++] =
    689 								linebuf[k3++];
    690 						}
    691 					}
    692 				} while (k1 <= spend);
    693 				genend = k2-1;
    694 				p1 = linebuf;
    695 				p2 = genbuf;
    696 				while (*p1++ = *p2++, p2 <= &genbuf[genend]);
    697 				spend = p1-1 - linebuf;
    698 			} else {
    699 				p1 = linebuf;
    700 				p2 = ipc->bptr.re1;
    701 				while((*p1 = p2[*p1 & 0377]) != 0)	p1++;
    702 			}
    703 			break;
    704 		case COCOM:
    705 		case ECOM:
    706 		case FCOM:
    707 		case CWCOM:
    708 			;
    709 	}
    710 
    711 }
    712 
    713 static int
    714 gline(int addr)
    715 {
    716 	register char	*p2;
    717 	register int	c;
    718 	register int	c1;
    719 	c1 = addr;
    720 	p2 = cbp;
    721 	for (;;) {
    722 		if (p2 >= ebp) {
    723 			if (f < 0 || (c = read(f, ibuf, sizeof ibuf)) <= 0) {
    724 				if (c1 > addr && dolflag == 0) {
    725 					c = 1;
    726 					ibuf[0] = '\n';
    727 					close(f);
    728 					f = -1;
    729 				} else
    730 					return(-1);
    731 			} else
    732 				ibrd += c;
    733 			p2 = ibuf;
    734 			ebp = ibuf+c;
    735 		}
    736 		if ((c = *p2++ & 0377) == '\n') {
    737 			ibrd--;
    738 			if(needdol && p2 >=  ebp) {
    739 				if(f<0||(c = read(f, ibuf, sizeof ibuf)) <= 0) {
    740 					close(f);
    741 					f = -1;
    742 					if(eargc == 0)
    743 							dolflag = 1;
    744 				} else
    745 					ibrd += c;
    746 
    747 				p2 = ibuf;
    748 				ebp = ibuf + c;
    749 			}
    750 			break;
    751 		}
    752 		if(c1 >= lbend)
    753 			growsp(NULL);
    754 		linebuf[c1++] = (char)c;
    755 		ibrd--;
    756 	}
    757 	lnum++;
    758 	if(c1 >= lbend)
    759 		growsp(NULL);
    760 	linebuf[c1] = 0;
    761 	cbp = p2;
    762 
    763 	sflag = 0;
    764 	return(c1);
    765 }
    766 
    767 static void
    768 arout(void)
    769 {
    770 	register char	*p1;
    771 	struct reptr **a;
    772 	FILE	*fi;
    773 	char	c;
    774 	int	t;
    775 
    776 	for (a = abuf; *a; a++) {
    777 		if((*a)->command == ACOM) {
    778 			for(p1 = (*a)->bptr.re1; *p1; ) {
    779 				putc(*p1&0377, stdout);
    780 				p1++;
    781 			}
    782 			putc('\n', stdout);
    783 		} else {
    784 			if((fi = fopen((*a)->bptr.re1, "r")) == NULL)
    785 				continue;
    786 			while((t = getc(fi)) != EOF) {
    787 				c = t;
    788 				putc(c&0377, stdout);
    789 			}
    790 			fclose(fi);
    791 		}
    792 	}
    793 	aptr = 1;
    794 	*A(aptr) = 0;
    795 }
    796 
    797 static void
    798 lcom(wint_t c, int valid)
    799 {
    800 	if (!valid) {
    801 		oout(c);
    802 		return;
    803 	}
    804 #if defined (SUS) || defined (SU3)
    805 	switch (c) {
    806 	case '\\':
    807 		mout("\\\\");
    808 		return;
    809 	case '\a':
    810 		mout("\\a");
    811 		return;
    812 	case '\b':
    813 		mout("\\b");
    814 		return;
    815 	case '\f':
    816 		mout("\\f");
    817 		return;
    818 	case '\r':
    819 		mout("\\r");
    820 		return;
    821 	case '\t':
    822 		mout("\\t");
    823 		return;
    824 	case '\v':
    825 		mout("\\v");
    826 		return;
    827 	}
    828 #else	/* !SUS, !SU3 */
    829 	if (c < 040) {
    830 		mout(trans[c]);
    831 		return;
    832 	}
    833 #endif	/* !SUS, !SU3 */
    834 	if (multibyte) {
    835 		if (iswprint(c))
    836 			wout(c);
    837 		else
    838 			nout(c);
    839 	} else {
    840 		if (isprint(c))
    841 			lout(c);
    842 		else
    843 			oout(c);
    844 	}
    845 }
    846 
    847 static void
    848 oout(int c)
    849 {
    850 	char lbuf[5], *p;
    851 	int d;
    852 	const char *nums = "01234567";
    853 
    854 	p = lbuf;
    855 	*p++ = '\\';
    856 	*p++ = nums[(c & ~077) >> 6];
    857 	c &= 077;
    858 	d = c & 07;
    859 	*p++ =  c > d ?  nums[(c-d)>>3] : nums[0];
    860 	*p++ = nums[d];
    861 	*p = '\0';
    862 	mout(lbuf);
    863 }
    864 
    865 static void
    866 mout(const char *p)
    867 {
    868 	while (*p != '\0') {
    869 		lout(*p & 0377);
    870 		p++;
    871 	}
    872 }
    873 
    874 static void
    875 nout(wint_t c)
    876 {
    877 	char	mb[MB_LEN_MAX+1];
    878 	char	*p;
    879 	int	i;
    880 
    881 	if ((i = wctomb(mb, c)) > 0) {
    882 		mb[i] = '\0';
    883 		for (p = mb; *p; p++)
    884 			oout(*p & 0377);
    885 	}
    886 }
    887 
    888 static void
    889 lout(int c)
    890 {
    891 	if (lcomlen++ > 70) {
    892 		putc('\\', stdout);
    893 		putc('\n', stdout);
    894 		lcomlen = 1;
    895 	}
    896 	putc(c, stdout);
    897 }
    898 
    899 static void
    900 wout(wint_t c)
    901 {
    902 	char	mb[MB_LEN_MAX+1], *p;
    903 	int	i, w;
    904 
    905 	if ((i = wctomb(mb, c)) > 0) {
    906 		w = wcwidth(c);
    907 		if (lcomlen + w > 70) {
    908 			putc('\\', stdout);
    909 			putc('\n', stdout);
    910 			lcomlen = 0;
    911 		}
    912 		mb[i] = '\0';
    913 		for (p = mb; *p; p++)
    914 			putc(*p & 0377, stdout);
    915 		lcomlen += w;
    916 	}
    917 }