blob: 28e3982f2b3074b559ebcb3d8bf4a4987615fffb [file] [log] [blame]
Rob Landley2acfd7b2005-05-11 23:12:49 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini comm implementation for busybox
4 *
5 * Copyright (C) 2005 by Robert Sullivan <cogito.ergo.cogito@gmail.com>
6 *
Rob Landleye104d5f2006-04-04 19:26:37 +00007 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Rob Landley2acfd7b2005-05-11 23:12:49 +00008 */
9
Rob Landley2acfd7b2005-05-11 23:12:49 +000010#include "busybox.h"
11
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000012#define COMM_OPT_1 (1 << 0)
13#define COMM_OPT_2 (1 << 1)
14#define COMM_OPT_3 (1 << 2)
Rob Landley2acfd7b2005-05-11 23:12:49 +000015
16/* writeline outputs the input given, appropriately aligned according to class */
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000017static void writeline(char *line, int class, int flags)
Mike Frysinger0d605e92005-05-12 22:25:41 +000018{
Mike Frysinger867a6082005-05-13 00:57:30 +000019 if (class == 0) {
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000020 if (flags & COMM_OPT_1)
Mike Frysinger0fb397e2005-05-13 00:58:18 +000021 return;
Mike Frysinger867a6082005-05-13 00:57:30 +000022 } else if (class == 1) {
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000023 if (flags & COMM_OPT_2)
Mike Frysingerdad4cf72005-05-12 22:50:12 +000024 return;
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000025 if (!(flags & COMM_OPT_1))
Mike Frysingerdad4cf72005-05-12 22:50:12 +000026 putchar('\t');
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000027 } else /*if (class == 2)*/ {
28 if (flags & COMM_OPT_3)
Mike Frysingerdad4cf72005-05-12 22:50:12 +000029 return;
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000030 if (!(flags & COMM_OPT_1))
Mike Frysingerdad4cf72005-05-12 22:50:12 +000031 putchar('\t');
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000032 if (!(flags & COMM_OPT_2))
Mike Frysingerdad4cf72005-05-12 22:50:12 +000033 putchar('\t');
Rob Landley2acfd7b2005-05-11 23:12:49 +000034 }
Mike Frysinger0d605e92005-05-12 22:25:41 +000035 fputs(line, stdout);
Rob Landley2acfd7b2005-05-11 23:12:49 +000036}
37
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000038int comm_main(int argc, char **argv);
39int comm_main(int argc, char **argv)
Mike Frysinger0d605e92005-05-12 22:25:41 +000040{
Mike Frysinger867a6082005-05-13 00:57:30 +000041#define LINE_LEN 100
42#define BB_EOF_0 0x1
43#define BB_EOF_1 0x2
44 char thisline[2][LINE_LEN];
Rob Landley2acfd7b2005-05-11 23:12:49 +000045 FILE *streams[2];
Mike Frysinger867a6082005-05-13 00:57:30 +000046 int i;
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000047 unsigned flags;
48
49 opt_complementary = "=2";
50 flags = getopt32(argc, argv, "123");
51 argv += optind;
Mike Frysinger0d605e92005-05-12 22:25:41 +000052
Mike Frysinger867a6082005-05-13 00:57:30 +000053 for (i = 0; i < 2; ++i) {
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000054 streams[i] = (argv[i][0] == '-' && !argv[i][1]) ? stdin : xfopen(argv[i], "r");
Mike Frysinger867a6082005-05-13 00:57:30 +000055 fgets(thisline[i], LINE_LEN, streams[i]);
Rob Landley2acfd7b2005-05-11 23:12:49 +000056 }
57
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000058 /* This is the real core of the program - lines are compared here */
59
Rob Landleye104d5f2006-04-04 19:26:37 +000060 while (*thisline[0] || *thisline[1]) {
Rob Landley2acfd7b2005-05-11 23:12:49 +000061 int order = 0;
Mike Frysinger867a6082005-05-13 00:57:30 +000062
63 i = 0;
64 if (feof(streams[0])) i |= BB_EOF_0;
65 if (feof(streams[1])) i |= BB_EOF_1;
Mike Frysinger0d605e92005-05-12 22:25:41 +000066
Rob Landleye104d5f2006-04-04 19:26:37 +000067 if (!*thisline[0])
Rob Landley2acfd7b2005-05-11 23:12:49 +000068 order = 1;
Rob Landleye104d5f2006-04-04 19:26:37 +000069 else if (!*thisline[1])
Rob Landley2acfd7b2005-05-11 23:12:49 +000070 order = -1;
71 else {
Mike Frysinger867a6082005-05-13 00:57:30 +000072 int tl0_len, tl1_len;
73 tl0_len = strlen(thisline[0]);
74 tl1_len = strlen(thisline[1]);
Rob Landley2acfd7b2005-05-11 23:12:49 +000075 order = memcmp(thisline[0], thisline[1], tl0_len < tl1_len ? tl0_len : tl1_len);
76 if (!order)
77 order = tl0_len < tl1_len ? -1 : tl0_len != tl1_len;
78 }
Mike Frysinger0d605e92005-05-12 22:25:41 +000079
Mike Frysinger867a6082005-05-13 00:57:30 +000080 if (order == 0 && !i)
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000081 writeline(thisline[1], 2, flags);
Mike Frysinger867a6082005-05-13 00:57:30 +000082 else if (order > 0 && !(i & BB_EOF_1))
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000083 writeline(thisline[1], 1, flags);
Mike Frysinger867a6082005-05-13 00:57:30 +000084 else if (order < 0 && !(i & BB_EOF_0))
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000085 writeline(thisline[0], 0, flags);
Mike Frysinger0d605e92005-05-12 22:25:41 +000086
Mike Frysinger867a6082005-05-13 00:57:30 +000087 if (i & BB_EOF_0 & BB_EOF_1) {
Rob Landley2acfd7b2005-05-11 23:12:49 +000088 break;
Mike Frysinger0d605e92005-05-12 22:25:41 +000089
Mike Frysinger867a6082005-05-13 00:57:30 +000090 } else if (i) {
91 i = (i & BB_EOF_0 ? 1 : 0);
92 while (!feof(streams[i])) {
93 if ((order < 0 && i) || (order > 0 && !i))
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +000094 writeline(thisline[i], i, flags);
Mike Frysinger867a6082005-05-13 00:57:30 +000095 fgets(thisline[i], LINE_LEN, streams[i]);
Rob Landley2acfd7b2005-05-11 23:12:49 +000096 }
Rob Landley2acfd7b2005-05-11 23:12:49 +000097 break;
Mike Frysinger0d605e92005-05-12 22:25:41 +000098
99 } else {
Rob Landley2acfd7b2005-05-11 23:12:49 +0000100 if (order >= 0)
Mike Frysinger867a6082005-05-13 00:57:30 +0000101 fgets(thisline[1], LINE_LEN, streams[1]);
Rob Landley2acfd7b2005-05-11 23:12:49 +0000102 if (order <= 0)
Mike Frysinger867a6082005-05-13 00:57:30 +0000103 fgets(thisline[0], LINE_LEN, streams[0]);
Rob Landley2acfd7b2005-05-11 23:12:49 +0000104 }
105 }
106
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +0000107 if (ENABLE_FEATURE_CLEAN_UP) {
108 fclose(streams[0]);
109 fclose(streams[1]);
110 }
Rob Landley2acfd7b2005-05-11 23:12:49 +0000111
Denis Vlasenkobb5b01c2007-04-07 00:45:27 +0000112 return EXIT_SUCCESS;
Rob Landley2acfd7b2005-05-11 23:12:49 +0000113}