f0a6a3b48c50392d4e2f9d2a03b0a1c3ab70f040
[oweals/busybox.git] / 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 printFlag=FALSE;
61     int quietFlag=FALSE;
62     int stopNow;
63     char *haystack;
64
65     argc--;
66     argv++;
67     if (argc < 1) {
68         usage(sed_usage);
69     }
70
71     if (**argv == '-') {
72         argc--;
73         cp = *argv++;
74         stopNow=FALSE;
75
76         while (*++cp && stopNow==FALSE)
77             switch (*cp) {
78             case 'n':
79                 quietFlag = TRUE;
80                 break;
81             case 'e':
82                 if (*(cp+1)==0 && --argc < 0) {
83                     fprintf(stderr, "A\n");
84                     usage( sed_usage);
85                 }
86                 cp = *argv++;
87                 while( *cp ) {
88                     if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
89                         char* pos=needle=cp+2;
90                         for(;;) {
91                             pos = strchr(pos, '/');
92                             if (pos==NULL) {
93                                 fprintf(stderr, "B\n");
94                                 usage( sed_usage);
95                             }
96                             if (*(pos-1) == '\\') {
97                                 pos++;
98                                 continue;
99                             }
100                             break;
101                         }
102                         *pos=0;
103                         newNeedle=++pos;
104                         for(;;) {
105                             pos = strchr(pos, '/');
106                             if (pos==NULL) {
107                                 fprintf(stderr, "C\n");
108                                 usage( sed_usage);
109                             }
110                             if (*(pos-1) == '\\') {
111                                 pos++;
112                                 continue;
113                             }
114                             break;
115                         }
116                         *pos=0;
117                         if (pos+2 != 0) {
118                             while (*++pos) {
119                                 fprintf(stderr, "pos='%s'\n", pos);
120                                 switch (*pos) {
121                                     case 'i':
122                                         ignoreCase=TRUE;
123                                         break;
124                                     case 'p':
125                                         printFlag=TRUE;
126                                         break;
127                                     case 'g':
128                                         break;
129                                     default:
130                                         usage( sed_usage);
131                                 }
132                             }
133                         }
134                     }
135                     cp++;
136                 }
137                 fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
138                 stopNow=TRUE;
139                 break;
140
141             default:
142                 fprintf(stderr, "D\n");
143                 usage(sed_usage);
144             }
145     }
146
147     while (argc-- > 0) {
148         name = *argv++;
149
150         fp = fopen (name, "r");
151         if (fp == NULL) {
152             perror (name);
153             continue;
154         }
155
156         haystack = (char*)malloc( 1024);
157         while (fgets (haystack, 1023, fp)) {
158
159             foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
160             if (foundOne==TRUE && printFlag==TRUE)
161                     fputs (haystack, stdout);
162             if (quietFlag==FALSE)
163                 fputs (haystack, stdout);
164             /* Avoid any mem leaks */
165             free(haystack);
166             haystack = (char*)malloc( BUF_SIZE);
167         }
168
169         if (ferror (fp))
170             perror (name);
171
172         fclose (fp);
173     }
174     exit( TRUE);
175 }
176
177
178 /* END CODE */
179
180