Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/uniq.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 12  Line 12 
12    
13  #include "libbb.h"  #include "libbb.h"
14    
 static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)  
 {  
  const char *n;  
   
  n = *argv;  
  if (n != NULL) {  
  if ((*n != '-') || n[1]) {  
  return xfopen(n, "r\0w" + read0write2);  
  }  
  }  
  return (read0write2) ? stdout : stdin;  
 }  
   
15  int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
16  int uniq_main(int argc UNUSED_PARAM, char **argv)  int uniq_main(int argc UNUSED_PARAM, char **argv)
17  {  {
18   FILE *in, *out;   const char *input_filename;
  const char *s0, *e0, *s1, *e1, *input_filename;  
  unsigned long dups;  
19   unsigned skip_fields, skip_chars, max_chars;   unsigned skip_fields, skip_chars, max_chars;
20   unsigned opt;   unsigned opt;
21   unsigned i;   char *cur_line;
22     const char *cur_compare;
23    
24   enum {   enum {
25   OPT_c = 0x1,   OPT_c = 0x1,
26   OPT_d = 0x2,   OPT_d = 0x2, /* print only dups */
27   OPT_u = 0x4,   OPT_u = 0x4, /* print only uniq */
28   OPT_f = 0x8,   OPT_f = 0x8,
29   OPT_s = 0x10,   OPT_s = 0x10,
30   OPT_w = 0x20,   OPT_w = 0x20,
31   };   };
32    
33   skip_fields = skip_chars = 0;   skip_fields = skip_chars = 0;
34   max_chars = -1;   max_chars = INT_MAX;
35    
36   opt_complementary = "f+:s+:w+";   opt_complementary = "f+:s+:w+";
37   opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars);   opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars);
38   argv += optind;   argv += optind;
39    
40   input_filename = *argv;   input_filename = argv[0];
41     if (input_filename) {
42   in = xgetoptfile_uniq_s(argv, 0);   const char *output;
43   if (*argv) {  
44   ++argv;   if (input_filename[0] != '-' || input_filename[1]) {
45   }   close(STDIN_FILENO); /* == 0 */
46   out = xgetoptfile_uniq_s(argv, 2);   xopen(input_filename, O_RDONLY); /* fd will be 0 */
47   if (*argv && argv[1]) {   }
48   bb_show_usage();   output = argv[1];
49     if (output) {
50     if (argv[2])
51     bb_show_usage();
52     if (output[0] != '-' || output[1]) {
53     // Won't work with "uniq - FILE" and closed stdin:
54     //close(STDOUT_FILENO);
55     //xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666);
56     xmove_fd(xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666), STDOUT_FILENO);
57     }
58     }
59   }   }
60    
61   s1 = e1 = NULL; /* prime the pump */   cur_compare = cur_line = NULL; /* prime the pump */
62    
63   do {   do {
64   s0 = s1;   unsigned i;
65   e0 = e1;   unsigned long dups;
66     char *old_line;
67     const char *old_compare;
68    
69     old_line = cur_line;
70     old_compare = cur_compare;
71   dups = 0;   dups = 0;
72    
73   /* gnu uniq ignores newlines */   /* gnu uniq ignores newlines */
74   while ((s1 = xmalloc_fgetline(in)) != NULL) {   while ((cur_line = xmalloc_fgetline(stdin)) != NULL) {
75   e1 = s1;   cur_compare = cur_line;
76   for (i = skip_fields; i; i--) {   for (i = skip_fields; i; i--) {
77   e1 = skip_whitespace(e1);   cur_compare = skip_whitespace(cur_compare);
78   e1 = skip_non_whitespace(e1);   cur_compare = skip_non_whitespace(cur_compare);
79   }   }
80   for (i = skip_chars; *e1 && i; i--) {   for (i = skip_chars; *cur_compare && i; i--) {
81   ++e1;   ++cur_compare;
82   }   }
83    
84   if (!s0 || strncmp(e0, e1, max_chars)) {   if (!old_line || strncmp(old_compare, cur_compare, max_chars)) {
85   break;   break;
86   }   }
87    
88   ++dups; /* note: testing for overflow seems excessive. */   free(cur_line);
89     ++dups; /* testing for overflow seems excessive */
90   }   }
91    
92   if (s0) {   if (old_line) {
93   if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_e) */   if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_u) */
94   fprintf(out, "\0%ld " + (opt & 1), dups + 1); /* 1 == OPT_c */   if (opt & OPT_c) {
95   fprintf(out, "%s\n", s0);   /* %7lu matches GNU coreutils 6.9 */
96     printf("%7lu ", dups + 1);
97     }
98     printf("%s\n", old_line);
99   }   }
100   free((void *)s0);   free(old_line);
101   }   }
102   } while (s1);   } while (cur_line);
103    
104   die_if_ferror(in, input_filename);   die_if_ferror(stdin, input_filename);
105    
106   fflush_stdout_and_exit(EXIT_SUCCESS);   fflush_stdout_and_exit(EXIT_SUCCESS);
107  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984