diff options
Diffstat (limited to 'sed.c')
-rw-r--r-- | sed.c | 522 |
1 files changed, 262 insertions, 260 deletions
@@ -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); } |