diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/ucbcmd/sed/sed1.c | |
download | illumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/ucbcmd/sed/sed1.c')
-rw-r--r-- | usr/src/ucbcmd/sed/sed1.c | 751 |
1 files changed, 751 insertions, 0 deletions
diff --git a/usr/src/ucbcmd/sed/sed1.c b/usr/src/ucbcmd/sed/sed1.c new file mode 100644 index 0000000000..49835169dd --- /dev/null +++ b/usr/src/ucbcmd/sed/sed1.c @@ -0,0 +1,751 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Copyright (c) 1984 AT&T */ +/* All Rights Reserved */ + + +/* + * Copyright (c) 1996, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ident "%Z%%M% %I% %E% SMI" /* from S5R3.1 1.7 */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "sed.h" +#include <regexp.h> + +union reptr *abuf[ABUFSIZE+1]; +union reptr **aptr; +char ibuf[BUFSIZ]; +char *cbp; +char *ebp; +char genbuf[LBSIZE+1]; +char *lcomend; +int dolflag; +int sflag; +int jflag; +int delflag; +long long lnum; +char holdsp[LBSIZE+1]; +char *spend; +char *hspend; +int nflag; +long long tlno[NLINES]; +int f; +char *ifname; +int numpass; +union reptr *pending; +char *trans[040] = { + "\\01", + "\\02", + "\\03", + "\\04", + "\\05", + "\\06", + "\\07", + "-<", + "->", + "\n", + "\\13", + "\\14", + "\\15", + "\\16", + "\\17", + "\\20", + "\\21", + "\\22", + "\\23", + "\\24", + "\\25", + "\\26", + "\\27", + "\\30", + "\\31", + "\\32", + "\\33", + "\\34", + "\\35", + "\\36", + "\\37" +}; +char rub[] = {"\\177"}; + +extern char TMMES[]; + +execute(file) +char *file; +{ + register char *p1, *p2; + register union reptr *ipc; + int c; + char *execp; + + if (file) { + if ((f = open(file, 0)) < 0) { + (void) fprintf(stderr, "sed: "); + perror(file); + } + ifname = file; + } else { + f = 0; + ifname = "standard input"; + } + + ebp = ibuf; + cbp = ibuf; + + if(pending) { + ipc = pending; + pending = 0; + goto yes; + } + + for(;;) { + if((execp = gline(linebuf)) == 0) { + (void) close(f); + return; + } + spend = execp; + + for(ipc = ptrspace; ipc->r1.command; ) { + + p1 = ipc->r1.ad1; + p2 = ipc->r1.ad2; + + if(p1) { + + if(ipc->r1.inar) { + if(*p2 == CEND) { + p1 = 0; + } else if(*p2 == CLNUM) { + c = (unsigned char)p2[1]; + if(lnum > tlno[c]) { + ipc->r1.inar = 0; + if(ipc->r1.negfl) + goto yes; + ipc++; + continue; + } + if(lnum == tlno[c]) { + ipc->r1.inar = 0; + } + } else if(match(p2, 0)) { + ipc->r1.inar = 0; + } + } else if(*p1 == CEND) { + if(!dolflag) { + if(ipc->r1.negfl) + goto yes; + ipc++; + continue; + } + + } else if(*p1 == CLNUM) { + c = (unsigned char)p1[1]; + if(lnum != tlno[c]) { + if(ipc->r1.negfl) + goto yes; + ipc++; + continue; + } + if(p2) + ipc->r1.inar = 1; + } else if(match(p1, 0)) { + if(p2) + ipc->r1.inar = 1; + } else { + if(ipc->r1.negfl) + goto yes; + ipc++; + continue; + } + } + + if(ipc->r1.negfl) { + ipc++; + continue; + } + yes: + command(ipc); + + if(delflag) + break; + + if(jflag) { + jflag = 0; + if((ipc = ipc->r2.lb1) == 0) { + ipc = ptrspace; + break; + } + } else + ipc++; + + } + if(!nflag && !delflag) { + for(p1 = linebuf; p1 < spend; p1++) + (void) putc(*p1, stdout); + (void) putc('\n', stdout); + } + + if(aptr > abuf) { + arout(); + } + + delflag = 0; + + } +} +match(expbuf, gf) +char *expbuf; +{ + register char *p1; + + if(gf) { + if(*expbuf) return(0); + locs = p1 = loc2; + } else { + p1 = linebuf; + locs = 0; + } + + circf = *expbuf++; + return(step(p1, expbuf)); +} + +substitute(ipc) +union reptr *ipc; +{ + if(match(ipc->r1.re1, 0) == 0) return(0); + + numpass = 0; + sflag = 0; /* Flags if any substitution was made */ + dosub(ipc->r1.rhs, ipc->r1.gfl); + + if(ipc->r1.gfl) { + while(*loc2) { + if(match(ipc->r1.re1, 1) == 0) break; + dosub(ipc->r1.rhs, ipc->r1.gfl); + } + } + return(sflag); +} + +dosub(rhsbuf,n) +char *rhsbuf; +int n; +{ + register char *lp, *sp, *rp; + int c; + + if(n > 0 && n < 999) + {numpass++; + if(n != numpass) return; + } + sflag = 1; + lp = linebuf; + sp = genbuf; + rp = rhsbuf; + while (lp < loc1) + *sp++ = *lp++; + while(c = *rp++) { + if (c == '&') + sp = place(sp, loc1, loc2); + else if (c == '\\') { + c = *rp++; + if (c >= '1' && c < NBRA+'1') + sp = place(sp, braslist[c-'1'], braelist[c-'1']); + else + *sp++ = c; + } else + *sp++ = c; + if (sp == &genbuf[LBSIZE+1]) { + (void) fprintf(stderr, "Output line too long.\n"); + *--sp = '\0'; + goto out; + } + } + lp = loc2; + loc2 = sp - genbuf + linebuf; + while(*sp++ = *lp++) + if (sp == &genbuf[LBSIZE+1]) { + (void) fprintf(stderr, "Output line too long.\n"); + *--sp = '\0'; + break; + } +out: + lp = linebuf; + sp = genbuf; + while (*lp++ = *sp++); + spend = lp-1; +} + +char *place(asp, al1, al2) +char *asp, *al1, *al2; +{ + register char *sp, *l1, *l2; + + sp = asp; + l1 = al1; + l2 = al2; + while (l1 < l2) { + *sp++ = *l1++; + if (sp == &genbuf[LBSIZE+1]) + break; + } + return(sp); +} + +command(ipc) +union reptr *ipc; +{ + register int i; + register char *p1, *p2, *p3; + char *execp; + + + switch(ipc->r1.command) { + + case ACOM: + if(aptr >= &abuf[ABUFSIZE]) { + (void) fprintf(stderr, "Too many appends or reads after line %lld\n", + lnum); + } else { + *aptr++ = ipc; + *aptr = 0; + } + break; + + case CCOM: + delflag = 1; + if(!ipc->r1.inar || dolflag) { + for(p1 = ipc->r1.re1; *p1; ) + (void) putc(*p1++, stdout); + (void) putc('\n', stdout); + } + break; + case DCOM: + delflag++; + break; + case CDCOM: + p1 = p2 = linebuf; + + while(*p1 != '\n') { + if(*p1++ == 0) { + delflag++; + return; + } + } + + p1++; + while(*p2++ = *p1++); + spend = p2-1; + jflag++; + break; + + case EQCOM: + (void) fprintf(stdout, "%lld\n", lnum); + break; + + case GCOM: + p1 = linebuf; + p2 = holdsp; + while(*p1++ = *p2++); + spend = p1-1; + break; + + case CGCOM: + *spend++ = '\n'; + p1 = spend; + p2 = holdsp; + do { + if (p1 == &linebuf[LBSIZE+1]) { + (void) fprintf(stderr, "Output line too long.\n"); + *--p1 = '\0'; + } + } while(*p1++ = *p2++); + spend = p1-1; + break; + + case HCOM: + p1 = holdsp; + p2 = linebuf; + while(*p1++ = *p2++); + hspend = p1-1; + break; + + case CHCOM: + *hspend++ = '\n'; + p1 = hspend; + p2 = linebuf; + do { + if (p1 == &holdsp[LBSIZE+1]) { + (void) fprintf(stderr, "Hold space overflowed.\n"); + *--p1 = '\0'; + } + } while(*p1++ = *p2++); + hspend = p1-1; + break; + + case ICOM: + for(p1 = ipc->r1.re1; *p1; ) + (void) putc(*p1++, stdout); + (void) putc('\n', stdout); + break; + + case BCOM: + jflag = 1; + break; + + + case LCOM: + p1 = linebuf; + p2 = genbuf; + genbuf[72] = 0; + while(*p1) + if((unsigned char)*p1 >= 040) { + if(*p1 == 0177) { + p3 = rub; + while(*p2++ = *p3++) + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + p2--; + p1++; + continue; + } + if(!isprint(*p1 & 0377)) { + *p2++ = '\\'; + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + *p2++ = (*p1 >> 6) + '0'; + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + *p2++ = ((*p1 >> 3) & 07) + '0'; + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + *p2++ = (*p1++ & 07) + '0'; + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + } else { + *p2++ = *p1++; + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + } + } else { + p3 = trans[(unsigned char)*p1-1]; + while(*p2++ = *p3++) + if(p2 >= lcomend) { + *p2 = '\\'; + (void) fprintf(stdout, "%s\n", genbuf); + p2 = genbuf; + } + p2--; + p1++; + } + *p2 = 0; + (void) fprintf(stdout, "%s\n", genbuf); + break; + + case NCOM: + if(!nflag) { + for(p1 = linebuf; p1 < spend; p1++) + (void) putc(*p1, stdout); + (void) putc('\n', stdout); + } + + if(aptr > abuf) + arout(); + if((execp = gline(linebuf)) == 0) { + pending = ipc; + delflag = 1; + break; + } + spend = execp; + + break; + case CNCOM: + if(aptr > abuf) + arout(); + *spend++ = '\n'; + if((execp = gline(spend)) == 0) { + pending = ipc; + delflag = 1; + break; + } + spend = execp; + break; + + case PCOM: + for(p1 = linebuf; p1 < spend; p1++) + (void) putc(*p1, stdout); + (void) putc('\n', stdout); + break; + case CPCOM: + cpcom: + for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; ) + (void) putc(*p1++, stdout); + (void) putc('\n', stdout); + break; + + case QCOM: + if(!nflag) { + for(p1 = linebuf; p1 < spend; p1++) + (void) putc(*p1, stdout); + (void) putc('\n', stdout); + } + if(aptr > abuf) arout(); + (void) fclose(stdout); + exit(0); + case RCOM: + if(aptr >= &abuf[ABUFSIZE]) { + (void) fprintf(stderr, "Too many appends or reads after line %lld\n", + lnum); + } else { + *aptr++ = ipc; + *aptr = 0; + } + break; + + case SCOM: + i = substitute(ipc); + if(ipc->r1.pfl && nflag && i) + if(ipc->r1.pfl == 1) { + for(p1 = linebuf; p1 < spend; p1++) + (void) putc(*p1, stdout); + (void) putc('\n', stdout); + } + else + goto cpcom; + if(i && ipc->r1.fcode) + goto wcom; + break; + + case TCOM: + if(sflag == 0) break; + sflag = 0; + jflag = 1; + break; + + wcom: + case WCOM: + (void) fprintf(ipc->r1.fcode, "%s\n", linebuf); + (void) fflush(ipc->r1.fcode); + break; + case XCOM: + p1 = linebuf; + p2 = genbuf; + while(*p2++ = *p1++); + p1 = holdsp; + p2 = linebuf; + while(*p2++ = *p1++); + spend = p2 - 1; + p1 = genbuf; + p2 = holdsp; + while(*p2++ = *p1++); + hspend = p2 - 1; + break; + + case YCOM: + p1 = linebuf; + p2 = ipc->r1.re1; + while(*p1 = p2[(unsigned char)*p1]) p1++; + break; + } + +} + +char *gline(addr) +char *addr; +{ + register char *p1, *p2; + register c; + sflag = 0; + p1 = addr; + p2 = cbp; + for (;;) { + if (p2 >= ebp) { + if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) { + return(0); + } + if(c < 0) { + (void) fprintf(stderr, "sed: error reading "); + perror(ifname); + exit(2); + } + p2 = ibuf; + ebp = ibuf+c; + } + if ((c = *p2++) == '\n') { + if(p2 >= ebp) { + if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) { + if(f >= 0) { + (void) close(f); + f = -1; + } + if(eargc == 0) + dolflag = 1; + } + if(c < 0) { + (void) fprintf(stderr, "sed: error reading "); + perror(ifname); + exit(2); + } + + p2 = ibuf; + ebp = ibuf + c; + } + break; + } + if(c) + if(p1 < &linebuf[LBSIZE]) + *p1++ = c; + } + lnum++; + *p1 = 0; + cbp = p2; + + return(p1); +} + +char *comple(x1, ep, x3, x4) +char *x1, *x3; +char x4; +register char *ep; +{ + register char *p; + + p = compile(x1, ep + 1, x3, x4); + if(p == ep + 1) + return(ep); + *ep = circf; + return(p); +} + +regerr(err) +register err; +{ + switch(err) { + + case 11: + comperr("Range endpoint too large: %s"); + break; + + case 16: + comperr("Bad number: %s"); + break; + + case 25: + comperr("``\\digit'' out of range: %s"); + break; + + case 36: + comperr("Illegal or missing delimiter: %s"); + break; + + case 41: + comperr("No remembered search string: %s"); + break; + + case 42: + comperr("\\( \\) imbalance: %s"); + break; + + case 43: + comperr("Too many \\(: %s"); + break; + + case 44: + comperr("More than 2 numbers given in \\{ \\}: %s"); + break; + + case 45: + comperr("} expected after \\: %s"); + break; + + case 46: + comperr("First number exceeds second in \\{ \\}: %s"); + break; + + case 49: + comperr("[ ] imbalance: %s"); + break; + + case 50: + comperr(TMMES); + break; + + default: + (void) fprintf(stderr, "Unknown regexp error code %d: %s\n", + err, linebuf); + exit(2); + break; + } +} + +arout() +{ + register char *p1; + FILE *fi; + char c; + int t; + + aptr = abuf - 1; + while(*++aptr) { + if((*aptr)->r1.command == ACOM) { + for(p1 = (*aptr)->r1.re1; *p1; ) + (void) putc(*p1++, stdout); + (void) putc('\n', stdout); + } else { + if((fi = fopen((*aptr)->r1.re1, "r")) == NULL) + continue; + while((t = getc(fi)) != EOF) { + c = t; + (void) putc(c, stdout); + } + (void) fclose(fi); + } + } + aptr = abuf; + *aptr = 0; +} + |