mirror of
https://git.busybox.net/busybox.git
synced 2024-11-24 06:03:27 +08:00
add to testsuite and fix yet another sed corner case
This commit is contained in:
parent
c562bb7487
commit
86811803e3
@ -724,6 +724,7 @@ static void add_input_file(FILE *file)
|
|||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
NO_EOL_CHAR = 1,
|
NO_EOL_CHAR = 1,
|
||||||
|
LAST_IS_NUL = 2,
|
||||||
};
|
};
|
||||||
static char *get_next_line(char *gets_char)
|
static char *get_next_line(char *gets_char)
|
||||||
{
|
{
|
||||||
@ -737,17 +738,24 @@ static char *get_next_line(char *gets_char)
|
|||||||
* doesn't end with either '\n' or '\0' */
|
* doesn't end with either '\n' or '\0' */
|
||||||
gc = NO_EOL_CHAR;
|
gc = NO_EOL_CHAR;
|
||||||
while (bbg.current_input_file < bbg.input_file_count) {
|
while (bbg.current_input_file < bbg.input_file_count) {
|
||||||
|
FILE *fp = bbg.input_file_list[bbg.current_input_file];
|
||||||
/* Read line up to a newline or NUL byte, inclusive,
|
/* Read line up to a newline or NUL byte, inclusive,
|
||||||
* return malloc'ed char[]. length of the chunk read
|
* return malloc'ed char[]. length of the chunk read
|
||||||
* is stored in len. NULL if EOF/error */
|
* is stored in len. NULL if EOF/error */
|
||||||
temp = bb_get_chunk_from_file(
|
temp = bb_get_chunk_from_file(fp, &len);
|
||||||
bbg.input_file_list[bbg.current_input_file], &len);
|
|
||||||
if (temp) {
|
if (temp) {
|
||||||
/* len > 0 here, it's ok to do temp[len-1] */
|
/* len > 0 here, it's ok to do temp[len-1] */
|
||||||
char c = temp[len-1];
|
char c = temp[len-1];
|
||||||
if (c == '\n' || c == '\0') {
|
if (c == '\n' || c == '\0') {
|
||||||
temp[len-1] = '\0';
|
temp[len-1] = '\0';
|
||||||
gc = c;
|
gc = c;
|
||||||
|
if (c == '\0') {
|
||||||
|
int ch = fgetc(fp);
|
||||||
|
if (ch != EOF)
|
||||||
|
ungetc(ch, fp);
|
||||||
|
else
|
||||||
|
gc = LAST_IS_NUL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* else we put NO_EOL_CHAR into *gets_char */
|
/* else we put NO_EOL_CHAR into *gets_char */
|
||||||
break;
|
break;
|
||||||
@ -761,7 +769,8 @@ static char *get_next_line(char *gets_char)
|
|||||||
* (note: *no* newline after "b bang"!) */
|
* (note: *no* newline after "b bang"!) */
|
||||||
}
|
}
|
||||||
/* Close this file and advance to next one */
|
/* Close this file and advance to next one */
|
||||||
fclose(bbg.input_file_list[bbg.current_input_file++]);
|
fclose(fp);
|
||||||
|
bbg.current_input_file++;
|
||||||
}
|
}
|
||||||
*gets_char = gc;
|
*gets_char = gc;
|
||||||
return temp;
|
return temp;
|
||||||
@ -785,20 +794,29 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
|
|||||||
{
|
{
|
||||||
char lpc = *last_puts_char;
|
char lpc = *last_puts_char;
|
||||||
|
|
||||||
/* Is this a first line from new file
|
/* Need to insert a '\n' between two files because first file's
|
||||||
* and old file didn't end with '\n' or '\0'? */
|
* last line wasn't terminated? */
|
||||||
if (lpc != '\n' && lpc != '\0') {
|
if (lpc != '\n' && lpc != '\0') {
|
||||||
fputc('\n', file);
|
fputc('\n', file);
|
||||||
lpc = '\n';
|
lpc = '\n';
|
||||||
}
|
}
|
||||||
fputs(s, file);
|
fputs(s, file);
|
||||||
|
|
||||||
/* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */
|
/* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */
|
||||||
if (s[0])
|
if (s[0])
|
||||||
lpc = 'x';
|
lpc = 'x';
|
||||||
if (last_gets_char != NO_EOL_CHAR) { /* had trailing '\n' or '\0'? */
|
|
||||||
|
/* had trailing '\0' and it was last char of file? */
|
||||||
|
if (last_gets_char == LAST_IS_NUL) {
|
||||||
|
fputc('\0', file);
|
||||||
|
lpc = 'x'; /* */
|
||||||
|
} else
|
||||||
|
/* had trailing '\n' or '\0'? */
|
||||||
|
if (last_gets_char != NO_EOL_CHAR) {
|
||||||
fputc(last_gets_char, file);
|
fputc(last_gets_char, file);
|
||||||
lpc = last_gets_char;
|
lpc = last_gets_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ferror(file)) {
|
if (ferror(file)) {
|
||||||
xfunc_error_retval = 4; /* It's what gnu sed exits with... */
|
xfunc_error_retval = 4; /* It's what gnu sed exits with... */
|
||||||
bb_error_msg_and_die(bb_msg_write_error);
|
bb_error_msg_and_die(bb_msg_write_error);
|
||||||
|
@ -143,6 +143,9 @@ testing "sed subst+write" \
|
|||||||
"sed -e 's/i/z/' -e 'woutputw' input -; echo -n X; cat outputw" \
|
"sed -e 's/i/z/' -e 'woutputw' input -; echo -n X; cat outputw" \
|
||||||
"thzngy\nagaznXthzngy\nagazn" "thingy" "again"
|
"thzngy\nagaznXthzngy\nagazn" "thingy" "again"
|
||||||
rm outputw
|
rm outputw
|
||||||
|
testing "sed trailing NUL" \
|
||||||
|
"sed 's/i/z/' input -" \
|
||||||
|
"a\0b\0\nc" "a\0b\0" "c"
|
||||||
|
|
||||||
# Test end-of-file matching behavior
|
# Test end-of-file matching behavior
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user