comm.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 source tree.
  8. */
  9. #include "libbb.h"
  10. #define COMM_OPT_1 (1 << 0)
  11. #define COMM_OPT_2 (1 << 1)
  12. #define COMM_OPT_3 (1 << 2)
  13. /* writeline outputs the input given, appropriately aligned according to class */
  14. static void writeline(char *line, int class)
  15. {
  16. int flags = option_mask32;
  17. if (class == 0) {
  18. if (flags & COMM_OPT_1)
  19. return;
  20. } else if (class == 1) {
  21. if (flags & COMM_OPT_2)
  22. return;
  23. if (!(flags & COMM_OPT_1))
  24. putchar('\t');
  25. } else /*if (class == 2)*/ {
  26. if (flags & COMM_OPT_3)
  27. return;
  28. if (!(flags & COMM_OPT_1))
  29. putchar('\t');
  30. if (!(flags & COMM_OPT_2))
  31. putchar('\t');
  32. }
  33. puts(line);
  34. }
  35. int comm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  36. int comm_main(int argc UNUSED_PARAM, char **argv)
  37. {
  38. char *thisline[2];
  39. FILE *stream[2];
  40. int i;
  41. int order;
  42. opt_complementary = "=2";
  43. getopt32(argv, "123");
  44. argv += optind;
  45. for (i = 0; i < 2; ++i) {
  46. stream[i] = xfopen_stdin(argv[i]);
  47. }
  48. order = 0;
  49. thisline[1] = thisline[0] = NULL;
  50. while (1) {
  51. if (order <= 0) {
  52. free(thisline[0]);
  53. thisline[0] = xmalloc_fgetline(stream[0]);
  54. }
  55. if (order >= 0) {
  56. free(thisline[1]);
  57. thisline[1] = xmalloc_fgetline(stream[1]);
  58. }
  59. i = !thisline[0] + (!thisline[1] << 1);
  60. if (i)
  61. break;
  62. order = strcmp(thisline[0], thisline[1]);
  63. if (order >= 0)
  64. writeline(thisline[1], order ? 1 : 2);
  65. else
  66. writeline(thisline[0], 0);
  67. }
  68. /* EOF at least on one of the streams */
  69. i &= 1;
  70. if (thisline[i]) {
  71. /* stream[i] is not at EOF yet */
  72. /* we did not print thisline[i] yet */
  73. char *p = thisline[i];
  74. writeline(p, i);
  75. while (1) {
  76. free(p);
  77. p = xmalloc_fgetline(stream[i]);
  78. if (!p)
  79. break;
  80. writeline(p, i);
  81. }
  82. }
  83. if (ENABLE_FEATURE_CLEAN_UP) {
  84. fclose(stream[0]);
  85. fclose(stream[1]);
  86. }
  87. return EXIT_SUCCESS;
  88. }