annotate toys/posix/uniq.c @ 674:7e846e281e38

New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
author Rob Landley <rob@landley.net>
date Mon, 08 Oct 2012 00:02:30 -0500
parents 6df4ccc0acbe
children 786841fdb1e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
1 /* vi: set sw=4 ts=4:
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
2 *
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
3 * uniq.c - report or filter out repeated lines in a file
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
4 *
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
5 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
6 *
656
6df4ccc0acbe Regularize command headers, update links to standards documents.
Rob Landley <rob@landley.net>
parents: 653
diff changeset
7 * See http://opengroup.org/onlinepubs/9699919799/utilities/uniq.html
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
8
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
9 USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_BIN))
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
10
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
11 config UNIQ
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
12 bool "uniq"
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
13 default y
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
14 help
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
15 usage: uniq [-cduiz] [-w maxchars] [-f fields] [-s char] [input_file [output_file]]
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
16
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
17 Report or filter out repeated lines in a file
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
18
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
19 -c show counts before each line
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
20 -d show only lines that are repeated
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
21 -u show only lines that are unique
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
22 -i ignore case when comparing lines
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
23 -z lines end with \0 not \n
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
24 -w compare maximum X chars per line
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
25 -f ignore first X fields
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
26 -s ignore first X chars
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
27 */
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
28
674
7e846e281e38 New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents: 656
diff changeset
29 #define FOR_uniq
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
30 #include "toys.h"
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
31
674
7e846e281e38 New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents: 656
diff changeset
32 GLOBALS(
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
33 long maxchars;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
34 long nchars;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
35 long nfields;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
36 long repeats;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
37 )
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
38
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
39 static char *skip(char *str)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
40 {
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
41 long nchars = TT.nchars, nfields;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
42
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
43 // Skip fields first
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
44 for (nfields = TT.nfields; nfields; str++) {
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
45 while (*str && isspace(*str)) str++;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
46 while (*str && !isspace(*str)) str++;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
47 nfields--;
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
48 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
49 // Skip chars
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
50 while (*str && nchars--) str++;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
51
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
52 return str;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
53 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
54
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
55 static void print_line(FILE *f, char *line)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
56 {
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
57 if (toys.optflags & (TT.repeats ? FLAG_u : FLAG_d)) return;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
58 if (toys.optflags & FLAG_c) fprintf(f, "%7lu ", TT.repeats + 1);
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
59 fputs(line, f);
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
60 if (toys.optflags & FLAG_z) fputc(0, f);
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
61 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
62
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
63 void uniq_main(void)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
64 {
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
65 FILE *infile = stdin, *outfile = stdout;
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
66 char *thisline = NULL, *prevline = NULL, *tmpline, eol = '\n';
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
67 size_t thissize, prevsize = 0, tmpsize;
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
68
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
69 if (toys.optc >= 1) infile = xfopen(toys.optargs[0], "r");
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
70 if (toys.optc >= 2) outfile = xfopen(toys.optargs[1], "w");
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
71
567
f1629eb63806 Refactor uniq.c a bit.
Rob Landley <rob@landley.net>
parents: 546
diff changeset
72 if (toys.optflags & FLAG_z) eol = 0;
546
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
73
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
74 // If first line can't be read
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
75 if (getdelim(&prevline, &prevsize, eol, infile) < 0)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
76 return;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
77
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
78 while (getdelim(&thisline, &thissize, eol, infile) > 0) {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
79 int diff;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
80 char *t1, *t2;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
81
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
82 // If requested get the chosen fields + character offsets.
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
83 if (TT.nfields || TT.nchars) {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
84 t1 = skip(thisline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
85 t2 = skip(prevline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
86 } else {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
87 t1 = thisline;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
88 t2 = prevline;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
89 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
90
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
91 if (TT.maxchars == 0) {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
92 diff = !(toys.optflags & FLAG_i)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
93 ? strcmp(t1, t2)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
94 : strcasecmp(t1, t2);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
95 } else {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
96 diff = !(toys.optflags & FLAG_i)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
97 ? strncmp(t1, t2, TT.maxchars)
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
98 : strncasecmp(t1, t2, TT.maxchars);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
99 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
100
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
101 if (diff == 0) { // same
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
102 TT.repeats++;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
103 } else {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
104 print_line(outfile, prevline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
105
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
106 TT.repeats = 0;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
107
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
108 tmpline = prevline;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
109 prevline = thisline;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
110 thisline = tmpline;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
111
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
112 tmpsize = prevsize;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
113 prevsize = thissize;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
114 thissize = tmpsize;
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
115 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
116 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
117
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
118 print_line(outfile, prevline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
119
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
120 if (CFG_TOYBOX_FREE) {
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
121 free(prevline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
122 free(thisline);
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
123 }
a095c02dc431 Implement uniq.
Georgi Chorbadzhiyski <gf@unixsol.org>
parents:
diff changeset
124 }