diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-11-10 12:48:38 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-11-10 12:52:02 +0000 |
| commit | af09683cfc5ffe05f3e42bb592fe15a753540d85 (patch) | |
| tree | 829a0801dd0d0603240dfcfe48e233f8600a06bf /coreutils/paste.c | |
| parent | f53dbcb8edbcfdad1721d0f5c9e8a16d54e983dc (diff) | |
| download | busybox-w32-af09683cfc5ffe05f3e42bb592fe15a753540d85.tar.gz busybox-w32-af09683cfc5ffe05f3e42bb592fe15a753540d85.tar.bz2 busybox-w32-af09683cfc5ffe05f3e42bb592fe15a753540d85.zip | |
paste: fix output when file lengths differ
If the files being pasted had different numbers of lines the
output was incorrect.
Rewrite the loop over all lines to allow for this. Add tests for
such conditions.
Adds 64-80 bytes.
(GitHub issue #542)
Diffstat (limited to 'coreutils/paste.c')
| -rw-r--r-- | coreutils/paste.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/coreutils/paste.c b/coreutils/paste.c index 3e5f20158..78a5c2a14 100644 --- a/coreutils/paste.c +++ b/coreutils/paste.c | |||
| @@ -34,15 +34,46 @@ | |||
| 34 | 34 | ||
| 35 | static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) | 35 | static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) |
| 36 | { | 36 | { |
| 37 | #if ENABLE_PLATFORM_MINGW32 | ||
| 38 | char **line = xmalloc(file_cnt * sizeof(char *)); | ||
| 39 | #else | ||
| 37 | char *line; | 40 | char *line; |
| 41 | #endif | ||
| 38 | char delim; | 42 | char delim; |
| 39 | int active_files = file_cnt; | 43 | int active_files = file_cnt; |
| 40 | int i; | 44 | int i; |
| 41 | 45 | ||
| 42 | while (active_files > 0) { | 46 | while (active_files > 0) { |
| 43 | int del_idx = 0; | 47 | int del_idx = 0; |
| 48 | #if ENABLE_PLATFORM_MINGW32 | ||
| 49 | int got_line = FALSE; | ||
| 50 | #endif | ||
| 44 | 51 | ||
| 45 | for (i = 0; i < file_cnt; ++i) { | 52 | for (i = 0; i < file_cnt; ++i) { |
| 53 | #if ENABLE_PLATFORM_MINGW32 | ||
| 54 | if (files[i]) { | ||
| 55 | line[i] = xmalloc_fgetline(files[i]); | ||
| 56 | if (!line[i]) { | ||
| 57 | fclose_if_not_stdin(files[i]); | ||
| 58 | files[i] = NULL; | ||
| 59 | --active_files; | ||
| 60 | } else { | ||
| 61 | got_line = TRUE; | ||
| 62 | } | ||
| 63 | } else { | ||
| 64 | line[i] = NULL; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | if (!got_line) | ||
| 69 | break; | ||
| 70 | |||
| 71 | for (i = 0; i < file_cnt; ++i) { | ||
| 72 | if (line[i]) { | ||
| 73 | fputs_stdout(line[i]); | ||
| 74 | free(line[i]); | ||
| 75 | } | ||
| 76 | #else | ||
| 46 | if (files[i] == NULL) | 77 | if (files[i] == NULL) |
| 47 | continue; | 78 | continue; |
| 48 | 79 | ||
| @@ -55,6 +86,7 @@ static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) | |||
| 55 | } | 86 | } |
| 56 | fputs_stdout(line); | 87 | fputs_stdout(line); |
| 57 | free(line); | 88 | free(line); |
| 89 | #endif | ||
| 58 | delim = '\n'; | 90 | delim = '\n'; |
| 59 | if (i != file_cnt - 1) { | 91 | if (i != file_cnt - 1) { |
| 60 | delim = delims[del_idx++]; | 92 | delim = delims[del_idx++]; |
| @@ -65,6 +97,9 @@ static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) | |||
| 65 | fputc(delim, stdout); | 97 | fputc(delim, stdout); |
| 66 | } | 98 | } |
| 67 | } | 99 | } |
| 100 | #if ENABLE_PLATFORM_MINGW32 | ||
| 101 | free(line); | ||
| 102 | #endif | ||
| 68 | } | 103 | } |
| 69 | 104 | ||
| 70 | static void paste_files_separate(FILE** files, char* delims, int del_cnt) | 105 | static void paste_files_separate(FILE** files, char* delims, int del_cnt) |
