toybox

changeset 557:feb909b2e6aa

Implement comm.
author Ilya Kuzmich <ilya.kuzmich@gmail.com>
date Thu, 22 Mar 2012 09:01:34 -0500
parents 56a53ff54096
children 8a1d45dd8af1
files toys/comm.c
diffstat 1 files changed, 91 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toys/comm.c	Thu Mar 22 09:01:34 2012 -0500
     1.3 @@ -0,0 +1,91 @@
     1.4 +/* vi: set sw=4 ts=4:
     1.5 + *
     1.6 + * comm.c - select or reject lines common to two files
     1.7 + *
     1.8 + * Copyright 2012 Ilya Kuzmich <ikv@safe-mail.net>
     1.9 + *
    1.10 + * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/comm.html
    1.11 +
    1.12 +USE_COMM(NEWTOY(comm, "123", TOYFLAG_USR|TOYFLAG_BIN))
    1.13 +
    1.14 +config COMM
    1.15 +	bool "comm"
    1.16 +	default n
    1.17 +	help
    1.18 +	  usage: comm [-123] FILE1 FILE2
    1.19 +
    1.20 +	  Reads FILE1 and FILE2, which should be ordered, and produces three text
    1.21 +	  columns as output: lines only in FILE1; lines only in FILE2; and lines
    1.22 +	  in both files. Filename "-" is a synonym for stdin.
    1.23 +
    1.24 +	  -1 suppress the output column of lines unique to FILE1
    1.25 +	  -2 suppress the output column of lines unique to FILE2
    1.26 +	  -3 suppress the output column of lines duplicated in FILE1 and FILE2
    1.27 +*/
    1.28 +
    1.29 +#include "toys.h"
    1.30 +
    1.31 +#define FLAG_SUPPRESS_3 1
    1.32 +#define FLAG_SUPPRESS_2 2
    1.33 +#define FLAG_SUPPRESS_1 4
    1.34 +
    1.35 +static void writeline(const char *line, int col)
    1.36 +{
    1.37 +	if (col == 0 && toys.optflags & FLAG_SUPPRESS_1) return;
    1.38 +	else if (col == 1) {
    1.39 +		if (toys.optflags & FLAG_SUPPRESS_2) return;
    1.40 +		if (!(toys.optflags & FLAG_SUPPRESS_1)) putchar('\t');
    1.41 +	} else if (col == 2) {
    1.42 +		if (toys.optflags & FLAG_SUPPRESS_3) return;
    1.43 +		if (!(toys.optflags & FLAG_SUPPRESS_1)) putchar('\t');
    1.44 +		if (!(toys.optflags & FLAG_SUPPRESS_2)) putchar('\t');
    1.45 +	}
    1.46 +	puts(line);
    1.47 +}
    1.48 +
    1.49 +void comm_main(void)
    1.50 +{
    1.51 +	int file[2];
    1.52 +	char *line[2];
    1.53 +	int i;
    1.54 +
    1.55 +	if (toys.optc != 2)
    1.56 +		perror_exit("exactly 2 operands required");
    1.57 +
    1.58 +	if (toys.optflags == (FLAG_SUPPRESS_1 | FLAG_SUPPRESS_2 | FLAG_SUPPRESS_3))
    1.59 +		return;
    1.60 +
    1.61 +	for (i = 0; i < 2; i++) {
    1.62 +		file[i] = strcmp("-", toys.optargs[i]) ? xopen(toys.optargs[i], O_RDONLY) : 0;
    1.63 +		line[i] = get_line(file[i]);
    1.64 +	}
    1.65 +
    1.66 +	while (line[0] && line[1]) {
    1.67 +		int order = strcmp(line[0], line[1]);
    1.68 +
    1.69 +		if (order == 0) {
    1.70 +			writeline(line[0], 2);
    1.71 +			for (i = 0; i < 2; i++) {
    1.72 +				free(line[i]);
    1.73 +				line[i] = get_line(file[i]);
    1.74 +			}
    1.75 +		} else {
    1.76 +			i = order < 0 ? 0 : 1;
    1.77 +			writeline(line[i], i);
    1.78 +			free(line[i]);
    1.79 +			line[i] = get_line(file[i]);
    1.80 +		}
    1.81 +	}
    1.82 +
    1.83 +	/* print rest of the longer file */
    1.84 +	for (i = line[0] ? 0 : 1; line[i];) {
    1.85 +		writeline(line[i], i);
    1.86 +		free(line[i]);
    1.87 +		line[i] = get_line(file[i]);
    1.88 +	}
    1.89 +
    1.90 +	if (CFG_TOYBOX_FREE) {
    1.91 +		for (i = 0; i < 2; i--)
    1.92 +			xclose(file[i]);
    1.93 +	}
    1.94 +}