source: trunk/minix/commands/simple/uniq.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.5 KB
Line 
1/* uniq - compact repeated lines Author: John Woods */
2/* Uniq [-udc] [-n] [+n] [infile [outfile]]
3 *
4 * Written 02/08/86 by John Woods, placed into public domain. Enjoy.
5 *
6 */
7
8/* If the symbol WRITE_ERROR is defined, uniq will exit(1) if it gets a
9 * write error on the output. This is not (of course) how V7 uniq does it,
10 * so undefine the symbol if you want to lose your output to a full disk
11 */
12
13#define WRITE_ERROR 1
14#include <ctype.h>
15#include <errno.h>
16#include <string.h>
17#include <stdlib.h>
18#include <stdio.h>
19
20char buffer[BUFSIZ];
21int uflag = 1; /* default is union of -d and -u outputs */
22int dflag = 1; /* flags are mutually exclusive */
23int cflag = 0;
24int fields = 0;
25int chars = 0;
26
27_PROTOTYPE(int main, (int argc, char **argv));
28_PROTOTYPE(FILE *xfopen, (char *fn, char *mode));
29_PROTOTYPE(char *skip, (char *s));
30_PROTOTYPE(int equal, (char *s1, char *s2));
31_PROTOTYPE(void show, (char *line, int count));
32_PROTOTYPE(int uniq, (void));
33_PROTOTYPE(void usage, (void));
34_PROTOTYPE(int getline, (char *buf, int count));
35
36FILE *xfopen(fn, mode)
37char *fn, *mode;
38{
39 FILE *p;
40
41 if ((p = fopen(fn, mode)) == NULL) {
42 perror("uniq");
43 fflush(stdout);
44 exit(1);
45 }
46 return(p);
47}
48
49int main(argc, argv)
50int argc;
51char *argv[];
52{
53 char *p;
54 int inf = -1, outf;
55
56 setbuf(stdout, buffer);
57 for (--argc, ++argv; argc > 0 && (**argv == '-' || **argv == '+');
58 --argc, ++argv) {
59 if (**argv == '+')
60 chars = atoi(*argv + 1);
61 else if (isdigit(argv[0][1]))
62 fields = atoi(*argv + 1);
63 else if (argv[0][1] == '\0')
64 inf = 0; /* - is stdin */
65 else
66 for (p = *argv + 1; *p; p++) {
67 switch (*p) {
68 case 'd':
69 dflag = 1;
70 uflag = 0;
71 break;
72 case 'u':
73 uflag = 1;
74 dflag = 0;
75 break;
76 case 'c': cflag = 1; break;
77 default: usage();
78 }
79 }
80 }
81
82 /* Input file */
83 if (argc == 0)
84 inf = 0;
85 else if (inf == -1) { /* if - was not given */
86 fclose(stdin);
87 xfopen(*argv++, "r");
88 argc--;
89 }
90 if (argc == 0)
91 outf = 1;
92 else {
93 fclose(stdout);
94 xfopen(*argv++, "w");
95 argc--;
96 }
97
98 uniq();
99 fflush(stdout);
100 return(0);
101}
102
103char *skip(s)
104char *s;
105{
106 int n;
107
108 /* Skip fields */
109 for (n = fields; n > 0; --n) {
110 /* Skip blanks */
111 while (*s && (*s == ' ' || *s == '\t')) s++;
112 if (!*s) return s;
113 while (*s && (*s != ' ' && *s != '\t')) s++;
114 if (!*s) return s;
115 }
116
117 /* Skip characters */
118 for (n = chars; n > 0; --n) {
119 if (!*s) return s;
120 s++;
121 }
122 return s;
123}
124
125int equal(s1, s2)
126char *s1, *s2;
127{
128 return !strcmp(skip(s1), skip(s2));
129}
130
131void show(line, count)
132char *line;
133int count;
134{
135 if (cflag)
136 printf("%4d %s", count, line);
137 else {
138 if ((uflag && count == 1) || (dflag && count != 1))
139 printf("%s", line);
140 }
141}
142
143/* The meat of the whole affair */
144char *nowline, *prevline, buf1[1024], buf2[1024];
145
146int uniq()
147{
148 char *p;
149 int seen;
150
151 /* Setup */
152 prevline = buf1;
153 if (getline(prevline, 1024) < 0) return(0);
154 seen = 1;
155 nowline = buf2;
156
157 /* Get nowline and compare if not equal, dump prevline and swap
158 * pointers else continue, bumping seen count */
159 while (getline(nowline, 1024) > 0) {
160 if (!equal(prevline, nowline)) {
161 show(prevline, seen);
162 seen = 1;
163 p = nowline;
164 nowline = prevline;
165 prevline = p;
166 } else
167 seen += 1;
168 }
169 show(prevline, seen);
170 return 0;
171}
172
173void usage()
174{
175 fprintf(stderr, "Usage: uniq [-udc] [+n] [-n] [input [output]]\n");
176}
177
178int getline(buf, count)
179char *buf;
180int count;
181{
182 int c;
183 int ct = 0;
184
185 while (ct++ < count) {
186 c = getc(stdin);
187 if (c < 0) return(-1);
188 *buf++ = c;
189 if (c == '\n') {
190 *buf++ = 0;
191 return(ct);
192 }
193 }
194 return(ct);
195}
Note: See TracBrowser for help on using the repository browser.