cc17b27a2b
3 sets of libraries are built now: . ack: all libraries that ack can compile (/usr/lib/i386/) . clang+elf: all libraries with minix headers (/usr/lib/) . clang+elf: all libraries with netbsd headers (/usr/netbsd/) Once everything can be compiled with netbsd libraries and headers, the /usr/netbsd hierarchy will be obsolete and its libraries compiled with netbsd headers will be installed in /usr/lib, and its headers in /usr/include. (i.e. minix libc and current minix headers set will be gone.) To use the NetBSD libc system (libraries + headers) before it is the default libc, see: http://wiki.minix3.org/en/DevelopersGuide/UsingNetBSDCode This wiki page also documents the maintenance of the patch files of minix-specific changes to imported NetBSD code. Changes in this commit: . libsys: Add NBSD compilation and create a safe NBSD-based libc. . Port rest of libraries (except libddekit) to new header system. . Enable compilation of libddekit with new headers. . Enable kernel compilation with new headers. . Enable drivers compilation with new headers. . Port legacy commands to new headers and libc. . Port servers to new headers. . Add <sys/sigcontext.h> in compat library. . Remove dependency file in tree. . Enable compilation of common/lib/libc/atomic in libsys . Do not generate RCSID strings in libc. . Temporarily disable zoneinfo as they are incompatible with NetBSD format . obj-nbsd for .gitignore . Procfs: use only integer arithmetic. (Antoine Leca) . Increase ramdisk size to create NBSD-based images. . Remove INCSYMLINKS handling hack. . Add nbsd_include/sys/exec_elf.h . Enable ELF compilation with NBSD libc. . Add 'make nbsdsrc' in tools to download reference NetBSD sources. . Automate minix-port.patch creation. . Avoid using fstavfs() as it is *extremely* slow and unneeded. . Set err() as PRIVATE to avoid name clash with libc. . [NBSD] servers/vm: remove compilation warnings. . u32 is not a long in NBSD headers. . UPDATING info on netbsd hierarchy . commands fixes for netbsd libc
199 lines
3.6 KiB
C
199 lines
3.6 KiB
C
/* uniq - compact repeated lines Author: John Woods */
|
|
/* Uniq [-udc] [-n] [+n] [infile [outfile]]
|
|
*
|
|
* Written 02/08/86 by John Woods, placed into public domain. Enjoy.
|
|
*
|
|
*/
|
|
|
|
/* If the symbol WRITE_ERROR is defined, uniq will exit(1) if it gets a
|
|
* write error on the output. This is not (of course) how V7 uniq does it,
|
|
* so undefine the symbol if you want to lose your output to a full disk
|
|
*/
|
|
|
|
#define WRITE_ERROR 1
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
char buffer[BUFSIZ];
|
|
int uflag = 1; /* default is union of -d and -u outputs */
|
|
int dflag = 1; /* flags are mutually exclusive */
|
|
int cflag = 0;
|
|
int fields = 0;
|
|
int chars = 0;
|
|
|
|
#ifdef __NBSD_LIBC
|
|
#define getline unix_getline
|
|
#endif
|
|
|
|
_PROTOTYPE(int main, (int argc, char **argv));
|
|
_PROTOTYPE(FILE *xfopen, (char *fn, char *mode));
|
|
_PROTOTYPE(char *skip, (char *s));
|
|
_PROTOTYPE(int equal, (char *s1, char *s2));
|
|
_PROTOTYPE(void show, (char *line, int count));
|
|
_PROTOTYPE(int uniq, (void));
|
|
_PROTOTYPE(void usage, (void));
|
|
_PROTOTYPE(int getline, (char *buf, int count));
|
|
|
|
FILE *xfopen(fn, mode)
|
|
char *fn, *mode;
|
|
{
|
|
FILE *p;
|
|
|
|
if ((p = fopen(fn, mode)) == NULL) {
|
|
perror("uniq");
|
|
fflush(stdout);
|
|
exit(1);
|
|
}
|
|
return(p);
|
|
}
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
char *p;
|
|
int inf = -1, outf;
|
|
|
|
setbuf(stdout, buffer);
|
|
for (--argc, ++argv; argc > 0 && (**argv == '-' || **argv == '+');
|
|
--argc, ++argv) {
|
|
if (**argv == '+')
|
|
chars = atoi(*argv + 1);
|
|
else if (isdigit(argv[0][1]))
|
|
fields = atoi(*argv + 1);
|
|
else if (argv[0][1] == '\0')
|
|
inf = 0; /* - is stdin */
|
|
else
|
|
for (p = *argv + 1; *p; p++) {
|
|
switch (*p) {
|
|
case 'd':
|
|
dflag = 1;
|
|
uflag = 0;
|
|
break;
|
|
case 'u':
|
|
uflag = 1;
|
|
dflag = 0;
|
|
break;
|
|
case 'c': cflag = 1; break;
|
|
default: usage();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Input file */
|
|
if (argc == 0)
|
|
inf = 0;
|
|
else if (inf == -1) { /* if - was not given */
|
|
fclose(stdin);
|
|
xfopen(*argv++, "r");
|
|
argc--;
|
|
}
|
|
if (argc == 0)
|
|
outf = 1;
|
|
else {
|
|
fclose(stdout);
|
|
xfopen(*argv++, "w");
|
|
argc--;
|
|
}
|
|
|
|
uniq();
|
|
fflush(stdout);
|
|
return(0);
|
|
}
|
|
|
|
char *skip(s)
|
|
char *s;
|
|
{
|
|
int n;
|
|
|
|
/* Skip fields */
|
|
for (n = fields; n > 0; --n) {
|
|
/* Skip blanks */
|
|
while (*s && (*s == ' ' || *s == '\t')) s++;
|
|
if (!*s) return s;
|
|
while (*s && (*s != ' ' && *s != '\t')) s++;
|
|
if (!*s) return s;
|
|
}
|
|
|
|
/* Skip characters */
|
|
for (n = chars; n > 0; --n) {
|
|
if (!*s) return s;
|
|
s++;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
int equal(s1, s2)
|
|
char *s1, *s2;
|
|
{
|
|
return !strcmp(skip(s1), skip(s2));
|
|
}
|
|
|
|
void show(line, count)
|
|
char *line;
|
|
int count;
|
|
{
|
|
if (cflag)
|
|
printf("%4d %s", count, line);
|
|
else {
|
|
if ((uflag && count == 1) || (dflag && count != 1))
|
|
printf("%s", line);
|
|
}
|
|
}
|
|
|
|
/* The meat of the whole affair */
|
|
char *nowline, *prevline, buf1[1024], buf2[1024];
|
|
|
|
int uniq()
|
|
{
|
|
char *p;
|
|
int seen;
|
|
|
|
/* Setup */
|
|
prevline = buf1;
|
|
if (getline(prevline, 1024) < 0) return(0);
|
|
seen = 1;
|
|
nowline = buf2;
|
|
|
|
/* Get nowline and compare if not equal, dump prevline and swap
|
|
* pointers else continue, bumping seen count */
|
|
while (getline(nowline, 1024) > 0) {
|
|
if (!equal(prevline, nowline)) {
|
|
show(prevline, seen);
|
|
seen = 1;
|
|
p = nowline;
|
|
nowline = prevline;
|
|
prevline = p;
|
|
} else
|
|
seen += 1;
|
|
}
|
|
show(prevline, seen);
|
|
return 0;
|
|
}
|
|
|
|
void usage()
|
|
{
|
|
fprintf(stderr, "Usage: uniq [-udc] [+n] [-n] [input [output]]\n");
|
|
}
|
|
|
|
int getline(buf, count)
|
|
char *buf;
|
|
int count;
|
|
{
|
|
int c;
|
|
int ct = 0;
|
|
|
|
while (ct++ < count) {
|
|
c = getc(stdin);
|
|
if (c < 0) return(-1);
|
|
*buf++ = c;
|
|
if (c == '\n') {
|
|
*buf++ = 0;
|
|
return(ct);
|
|
}
|
|
}
|
|
return(ct);
|
|
}
|