← Commit list

2570b43e8

Glenn L McGrath
Glenn L McGrath
2003-09-16
FAILED Duration: 78s

Subject

Configuration option to define wether to follows GNU sed's behaviour or the posix standard. Put the cleanup code back the way it was.

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

editors/Config.in+13 -0
@@ -42,6 +42,19 @@ config CONFIG_FEATURE_SED_EMBEDED_NEWLINE
It works by translating '\n' to "\n" and back.
It may introduce unexpected results if you use "\n" in your text.
+config CONFIG_FEATURE_SED_GNU_COMPATABILITY
+ bool " Behave consistent with GNU sed"
+ default y
+ depends on CONFIG_SED
+ help
+ Where GNU sed doesnt follow the posix standard, do as GNU sed does.
+ Current difference are in
+ - N command with odd number of lines (see GNU sed info page)
+ - Blanks before substitution flags eg.
+ GNU sed interprets 's/a/b/ g' as 's/a/b/g'
+ Standard says 's/a/b/ g' should be 's/a/b/;g'
+ - GNU sed allows blanks between a '!' and the function.
+
config CONFIG_VI
bool "vi"
default n
editors/sed.c+36 -26
@@ -45,9 +45,11 @@
- GNU extensions
- and more.
- Bugs:
-
- - lots
+ Todo:
+
+ - Create a wrapper around regex to make libc's regex conform with sed
+ - Fix bugs
+
Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html
*/
@@ -298,7 +300,15 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
}
/* process the flags */
- while (substr[++idx]) {
+#ifndef CONFIG_FEATURE_SED_GNU_COMPATABILITY
+ idx++;
+#else
+ /* GNU sed allows blanks before the flag, this can lead to an incosistent
+ * interpretation of 's/a/b/ g' as being either 's/a/b/g' or 's/a/b/;g'.
+ * which results in very different behaviour.
+ */
+ while (substr[++idx])
+#endif
switch (substr[idx]) {
case 'g':
if (match[0] != '^') {
@@ -312,16 +322,20 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
case 'p':
sed_cmd->sub_p = 1;
break;
+#ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY
default:
/* any whitespace or semicolon trailing after a s/// is ok */
if (strchr(semicolon_whitespace, substr[idx]))
goto out;
- /* else */
bb_error_msg_and_die("bad option in substitution expression");
+#endif
}
- }
- out:
+#ifndef CONFIG_FEATURE_SED_GNU_COMPATABILITY
+ idx++;
+#else
+out:
+#endif
/* compile the match string into a regex */
if (*match != '\0') {
/* If match is empty, we use last regex used at runtime */
@@ -556,15 +570,12 @@ static char *add_cmd(char *cmdstr)
sed_cmd->invert = 1;
cmdstr++;
-#ifdef SED_FEATURE_STRICT_CHECKING
+#ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY
/* According to the spec
* It is unspecified whether <blank>s can follow a '!' character,
* and conforming applications shall not follow a '!' character
* with <blank>s.
*/
- if (isblank(cmdstr[idx]) {
- bb_error_msg_and_die("blank follows '!'");}
-#else
/* skip whitespace before the command */
while (isspace(*cmdstr)) {
cmdstr++;
@@ -931,7 +942,6 @@ static void process_file(FILE * file)
}
/* we also print the line if we were given the 'p' flag
* (this is quite possibly the second printing) */
-// if ((sed_cmd->sub_p) && (!altered || substituted)) {
if ((sed_cmd->sub_p) && (altered || substituted)) {
puts(pattern_space);
}
@@ -1007,20 +1017,25 @@ static void process_file(FILE * file)
}
break;
case 'N': /* Append the next line to the current line */
- if (next_line) {
- pattern_space =
- realloc(pattern_space,
- strlen(pattern_space) + strlen(next_line) + 2);
- strcat(pattern_space, "\n");
- strcat(pattern_space, next_line);
- next_line = bb_get_chomped_line_from_file(file);
- linenum++;
- } else {
+ if (next_line == NULL) {
/* Jump to end of script and exist */
deleted = 1;
free(next_line);
+#ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY
+ /* GNU sed will add the newline character
+ * The GNU sed info page labels this as a bug that wont be fixed
+ */
+ next_line = calloc(1,1);
+#else
next_line = NULL;
+ break;
+#endif
}
+ pattern_space = realloc(pattern_space, strlen(pattern_space) + strlen(next_line) + 2);
+ strcat(pattern_space, "\n");
+ strcat(pattern_space, next_line);
+ next_line = bb_get_chomped_line_from_file(file);
+ linenum++;
break;
case 't':
if (substituted)
@@ -1164,12 +1179,10 @@ extern int sed_main(int argc, char **argv)
{
int opt, status = EXIT_SUCCESS;
-#if 0 /* This doesnt seem to be working */
#ifdef CONFIG_FEATURE_CLEAN_UP
/* destroy command strings on exit */
if (atexit(destroy_cmd_strs) == -1)
bb_perror_msg_and_die("atexit");
-#endif
#endif
/* do normal option parsing */
@@ -1223,8 +1236,5 @@ extern int sed_main(int argc, char **argv)
}
}
-#ifdef CONFIG_FEATURE_CLEAN_UP
- destroy_cmd_strs();
-#endif
return status;
}
libbb/get_line_from_file.c+1 -2
@@ -40,7 +40,7 @@ static char *private_get_line_from_file(FILE *file, int c)
while ((ch = getc(file)) != EOF) {
/* grow the line buffer as necessary */
- if (idx > linebufsz-2) {
+ if (idx > linebufsz - 2) {
linebuf = xrealloc(linebuf, linebufsz += GROWBY);
}
linebuf[idx++] = (char)ch;
@@ -51,7 +51,6 @@ static char *private_get_line_from_file(FILE *file, int c)
break;
}
}
-
if (linebuf) {
if (ferror(file)) {
free(linebuf);
testsuite/sed/sed-append-next-line+6 -1
@@ -1,4 +1,6 @@
-busybox sed -n 'N;p'>output <<EOF
+# XFAIL
+# This will fail if CONFIG_FEATURE_SED_GNU_COMPATABILITY is defined
+busybox sed 'N;p'>output <<EOF
a
b
c
@@ -6,4 +8,7 @@ EOF
cmp -s output - <<EOF
a
b
+a
+b
+c
EOF
testsuite/sed/sed-append-next-line-gnu+14 -0
@@ -0,0 +1,14 @@
+# FEATURE: CONFIG_FEATURE_SED_GNU_COMPATABILITY
+busybox sed 'N;p'>output <<EOF
+a
+b
+c
+EOF
+cmp -s output - <<EOF
+a
+b
+a
+b
+c
+
+EOF