a3e635d3a36990b1a53e2d5b691c5c5be4450341
[oweals/busybox.git] / editors / sed.c
1 /*
2  * Mini sed implementation for busybox
3  *
4  *
5  * Copyright (C) 1999 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 #include "internal.h"
25 #include "regexp.h"
26 #include <stdio.h>
27 #include <dirent.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <signal.h>
31 #include <time.h>
32 #include <ctype.h>
33
34 static const char sed_usage[] = 
35 "sed [-n] [-e script] [file...]\n"
36 "Allowed scripts come in the following form:\n\n"
37 "'s/regexp/replacement/[gp]'\n"
38 "\tattempt to match regexp against the pattern space\n"
39 "\tand if successful replaces the matched portion with replacement.\n\n"
40 "Options:\n"
41 "-e\tadd the script to the commands to be executed\n"
42 "-n\tsuppress automatic printing of pattern space\n\n"
43 #if defined BB_REGEXP
44 "This version of sed matches full regexps.\n";
45 #else
46 "This version of sed matches strings (not full regexps).\n";
47 #endif
48
49
50
51
52 extern int sed_main (int argc, char **argv)
53 {
54     FILE *fp;
55     char *needle=NULL, *newNeedle=NULL;
56     char *name;
57     char *cp;
58     int ignoreCase=FALSE;
59     int foundOne=FALSE;
60     int noprintFlag=FALSE;
61     int stopNow;
62     char *haystack;
63
64     argc--;
65     argv++;
66     if (argc < 1) {
67         usage(sed_usage);
68     }
69
70     if (**argv == '-') {
71         argc--;
72         cp = *argv++;
73         stopNow=FALSE;
74
75         while (*++cp && stopNow==FALSE)
76             switch (*cp) {
77             case 'n':
78                 noprintFlag = TRUE;
79                 break;
80             case 'e':
81                 if (*(cp+1)==0 && --argc < 0) {
82                     fprintf(stderr, "A\n");
83                     usage( sed_usage);
84                 }
85                 cp = *argv++;
86                 while( *cp ) {
87                     if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
88                         char* pos=needle=cp+2;
89                         for(;;) {
90                             pos = strchr(pos, '/');
91                             if (pos==NULL) {
92                                 fprintf(stderr, "B\n");
93                                 usage( sed_usage);
94                             }
95                             if (*(pos-1) == '\\') {
96                                 pos++;
97                                 continue;
98                             }
99                             break;
100                         }
101                         *pos=0;
102                         newNeedle=++pos;
103                         for(;;) {
104                             pos = strchr(pos, '/');
105                             if (pos==NULL) {
106                                 fprintf(stderr, "C\n");
107                                 usage( sed_usage);
108                             }
109                             if (*(pos-1) == '\\') {
110                                 pos++;
111                                 continue;
112                             }
113                             break;
114                         }
115                         *pos=0;
116                     }
117                     cp++;
118                 }
119                 fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
120                 stopNow=TRUE;
121                 break;
122
123             default:
124                 fprintf(stderr, "D\n");
125                 usage(sed_usage);
126             }
127     }
128
129     fprintf(stderr, "argc=%d\n", argc);
130     while (argc-- > 0) {
131         name = *argv++;
132
133         fp = fopen (name, "r");
134         if (fp == NULL) {
135             perror (name);
136             continue;
137         }
138         fprintf(stderr, "filename is '%s'\n", name);
139
140         haystack = (char*)malloc( 80);
141         while (fgets (haystack, sizeof (haystack), fp)) {
142
143             foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
144             if (noprintFlag==TRUE && foundOne==TRUE)
145                 fputs (haystack, stdout);
146             else
147                 fputs (haystack, stdout);
148             /* Avoid any mem leaks */
149             free(haystack);
150             haystack = (char*)malloc( BUF_SIZE);
151         }
152
153         if (ferror (fp))
154             perror (name);
155
156         fclose (fp);
157     }
158     exit( TRUE);
159 }
160
161
162 /* END CODE */
163
164