10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*8591SJayakara.Kini@Sun.COM * Common Development and Distribution License (the "License").
6*8591SJayakara.Kini@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21640Sbasabi /*
22*8591SJayakara.Kini@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23640Sbasabi * Use is subject to license terms.
24640Sbasabi */
25640Sbasabi
260Sstevel@tonic-gate /* Copyright (c) 1984 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <sys/param.h>
310Sstevel@tonic-gate #include "sed.h"
32640Sbasabi
330Sstevel@tonic-gate #define NWFILES 11 /* 10 plus one for standard output */
340Sstevel@tonic-gate FILE *fin;
350Sstevel@tonic-gate FILE *fcode[NWFILES];
360Sstevel@tonic-gate char *lastre;
370Sstevel@tonic-gate char sseof;
380Sstevel@tonic-gate union reptr *ptrend;
390Sstevel@tonic-gate int eflag;
40640Sbasabi extern int nbra;
410Sstevel@tonic-gate char linebuf[LBSIZE+1];
420Sstevel@tonic-gate int gflag;
430Sstevel@tonic-gate int nlno;
440Sstevel@tonic-gate char *fname[NWFILES];
450Sstevel@tonic-gate int nfiles;
460Sstevel@tonic-gate union reptr ptrspace[PTRSIZE];
470Sstevel@tonic-gate union reptr *rep;
480Sstevel@tonic-gate char *cp;
490Sstevel@tonic-gate char respace[RESIZE];
500Sstevel@tonic-gate struct label ltab[LABSIZE];
510Sstevel@tonic-gate struct label *lab;
520Sstevel@tonic-gate struct label *labend;
530Sstevel@tonic-gate int depth;
540Sstevel@tonic-gate int eargc;
550Sstevel@tonic-gate char **eargv;
560Sstevel@tonic-gate union reptr **cmpend[DEPTH];
570Sstevel@tonic-gate
580Sstevel@tonic-gate #define CCEOF 22
590Sstevel@tonic-gate
600Sstevel@tonic-gate struct label *labtab = ltab;
610Sstevel@tonic-gate
620Sstevel@tonic-gate char ETMES[] = "Extra text at end of command: %s";
630Sstevel@tonic-gate char SMMES[] = "Space missing before filename: %s";
640Sstevel@tonic-gate char TMMES[] = "Too much command text: %s";
650Sstevel@tonic-gate char LTL[] = "Label too long: %s";
660Sstevel@tonic-gate char AD0MES[] = "No addresses allowed: %s";
670Sstevel@tonic-gate char AD1MES[] = "Only one address allowed: %s";
680Sstevel@tonic-gate char TOOBIG[] = "Suffix too large - 512 max: %s";
690Sstevel@tonic-gate
70640Sbasabi extern int sed; /* IMPORTANT flag !!! */
710Sstevel@tonic-gate extern char *comple();
720Sstevel@tonic-gate
730Sstevel@tonic-gate extern char *malloc();
740Sstevel@tonic-gate
75640Sbasabi static void dechain(void);
76640Sbasabi static void fcomp(void);
77640Sbasabi
78640Sbasabi int
main(int argc,char * argv[])79640Sbasabi main(int argc, char *argv[])
800Sstevel@tonic-gate {
810Sstevel@tonic-gate int flag_found = 0;
820Sstevel@tonic-gate
830Sstevel@tonic-gate sed = 1;
840Sstevel@tonic-gate eargc = argc;
850Sstevel@tonic-gate eargv = argv;
860Sstevel@tonic-gate
870Sstevel@tonic-gate aptr = abuf;
880Sstevel@tonic-gate lab = labtab + 1; /* 0 reserved for end-pointer */
890Sstevel@tonic-gate rep = ptrspace;
900Sstevel@tonic-gate rep->r1.ad1 = respace;
910Sstevel@tonic-gate lcomend = &genbuf[71];
920Sstevel@tonic-gate ptrend = &ptrspace[PTRSIZE];
930Sstevel@tonic-gate labend = &labtab[LABSIZE];
940Sstevel@tonic-gate lnum = 0;
950Sstevel@tonic-gate pending = 0;
960Sstevel@tonic-gate depth = 0;
970Sstevel@tonic-gate spend = linebuf;
980Sstevel@tonic-gate hspend = holdsp; /* Avoid "bus error" under "H" cmd. */
990Sstevel@tonic-gate fcode[0] = stdout;
1000Sstevel@tonic-gate fname[0] = "";
1010Sstevel@tonic-gate nfiles = 1;
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate if(eargc == 1)
1040Sstevel@tonic-gate exit(0);
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate setlocale(LC_ALL, ""); /* get locale environment */
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate while (--eargc > 0 && (++eargv)[0][0] == '-')
1100Sstevel@tonic-gate switch (eargv[0][1]) {
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate case 'n':
1130Sstevel@tonic-gate nflag++;
1140Sstevel@tonic-gate continue;
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate case 'f':
1170Sstevel@tonic-gate flag_found = 1;
1180Sstevel@tonic-gate if(eargc-- <= 0) exit(2);
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate if((fin = fopen(*++eargv, "r")) == NULL) {
1210Sstevel@tonic-gate (void) fprintf(stderr, "sed: ");
1220Sstevel@tonic-gate perror(*eargv);
1230Sstevel@tonic-gate exit(2);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate fcomp();
1270Sstevel@tonic-gate (void) fclose(fin);
1280Sstevel@tonic-gate continue;
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate case 'e':
1310Sstevel@tonic-gate flag_found = 1;
1320Sstevel@tonic-gate eflag++;
1330Sstevel@tonic-gate fcomp();
1340Sstevel@tonic-gate eflag = 0;
1350Sstevel@tonic-gate continue;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate case 'g':
1380Sstevel@tonic-gate gflag++;
1390Sstevel@tonic-gate continue;
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate default:
1420Sstevel@tonic-gate (void) fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]);
1430Sstevel@tonic-gate exit(2);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate if(rep == ptrspace && !flag_found) {
1480Sstevel@tonic-gate eargv--;
1490Sstevel@tonic-gate eargc++;
1500Sstevel@tonic-gate eflag++;
1510Sstevel@tonic-gate fcomp();
1520Sstevel@tonic-gate eargv++;
1530Sstevel@tonic-gate eargc--;
1540Sstevel@tonic-gate eflag = 0;
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate if(depth)
1580Sstevel@tonic-gate comperr("Too many {'s");
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate labtab->address = rep;
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate dechain();
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate if(eargc <= 0)
1650Sstevel@tonic-gate execute((char *)NULL);
1660Sstevel@tonic-gate else while(--eargc >= 0) {
1670Sstevel@tonic-gate execute(*eargv++);
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate (void) fclose(stdout);
170640Sbasabi return (0);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate
173640Sbasabi static void
fcomp(void)174640Sbasabi fcomp(void)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate
177640Sbasabi char *p, *op, *tp;
1780Sstevel@tonic-gate char *address();
1790Sstevel@tonic-gate union reptr *pt, *pt1;
1800Sstevel@tonic-gate int i, ii;
1810Sstevel@tonic-gate struct label *lpt;
1820Sstevel@tonic-gate char fnamebuf[MAXPATHLEN];
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate op = lastre;
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate if(rline(linebuf, &linebuf[LBSIZE+1]) < 0) return;
1870Sstevel@tonic-gate if(*linebuf == '#') {
1880Sstevel@tonic-gate if(linebuf[1] == 'n')
1890Sstevel@tonic-gate nflag = 1;
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate else {
1920Sstevel@tonic-gate cp = linebuf;
1930Sstevel@tonic-gate goto comploop;
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate for(;;) {
1970Sstevel@tonic-gate if(rline(linebuf, &linebuf[LBSIZE+1]) < 0) break;
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate cp = linebuf;
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate comploop:
202640Sbasabi /* (void) fprintf(stderr, "cp: %s\n", cp); DEBUG */
2030Sstevel@tonic-gate while(*cp == ' ' || *cp == '\t') cp++;
2040Sstevel@tonic-gate if(*cp == '\0' || *cp == '#') continue;
2050Sstevel@tonic-gate if(*cp == ';') {
2060Sstevel@tonic-gate cp++;
2070Sstevel@tonic-gate goto comploop;
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate p = address(rep->r1.ad1);
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate if(p == rep->r1.ad1) {
2130Sstevel@tonic-gate if(op)
2140Sstevel@tonic-gate rep->r1.ad1 = op;
2150Sstevel@tonic-gate else
2160Sstevel@tonic-gate comperr("First RE may not be null: %s");
2170Sstevel@tonic-gate } else if(p == 0) {
2180Sstevel@tonic-gate p = rep->r1.ad1;
2190Sstevel@tonic-gate rep->r1.ad1 = 0;
2200Sstevel@tonic-gate } else {
2210Sstevel@tonic-gate op = rep->r1.ad1;
2220Sstevel@tonic-gate if(*cp == ',' || *cp == ';') {
2230Sstevel@tonic-gate cp++;
2240Sstevel@tonic-gate rep->r1.ad2 = p;
2250Sstevel@tonic-gate p = address(rep->r1.ad2);
2260Sstevel@tonic-gate if(p == 0)
2270Sstevel@tonic-gate comperr("Illegal line number: %s");
2280Sstevel@tonic-gate if(p == rep->r1.ad2)
2290Sstevel@tonic-gate rep->r1.ad2 = op;
2300Sstevel@tonic-gate else
2310Sstevel@tonic-gate op = rep->r1.ad2;
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate } else
2340Sstevel@tonic-gate rep->r1.ad2 = 0;
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate if(p > &respace[RESIZE-1])
2380Sstevel@tonic-gate comperr(TMMES);
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate while(*cp == ' ' || *cp == '\t') cp++;
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate swit:
2430Sstevel@tonic-gate switch(*cp++) {
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate default:
2460Sstevel@tonic-gate comperr("Unrecognized command: %s");
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate case '!':
2490Sstevel@tonic-gate rep->r1.negfl = 1;
2500Sstevel@tonic-gate goto swit;
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate case '{':
2530Sstevel@tonic-gate rep->r1.command = BCOM;
2540Sstevel@tonic-gate rep->r1.negfl = !(rep->r1.negfl);
2550Sstevel@tonic-gate cmpend[depth++] = &rep->r2.lb1;
2560Sstevel@tonic-gate if(++rep >= ptrend)
2570Sstevel@tonic-gate comperr("Too many commands: %s");
2580Sstevel@tonic-gate rep->r1.ad1 = p;
2590Sstevel@tonic-gate if(*cp == '\0') continue;
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate goto comploop;
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate case '}':
2640Sstevel@tonic-gate if(rep->r1.ad1)
2650Sstevel@tonic-gate comperr(AD0MES);
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate if(--depth < 0)
2680Sstevel@tonic-gate comperr("Too many }'s");
2690Sstevel@tonic-gate *cmpend[depth] = rep;
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate rep->r1.ad1 = p;
2720Sstevel@tonic-gate continue;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate case '=':
2750Sstevel@tonic-gate rep->r1.command = EQCOM;
2760Sstevel@tonic-gate if(rep->r1.ad2)
2770Sstevel@tonic-gate comperr(AD1MES);
2780Sstevel@tonic-gate break;
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate case ':':
2810Sstevel@tonic-gate if(rep->r1.ad1)
2820Sstevel@tonic-gate comperr(AD0MES);
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate while(*cp++ == ' ');
2850Sstevel@tonic-gate cp--;
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate tp = lab->asc;
2890Sstevel@tonic-gate while((*tp++ = *cp++))
290*8591SJayakara.Kini@Sun.COM if(tp >= &(lab->asc[9]))
2910Sstevel@tonic-gate comperr(LTL);
2920Sstevel@tonic-gate *--tp = '\0';
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate if(lpt = search(lab)) {
2950Sstevel@tonic-gate if(lpt->address)
2960Sstevel@tonic-gate comperr("Duplicate labels: %s");
2970Sstevel@tonic-gate } else {
2980Sstevel@tonic-gate lab->chain = 0;
2990Sstevel@tonic-gate lpt = lab;
3000Sstevel@tonic-gate if(++lab >= labend)
3010Sstevel@tonic-gate comperr("Too many labels: %s");
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate lpt->address = rep;
3040Sstevel@tonic-gate rep->r1.ad1 = p;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate continue;
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate case 'a':
3090Sstevel@tonic-gate rep->r1.command = ACOM;
3100Sstevel@tonic-gate if(rep->r1.ad2)
3110Sstevel@tonic-gate comperr(AD1MES);
3120Sstevel@tonic-gate if(*cp == '\\') cp++;
3130Sstevel@tonic-gate if(*cp++ != '\n')
3140Sstevel@tonic-gate comperr(ETMES);
3150Sstevel@tonic-gate rep->r1.re1 = p;
3160Sstevel@tonic-gate if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
3170Sstevel@tonic-gate comperr(TMMES);
3180Sstevel@tonic-gate break;
3190Sstevel@tonic-gate case 'c':
3200Sstevel@tonic-gate rep->r1.command = CCOM;
3210Sstevel@tonic-gate if(*cp == '\\') cp++;
3220Sstevel@tonic-gate if(*cp++ != ('\n'))
3230Sstevel@tonic-gate comperr(ETMES);
3240Sstevel@tonic-gate rep->r1.re1 = p;
3250Sstevel@tonic-gate if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
3260Sstevel@tonic-gate comperr(TMMES);
3270Sstevel@tonic-gate break;
3280Sstevel@tonic-gate case 'i':
3290Sstevel@tonic-gate rep->r1.command = ICOM;
3300Sstevel@tonic-gate if(rep->r1.ad2)
3310Sstevel@tonic-gate comperr(AD1MES);
3320Sstevel@tonic-gate if(*cp == '\\') cp++;
3330Sstevel@tonic-gate if(*cp++ != ('\n'))
3340Sstevel@tonic-gate comperr(ETMES);
3350Sstevel@tonic-gate rep->r1.re1 = p;
3360Sstevel@tonic-gate if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
3370Sstevel@tonic-gate comperr(TMMES);
3380Sstevel@tonic-gate break;
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate case 'g':
3410Sstevel@tonic-gate rep->r1.command = GCOM;
3420Sstevel@tonic-gate break;
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate case 'G':
3450Sstevel@tonic-gate rep->r1.command = CGCOM;
3460Sstevel@tonic-gate break;
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate case 'h':
3490Sstevel@tonic-gate rep->r1.command = HCOM;
3500Sstevel@tonic-gate break;
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate case 'H':
3530Sstevel@tonic-gate rep->r1.command = CHCOM;
3540Sstevel@tonic-gate break;
3550Sstevel@tonic-gate
3560Sstevel@tonic-gate case 't':
3570Sstevel@tonic-gate rep->r1.command = TCOM;
3580Sstevel@tonic-gate goto jtcommon;
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate case 'b':
3610Sstevel@tonic-gate rep->r1.command = BCOM;
3620Sstevel@tonic-gate jtcommon:
3630Sstevel@tonic-gate while(*cp++ == ' ');
3640Sstevel@tonic-gate cp--;
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate if(*cp == '\0') {
3670Sstevel@tonic-gate if(pt = labtab->chain) {
3680Sstevel@tonic-gate while(pt1 = pt->r2.lb1)
3690Sstevel@tonic-gate pt = pt1;
3700Sstevel@tonic-gate pt->r2.lb1 = rep;
3710Sstevel@tonic-gate } else
3720Sstevel@tonic-gate labtab->chain = rep;
3730Sstevel@tonic-gate break;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate tp = lab->asc;
3760Sstevel@tonic-gate while((*tp++ = *cp++))
377*8591SJayakara.Kini@Sun.COM if(tp >= &(lab->asc[9]))
3780Sstevel@tonic-gate comperr(LTL);
3790Sstevel@tonic-gate cp--;
3800Sstevel@tonic-gate *--tp = '\0';
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate if(lpt = search(lab)) {
3830Sstevel@tonic-gate if(lpt->address) {
3840Sstevel@tonic-gate rep->r2.lb1 = lpt->address;
3850Sstevel@tonic-gate } else {
3860Sstevel@tonic-gate pt = lpt->chain;
3870Sstevel@tonic-gate while(pt1 = pt->r2.lb1)
3880Sstevel@tonic-gate pt = pt1;
3890Sstevel@tonic-gate pt->r2.lb1 = rep;
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate } else {
3920Sstevel@tonic-gate lab->chain = rep;
3930Sstevel@tonic-gate lab->address = 0;
3940Sstevel@tonic-gate if(++lab >= labend)
3950Sstevel@tonic-gate comperr("Too many labels: %s");
3960Sstevel@tonic-gate }
3970Sstevel@tonic-gate break;
3980Sstevel@tonic-gate
3990Sstevel@tonic-gate case 'n':
4000Sstevel@tonic-gate rep->r1.command = NCOM;
4010Sstevel@tonic-gate break;
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate case 'N':
4040Sstevel@tonic-gate rep->r1.command = CNCOM;
4050Sstevel@tonic-gate break;
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate case 'p':
4080Sstevel@tonic-gate rep->r1.command = PCOM;
4090Sstevel@tonic-gate break;
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate case 'P':
4120Sstevel@tonic-gate rep->r1.command = CPCOM;
4130Sstevel@tonic-gate break;
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate case 'r':
4160Sstevel@tonic-gate rep->r1.command = RCOM;
4170Sstevel@tonic-gate if(rep->r1.ad2)
4180Sstevel@tonic-gate comperr(AD1MES);
4190Sstevel@tonic-gate if(*cp++ != ' ')
4200Sstevel@tonic-gate comperr(SMMES);
4210Sstevel@tonic-gate rep->r1.re1 = p;
4220Sstevel@tonic-gate if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
4230Sstevel@tonic-gate comperr(TMMES);
4240Sstevel@tonic-gate break;
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate case 'd':
4270Sstevel@tonic-gate rep->r1.command = DCOM;
4280Sstevel@tonic-gate break;
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate case 'D':
4310Sstevel@tonic-gate rep->r1.command = CDCOM;
4320Sstevel@tonic-gate rep->r2.lb1 = ptrspace;
4330Sstevel@tonic-gate break;
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate case 'q':
4360Sstevel@tonic-gate rep->r1.command = QCOM;
4370Sstevel@tonic-gate if(rep->r1.ad2)
4380Sstevel@tonic-gate comperr(AD1MES);
4390Sstevel@tonic-gate break;
4400Sstevel@tonic-gate
4410Sstevel@tonic-gate case 'l':
4420Sstevel@tonic-gate rep->r1.command = LCOM;
4430Sstevel@tonic-gate break;
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate case 's':
4460Sstevel@tonic-gate rep->r1.command = SCOM;
4470Sstevel@tonic-gate sseof = *cp++;
4480Sstevel@tonic-gate rep->r1.re1 = p;
4490Sstevel@tonic-gate p = comple((char *) 0, rep->r1.re1, &respace[RESIZE-1], sseof);
4500Sstevel@tonic-gate if(p == rep->r1.re1) {
4510Sstevel@tonic-gate if(op)
4520Sstevel@tonic-gate rep->r1.re1 = op;
4530Sstevel@tonic-gate else
4540Sstevel@tonic-gate comperr("First RE may not be null: %s");
4550Sstevel@tonic-gate } else
4560Sstevel@tonic-gate op = rep->r1.re1;
4570Sstevel@tonic-gate rep->r1.rhs = p;
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate p = compsub(rep->r1.rhs);
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate if(*cp == 'g') {
4620Sstevel@tonic-gate cp++;
4630Sstevel@tonic-gate rep->r1.gfl = 999;
4640Sstevel@tonic-gate } else if(gflag)
4650Sstevel@tonic-gate rep->r1.gfl = 999;
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate if(*cp >= '1' && *cp <= '9')
4680Sstevel@tonic-gate {i = *cp - '0';
4690Sstevel@tonic-gate cp++;
4700Sstevel@tonic-gate while(1)
4710Sstevel@tonic-gate {ii = *cp;
4720Sstevel@tonic-gate if(ii < '0' || ii > '9') break;
4730Sstevel@tonic-gate i = i*10 + ii - '0';
4740Sstevel@tonic-gate if(i > 512)
4750Sstevel@tonic-gate comperr(TOOBIG);
4760Sstevel@tonic-gate cp++;
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate rep->r1.gfl = i;
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate if(*cp == 'p') {
4820Sstevel@tonic-gate cp++;
4830Sstevel@tonic-gate rep->r1.pfl = 1;
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate
4860Sstevel@tonic-gate if(*cp == 'P') {
4870Sstevel@tonic-gate cp++;
4880Sstevel@tonic-gate rep->r1.pfl = 2;
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate if(*cp == 'w') {
4920Sstevel@tonic-gate cp++;
4930Sstevel@tonic-gate if(*cp++ != ' ')
4940Sstevel@tonic-gate comperr(SMMES);
4950Sstevel@tonic-gate if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
4960Sstevel@tonic-gate comperr("File name too long: %s");
4970Sstevel@tonic-gate for(i = nfiles - 1; i >= 0; i--)
4980Sstevel@tonic-gate if(strcmp(fnamebuf,fname[i]) == 0) {
4990Sstevel@tonic-gate rep->r1.fcode = fcode[i];
5000Sstevel@tonic-gate goto done;
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate if(nfiles >= NWFILES)
5030Sstevel@tonic-gate comperr("Too many files in w commands: %s");
5040Sstevel@tonic-gate
5050Sstevel@tonic-gate i = strlen(fnamebuf) + 1;
5060Sstevel@tonic-gate if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
5070Sstevel@tonic-gate (void) fprintf(stderr, "sed: Out of memory\n");
5080Sstevel@tonic-gate exit(2);
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate (void) strcpy(fname[nfiles], fnamebuf);
5110Sstevel@tonic-gate if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
5120Sstevel@tonic-gate (void) fprintf(stderr, "sed: Cannot open ");
5130Sstevel@tonic-gate perror(fname[nfiles]);
5140Sstevel@tonic-gate exit(2);
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate fcode[nfiles++] = rep->r1.fcode;
5170Sstevel@tonic-gate }
5180Sstevel@tonic-gate break;
5190Sstevel@tonic-gate
5200Sstevel@tonic-gate case 'w':
5210Sstevel@tonic-gate rep->r1.command = WCOM;
5220Sstevel@tonic-gate if(*cp++ != ' ')
5230Sstevel@tonic-gate comperr(SMMES);
5240Sstevel@tonic-gate if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
5250Sstevel@tonic-gate comperr("File name too long: %s");
5260Sstevel@tonic-gate for(i = nfiles - 1; i >= 0; i--)
5270Sstevel@tonic-gate if(strcmp(fnamebuf, fname[i]) == 0) {
5280Sstevel@tonic-gate rep->r1.fcode = fcode[i];
5290Sstevel@tonic-gate goto done;
5300Sstevel@tonic-gate }
5310Sstevel@tonic-gate if(nfiles >= NWFILES)
5320Sstevel@tonic-gate comperr("Too many files in w commands: %s");
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate i = strlen(fnamebuf) + 1;
5350Sstevel@tonic-gate if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
5360Sstevel@tonic-gate (void) fprintf(stderr, "sed: Out of memory\n");
5370Sstevel@tonic-gate exit(2);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate (void) strcpy(fname[nfiles], fnamebuf);
5400Sstevel@tonic-gate if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
5410Sstevel@tonic-gate (void) fprintf(stderr, "sed: Cannot create ");
5420Sstevel@tonic-gate perror(fname[nfiles]);
5430Sstevel@tonic-gate exit(2);
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate fcode[nfiles++] = rep->r1.fcode;
5460Sstevel@tonic-gate break;
5470Sstevel@tonic-gate
5480Sstevel@tonic-gate case 'x':
5490Sstevel@tonic-gate rep->r1.command = XCOM;
5500Sstevel@tonic-gate break;
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate case 'y':
5530Sstevel@tonic-gate rep->r1.command = YCOM;
5540Sstevel@tonic-gate sseof = *cp++;
5550Sstevel@tonic-gate rep->r1.re1 = p;
5560Sstevel@tonic-gate p = ycomp(rep->r1.re1);
5570Sstevel@tonic-gate break;
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate done:
5610Sstevel@tonic-gate if(++rep >= ptrend)
5620Sstevel@tonic-gate comperr("Too many commands, last: %s");
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate rep->r1.ad1 = p;
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate if(*cp++ != '\0') {
5670Sstevel@tonic-gate if(cp[-1] == ';')
5680Sstevel@tonic-gate goto comploop;
5690Sstevel@tonic-gate comperr(ETMES);
5700Sstevel@tonic-gate }
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate rep->r1.command = 0;
5730Sstevel@tonic-gate lastre = op;
5740Sstevel@tonic-gate }
575640Sbasabi
compsub(rhsbuf)5760Sstevel@tonic-gate char *compsub(rhsbuf)
5770Sstevel@tonic-gate char *rhsbuf;
5780Sstevel@tonic-gate {
579640Sbasabi char *p, *q;
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate p = rhsbuf;
5820Sstevel@tonic-gate q = cp;
5830Sstevel@tonic-gate for(;;) {
5840Sstevel@tonic-gate if(p > &respace[RESIZE-1])
5850Sstevel@tonic-gate comperr(TMMES);
5860Sstevel@tonic-gate if((*p = *q++) == '\\') {
5870Sstevel@tonic-gate p++;
5880Sstevel@tonic-gate if(p > &respace[RESIZE-1])
5890Sstevel@tonic-gate comperr(TMMES);
5900Sstevel@tonic-gate *p = *q++;
5910Sstevel@tonic-gate if(*p > nbra + '0' && *p <= '9')
5920Sstevel@tonic-gate comperr("``\\digit'' out of range: %s");
5930Sstevel@tonic-gate p++;
5940Sstevel@tonic-gate continue;
5950Sstevel@tonic-gate }
5960Sstevel@tonic-gate if(*p == sseof) {
5970Sstevel@tonic-gate *p++ = '\0';
5980Sstevel@tonic-gate cp = q;
5990Sstevel@tonic-gate return(p);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate if(*p++ == '\0')
6020Sstevel@tonic-gate comperr("Ending delimiter missing on substitution: %s");
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate
607640Sbasabi int
rline(lbuf,lbend)6080Sstevel@tonic-gate rline(lbuf, lbend)
6090Sstevel@tonic-gate char *lbuf;
6100Sstevel@tonic-gate char *lbend;
6110Sstevel@tonic-gate {
612640Sbasabi char *p, *q;
613640Sbasabi int t;
6140Sstevel@tonic-gate static char *saveq;
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate p = lbuf;
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate if(eflag) {
6190Sstevel@tonic-gate if(eflag > 0) {
6200Sstevel@tonic-gate eflag = -1;
6210Sstevel@tonic-gate if(--eargc <= 0)
6220Sstevel@tonic-gate exit(2);
6230Sstevel@tonic-gate q = *++eargv;
6240Sstevel@tonic-gate while((t = *q++) != '\0') {
6250Sstevel@tonic-gate if(t == '\n') {
6260Sstevel@tonic-gate saveq = q;
6270Sstevel@tonic-gate goto out1;
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate if (p < lbend)
6300Sstevel@tonic-gate *p++ = t;
6310Sstevel@tonic-gate if(t == '\\') {
6320Sstevel@tonic-gate if((t = *q++) == '\0') {
6330Sstevel@tonic-gate saveq = 0;
6340Sstevel@tonic-gate return(-1);
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate if (p < lbend)
6370Sstevel@tonic-gate *p++ = t;
6380Sstevel@tonic-gate }
6390Sstevel@tonic-gate }
6400Sstevel@tonic-gate saveq = 0;
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate out1:
6430Sstevel@tonic-gate if (p == lbend)
6440Sstevel@tonic-gate comperr("Command line too long");
6450Sstevel@tonic-gate *p = '\0';
6460Sstevel@tonic-gate return(1);
6470Sstevel@tonic-gate }
6480Sstevel@tonic-gate if((q = saveq) == 0) return(-1);
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate while((t = *q++) != '\0') {
6510Sstevel@tonic-gate if(t == '\n') {
6520Sstevel@tonic-gate saveq = q;
6530Sstevel@tonic-gate goto out2;
6540Sstevel@tonic-gate }
6550Sstevel@tonic-gate if(p < lbend)
6560Sstevel@tonic-gate *p++ = t;
6570Sstevel@tonic-gate if(t == '\\') {
6580Sstevel@tonic-gate if((t = *q++) == '\0') {
6590Sstevel@tonic-gate saveq = 0;
6600Sstevel@tonic-gate return(-1);
6610Sstevel@tonic-gate }
6620Sstevel@tonic-gate if (p < lbend)
6630Sstevel@tonic-gate *p++ = t;
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate }
6660Sstevel@tonic-gate saveq = 0;
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate out2:
6690Sstevel@tonic-gate if (p == lbend)
6700Sstevel@tonic-gate comperr("Command line too long");
6710Sstevel@tonic-gate *p = '\0';
6720Sstevel@tonic-gate return(1);
6730Sstevel@tonic-gate }
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate while((t = getc(fin)) != EOF) {
6760Sstevel@tonic-gate if(t == '\n') {
6770Sstevel@tonic-gate if (p == lbend)
6780Sstevel@tonic-gate comperr("Command line too long");
6790Sstevel@tonic-gate *p = '\0';
6800Sstevel@tonic-gate return(1);
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate if (p < lbend)
6830Sstevel@tonic-gate *p++ = t;
6840Sstevel@tonic-gate if(t == '\\') {
6850Sstevel@tonic-gate if((t = getc(fin)) == EOF)
6860Sstevel@tonic-gate break;
6870Sstevel@tonic-gate if(p < lbend)
6880Sstevel@tonic-gate *p++ = t;
6890Sstevel@tonic-gate }
6900Sstevel@tonic-gate }
6910Sstevel@tonic-gate if(ferror(fin)) {
6920Sstevel@tonic-gate perror("sed: Error reading pattern file");
6930Sstevel@tonic-gate exit(2);
6940Sstevel@tonic-gate }
6950Sstevel@tonic-gate return(-1);
6960Sstevel@tonic-gate }
6970Sstevel@tonic-gate
address(expbuf)6980Sstevel@tonic-gate char *address(expbuf)
6990Sstevel@tonic-gate char *expbuf;
7000Sstevel@tonic-gate {
701640Sbasabi char *rcp;
7020Sstevel@tonic-gate long long lno;
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate if(*cp == '$') {
7050Sstevel@tonic-gate if (expbuf > &respace[RESIZE-2])
7060Sstevel@tonic-gate comperr(TMMES);
7070Sstevel@tonic-gate cp++;
7080Sstevel@tonic-gate *expbuf++ = CEND;
7090Sstevel@tonic-gate *expbuf++ = CCEOF;
7100Sstevel@tonic-gate return(expbuf);
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate if (*cp == '/' || *cp == '\\' ) {
7130Sstevel@tonic-gate if ( *cp == '\\' )
7140Sstevel@tonic-gate cp++;
7150Sstevel@tonic-gate sseof = *cp++;
7160Sstevel@tonic-gate return(comple((char *) 0, expbuf, &respace[RESIZE-1], sseof));
7170Sstevel@tonic-gate }
7180Sstevel@tonic-gate
7190Sstevel@tonic-gate rcp = cp;
7200Sstevel@tonic-gate lno = 0;
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate while(*rcp >= '0' && *rcp <= '9')
7230Sstevel@tonic-gate lno = lno*10 + *rcp++ - '0';
7240Sstevel@tonic-gate
7250Sstevel@tonic-gate if(rcp > cp) {
7260Sstevel@tonic-gate if (expbuf > &respace[RESIZE-3])
7270Sstevel@tonic-gate comperr(TMMES);
7280Sstevel@tonic-gate *expbuf++ = CLNUM;
7290Sstevel@tonic-gate *expbuf++ = nlno;
7300Sstevel@tonic-gate tlno[nlno++] = lno;
7310Sstevel@tonic-gate if(nlno >= NLINES)
7320Sstevel@tonic-gate comperr("Too many line numbers: %s");
7330Sstevel@tonic-gate *expbuf++ = CCEOF;
7340Sstevel@tonic-gate cp = rcp;
7350Sstevel@tonic-gate return(expbuf);
7360Sstevel@tonic-gate }
7370Sstevel@tonic-gate return(0);
7380Sstevel@tonic-gate }
7390Sstevel@tonic-gate
text(textbuf,tbend)7400Sstevel@tonic-gate char *text(textbuf, tbend)
7410Sstevel@tonic-gate char *textbuf;
7420Sstevel@tonic-gate char *tbend;
7430Sstevel@tonic-gate {
744640Sbasabi char *p, *q;
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate p = textbuf;
7470Sstevel@tonic-gate q = cp;
7480Sstevel@tonic-gate #ifndef S5EMUL
7490Sstevel@tonic-gate /*
7500Sstevel@tonic-gate * Strip off indentation from text to be inserted.
7510Sstevel@tonic-gate */
7520Sstevel@tonic-gate while(*q == '\t' || *q == ' ') q++;
7530Sstevel@tonic-gate #endif
7540Sstevel@tonic-gate for(;;) {
7550Sstevel@tonic-gate
7560Sstevel@tonic-gate if(p > tbend)
7570Sstevel@tonic-gate return(NULL); /* overflowed the buffer */
7580Sstevel@tonic-gate if((*p = *q++) == '\\')
7590Sstevel@tonic-gate *p = *q++;
7600Sstevel@tonic-gate if(*p == '\0') {
7610Sstevel@tonic-gate cp = --q;
7620Sstevel@tonic-gate return(++p);
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate #ifndef S5EMUL
7650Sstevel@tonic-gate /*
7660Sstevel@tonic-gate * Strip off indentation from text to be inserted.
7670Sstevel@tonic-gate */
7680Sstevel@tonic-gate if(*p == '\n') {
7690Sstevel@tonic-gate while(*q == '\t' || *q == ' ') q++;
7700Sstevel@tonic-gate }
7710Sstevel@tonic-gate #endif
7720Sstevel@tonic-gate p++;
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate }
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate
search(ptr)7770Sstevel@tonic-gate struct label *search(ptr)
7780Sstevel@tonic-gate struct label *ptr;
7790Sstevel@tonic-gate {
7800Sstevel@tonic-gate struct label *rp;
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate rp = labtab;
7830Sstevel@tonic-gate while(rp < ptr) {
7840Sstevel@tonic-gate if(strcmp(rp->asc, ptr->asc) == 0)
7850Sstevel@tonic-gate return(rp);
7860Sstevel@tonic-gate rp++;
7870Sstevel@tonic-gate }
7880Sstevel@tonic-gate
7890Sstevel@tonic-gate return(0);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate
793640Sbasabi static void
dechain(void)794640Sbasabi dechain(void)
7950Sstevel@tonic-gate {
7960Sstevel@tonic-gate struct label *lptr;
7970Sstevel@tonic-gate union reptr *rptr, *trptr;
7980Sstevel@tonic-gate
7990Sstevel@tonic-gate for(lptr = labtab; lptr < lab; lptr++) {
8000Sstevel@tonic-gate
8010Sstevel@tonic-gate if(lptr->address == 0) {
8020Sstevel@tonic-gate (void) fprintf(stderr, "sed: Undefined label: %s\n", lptr->asc);
8030Sstevel@tonic-gate exit(2);
8040Sstevel@tonic-gate }
8050Sstevel@tonic-gate
8060Sstevel@tonic-gate if(lptr->chain) {
8070Sstevel@tonic-gate rptr = lptr->chain;
8080Sstevel@tonic-gate while(trptr = rptr->r2.lb1) {
8090Sstevel@tonic-gate rptr->r2.lb1 = lptr->address;
8100Sstevel@tonic-gate rptr = trptr;
8110Sstevel@tonic-gate }
8120Sstevel@tonic-gate rptr->r2.lb1 = lptr->address;
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate }
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate
ycomp(expbuf)8170Sstevel@tonic-gate char *ycomp(expbuf)
8180Sstevel@tonic-gate char *expbuf;
8190Sstevel@tonic-gate {
820640Sbasabi char c;
821640Sbasabi char *ep, *tsp;
822640Sbasabi int i;
8230Sstevel@tonic-gate char *sp;
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate ep = expbuf;
8260Sstevel@tonic-gate if(ep + 0377 > &respace[RESIZE-1])
8270Sstevel@tonic-gate comperr(TMMES);
8280Sstevel@tonic-gate sp = cp;
8290Sstevel@tonic-gate for(tsp = cp; (c = *tsp) != sseof; tsp++) {
8300Sstevel@tonic-gate if(c == '\\')
8310Sstevel@tonic-gate tsp++;
8320Sstevel@tonic-gate if(c == '\0' || c == '\n')
8330Sstevel@tonic-gate comperr("Ending delimiter missing on string: %s");
8340Sstevel@tonic-gate }
8350Sstevel@tonic-gate tsp++;
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate while((c = *sp++) != sseof) {
8380Sstevel@tonic-gate c &= 0377;
8390Sstevel@tonic-gate if(c == '\\' && *sp == 'n') {
8400Sstevel@tonic-gate sp++;
8410Sstevel@tonic-gate c = '\n';
8420Sstevel@tonic-gate }
8430Sstevel@tonic-gate if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
8440Sstevel@tonic-gate ep[c] = '\n';
8450Sstevel@tonic-gate tsp++;
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate if(ep[c] == sseof || ep[c] == '\0')
8480Sstevel@tonic-gate comperr("Transform strings not the same size: %s");
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate if(*tsp != sseof) {
8510Sstevel@tonic-gate if(*tsp == '\0')
8520Sstevel@tonic-gate comperr("Ending delimiter missing on string: %s");
8530Sstevel@tonic-gate else
8540Sstevel@tonic-gate comperr("Transform strings not the same size: %s");
8550Sstevel@tonic-gate }
8560Sstevel@tonic-gate cp = ++tsp;
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate for(i = 0; i < 0400; i++)
8590Sstevel@tonic-gate if(ep[i] == 0)
8600Sstevel@tonic-gate ep[i] = i;
8610Sstevel@tonic-gate
8620Sstevel@tonic-gate return(ep + 0400);
8630Sstevel@tonic-gate }
864640Sbasabi
865640Sbasabi void
comperr(char * msg)866640Sbasabi comperr(char *msg)
8670Sstevel@tonic-gate {
8680Sstevel@tonic-gate (void) fprintf(stderr, "sed: ");
8690Sstevel@tonic-gate (void) fprintf(stderr, msg, linebuf);
8700Sstevel@tonic-gate (void) putc('\n', stderr);
8710Sstevel@tonic-gate exit(2);
8720Sstevel@tonic-gate }
873