4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984 AT&T */
27 /* All Rights Reserved */
30 #include <sys/param.h>
33 #define NWFILES 11 /* 10 plus one for standard output */
41 char linebuf
[LBSIZE
+1];
46 union reptr ptrspace
[PTRSIZE
];
50 struct label ltab
[LABSIZE
];
56 union reptr
**cmpend
[DEPTH
];
60 struct label
*labtab
= ltab
;
62 char ETMES
[] = "Extra text at end of command: %s";
63 char SMMES
[] = "Space missing before filename: %s";
64 char TMMES
[] = "Too much command text: %s";
65 char LTL
[] = "Label too long: %s";
66 char AD0MES
[] = "No addresses allowed: %s";
67 char AD1MES
[] = "Only one address allowed: %s";
68 char TOOBIG
[] = "Suffix too large - 512 max: %s";
70 extern int sed
; /* IMPORTANT flag !!! */
71 extern char *comple();
73 extern char *malloc();
75 static void dechain(void);
76 static void fcomp(void);
79 main(int argc
, char *argv
[])
88 lab
= labtab
+ 1; /* 0 reserved for end-pointer */
90 rep
->r1
.ad1
= respace
;
91 lcomend
= &genbuf
[71];
92 ptrend
= &ptrspace
[PTRSIZE
];
93 labend
= &labtab
[LABSIZE
];
98 hspend
= holdsp
; /* Avoid "bus error" under "H" cmd. */
107 setlocale(LC_ALL
, ""); /* get locale environment */
109 while (--eargc
> 0 && (++eargv
)[0][0] == '-')
110 switch (eargv
[0][1]) {
118 if(eargc
-- <= 0) exit(2);
120 if((fin
= fopen(*++eargv
, "r")) == NULL
) {
121 (void) fprintf(stderr
, "sed: ");
142 (void) fprintf(stderr
, "sed: Unknown flag: %c\n", eargv
[0][1]);
147 if(rep
== ptrspace
&& !flag_found
) {
158 comperr("Too many {'s");
160 labtab
->address
= rep
;
165 execute((char *)NULL
);
166 else while(--eargc
>= 0) {
169 (void) fclose(stdout
);
179 union reptr
*pt
, *pt1
;
182 char fnamebuf
[MAXPATHLEN
];
186 if(rline(linebuf
, &linebuf
[LBSIZE
+1]) < 0) return;
187 if(*linebuf
== '#') {
188 if(linebuf
[1] == 'n')
197 if(rline(linebuf
, &linebuf
[LBSIZE
+1]) < 0) break;
202 /* (void) fprintf(stderr, "cp: %s\n", cp); DEBUG */
203 while(*cp
== ' ' || *cp
== '\t') cp
++;
204 if(*cp
== '\0' || *cp
== '#') continue;
210 p
= address(rep
->r1
.ad1
);
212 if(p
== rep
->r1
.ad1
) {
216 comperr("First RE may not be null: %s");
222 if(*cp
== ',' || *cp
== ';') {
225 p
= address(rep
->r1
.ad2
);
227 comperr("Illegal line number: %s");
237 if(p
> &respace
[RESIZE
-1])
240 while(*cp
== ' ' || *cp
== '\t') cp
++;
246 comperr("Unrecognized command: %s");
253 rep
->r1
.command
= BCOM
;
254 rep
->r1
.negfl
= !(rep
->r1
.negfl
);
255 cmpend
[depth
++] = &rep
->r2
.lb1
;
257 comperr("Too many commands: %s");
259 if(*cp
== '\0') continue;
268 comperr("Too many }'s");
269 *cmpend
[depth
] = rep
;
275 rep
->r1
.command
= EQCOM
;
289 while((*tp
++ = *cp
++))
290 if(tp
>= &(lab
->asc
[9]))
294 if(lpt
= search(lab
)) {
296 comperr("Duplicate labels: %s");
301 comperr("Too many labels: %s");
309 rep
->r1
.command
= ACOM
;
312 if(*cp
== '\\') cp
++;
316 if ((p
= text(rep
->r1
.re1
, &respace
[RESIZE
-1])) == NULL
)
320 rep
->r1
.command
= CCOM
;
321 if(*cp
== '\\') cp
++;
325 if ((p
= text(rep
->r1
.re1
, &respace
[RESIZE
-1])) == NULL
)
329 rep
->r1
.command
= ICOM
;
332 if(*cp
== '\\') cp
++;
336 if ((p
= text(rep
->r1
.re1
, &respace
[RESIZE
-1])) == NULL
)
341 rep
->r1
.command
= GCOM
;
345 rep
->r1
.command
= CGCOM
;
349 rep
->r1
.command
= HCOM
;
353 rep
->r1
.command
= CHCOM
;
357 rep
->r1
.command
= TCOM
;
361 rep
->r1
.command
= BCOM
;
367 if(pt
= labtab
->chain
) {
368 while(pt1
= pt
->r2
.lb1
)
376 while((*tp
++ = *cp
++))
377 if(tp
>= &(lab
->asc
[9]))
382 if(lpt
= search(lab
)) {
384 rep
->r2
.lb1
= lpt
->address
;
387 while(pt1
= pt
->r2
.lb1
)
395 comperr("Too many labels: %s");
400 rep
->r1
.command
= NCOM
;
404 rep
->r1
.command
= CNCOM
;
408 rep
->r1
.command
= PCOM
;
412 rep
->r1
.command
= CPCOM
;
416 rep
->r1
.command
= RCOM
;
422 if ((p
= text(rep
->r1
.re1
, &respace
[RESIZE
-1])) == NULL
)
427 rep
->r1
.command
= DCOM
;
431 rep
->r1
.command
= CDCOM
;
432 rep
->r2
.lb1
= ptrspace
;
436 rep
->r1
.command
= QCOM
;
442 rep
->r1
.command
= LCOM
;
446 rep
->r1
.command
= SCOM
;
449 p
= comple((char *) 0, rep
->r1
.re1
, &respace
[RESIZE
-1], sseof
);
450 if(p
== rep
->r1
.re1
) {
454 comperr("First RE may not be null: %s");
459 p
= compsub(rep
->r1
.rhs
);
467 if(*cp
>= '1' && *cp
<= '9')
472 if(ii
< '0' || ii
> '9') break;
495 if (text(fnamebuf
, &fnamebuf
[MAXPATHLEN
]) == NULL
)
496 comperr("File name too long: %s");
497 for(i
= nfiles
- 1; i
>= 0; i
--)
498 if(strcmp(fnamebuf
,fname
[i
]) == 0) {
499 rep
->r1
.fcode
= fcode
[i
];
502 if(nfiles
>= NWFILES
)
503 comperr("Too many files in w commands: %s");
505 i
= strlen(fnamebuf
) + 1;
506 if ((fname
[nfiles
] = malloc((unsigned)i
)) == NULL
) {
507 (void) fprintf(stderr
, "sed: Out of memory\n");
510 (void) strcpy(fname
[nfiles
], fnamebuf
);
511 if((rep
->r1
.fcode
= fopen(fname
[nfiles
], "w")) == NULL
) {
512 (void) fprintf(stderr
, "sed: Cannot open ");
513 perror(fname
[nfiles
]);
516 fcode
[nfiles
++] = rep
->r1
.fcode
;
521 rep
->r1
.command
= WCOM
;
524 if (text(fnamebuf
, &fnamebuf
[MAXPATHLEN
]) == NULL
)
525 comperr("File name too long: %s");
526 for(i
= nfiles
- 1; i
>= 0; i
--)
527 if(strcmp(fnamebuf
, fname
[i
]) == 0) {
528 rep
->r1
.fcode
= fcode
[i
];
531 if(nfiles
>= NWFILES
)
532 comperr("Too many files in w commands: %s");
534 i
= strlen(fnamebuf
) + 1;
535 if ((fname
[nfiles
] = malloc((unsigned)i
)) == NULL
) {
536 (void) fprintf(stderr
, "sed: Out of memory\n");
539 (void) strcpy(fname
[nfiles
], fnamebuf
);
540 if((rep
->r1
.fcode
= fopen(fname
[nfiles
], "w")) == NULL
) {
541 (void) fprintf(stderr
, "sed: Cannot create ");
542 perror(fname
[nfiles
]);
545 fcode
[nfiles
++] = rep
->r1
.fcode
;
549 rep
->r1
.command
= XCOM
;
553 rep
->r1
.command
= YCOM
;
556 p
= ycomp(rep
->r1
.re1
);
562 comperr("Too many commands, last: %s");
576 char *compsub(rhsbuf
)
584 if(p
> &respace
[RESIZE
-1])
586 if((*p
= *q
++) == '\\') {
588 if(p
> &respace
[RESIZE
-1])
591 if(*p
> nbra
+ '0' && *p
<= '9')
592 comperr("``\\digit'' out of range: %s");
602 comperr("Ending delimiter missing on substitution: %s");
624 while((t
= *q
++) != '\0') {
632 if((t
= *q
++) == '\0') {
644 comperr("Command line too long");
648 if((q
= saveq
) == 0) return(-1);
650 while((t
= *q
++) != '\0') {
658 if((t
= *q
++) == '\0') {
670 comperr("Command line too long");
675 while((t
= getc(fin
)) != EOF
) {
678 comperr("Command line too long");
685 if((t
= getc(fin
)) == EOF
)
692 perror("sed: Error reading pattern file");
698 char *address(expbuf
)
705 if (expbuf
> &respace
[RESIZE
-2])
712 if (*cp
== '/' || *cp
== '\\' ) {
716 return(comple((char *) 0, expbuf
, &respace
[RESIZE
-1], sseof
));
722 while(*rcp
>= '0' && *rcp
<= '9')
723 lno
= lno
*10 + *rcp
++ - '0';
726 if (expbuf
> &respace
[RESIZE
-3])
732 comperr("Too many line numbers: %s");
740 char *text(textbuf
, tbend
)
750 * Strip off indentation from text to be inserted.
752 while(*q
== '\t' || *q
== ' ') q
++;
757 return(NULL
); /* overflowed the buffer */
758 if((*p
= *q
++) == '\\')
766 * Strip off indentation from text to be inserted.
769 while(*q
== '\t' || *q
== ' ') q
++;
777 struct label
*search(ptr
)
784 if(strcmp(rp
->asc
, ptr
->asc
) == 0)
797 union reptr
*rptr
, *trptr
;
799 for(lptr
= labtab
; lptr
< lab
; lptr
++) {
801 if(lptr
->address
== 0) {
802 (void) fprintf(stderr
, "sed: Undefined label: %s\n", lptr
->asc
);
808 while(trptr
= rptr
->r2
.lb1
) {
809 rptr
->r2
.lb1
= lptr
->address
;
812 rptr
->r2
.lb1
= lptr
->address
;
826 if(ep
+ 0377 > &respace
[RESIZE
-1])
829 for(tsp
= cp
; (c
= *tsp
) != sseof
; tsp
++) {
832 if(c
== '\0' || c
== '\n')
833 comperr("Ending delimiter missing on string: %s");
837 while((c
= *sp
++) != sseof
) {
839 if(c
== '\\' && *sp
== 'n') {
843 if((ep
[c
] = *tsp
++) == '\\' && *tsp
== 'n') {
847 if(ep
[c
] == sseof
|| ep
[c
] == '\0')
848 comperr("Transform strings not the same size: %s");
852 comperr("Ending delimiter missing on string: %s");
854 comperr("Transform strings not the same size: %s");
858 for(i
= 0; i
< 0400; i
++)
868 (void) fprintf(stderr
, "sed: ");
869 (void) fprintf(stderr
, msg
, linebuf
);
870 (void) putc('\n', stderr
);