Plan 9 from Bell Labs’s /usr/web/sources/patch/sorry/uniq-libstring/uniq.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * Deal with duplicated lines in a file
 */
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <String.h>
#include <ctype.h>

int	fields	= 0;
int	letters	= 0;
int	linec	= 0;
char	mode;
int	uniq;
String	*b1, *b2;
Biobuf	fin;
Biobuf	fout;

String*	gline(void);
void	pline(String *buf);
int	equal(String *b1, String *b2);
char*	skip(char *s);

void
main(int argc, char *argv[])
{
	int f;

	argv0 = argv[0];
	f = 0;
	while(argc > 1) {
		if(*argv[1] == '-') {
			if(isdigit(argv[1][1]))
				fields = atoi(&argv[1][1]);
			else
				mode = argv[1][1];
			argc--;
			argv++;
			continue;
		}
		if(*argv[1] == '+') {
			letters = atoi(&argv[1][1]);
			argc--;
			argv++;
			continue;
		}
		f = open(argv[1], 0);
		if(f < 0)
			sysfatal("cannot open %s", argv[1]);
		break;
	}
	if(argc > 2)
		sysfatal("unexpected argument %s", argv[2]);
	Binit(&fin, f, OREAD);
	Binit(&fout, 1, OWRITE);

	if((b1 = gline()) == nil)
		exits(0);
	for(;;) {
		linec++;
		if((b2 = gline()) == nil) {
			pline(b1);
			exits(0);
		}
		if(!equal(b1, b2)) {
			pline(b1);
			linec = 0;
			do {
				linec++;
				if((b1 = gline()) == nil) {
					pline(b2);
					exits(0);
				}
			} while(equal(b2, b1));
			pline(b2);
			linec = 0;
		}
	}
}

String *
gline(void)
{
	char *t;

	if((t = Brdstr(&fin, '\n', 1)) == 0)
		return nil;
	return s_copy(t);
}

void
pline(String *buf)
{
	switch(mode) {

	case 'u':
		if(uniq){
			uniq = 0;
			return;
		}
		break;

	case 'd':
		if(uniq)
			break;
		return;

	case 'c':
		Bprint(&fout, "%4d ", linec);
	}
	uniq = 0;
	Bprint(&fout, "%s\n", s_to_c(buf));
}

int
equal(String *d1, String *d2)
{
	char c, *b1, *b2;

	b1 = s_to_c(d1);
	b2 = s_to_c(d2);
	if(s_len(d1) != s_len(d2))
		return 0;
	if(fields || letters){
		b1 = skip(b1);
		b2 = skip(b2);
	}
	for(;;){
		c = *b1++;
		if(c != *b2++) {
			if(c == 0 && mode == 's')
				return 1;
			return 0;
		}
		if(c == 0) {
			uniq++;
			return 1;
		}
	}
}

char*
skip(char *s)
{
	int nf, nl;

	nf = nl = 0;
	while(nf++ < fields) {
		while(*s == ' ' || *s == '\t')
			s++;
		while(!(*s == ' ' || *s == '\t' || *s == 0) ) 
			s++;
	}
	while(nl++ < letters && *s != 0) 
			s++;
	return s;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.