1 /* vi: set sw=4 ts=4: */
3 * Mini sed implementation for busybox
6 * Copyright (C) 1999,2000 by Lineo, inc.
7 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
9 * Modifications for addresses and append command have been
10 * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org>
12 * Copyright (C) 1999 Marco Pantaleoni.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 static const char sed_usage[] =
41 "sed [-n] -e script [file...]\n\n"
42 "Allowed sed scripts come in the following form:\n"
43 "\t'ADDR [!] COMMAND'\n\n"
44 "\twhere address ADDR can be:\n"
45 "\t NUMBER Match specified line number\n"
46 "\t $ Match last line\n"
47 "\t /REGEXP/ Match specified regexp\n"
48 "\t (! inverts the meaning of the match)\n\n"
49 "\tand COMMAND can be:\n"
50 "\t s/regexp/replacement/[igp]\n"
51 "\t which attempt to match regexp against the pattern space\n"
52 "\t and if successful replaces the matched portion with replacement.\n\n"
54 "\t which appends TEXT after the pattern space\n"
56 "-e\tadd the script to the commands to be executed\n"
57 "-n\tsuppress automatic printing of pattern space\n\n"
59 "This version of sed matches full regular expresions.\n";
61 "This version of sed matches strings (not full regular expresions).\n";
64 /* Flags & variables */
66 typedef enum { f_none, f_replace, f_append } sed_function;
70 static int addr_line = NO_LINE;
71 static char *addr_pattern = NULL;
72 static int negated = 0;
74 #define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0)
78 static inline int at_last(FILE * fp)
87 if ((ch = fgetc(fp)) == EOF)
94 static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
95 int ignoreCase, int printFlag, int quietFlag)
98 char haystack[BUFSIZE];
101 while (fgets(haystack, BUFSIZE - 1, fp)) {
104 doit = !find_match(haystack, addr_pattern, FALSE);
105 } else if (addr_line == NO_LINE)
107 else if (addr_line == LAST_LINE) {
111 if (line == addr_line)
118 replace_match(haystack, needle, newNeedle, ignoreCase);
120 if (foundOne == TRUE && printFlag == TRUE) {
121 fprintf(stdout, haystack);
125 if (quietFlag == FALSE) {
126 fprintf(stdout, haystack);
133 static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
135 char buffer[BUFSIZE];
138 while (fgets(buffer, BUFSIZE - 1, fp)) {
141 doit = !find_match(buffer, addr_pattern, FALSE);
142 } else if (addr_line == NO_LINE)
144 else if (addr_line == LAST_LINE) {
148 if (line == addr_line)
153 if (quietFlag == FALSE) {
154 fprintf(stdout, buffer);
157 fputs(appendline, stdout);
165 extern int sed_main(int argc, char **argv)
168 char *needle = NULL, *newNeedle = NULL;
171 int ignoreCase = FALSE;
172 int printFlag = FALSE;
173 int quietFlag = FALSE;
175 char *line_s = NULL, saved;
176 char *appendline = NULL;
178 sed_function sed_f = f_none;
193 while (*++cp && stopNow == FALSE) {
199 if (*(cp + 1) == 0 && --argc < 0) {
205 /* Read address if present */
208 addr_line = LAST_LINE;
211 if (isdigit(*cp)) { /* LINE ADDRESS */
219 addr_line = atoi(line_s);
222 } else if (*cp == '/') { /* PATTERN ADDRESS */
223 pos = addr_pattern = cp + 1;
224 pos = strchr(pos, '/');
242 case 's': /* REPLACE */
243 if (strlen(cp) <= 3 || *(cp + 1) != '/')
247 pos = needle = cp + 2;
250 pos = strchr(pos, '/');
254 if (*(pos - 1) == '\\') {
263 pos = strchr(pos, '/');
267 if (*(pos - 1) == '\\') {
291 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
294 case 'a': /* APPEND */
299 /* fprintf(stderr, "append '%s'\n", appendline); */
317 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
321 do_sed_append(stdin, appendline, quietFlag);
328 fp = fopen(name, "r");
338 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
342 do_sed_append(fp, appendline, quietFlag);