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.

function                                             old     new   delta
paste_main                                           448     528     +80
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 80/0)               Total: 80 bytes

Signed-off-by: Ron Yorston <[email protected]>
---
 coreutils/paste.c                | 36 +++++++++++++++++++++-----------
 testsuite/paste/paste-long-short | 19 +++++++++++++++++
 testsuite/paste/paste-short-long | 19 +++++++++++++++++
 3 files changed, 62 insertions(+), 12 deletions(-)
 create mode 100644 testsuite/paste/paste-long-short
 create mode 100644 testsuite/paste/paste-short-long

diff --git a/coreutils/paste.c b/coreutils/paste.c
index 3e5f20158..363340e3d 100644
--- a/coreutils/paste.c
+++ b/coreutils/paste.c
@@ -34,27 +34,38 @@
 
 static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt)
 {
-       char *line;
+       char **line = xmalloc(file_cnt * sizeof(char *));
        char delim;
        int active_files = file_cnt;
        int i;
 
        while (active_files > 0) {
                int del_idx = 0;
+               int got_line = FALSE;
 
                for (i = 0; i < file_cnt; ++i) {
-                       if (files[i] == NULL)
-                               continue;
-
-                       line = xmalloc_fgetline(files[i]);
-                       if (!line) {
-                               fclose_if_not_stdin(files[i]);
-                               files[i] = NULL;
-                               --active_files;
-                               continue;
+                       if (files[i]) {
+                               line[i] = xmalloc_fgetline(files[i]);
+                               if (!line[i]) {
+                                       fclose_if_not_stdin(files[i]);
+                                       files[i] = NULL;
+                                       --active_files;
+                               } else {
+                                       got_line = TRUE;
+                               }
+                       } else {
+                               line[i] = NULL;
+                       }
+               }
+
+               if (!got_line)
+                       break;
+
+               for (i = 0; i < file_cnt; ++i) {
+                       if (line[i]) {
+                               fputs_stdout(line[i]);
+                               free(line[i]);
                        }
-                       fputs_stdout(line);
-                       free(line);
                        delim = '\n';
                        if (i != file_cnt - 1) {
                                delim = delims[del_idx++];
@@ -65,6 +76,7 @@ static void paste_files(FILE** files, int file_cnt, char* 
delims, int del_cnt)
                                fputc(delim, stdout);
                }
        }
+       free(line);
 }
 
 static void paste_files_separate(FILE** files, char* delims, int del_cnt)
diff --git a/testsuite/paste/paste-long-short b/testsuite/paste/paste-long-short
new file mode 100644
index 000000000..e626d730e
--- /dev/null
+++ b/testsuite/paste/paste-long-short
@@ -0,0 +1,19 @@
+cat > foo <<EOF
+foo1
+foo2
+foo3
+EOF
+
+cat > bar <<EOF
+bar1
+bar2
+EOF
+
+cat > baz <<EOF
+foo1   bar1
+foo2   bar2
+foo3   
+EOF
+
+busybox paste foo bar > qux
+diff -u baz qux
diff --git a/testsuite/paste/paste-short-long b/testsuite/paste/paste-short-long
new file mode 100644
index 000000000..785da60a7
--- /dev/null
+++ b/testsuite/paste/paste-short-long
@@ -0,0 +1,19 @@
+cat > foo <<EOF
+foo1
+foo2
+EOF
+
+cat > bar <<EOF
+bar1
+bar2
+bar3
+EOF
+
+cat > baz <<EOF
+foo1   bar1
+foo2   bar2
+       bar3
+EOF
+
+busybox paste foo bar > qux
+diff -u baz qux
-- 
2.51.1

_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to