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 {
|
||||
NO_EOL_CHAR = 1,
|
||||
LAST_IS_NUL = 2,
|
||||
};
|
||||
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' */
|
||||
gc = NO_EOL_CHAR;
|
||||
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,
|
||||
* return malloc'ed char[]. length of the chunk read
|
||||
* is stored in len. NULL if EOF/error */
|
||||
temp = bb_get_chunk_from_file(
|
||||
bbg.input_file_list[bbg.current_input_file], &len);
|
||||
temp = bb_get_chunk_from_file(fp, &len);
|
||||
if (temp) {
|
||||
/* len > 0 here, it's ok to do temp[len-1] */
|
||||
char c = temp[len-1];
|
||||
if (c == '\n' || c == '\0') {
|
||||
temp[len-1] = '\0';
|
||||
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 */
|
||||
break;
|
||||
@ -761,7 +769,8 @@ static char *get_next_line(char *gets_char)
|
||||
* (note: *no* newline after "b bang"!) */
|
||||
}
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
/* Is this a first line from new file
|
||||
* and old file didn't end with '\n' or '\0'? */
|
||||
/* Need to insert a '\n' between two files because first file's
|
||||
* last line wasn't terminated? */
|
||||
if (lpc != '\n' && lpc != '\0') {
|
||||
fputc('\n', file);
|
||||
lpc = '\n';
|
||||
}
|
||||
fputs(s, file);
|
||||
|
||||
/* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */
|
||||
if (s[0])
|
||||
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);
|
||||
lpc = last_gets_char;
|
||||
}
|
||||
|
||||
if (ferror(file)) {
|
||||
xfunc_error_retval = 4; /* It's what gnu sed exits with... */
|
||||
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" \
|
||||
"thzngy\nagaznXthzngy\nagazn" "thingy" "again"
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user