summaryrefslogtreecommitdiff
path: root/sed.c
diff options
context:
space:
mode:
Diffstat (limited to 'sed.c')
-rw-r--r--sed.c522
1 files changed, 262 insertions, 260 deletions
diff --git a/sed.c b/sed.c
index 2577724..3a7737e 100644
--- a/sed.c
+++ b/sed.c
@@ -1,3 +1,4 @@
+/* vi: set sw=4 ts=4: */
/*
* Mini sed implementation for busybox
*
@@ -37,27 +38,27 @@
#include <ctype.h>
static const char sed_usage[] =
- "sed [-n] -e script [file...]\n\n"
- "Allowed sed scripts come in the following form:\n"
- "\t'ADDR [!] COMMAND'\n\n"
- "\twhere address ADDR can be:\n"
- "\t NUMBER Match specified line number\n"
- "\t $ Match last line\n"
- "\t /REGEXP/ Match specified regexp\n"
- "\t (! inverts the meaning of the match)\n\n"
- "\tand COMMAND can be:\n"
- "\t s/regexp/replacement/[igp]\n"
- "\t which attempt to match regexp against the pattern space\n"
- "\t and if successful replaces the matched portion with replacement.\n\n"
- "\t aTEXT\n"
- "\t which appends TEXT after the pattern space\n"
- "Options:\n"
- "-e\tadd the script to the commands to be executed\n"
- "-n\tsuppress automatic printing of pattern space\n\n"
+ "sed [-n] -e script [file...]\n\n"
+ "Allowed sed scripts come in the following form:\n"
+ "\t'ADDR [!] COMMAND'\n\n"
+ "\twhere address ADDR can be:\n"
+ "\t NUMBER Match specified line number\n"
+ "\t $ Match last line\n"
+ "\t /REGEXP/ Match specified regexp\n"
+ "\t (! inverts the meaning of the match)\n\n"
+ "\tand COMMAND can be:\n"
+ "\t s/regexp/replacement/[igp]\n"
+ "\t which attempt to match regexp against the pattern space\n"
+ "\t and if successful replaces the matched portion with replacement.\n\n"
+ "\t aTEXT\n"
+ "\t which appends TEXT after the pattern space\n"
+ "Options:\n"
+ "-e\tadd the script to the commands to be executed\n"
+ "-n\tsuppress automatic printing of pattern space\n\n"
#if defined BB_REGEXP
- "This version of sed matches full regular expresions.\n";
+ "This version of sed matches full regular expresions.\n";
#else
- "This version of sed matches strings (not full regular expresions).\n";
+ "This version of sed matches strings (not full regular expresions).\n";
#endif
/* Flags & variables */
@@ -76,276 +77,277 @@ static int negated = 0;
static inline int at_last(FILE * fp)
{
- int res = 0;
-
- if (feof(fp))
- return 1;
- else {
- char ch;
- if ((ch = fgetc(fp)) == EOF)
- res++;
- ungetc(ch, fp);
- }
- return res;
+ int res = 0;
+
+ if (feof(fp))
+ return 1;
+ else {
+ char ch;
+
+ if ((ch = fgetc(fp)) == EOF)
+ res++;
+ ungetc(ch, fp);
+ }
+ return res;
}
static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
- int ignoreCase, int printFlag, int quietFlag)
+ int ignoreCase, int printFlag, int quietFlag)
{
- int foundOne = FALSE;
- char haystack[BUFSIZE];
- int line = 1, doit;
-
- while (fgets(haystack, BUFSIZE - 1, fp)) {
- doit = 0;
- if (addr_pattern) {
- doit = !find_match(haystack, addr_pattern, FALSE);
- } else if (addr_line == NO_LINE)
- doit = 1;
- else if (addr_line == LAST_LINE) {
- if (at_last(fp))
- doit = 1;
- } else {
- if (line == addr_line)
- doit = 1;
- }
- if (negated)
- doit = 1 - doit;
- if (doit) {
- foundOne =
- replace_match(haystack, needle, newNeedle, ignoreCase);
-
- if (foundOne == TRUE && printFlag == TRUE) {
- fprintf(stdout, haystack);
- }
- }
+ int foundOne = FALSE;
+ char haystack[BUFSIZE];
+ int line = 1, doit;
+
+ while (fgets(haystack, BUFSIZE - 1, fp)) {
+ doit = 0;
+ if (addr_pattern) {
+ doit = !find_match(haystack, addr_pattern, FALSE);
+ } else if (addr_line == NO_LINE)
+ doit = 1;
+ else if (addr_line == LAST_LINE) {
+ if (at_last(fp))
+ doit = 1;
+ } else {
+ if (line == addr_line)
+ doit = 1;
+ }
+ if (negated)
+ doit = 1 - doit;
+ if (doit) {
+ foundOne =
+ replace_match(haystack, needle, newNeedle, ignoreCase);
+
+ if (foundOne == TRUE && printFlag == TRUE) {
+ fprintf(stdout, haystack);
+ }
+ }
- if (quietFlag == FALSE) {
- fprintf(stdout, haystack);
- }
+ if (quietFlag == FALSE) {
+ fprintf(stdout, haystack);
+ }
- line++;
- }
+ line++;
+ }
}
static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
{
- char buffer[BUFSIZE];
- int line = 1, doit;
-
- while (fgets(buffer, BUFSIZE - 1, fp)) {
- doit = 0;
- if (addr_pattern) {
- doit = !find_match(buffer, addr_pattern, FALSE);
- } else if (addr_line == NO_LINE)
- doit = 1;
- else if (addr_line == LAST_LINE) {
- if (at_last(fp))
- doit = 1;
- } else {
- if (line == addr_line)
- doit = 1;
- }
- if (negated)
- doit = 1 - doit;
- if (quietFlag == FALSE) {
- fprintf(stdout, buffer);
- }
- if (doit) {
- fputs(appendline, stdout);
- fputc('\n', stdout);
- }
+ char buffer[BUFSIZE];
+ int line = 1, doit;
+
+ while (fgets(buffer, BUFSIZE - 1, fp)) {
+ doit = 0;
+ if (addr_pattern) {
+ doit = !find_match(buffer, addr_pattern, FALSE);
+ } else if (addr_line == NO_LINE)
+ doit = 1;
+ else if (addr_line == LAST_LINE) {
+ if (at_last(fp))
+ doit = 1;
+ } else {
+ if (line == addr_line)
+ doit = 1;
+ }
+ if (negated)
+ doit = 1 - doit;
+ if (quietFlag == FALSE) {
+ fprintf(stdout, buffer);
+ }
+ if (doit) {
+ fputs(appendline, stdout);
+ fputc('\n', stdout);
+ }
- line++;
- }
+ line++;
+ }
}
extern int sed_main(int argc, char **argv)
{
- FILE *fp;
- char *needle = NULL, *newNeedle = NULL;
- char *name;
- char *cp;
- int ignoreCase = FALSE;
- int printFlag = FALSE;
- int quietFlag = FALSE;
- int stopNow;
- char *line_s = NULL, saved;
- char *appendline = NULL;
- char *pos;
- sed_function sed_f = f_none;
-
- argc--;
- argv++;
- if (argc < 1) {
- usage(sed_usage);
- }
-
- if (**argv == '-') {
- argc--;
- cp = *argv++;
- stopNow = FALSE;
-
- while (*++cp && stopNow == FALSE) {
- switch (*cp) {
- case 'n':
- quietFlag = TRUE;
- break;
- case 'e':
- if (*(cp + 1) == 0 && --argc < 0) {
- usage(sed_usage);
- }
- if (*++cp != 's')
- cp = *argv++;
-
- /* Read address if present */
- SKIPSPACES(cp);
- if (*cp == '$') {
- addr_line = LAST_LINE;
- cp++;
- } else {
- if (isdigit(*cp)) { /* LINE ADDRESS */
- line_s = cp;
- while (isdigit(*cp))
- cp++;
- if (cp > line_s) {
- /* numeric line */
- saved = *cp;
- *cp = '\0';
- addr_line = atoi(line_s);
- *cp = saved;
- }
- } else if (*cp == '/') { /* PATTERN ADDRESS */
- pos = addr_pattern = cp + 1;
- pos = strchr(pos, '/');
- if (!pos)
- usage(sed_usage);
- *pos = '\0';
- cp = pos + 1;
- }
- }
-
- SKIPSPACES(cp);
- if (*cp == '!') {
- negated++;
- cp++;
- }
+ FILE *fp;
+ char *needle = NULL, *newNeedle = NULL;
+ char *name;
+ char *cp;
+ int ignoreCase = FALSE;
+ int printFlag = FALSE;
+ int quietFlag = FALSE;
+ int stopNow;
+ char *line_s = NULL, saved;
+ char *appendline = NULL;
+ char *pos;
+ sed_function sed_f = f_none;
- /* Read command */
+ argc--;
+ argv++;
+ if (argc < 1) {
+ usage(sed_usage);
+ }
- SKIPSPACES(cp);
- switch (*cp) {
- case 's': /* REPLACE */
- if (strlen(cp) <= 3 || *(cp + 1) != '/')
- break;
- sed_f = f_replace;
+ if (**argv == '-') {
+ argc--;
+ cp = *argv++;
+ stopNow = FALSE;
- pos = needle = cp + 2;
+ while (*++cp && stopNow == FALSE) {
+ switch (*cp) {
+ case 'n':
+ quietFlag = TRUE;
+ break;
+ case 'e':
+ if (*(cp + 1) == 0 && --argc < 0) {
+ usage(sed_usage);
+ }
+ if (*++cp != 's')
+ cp = *argv++;
+
+ /* Read address if present */
+ SKIPSPACES(cp);
+ if (*cp == '$') {
+ addr_line = LAST_LINE;
+ cp++;
+ } else {
+ if (isdigit(*cp)) { /* LINE ADDRESS */
+ line_s = cp;
+ while (isdigit(*cp))
+ cp++;
+ if (cp > line_s) {
+ /* numeric line */
+ saved = *cp;
+ *cp = '\0';
+ addr_line = atoi(line_s);
+ *cp = saved;
+ }
+ } else if (*cp == '/') { /* PATTERN ADDRESS */
+ pos = addr_pattern = cp + 1;
+ pos = strchr(pos, '/');
+ if (!pos)
+ usage(sed_usage);
+ *pos = '\0';
+ cp = pos + 1;
+ }
+ }
+
+ SKIPSPACES(cp);
+ if (*cp == '!') {
+ negated++;
+ cp++;
+ }
+
+ /* Read command */
+
+ SKIPSPACES(cp);
+ switch (*cp) {
+ case 's': /* REPLACE */
+ if (strlen(cp) <= 3 || *(cp + 1) != '/')
+ break;
+ sed_f = f_replace;
+
+ pos = needle = cp + 2;
+
+ for (;;) {
+ pos = strchr(pos, '/');
+ if (pos == NULL) {
+ usage(sed_usage);
+ }
+ if (*(pos - 1) == '\\') {
+ pos++;
+ continue;
+ }
+ break;
+ }
+ *pos = 0;
+ newNeedle = ++pos;
+ for (;;) {
+ pos = strchr(pos, '/');
+ if (pos == NULL) {
+ usage(sed_usage);
+ }
+ if (*(pos - 1) == '\\') {
+ pos++;
+ continue;
+ }
+ break;
+ }
+ *pos = 0;
+ if (pos + 2 != 0) {
+ while (*++pos) {
+ switch (*pos) {
+ case 'i':
+ ignoreCase = TRUE;
+ break;
+ case 'p':
+ printFlag = TRUE;
+ break;
+ case 'g':
+ break;
+ default:
+ usage(sed_usage);
+ }
+ }
+ }
+ cp = pos;
+ /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
+ break;
+
+ case 'a': /* APPEND */
+ if (strlen(cp) < 2)
+ break;
+ sed_f = f_append;
+ appendline = ++cp;
+ /* fprintf(stderr, "append '%s'\n", appendline); */
+ break;
+ }
+
+ stopNow = TRUE;
+ break;
- for (;;) {
- pos = strchr(pos, '/');
- if (pos == NULL) {
- usage(sed_usage);
- }
- if (*(pos - 1) == '\\') {
- pos++;
- continue;
+ default:
+ usage(sed_usage);
}
+ }
+ }
+
+ if (argc == 0) {
+ switch (sed_f) {
+ case f_none:
break;
- }
- *pos = 0;
- newNeedle = ++pos;
- for (;;) {
- pos = strchr(pos, '/');
- if (pos == NULL) {
- usage(sed_usage);
- }
- if (*(pos - 1) == '\\') {
- pos++;
- continue;
- }
+ case f_replace:
+ do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
+ quietFlag);
break;
- }
- *pos = 0;
- if (pos + 2 != 0) {
- while (*++pos) {
- switch (*pos) {
- case 'i':
- ignoreCase = TRUE;
+ case f_append:
+ do_sed_append(stdin, appendline, quietFlag);
+ break;
+ }
+ } else {
+ while (argc-- > 0) {
+ name = *argv++;
+
+ fp = fopen(name, "r");
+ if (fp == NULL) {
+ perror(name);
+ continue;
+ }
+
+ switch (sed_f) {
+ case f_none:
break;
- case 'p':
- printFlag = TRUE;
+ case f_replace:
+ do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
+ quietFlag);
break;
- case 'g':
+ case f_append:
+ do_sed_append(fp, appendline, quietFlag);
break;
- default:
- usage(sed_usage);
- }
}
- }
- cp = pos;
- /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
- break;
- case 'a': /* APPEND */
- if (strlen(cp) < 2)
- break;
- sed_f = f_append;
- appendline = ++cp;
- /* fprintf(stderr, "append '%s'\n", appendline); */
- break;
- }
+ if (ferror(fp))
+ perror(name);
- stopNow = TRUE;
- break;
-
- default:
- usage(sed_usage);
- }
- }
- }
-
- if (argc == 0) {
- switch (sed_f) {
- case f_none:
- break;
- case f_replace:
- do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
- quietFlag);
- break;
- case f_append:
- do_sed_append(stdin, appendline, quietFlag);
- break;
- }
- } else {
- while (argc-- > 0) {
- name = *argv++;
-
- fp = fopen(name, "r");
- if (fp == NULL) {
- perror(name);
- continue;
- }
-
- switch (sed_f) {
- case f_none:
- break;
- case f_replace:
- do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
- quietFlag);
- break;
- case f_append:
- do_sed_append(fp, appendline, quietFlag);
- break;
- }
-
- if (ferror(fp))
- perror(name);
-
- fclose(fp);
+ fclose(fp);
+ }
}
- }
- exit(TRUE);
+ exit(TRUE);
}