2 * Mini sed implementation for busybox
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
8 * Modifications for addresses and append command have been
9 * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org>
11 * Copyright (C) 1999 Marco Pantaleoni.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 static const char sed_usage[] =
40 "sed [-n] -e script [file...]\n\n"
41 "Allowed sed scripts come in the following form:\n"
42 "\t'ADDR [!] COMMAND'\n\n"
43 "\twhere address ADDR can be:\n"
44 "\t NUMBER Match specified line number\n"
45 "\t $ Match last line\n"
46 "\t /REGEXP/ Match specified regexp\n"
47 "\t (! inverts the meaning of the match)\n\n"
48 "\tand COMMAND can be:\n"
49 "\t s/regexp/replacement/[gp]\n"
50 "\t which attempt to match regexp against the pattern space\n"
51 "\t and if successful replaces the matched portion with replacement.\n\n"
53 "\t which appends TEXT after the pattern space\n"
55 "-e\tadd the script to the commands to be executed\n"
56 "-n\tsuppress automatic printing of pattern space\n\n"
58 "This version of sed matches full regular expresions.\n";
60 "This version of sed matches strings (not full regular expresions).\n";
63 /* Flags & variables */
65 typedef enum { f_none, f_replace, f_append } sed_function;
69 static int addr_line = NO_LINE;
70 static char *addr_pattern = NULL;
71 static int negated = 0;
73 #define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0)
77 static inline int at_last(FILE * fp)
85 if ((ch = fgetc(fp)) == EOF)
92 static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
93 int ignoreCase, int printFlag, int quietFlag)
96 char haystack[BUFSIZE];
99 while (fgets(haystack, BUFSIZE - 1, fp)) {
102 doit = !find_match(haystack, addr_pattern, FALSE);
103 } else if (addr_line == NO_LINE)
105 else if (addr_line == LAST_LINE) {
109 if (line == addr_line)
116 replace_match(haystack, needle, newNeedle, ignoreCase);
118 if (foundOne == TRUE && printFlag == TRUE) {
119 fprintf(stdout, haystack);
123 if (quietFlag == FALSE) {
124 fprintf(stdout, haystack);
131 static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
133 char buffer[BUFSIZE];
136 while (fgets(buffer, BUFSIZE - 1, fp)) {
139 doit = !find_match(buffer, addr_pattern, FALSE);
140 } else if (addr_line == NO_LINE)
142 else if (addr_line == LAST_LINE) {
146 if (line == addr_line)
151 if (quietFlag == FALSE) {
152 fprintf(stdout, buffer);
155 fputs(appendline, stdout);
163 extern int sed_main(int argc, char **argv)
166 char *needle = NULL, *newNeedle = NULL;
169 int ignoreCase = FALSE;
170 int printFlag = FALSE;
171 int quietFlag = FALSE;
173 char *line_s = NULL, saved;
174 char *appendline = NULL;
176 sed_function sed_f = f_none;
189 while (*++cp && stopNow == FALSE) {
195 if (*(cp + 1) == 0 && --argc < 0) {
201 /* Read address if present */
204 addr_line = LAST_LINE;
207 if (isdigit(*cp)) { /* LINE ADDRESS */
215 addr_line = atoi(line_s);
218 } else if (*cp == '/') { /* PATTERN ADDRESS */
219 pos = addr_pattern = cp + 1;
220 pos = strchr(pos, '/');
238 case 's': /* REPLACE */
239 if (strlen(cp) <= 3 || *(cp + 1) != '/')
243 pos = needle = cp + 2;
246 pos = strchr(pos, '/');
250 if (*(pos - 1) == '\\') {
259 pos = strchr(pos, '/');
263 if (*(pos - 1) == '\\') {
287 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
290 case 'a': /* APPEND */
295 /* fprintf(stderr, "append '%s'\n", appendline); */
313 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
317 do_sed_append(stdin, appendline, quietFlag);
324 fp = fopen(name, "r");
334 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
338 do_sed_append(fp, appendline, quietFlag);