1/* 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 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 */ 9 10#include "libbb.h" 11 12#define COMM_OPT_1 (1 << 0) 13#define COMM_OPT_2 (1 << 1) 14#define COMM_OPT_3 (1 << 2) 15 16/* writeline outputs the input given, appropriately aligned according to class */ 17static void writeline(char *line, int class, int flags) 18{ 19 if (class == 0) { 20 if (flags & COMM_OPT_1) 21 return; 22 } else if (class == 1) { 23 if (flags & COMM_OPT_2) 24 return; 25 if (!(flags & COMM_OPT_1)) 26 putchar('\t'); 27 } else /*if (class == 2)*/ { 28 if (flags & COMM_OPT_3) 29 return; 30 if (!(flags & COMM_OPT_1)) 31 putchar('\t'); 32 if (!(flags & COMM_OPT_2)) 33 putchar('\t'); 34 } 35 fputs(line, stdout); 36} 37 38int comm_main(int argc, char **argv); 39int comm_main(int argc, char **argv) 40{ 41#define LINE_LEN 100 42#define BB_EOF_0 0x1 43#define BB_EOF_1 0x2 44 char thisline[2][LINE_LEN]; 45 FILE *streams[2]; 46 int i; 47 unsigned flags; 48 49 opt_complementary = "=2"; 50 flags = getopt32(argv, "123"); 51 argv += optind; 52 53 for (i = 0; i < 2; ++i) { 54 streams[i] = (argv[i][0] == '-' && !argv[i][1]) ? stdin : xfopen(argv[i], "r"); 55 fgets(thisline[i], LINE_LEN, streams[i]); 56 } 57 58 /* This is the real core of the program - lines are compared here */ 59 60 while (*thisline[0] || *thisline[1]) { 61 int order = 0; 62 63 i = 0; 64 if (feof(streams[0])) i |= BB_EOF_0; 65 if (feof(streams[1])) i |= BB_EOF_1; 66 67 if (!*thisline[0]) 68 order = 1; 69 else if (!*thisline[1]) 70 order = -1; 71 else { 72 int tl0_len, tl1_len; 73 tl0_len = strlen(thisline[0]); 74 tl1_len = strlen(thisline[1]); 75 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 } 79 80 if (order == 0 && !i) 81 writeline(thisline[1], 2, flags); 82 else if (order > 0 && !(i & BB_EOF_1)) 83 writeline(thisline[1], 1, flags); 84 else if (order < 0 && !(i & BB_EOF_0)) 85 writeline(thisline[0], 0, flags); 86 87 if (i & BB_EOF_0 & BB_EOF_1) { 88 break; 89 90 } else if (i) { 91 i = (i & BB_EOF_0 ? 1 : 0); 92 while (!feof(streams[i])) { 93 if ((order < 0 && i) || (order > 0 && !i)) 94 writeline(thisline[i], i, flags); 95 fgets(thisline[i], LINE_LEN, streams[i]); 96 } 97 break; 98 99 } else { 100 if (order >= 0) 101 fgets(thisline[1], LINE_LEN, streams[1]); 102 if (order <= 0) 103 fgets(thisline[0], LINE_LEN, streams[0]); 104 } 105 } 106 107 if (ENABLE_FEATURE_CLEAN_UP) { 108 fclose(streams[0]); 109 fclose(streams[1]); 110 } 111 112 return EXIT_SUCCESS; 113} 114