xref: /third_party/toybox/toys/posix/comm.c (revision 0f66f451)
10f66f451Sopenharmony_ci/* comm.c - select or reject lines common to two files
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2012 Ilya Kuzmich <ikv@safe-mail.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/comm.html
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ci// <# and ># take single digit, so 321 define flags
80f66f451Sopenharmony_ciUSE_COMM(NEWTOY(comm, "<2>2321", TOYFLAG_USR|TOYFLAG_BIN))
90f66f451Sopenharmony_ci
100f66f451Sopenharmony_ciconfig COMM
110f66f451Sopenharmony_ci  bool "comm"
120f66f451Sopenharmony_ci  default y
130f66f451Sopenharmony_ci  help
140f66f451Sopenharmony_ci    usage: comm [-123] FILE1 FILE2
150f66f451Sopenharmony_ci
160f66f451Sopenharmony_ci    Read FILE1 and FILE2, which should be ordered, and produce three text
170f66f451Sopenharmony_ci    columns as output: lines only in FILE1; lines only in FILE2; and lines
180f66f451Sopenharmony_ci    in both files. Filename "-" is a synonym for stdin.
190f66f451Sopenharmony_ci
200f66f451Sopenharmony_ci    -1	Suppress the output column of lines unique to FILE1
210f66f451Sopenharmony_ci    -2	Suppress the output column of lines unique to FILE2
220f66f451Sopenharmony_ci    -3	Suppress the output column of lines duplicated in FILE1 and FILE2
230f66f451Sopenharmony_ci*/
240f66f451Sopenharmony_ci
250f66f451Sopenharmony_ci#define FOR_comm
260f66f451Sopenharmony_ci#include "toys.h"
270f66f451Sopenharmony_ci
280f66f451Sopenharmony_cistatic void writeline(const char *line, int col)
290f66f451Sopenharmony_ci{
300f66f451Sopenharmony_ci  if (col == 0 && toys.optflags & FLAG_1) return;
310f66f451Sopenharmony_ci  else if (col == 1) {
320f66f451Sopenharmony_ci    if (toys.optflags & FLAG_2) return;
330f66f451Sopenharmony_ci    if (!(toys.optflags & FLAG_1)) putchar('\t');
340f66f451Sopenharmony_ci  } else if (col == 2) {
350f66f451Sopenharmony_ci    if (toys.optflags & FLAG_3) return;
360f66f451Sopenharmony_ci    if (!(toys.optflags & FLAG_1)) putchar('\t');
370f66f451Sopenharmony_ci    if (!(toys.optflags & FLAG_2)) putchar('\t');
380f66f451Sopenharmony_ci  }
390f66f451Sopenharmony_ci  puts(line);
400f66f451Sopenharmony_ci}
410f66f451Sopenharmony_ci
420f66f451Sopenharmony_civoid comm_main(void)
430f66f451Sopenharmony_ci{
440f66f451Sopenharmony_ci  int file[2];
450f66f451Sopenharmony_ci  char *line[2];
460f66f451Sopenharmony_ci  int i;
470f66f451Sopenharmony_ci
480f66f451Sopenharmony_ci  if (toys.optflags == 7) return;
490f66f451Sopenharmony_ci
500f66f451Sopenharmony_ci  for (i = 0; i < 2; i++) {
510f66f451Sopenharmony_ci    file[i] = xopenro(toys.optargs[i]);
520f66f451Sopenharmony_ci    line[i] = get_line(file[i]);
530f66f451Sopenharmony_ci  }
540f66f451Sopenharmony_ci
550f66f451Sopenharmony_ci  while (line[0] && line[1]) {
560f66f451Sopenharmony_ci    int order = strcmp(line[0], line[1]);
570f66f451Sopenharmony_ci
580f66f451Sopenharmony_ci    if (order == 0) {
590f66f451Sopenharmony_ci      writeline(line[0], 2);
600f66f451Sopenharmony_ci      for (i = 0; i < 2; i++) {
610f66f451Sopenharmony_ci        free(line[i]);
620f66f451Sopenharmony_ci        line[i] = get_line(file[i]);
630f66f451Sopenharmony_ci      }
640f66f451Sopenharmony_ci    } else {
650f66f451Sopenharmony_ci      i = order < 0 ? 0 : 1;
660f66f451Sopenharmony_ci      writeline(line[i], i);
670f66f451Sopenharmony_ci      free(line[i]);
680f66f451Sopenharmony_ci      line[i] = get_line(file[i]);
690f66f451Sopenharmony_ci    }
700f66f451Sopenharmony_ci  }
710f66f451Sopenharmony_ci
720f66f451Sopenharmony_ci  /* print rest of the longer file */
730f66f451Sopenharmony_ci  for (i = line[0] ? 0 : 1; line[i];) {
740f66f451Sopenharmony_ci    writeline(line[i], i);
750f66f451Sopenharmony_ci    free(line[i]);
760f66f451Sopenharmony_ci    line[i] = get_line(file[i]);
770f66f451Sopenharmony_ci  }
780f66f451Sopenharmony_ci
790f66f451Sopenharmony_ci  if (CFG_TOYBOX_FREE) for (i = 0; i < 2; i++) xclose(file[i]);
800f66f451Sopenharmony_ci}
81