- /* go through every line in the file */
- do {
- char *next_line;
- sed_cmd_t *sed_cmd;
- int substituted = 0;
-
- /* Read one line in advance so we can act on the last line, the '$' address */
- next_line = bb_get_chomped_line_from_file(file);
-
- linenum++;
- altered = 0;
- force_print = 0;
-
- /* for every line, go through all the commands */
- for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
- int deleted = 0;
-
- /*
- * entry point into sedding...
- */
- int matched = (
- /* no range necessary */
- (sed_cmd->beg_line == 0 && sed_cmd->end_line == 0 &&
- sed_cmd->beg_match == NULL &&
- sed_cmd->end_match == NULL) ||
- /* this line number is the first address we're looking for */
- (sed_cmd->beg_line && (sed_cmd->beg_line == linenum)) ||
- /* this line matches our first address regex */
- (sed_cmd->beg_match && (regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0) == 0)) ||
- /* we are currently within the beginning & ending address range */
- still_in_range || ((sed_cmd->beg_line == -1) && (next_line == NULL))
- );
-
- if (sed_cmd->invert ^ matched) {
-
- /*
- * actual sedding
- */
- switch (sed_cmd->cmd) {
- case '=':
- printf("%d\n", linenum);
- break;
- case 'P': { /* Write the current pattern space upto the first newline */
- char *tmp = strchr(pattern_space, '\n');
- if (tmp) {
- *tmp = '\0';
- }
- }
- case 'p': /* Write the current pattern space to output */
- puts(pattern_space);
- break;
- case 'd':
- altered++;
- deleted = 1;
- break;
-
- case 's':
-
- /*
- * Some special cases for 's' printing to make it compliant with
- * GNU sed printing behavior (aka "The -n | s///p Matrix"):
- *
- * -n ONLY = never print anything regardless of any successful
- * substitution
- *
- * s///p ONLY = always print successful substitutions, even if
- * the pattern_space is going to be printed anyway (pattern_space
- * will be printed twice).
- *
- * -n AND s///p = print ONLY a successful substitution ONE TIME;
- * no other lines are printed - this is the reason why the 'p'
- * flag exists in the first place.
- */
-
-#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
- /* HACK: escape newlines twice so regex can match them */
- {
- int offset = 0;
- while(strchr(pattern_space + offset, '\n') != NULL) {
- char *tmp;
- pattern_space = xrealloc(pattern_space, strlen(pattern_space) + 2);
- tmp = strchr(pattern_space + offset, '\n');
- memmove(tmp + 1, tmp, strlen(tmp) + 1);
- tmp[0] = '\\';
- tmp[1] = 'n';
- offset = tmp - pattern_space + 2;
- }
- }
-#endif
- /* we print the pattern_space once, unless we were told to be quiet */
- substituted = do_subst_command(sed_cmd, &pattern_space);
-
-#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
- /* undo HACK: escape newlines twice so regex can match them */
- {
- char *tmp = pattern_space;
-
- while((tmp = strstr(tmp, "\\n")) != NULL) {
- memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
- tmp[0] = '\n';
- }
- }
-#endif
- altered |= substituted;
- if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) {
- force_print = 1;
- }