Home | History | Annotate | Download | only in sed
      1     0    stevel /*
      2     0    stevel  * CDDL HEADER START
      3     0    stevel  *
      4     0    stevel  * The contents of this file are subject to the terms of the
      5  8591  Jayakara  * Common Development and Distribution License (the "License").
      6  8591  Jayakara  * You may not use this file except in compliance with the License.
      7     0    stevel  *
      8     0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0    stevel  * or http://www.opensolaris.org/os/licensing.
     10     0    stevel  * See the License for the specific language governing permissions
     11     0    stevel  * and limitations under the License.
     12     0    stevel  *
     13     0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0    stevel  *
     19     0    stevel  * CDDL HEADER END
     20     0    stevel  */
     21   640    basabi /*
     22  8591  Jayakara  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23   640    basabi  * Use is subject to license terms.
     24   640    basabi  */
     25   640    basabi 
     26     0    stevel /*	Copyright (c) 1984 AT&T	*/
     27     0    stevel /*	  All Rights Reserved  	*/
     28     0    stevel 
     29     0    stevel #include <stdio.h>
     30     0    stevel #include <sys/param.h>
     31     0    stevel #include "sed.h"
     32   640    basabi 
     33     0    stevel #define	NWFILES		11	/* 10 plus one for standard output */
     34     0    stevel FILE	*fin;
     35     0    stevel FILE    *fcode[NWFILES];
     36     0    stevel char    *lastre;
     37     0    stevel char    sseof;
     38     0    stevel union reptr     *ptrend;
     39     0    stevel int     eflag;
     40   640    basabi extern	int	nbra;
     41     0    stevel char    linebuf[LBSIZE+1];
     42     0    stevel int     gflag;
     43     0    stevel int     nlno;
     44     0    stevel char    *fname[NWFILES];
     45     0    stevel int     nfiles;
     46     0    stevel union reptr ptrspace[PTRSIZE];
     47     0    stevel union reptr *rep;
     48     0    stevel char    *cp;
     49     0    stevel char    respace[RESIZE];
     50     0    stevel struct label ltab[LABSIZE];
     51     0    stevel struct label    *lab;
     52     0    stevel struct label    *labend;
     53     0    stevel int     depth;
     54     0    stevel int     eargc;
     55     0    stevel char    **eargv;
     56     0    stevel union reptr     **cmpend[DEPTH];
     57     0    stevel 
     58     0    stevel #define CCEOF	22
     59     0    stevel 
     60     0    stevel struct label    *labtab = ltab;
     61     0    stevel 
     62     0    stevel char	ETMES[]		= "Extra text at end of command: %s";
     63     0    stevel char	SMMES[]		= "Space missing before filename: %s";
     64     0    stevel char    TMMES[]		= "Too much command text: %s";
     65     0    stevel char    LTL[]  		= "Label too long: %s";
     66     0    stevel char    AD0MES[]	= "No addresses allowed: %s";
     67     0    stevel char    AD1MES[]	= "Only one address allowed: %s";
     68     0    stevel char	TOOBIG[]	= "Suffix too large - 512 max: %s";
     69     0    stevel 
     70   640    basabi extern int sed;	  /* IMPORTANT flag !!! */
     71     0    stevel extern char *comple();
     72     0    stevel 
     73     0    stevel extern char *malloc();
     74     0    stevel 
     75   640    basabi static void dechain(void);
     76   640    basabi static void fcomp(void);
     77   640    basabi 
     78   640    basabi int
     79   640    basabi main(int argc, char *argv[])
     80     0    stevel {
     81     0    stevel 	int flag_found = 0;
     82     0    stevel 
     83     0    stevel 	sed = 1;
     84     0    stevel 	eargc = argc;
     85     0    stevel 	eargv = argv;
     86     0    stevel 
     87     0    stevel 	aptr = abuf;
     88     0    stevel 	lab = labtab + 1;       /* 0 reserved for end-pointer */
     89     0    stevel 	rep = ptrspace;
     90     0    stevel 	rep->r1.ad1 = respace;
     91     0    stevel 	lcomend = &genbuf[71];
     92     0    stevel 	ptrend = &ptrspace[PTRSIZE];
     93     0    stevel 	labend = &labtab[LABSIZE];
     94     0    stevel 	lnum = 0;
     95     0    stevel 	pending = 0;
     96     0    stevel 	depth = 0;
     97     0    stevel 	spend = linebuf;
     98     0    stevel 	hspend = holdsp;	/* Avoid "bus error" under "H" cmd. */
     99     0    stevel 	fcode[0] = stdout;
    100     0    stevel 	fname[0] = "";
    101     0    stevel 	nfiles = 1;
    102     0    stevel 
    103     0    stevel 	if(eargc == 1)
    104     0    stevel 		exit(0);
    105     0    stevel 
    106     0    stevel 
    107     0    stevel 	setlocale(LC_ALL, "");		/* get locale environment */
    108     0    stevel 
    109     0    stevel 	while (--eargc > 0 && (++eargv)[0][0] == '-')
    110     0    stevel 		switch (eargv[0][1]) {
    111     0    stevel 
    112     0    stevel 		case 'n':
    113     0    stevel 			nflag++;
    114     0    stevel 			continue;
    115     0    stevel 
    116     0    stevel 		case 'f':
    117     0    stevel 			flag_found = 1;
    118     0    stevel 			if(eargc-- <= 0)	exit(2);
    119     0    stevel 
    120     0    stevel 			if((fin = fopen(*++eargv, "r")) == NULL) {
    121     0    stevel 				(void) fprintf(stderr, "sed: ");
    122     0    stevel 				perror(*eargv);
    123     0    stevel 				exit(2);
    124     0    stevel 			}
    125     0    stevel 
    126     0    stevel 			fcomp();
    127     0    stevel 			(void) fclose(fin);
    128     0    stevel 			continue;
    129     0    stevel 
    130     0    stevel 		case 'e':
    131     0    stevel 			flag_found = 1;
    132     0    stevel 			eflag++;
    133     0    stevel 			fcomp();
    134     0    stevel 			eflag = 0;
    135     0    stevel 			continue;
    136     0    stevel 
    137     0    stevel 		case 'g':
    138     0    stevel 			gflag++;
    139     0    stevel 			continue;
    140     0    stevel 
    141     0    stevel 		default:
    142     0    stevel 			(void) fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]);
    143     0    stevel 			exit(2);
    144     0    stevel 		}
    145     0    stevel 
    146     0    stevel 
    147     0    stevel 	if(rep == ptrspace && !flag_found) {
    148     0    stevel 		eargv--;
    149     0    stevel 		eargc++;
    150     0    stevel 		eflag++;
    151     0    stevel 		fcomp();
    152     0    stevel 		eargv++;
    153     0    stevel 		eargc--;
    154     0    stevel 		eflag = 0;
    155     0    stevel 	}
    156     0    stevel 
    157     0    stevel 	if(depth)
    158     0    stevel 		comperr("Too many {'s");
    159     0    stevel 
    160     0    stevel 	labtab->address = rep;
    161     0    stevel 
    162     0    stevel 	dechain();
    163     0    stevel 
    164     0    stevel 	if(eargc <= 0)
    165     0    stevel 		execute((char *)NULL);
    166     0    stevel 	else while(--eargc >= 0) {
    167     0    stevel 		execute(*eargv++);
    168     0    stevel 	}
    169     0    stevel 	(void) fclose(stdout);
    170   640    basabi 	return (0);
    171     0    stevel }
    172     0    stevel 
    173   640    basabi static void
    174   640    basabi fcomp(void)
    175     0    stevel {
    176     0    stevel 
    177   640    basabi 	char   *p, *op, *tp;
    178     0    stevel 	char    *address();
    179     0    stevel 	union reptr     *pt, *pt1;
    180     0    stevel 	int     i, ii;
    181     0    stevel 	struct label    *lpt;
    182     0    stevel 	char fnamebuf[MAXPATHLEN];
    183     0    stevel 
    184     0    stevel 	op = lastre;
    185     0    stevel 
    186     0    stevel 	if(rline(linebuf, &linebuf[LBSIZE+1]) < 0)  return;
    187     0    stevel 	if(*linebuf == '#') {
    188     0    stevel 		if(linebuf[1] == 'n')
    189     0    stevel 			nflag = 1;
    190     0    stevel 	}
    191     0    stevel 	else {
    192     0    stevel 		cp = linebuf;
    193     0    stevel 		goto comploop;
    194     0    stevel 	}
    195     0    stevel 
    196     0    stevel 	for(;;) {
    197     0    stevel 		if(rline(linebuf, &linebuf[LBSIZE+1]) < 0)  break;
    198     0    stevel 
    199     0    stevel 		cp = linebuf;
    200     0    stevel 
    201     0    stevel comploop:
    202   640    basabi /*		(void) fprintf(stderr, "cp: %s\n", cp); DEBUG */
    203     0    stevel 		while(*cp == ' ' || *cp == '\t')	cp++;
    204     0    stevel 		if(*cp == '\0' || *cp == '#')	 continue;
    205     0    stevel 		if(*cp == ';') {
    206     0    stevel 			cp++;
    207     0    stevel 			goto comploop;
    208     0    stevel 		}
    209     0    stevel 
    210     0    stevel 		p = address(rep->r1.ad1);
    211     0    stevel 
    212     0    stevel 		if(p == rep->r1.ad1) {
    213     0    stevel 			if(op)
    214     0    stevel 				rep->r1.ad1 = op;
    215     0    stevel 			else
    216     0    stevel 				comperr("First RE may not be null: %s");
    217     0    stevel 		} else if(p == 0) {
    218     0    stevel 			p = rep->r1.ad1;
    219     0    stevel 			rep->r1.ad1 = 0;
    220     0    stevel 		} else {
    221     0    stevel 			op = rep->r1.ad1;
    222     0    stevel 			if(*cp == ',' || *cp == ';') {
    223     0    stevel 				cp++;
    224     0    stevel 				rep->r1.ad2 = p;
    225     0    stevel 				p = address(rep->r1.ad2);
    226     0    stevel 				if(p == 0)
    227     0    stevel 					comperr("Illegal line number: %s");
    228     0    stevel 				if(p == rep->r1.ad2)
    229     0    stevel 					rep->r1.ad2 = op;
    230     0    stevel 				else
    231     0    stevel 					op = rep->r1.ad2;
    232     0    stevel 
    233     0    stevel 			} else
    234     0    stevel 				rep->r1.ad2 = 0;
    235     0    stevel 		}
    236     0    stevel 
    237     0    stevel 		if(p > &respace[RESIZE-1])
    238     0    stevel 			comperr(TMMES);
    239     0    stevel 
    240     0    stevel 		while(*cp == ' ' || *cp == '\t')	cp++;
    241     0    stevel 
    242     0    stevel swit:
    243     0    stevel 		switch(*cp++) {
    244     0    stevel 
    245     0    stevel 			default:
    246     0    stevel 				comperr("Unrecognized command: %s");
    247     0    stevel 
    248     0    stevel 			case '!':
    249     0    stevel 				rep->r1.negfl = 1;
    250     0    stevel 				goto swit;
    251     0    stevel 
    252     0    stevel 			case '{':
    253     0    stevel 				rep->r1.command = BCOM;
    254     0    stevel 				rep->r1.negfl = !(rep->r1.negfl);
    255     0    stevel 				cmpend[depth++] = &rep->r2.lb1;
    256     0    stevel 				if(++rep >= ptrend)
    257     0    stevel 					comperr("Too many commands: %s");
    258     0    stevel 				rep->r1.ad1 = p;
    259     0    stevel 				if(*cp == '\0') continue;
    260     0    stevel 
    261     0    stevel 				goto comploop;
    262     0    stevel 
    263     0    stevel 			case '}':
    264     0    stevel 				if(rep->r1.ad1)
    265     0    stevel 					comperr(AD0MES);
    266     0    stevel 
    267     0    stevel 				if(--depth < 0)
    268     0    stevel 					comperr("Too many }'s");
    269     0    stevel 				*cmpend[depth] = rep;
    270     0    stevel 
    271     0    stevel 				rep->r1.ad1 = p;
    272     0    stevel 				continue;
    273     0    stevel 
    274     0    stevel 			case '=':
    275     0    stevel 				rep->r1.command = EQCOM;
    276     0    stevel 				if(rep->r1.ad2)
    277     0    stevel 					comperr(AD1MES);
    278     0    stevel 				break;
    279     0    stevel 
    280     0    stevel 			case ':':
    281     0    stevel 				if(rep->r1.ad1)
    282     0    stevel 					comperr(AD0MES);
    283     0    stevel 
    284     0    stevel 				while(*cp++ == ' ');
    285     0    stevel 				cp--;
    286     0    stevel 
    287     0    stevel 
    288     0    stevel 				tp = lab->asc;
    289     0    stevel 				while((*tp++ = *cp++))
    290  8591  Jayakara 					if(tp >= &(lab->asc[9]))
    291     0    stevel 						comperr(LTL);
    292     0    stevel 				*--tp = '\0';
    293     0    stevel 
    294     0    stevel 				if(lpt = search(lab)) {
    295     0    stevel 					if(lpt->address)
    296     0    stevel 						comperr("Duplicate labels: %s");
    297     0    stevel 				} else {
    298     0    stevel 					lab->chain = 0;
    299     0    stevel 					lpt = lab;
    300     0    stevel 					if(++lab >= labend)
    301     0    stevel 						comperr("Too many labels: %s");
    302     0    stevel 				}
    303     0    stevel 				lpt->address = rep;
    304     0    stevel 				rep->r1.ad1 = p;
    305     0    stevel 
    306     0    stevel 				continue;
    307     0    stevel 
    308     0    stevel 			case 'a':
    309     0    stevel 				rep->r1.command = ACOM;
    310     0    stevel 				if(rep->r1.ad2)
    311     0    stevel 					comperr(AD1MES);
    312     0    stevel 				if(*cp == '\\') cp++;
    313     0    stevel 				if(*cp++ != '\n')
    314     0    stevel 					comperr(ETMES);
    315     0    stevel 				rep->r1.re1 = p;
    316     0    stevel 				if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
    317     0    stevel 					comperr(TMMES);
    318     0    stevel 				break;
    319     0    stevel 			case 'c':
    320     0    stevel 				rep->r1.command = CCOM;
    321     0    stevel 				if(*cp == '\\') cp++;
    322     0    stevel 				if(*cp++ != ('\n'))
    323     0    stevel 					comperr(ETMES);
    324     0    stevel 				rep->r1.re1 = p;
    325     0    stevel 				if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
    326     0    stevel 					comperr(TMMES);
    327     0    stevel 				break;
    328     0    stevel 			case 'i':
    329     0    stevel 				rep->r1.command = ICOM;
    330     0    stevel 				if(rep->r1.ad2)
    331     0    stevel 					comperr(AD1MES);
    332     0    stevel 				if(*cp == '\\') cp++;
    333     0    stevel 				if(*cp++ != ('\n'))
    334     0    stevel 					comperr(ETMES);
    335     0    stevel 				rep->r1.re1 = p;
    336     0    stevel 				if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
    337     0    stevel 					comperr(TMMES);
    338     0    stevel 				break;
    339     0    stevel 
    340     0    stevel 			case 'g':
    341     0    stevel 				rep->r1.command = GCOM;
    342     0    stevel 				break;
    343     0    stevel 
    344     0    stevel 			case 'G':
    345     0    stevel 				rep->r1.command = CGCOM;
    346     0    stevel 				break;
    347     0    stevel 
    348     0    stevel 			case 'h':
    349     0    stevel 				rep->r1.command = HCOM;
    350     0    stevel 				break;
    351     0    stevel 
    352     0    stevel 			case 'H':
    353     0    stevel 				rep->r1.command = CHCOM;
    354     0    stevel 				break;
    355     0    stevel 
    356     0    stevel 			case 't':
    357     0    stevel 				rep->r1.command = TCOM;
    358     0    stevel 				goto jtcommon;
    359     0    stevel 
    360     0    stevel 			case 'b':
    361     0    stevel 				rep->r1.command = BCOM;
    362     0    stevel jtcommon:
    363     0    stevel 				while(*cp++ == ' ');
    364     0    stevel 				cp--;
    365     0    stevel 
    366     0    stevel 				if(*cp == '\0') {
    367     0    stevel 					if(pt = labtab->chain) {
    368     0    stevel 						while(pt1 = pt->r2.lb1)
    369     0    stevel 							pt = pt1;
    370     0    stevel 						pt->r2.lb1 = rep;
    371     0    stevel 					} else
    372     0    stevel 						labtab->chain = rep;
    373     0    stevel 					break;
    374     0    stevel 				}
    375     0    stevel 				tp = lab->asc;
    376     0    stevel 				while((*tp++ = *cp++))
    377  8591  Jayakara 					if(tp >= &(lab->asc[9]))
    378     0    stevel 						comperr(LTL);
    379     0    stevel 				cp--;
    380     0    stevel 				*--tp = '\0';
    381     0    stevel 
    382     0    stevel 				if(lpt = search(lab)) {
    383     0    stevel 					if(lpt->address) {
    384     0    stevel 						rep->r2.lb1 = lpt->address;
    385     0    stevel 					} else {
    386     0    stevel 						pt = lpt->chain;
    387     0    stevel 						while(pt1 = pt->r2.lb1)
    388     0    stevel 							pt = pt1;
    389     0    stevel 						pt->r2.lb1 = rep;
    390     0    stevel 					}
    391     0    stevel 				} else {
    392     0    stevel 					lab->chain = rep;
    393     0    stevel 					lab->address = 0;
    394     0    stevel 					if(++lab >= labend)
    395     0    stevel 						comperr("Too many labels: %s");
    396     0    stevel 				}
    397     0    stevel 				break;
    398     0    stevel 
    399     0    stevel 			case 'n':
    400     0    stevel 				rep->r1.command = NCOM;
    401     0    stevel 				break;
    402     0    stevel 
    403     0    stevel 			case 'N':
    404     0    stevel 				rep->r1.command = CNCOM;
    405     0    stevel 				break;
    406     0    stevel 
    407     0    stevel 			case 'p':
    408     0    stevel 				rep->r1.command = PCOM;
    409     0    stevel 				break;
    410     0    stevel 
    411     0    stevel 			case 'P':
    412     0    stevel 				rep->r1.command = CPCOM;
    413     0    stevel 				break;
    414     0    stevel 
    415     0    stevel 			case 'r':
    416     0    stevel 				rep->r1.command = RCOM;
    417     0    stevel 				if(rep->r1.ad2)
    418     0    stevel 					comperr(AD1MES);
    419     0    stevel 				if(*cp++ != ' ')
    420     0    stevel 					comperr(SMMES);
    421     0    stevel 				rep->r1.re1 = p;
    422     0    stevel 				if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
    423     0    stevel 					comperr(TMMES);
    424     0    stevel 				break;
    425     0    stevel 
    426     0    stevel 			case 'd':
    427     0    stevel 				rep->r1.command = DCOM;
    428     0    stevel 				break;
    429     0    stevel 
    430     0    stevel 			case 'D':
    431     0    stevel 				rep->r1.command = CDCOM;
    432     0    stevel 				rep->r2.lb1 = ptrspace;
    433     0    stevel 				break;
    434     0    stevel 
    435     0    stevel 			case 'q':
    436     0    stevel 				rep->r1.command = QCOM;
    437     0    stevel 				if(rep->r1.ad2)
    438     0    stevel 					comperr(AD1MES);
    439     0    stevel 				break;
    440     0    stevel 
    441     0    stevel 			case 'l':
    442     0    stevel 				rep->r1.command = LCOM;
    443     0    stevel 				break;
    444     0    stevel 
    445     0    stevel 			case 's':
    446     0    stevel 				rep->r1.command = SCOM;
    447     0    stevel 				sseof = *cp++;
    448     0    stevel 				rep->r1.re1 = p;
    449     0    stevel 				p = comple((char *) 0, rep->r1.re1, &respace[RESIZE-1], sseof);
    450     0    stevel 				if(p == rep->r1.re1) {
    451     0    stevel 					if(op)
    452     0    stevel 						rep->r1.re1 = op;
    453     0    stevel 					else
    454     0    stevel 						comperr("First RE may not be null: %s");
    455     0    stevel 				} else
    456     0    stevel 					op = rep->r1.re1;
    457     0    stevel 				rep->r1.rhs = p;
    458     0    stevel 
    459     0    stevel 				p = compsub(rep->r1.rhs);
    460     0    stevel 
    461     0    stevel 				if(*cp == 'g') {
    462     0    stevel 					cp++;
    463     0    stevel 					rep->r1.gfl = 999;
    464     0    stevel 				} else if(gflag)
    465     0    stevel 					rep->r1.gfl = 999;
    466     0    stevel 
    467     0    stevel 				if(*cp >= '1' && *cp <= '9')
    468     0    stevel 					{i = *cp - '0';
    469     0    stevel 					cp++;
    470     0    stevel 					while(1)
    471     0    stevel 						{ii = *cp;
    472     0    stevel 						if(ii < '0' || ii > '9') break;
    473     0    stevel 						i = i*10 + ii - '0';
    474     0    stevel 						if(i > 512)
    475     0    stevel 							comperr(TOOBIG);
    476     0    stevel 						cp++;
    477     0    stevel 						}
    478     0    stevel 					rep->r1.gfl = i;
    479     0    stevel 					}
    480     0    stevel 
    481     0    stevel 				if(*cp == 'p') {
    482     0    stevel 					cp++;
    483     0    stevel 					rep->r1.pfl = 1;
    484     0    stevel 				}
    485     0    stevel 
    486     0    stevel 				if(*cp == 'P') {
    487     0    stevel 					cp++;
    488     0    stevel 					rep->r1.pfl = 2;
    489     0    stevel 				}
    490     0    stevel 
    491     0    stevel 				if(*cp == 'w') {
    492     0    stevel 					cp++;
    493     0    stevel 					if(*cp++ !=  ' ')
    494     0    stevel 						comperr(SMMES);
    495     0    stevel 					if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
    496     0    stevel 						comperr("File name too long: %s");
    497     0    stevel 					for(i = nfiles - 1; i >= 0; i--)
    498     0    stevel 						if(strcmp(fnamebuf,fname[i]) == 0) {
    499     0    stevel 							rep->r1.fcode = fcode[i];
    500     0    stevel 							goto done;
    501     0    stevel 						}
    502     0    stevel 					if(nfiles >= NWFILES)
    503     0    stevel 						comperr("Too many files in w commands: %s");
    504     0    stevel 
    505     0    stevel 					i = strlen(fnamebuf) + 1;
    506     0    stevel 					if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
    507     0    stevel 						(void) fprintf(stderr, "sed: Out of memory\n");
    508     0    stevel 						exit(2);
    509     0    stevel 					}
    510     0    stevel 					(void) strcpy(fname[nfiles], fnamebuf);
    511     0    stevel 					if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
    512     0    stevel 						(void) fprintf(stderr, "sed: Cannot open ");
    513     0    stevel 						perror(fname[nfiles]);
    514     0    stevel 						exit(2);
    515     0    stevel 					}
    516     0    stevel 					fcode[nfiles++] = rep->r1.fcode;
    517     0    stevel 				}
    518     0    stevel 				break;
    519     0    stevel 
    520     0    stevel 			case 'w':
    521     0    stevel 				rep->r1.command = WCOM;
    522     0    stevel 				if(*cp++ != ' ')
    523     0    stevel 					comperr(SMMES);
    524     0    stevel 				if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
    525     0    stevel 					comperr("File name too long: %s");
    526     0    stevel 				for(i = nfiles - 1; i >= 0; i--)
    527     0    stevel 					if(strcmp(fnamebuf, fname[i]) == 0) {
    528     0    stevel 						rep->r1.fcode = fcode[i];
    529     0    stevel 						goto done;
    530     0    stevel 					}
    531     0    stevel 				if(nfiles >= NWFILES)
    532     0    stevel 					comperr("Too many files in w commands: %s");
    533     0    stevel 
    534     0    stevel 				i = strlen(fnamebuf) + 1;
    535     0    stevel 				if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
    536     0    stevel 					(void) fprintf(stderr, "sed: Out of memory\n");
    537     0    stevel 					exit(2);
    538     0    stevel 				}
    539     0    stevel 				(void) strcpy(fname[nfiles], fnamebuf);
    540     0    stevel 				if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
    541     0    stevel 					(void) fprintf(stderr, "sed: Cannot create ");
    542     0    stevel 					perror(fname[nfiles]);
    543     0    stevel 					exit(2);
    544     0    stevel 				}
    545     0    stevel 				fcode[nfiles++] = rep->r1.fcode;
    546     0    stevel 				break;
    547     0    stevel 
    548     0    stevel 			case 'x':
    549     0    stevel 				rep->r1.command = XCOM;
    550     0    stevel 				break;
    551     0    stevel 
    552     0    stevel 			case 'y':
    553     0    stevel 				rep->r1.command = YCOM;
    554     0    stevel 				sseof = *cp++;
    555     0    stevel 				rep->r1.re1 = p;
    556     0    stevel 				p = ycomp(rep->r1.re1);
    557     0    stevel 				break;
    558     0    stevel 
    559     0    stevel 		}
    560     0    stevel done:
    561     0    stevel 		if(++rep >= ptrend)
    562     0    stevel 			comperr("Too many commands, last: %s");
    563     0    stevel 
    564     0    stevel 		rep->r1.ad1 = p;
    565     0    stevel 
    566     0    stevel 		if(*cp++ != '\0') {
    567     0    stevel 			if(cp[-1] == ';')
    568     0    stevel 				goto comploop;
    569     0    stevel 			comperr(ETMES);
    570     0    stevel 		}
    571     0    stevel 	}
    572     0    stevel 	rep->r1.command = 0;
    573     0    stevel 	lastre = op;
    574     0    stevel }
    575   640    basabi 
    576     0    stevel char    *compsub(rhsbuf)
    577     0    stevel char    *rhsbuf;
    578     0    stevel {
    579   640    basabi 	char   *p, *q;
    580     0    stevel 
    581     0    stevel 	p = rhsbuf;
    582     0    stevel 	q = cp;
    583     0    stevel 	for(;;) {
    584     0    stevel 		if(p > &respace[RESIZE-1])
    585     0    stevel 			comperr(TMMES);
    586     0    stevel 		if((*p = *q++) == '\\') {
    587     0    stevel 			p++;
    588     0    stevel 			if(p > &respace[RESIZE-1])
    589     0    stevel 				comperr(TMMES);
    590     0    stevel 			*p = *q++;
    591     0    stevel 			if(*p > nbra + '0' && *p <= '9')
    592     0    stevel 				comperr("``\\digit'' out of range: %s");
    593     0    stevel 			p++;
    594     0    stevel 			continue;
    595     0    stevel 		}
    596     0    stevel 		if(*p == sseof) {
    597     0    stevel 			*p++ = '\0';
    598     0    stevel 			cp = q;
    599     0    stevel 			return(p);
    600     0    stevel 		}
    601     0    stevel   		if(*p++ == '\0')
    602     0    stevel 			comperr("Ending delimiter missing on substitution: %s");
    603     0    stevel 
    604     0    stevel 	}
    605     0    stevel }
    606     0    stevel 
    607   640    basabi int
    608     0    stevel rline(lbuf, lbend)
    609     0    stevel char    *lbuf;
    610     0    stevel char	*lbend;
    611     0    stevel {
    612   640    basabi 	char   *p, *q;
    613   640    basabi 	int	t;
    614     0    stevel 	static char     *saveq;
    615     0    stevel 
    616     0    stevel 	p = lbuf;
    617     0    stevel 
    618     0    stevel 	if(eflag) {
    619     0    stevel 		if(eflag > 0) {
    620     0    stevel 			eflag = -1;
    621     0    stevel 			if(--eargc <= 0)
    622     0    stevel 				exit(2);
    623     0    stevel 			q = *++eargv;
    624     0    stevel 			while((t = *q++) != '\0') {
    625     0    stevel 				if(t == '\n') {
    626     0    stevel 					saveq = q;
    627     0    stevel 					goto out1;
    628     0    stevel 				}
    629     0    stevel 				if (p < lbend)
    630     0    stevel 					*p++ = t;
    631     0    stevel 				if(t == '\\') {
    632     0    stevel 					if((t = *q++) == '\0') {
    633     0    stevel 						saveq = 0;
    634     0    stevel 						return(-1);
    635     0    stevel 					}
    636     0    stevel 					if (p < lbend)
    637     0    stevel 						*p++ = t;
    638     0    stevel 				}
    639     0    stevel 			}
    640     0    stevel 			saveq = 0;
    641     0    stevel 
    642     0    stevel 		out1:
    643     0    stevel 			if (p == lbend)
    644     0    stevel 				comperr("Command line too long");
    645     0    stevel 			*p = '\0';
    646     0    stevel 			return(1);
    647     0    stevel 		}
    648     0    stevel 		if((q = saveq) == 0)    return(-1);
    649     0    stevel 
    650     0    stevel 		while((t = *q++) != '\0') {
    651     0    stevel 			if(t == '\n') {
    652     0    stevel 				saveq = q;
    653     0    stevel 				goto out2;
    654     0    stevel 			}
    655     0    stevel 			if(p < lbend)
    656     0    stevel 				*p++ = t;
    657     0    stevel 			if(t == '\\') {
    658     0    stevel 				if((t = *q++) == '\0') {
    659     0    stevel 					saveq = 0;
    660     0    stevel 					return(-1);
    661     0    stevel 				}
    662     0    stevel 				if (p < lbend)
    663     0    stevel 					*p++ = t;
    664     0    stevel 			}
    665     0    stevel 		}
    666     0    stevel 		saveq = 0;
    667     0    stevel 
    668     0    stevel 	out2:
    669     0    stevel 		if (p == lbend)
    670     0    stevel 			comperr("Command line too long");
    671     0    stevel 		*p = '\0';
    672     0    stevel 		return(1);
    673     0    stevel 	}
    674     0    stevel 
    675     0    stevel 	while((t = getc(fin)) != EOF) {
    676     0    stevel 		if(t == '\n') {
    677     0    stevel 			if (p == lbend)
    678     0    stevel 				comperr("Command line too long");
    679     0    stevel 			*p = '\0';
    680     0    stevel 			return(1);
    681     0    stevel 		}
    682     0    stevel 		if (p < lbend)
    683     0    stevel 			*p++ = t;
    684     0    stevel 		if(t == '\\') {
    685     0    stevel 			if((t = getc(fin)) == EOF)
    686     0    stevel 				break;
    687     0    stevel 			if(p < lbend)
    688     0    stevel 				*p++ = t;
    689     0    stevel 		}
    690     0    stevel 	}
    691     0    stevel 	if(ferror(fin)) {
    692     0    stevel 		perror("sed: Error reading pattern file");
    693     0    stevel 		exit(2);
    694     0    stevel 	}
    695     0    stevel 	return(-1);
    696     0    stevel }
    697     0    stevel 
    698     0    stevel char    *address(expbuf)
    699     0    stevel char    *expbuf;
    700     0    stevel {
    701   640    basabi 	char   *rcp;
    702     0    stevel 	long long	lno;
    703     0    stevel 
    704     0    stevel 	if(*cp == '$') {
    705     0    stevel 		if (expbuf > &respace[RESIZE-2])
    706     0    stevel 			comperr(TMMES);
    707     0    stevel 		cp++;
    708     0    stevel 		*expbuf++ = CEND;
    709     0    stevel 		*expbuf++ = CCEOF;
    710     0    stevel 		return(expbuf);
    711     0    stevel 	}
    712     0    stevel 	if (*cp == '/' || *cp == '\\' ) {
    713     0    stevel 		if ( *cp == '\\' )
    714     0    stevel 			cp++;
    715     0    stevel 		sseof = *cp++;
    716     0    stevel 		return(comple((char *) 0, expbuf, &respace[RESIZE-1], sseof));
    717     0    stevel 	}
    718     0    stevel 
    719     0    stevel 	rcp = cp;
    720     0    stevel 	lno = 0;
    721     0    stevel 
    722     0    stevel 	while(*rcp >= '0' && *rcp <= '9')
    723     0    stevel 		lno = lno*10 + *rcp++ - '0';
    724     0    stevel 
    725     0    stevel 	if(rcp > cp) {
    726     0    stevel 		if (expbuf > &respace[RESIZE-3])
    727     0    stevel 			comperr(TMMES);
    728     0    stevel 		*expbuf++ = CLNUM;
    729     0    stevel 		*expbuf++ = nlno;
    730     0    stevel 		tlno[nlno++] = lno;
    731     0    stevel 		if(nlno >= NLINES)
    732     0    stevel 			comperr("Too many line numbers: %s");
    733     0    stevel 		*expbuf++ = CCEOF;
    734     0    stevel 		cp = rcp;
    735     0    stevel 		return(expbuf);
    736     0    stevel 	}
    737     0    stevel 	return(0);
    738     0    stevel }
    739     0    stevel 
    740     0    stevel char    *text(textbuf, tbend)
    741     0    stevel char    *textbuf;
    742     0    stevel char	*tbend;
    743     0    stevel {
    744   640    basabi 	char   *p, *q;
    745     0    stevel 
    746     0    stevel 	p = textbuf;
    747     0    stevel 	q = cp;
    748     0    stevel #ifndef S5EMUL
    749     0    stevel 	/*
    750     0    stevel 	 * Strip off indentation from text to be inserted.
    751     0    stevel 	 */
    752     0    stevel 	while(*q == '\t' || *q == ' ')	q++;
    753     0    stevel #endif
    754     0    stevel 	for(;;) {
    755     0    stevel 
    756     0    stevel 		if(p > tbend)
    757     0    stevel 			return(NULL);	/* overflowed the buffer */
    758     0    stevel 		if((*p = *q++) == '\\')
    759     0    stevel 			*p = *q++;
    760     0    stevel 		if(*p == '\0') {
    761     0    stevel 			cp = --q;
    762     0    stevel 			return(++p);
    763     0    stevel 		}
    764     0    stevel #ifndef S5EMUL
    765     0    stevel 		/*
    766     0    stevel 		 * Strip off indentation from text to be inserted.
    767     0    stevel 		 */
    768     0    stevel 		if(*p == '\n') {
    769     0    stevel 			while(*q == '\t' || *q == ' ')	q++;
    770     0    stevel 		}
    771     0    stevel #endif
    772     0    stevel 		p++;
    773     0    stevel 	}
    774     0    stevel }
    775     0    stevel 
    776     0    stevel 
    777     0    stevel struct label    *search(ptr)
    778     0    stevel struct label    *ptr;
    779     0    stevel {
    780     0    stevel 	struct label    *rp;
    781     0    stevel 
    782     0    stevel 	rp = labtab;
    783     0    stevel 	while(rp < ptr) {
    784     0    stevel 		if(strcmp(rp->asc, ptr->asc) == 0)
    785     0    stevel 			return(rp);
    786     0    stevel 		rp++;
    787     0    stevel 	}
    788     0    stevel 
    789     0    stevel 	return(0);
    790     0    stevel }
    791     0    stevel 
    792     0    stevel 
    793   640    basabi static void
    794   640    basabi dechain(void)
    795     0    stevel {
    796     0    stevel 	struct label    *lptr;
    797     0    stevel 	union reptr     *rptr, *trptr;
    798     0    stevel 
    799     0    stevel 	for(lptr = labtab; lptr < lab; lptr++) {
    800     0    stevel 
    801     0    stevel 		if(lptr->address == 0) {
    802     0    stevel 			(void) fprintf(stderr, "sed: Undefined label: %s\n", lptr->asc);
    803     0    stevel 			exit(2);
    804     0    stevel 		}
    805     0    stevel 
    806     0    stevel 		if(lptr->chain) {
    807     0    stevel 			rptr = lptr->chain;
    808     0    stevel 			while(trptr = rptr->r2.lb1) {
    809     0    stevel 				rptr->r2.lb1 = lptr->address;
    810     0    stevel 				rptr = trptr;
    811     0    stevel 			}
    812     0    stevel 			rptr->r2.lb1 = lptr->address;
    813     0    stevel 		}
    814     0    stevel 	}
    815     0    stevel }
    816     0    stevel 
    817     0    stevel char *ycomp(expbuf)
    818     0    stevel char    *expbuf;
    819     0    stevel {
    820   640    basabi 	char	c;
    821   640    basabi 	char *ep, *tsp;
    822   640    basabi 	int i;
    823     0    stevel 	char    *sp;
    824     0    stevel 
    825     0    stevel 	ep = expbuf;
    826     0    stevel 	if(ep + 0377 > &respace[RESIZE-1])
    827     0    stevel 		comperr(TMMES);
    828     0    stevel 	sp = cp;
    829     0    stevel 	for(tsp = cp; (c = *tsp) != sseof; tsp++) {
    830     0    stevel 		if(c == '\\')
    831     0    stevel 			tsp++;
    832     0    stevel 		if(c == '\0' || c == '\n')
    833     0    stevel 			comperr("Ending delimiter missing on string: %s");
    834     0    stevel 	}
    835     0    stevel 	tsp++;
    836     0    stevel 
    837     0    stevel 	while((c = *sp++) != sseof) {
    838     0    stevel 		c &= 0377;
    839     0    stevel 		if(c == '\\' && *sp == 'n') {
    840     0    stevel 			sp++;
    841     0    stevel 			c = '\n';
    842     0    stevel 		}
    843     0    stevel 		if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
    844     0    stevel 			ep[c] = '\n';
    845     0    stevel 			tsp++;
    846     0    stevel 		}
    847     0    stevel 		if(ep[c] == sseof || ep[c] == '\0')
    848     0    stevel 			comperr("Transform strings not the same size: %s");
    849     0    stevel 	}
    850     0    stevel 	if(*tsp != sseof) {
    851     0    stevel 		if(*tsp == '\0')
    852     0    stevel 			comperr("Ending delimiter missing on string: %s");
    853     0    stevel 		else
    854     0    stevel 			comperr("Transform strings not the same size: %s");
    855     0    stevel 	}
    856     0    stevel 	cp = ++tsp;
    857     0    stevel 
    858     0    stevel 	for(i = 0; i < 0400; i++)
    859     0    stevel 		if(ep[i] == 0)
    860     0    stevel 			ep[i] = i;
    861     0    stevel 
    862     0    stevel 	return(ep + 0400);
    863     0    stevel }
    864   640    basabi 
    865   640    basabi void
    866   640    basabi comperr(char *msg)
    867     0    stevel {
    868     0    stevel 	(void) fprintf(stderr, "sed: ");
    869     0    stevel 	(void) fprintf(stderr, msg, linebuf);
    870     0    stevel 	(void) putc('\n', stderr);
    871     0    stevel 	exit(2);
    872     0    stevel }
    873