morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base
Log | Files | Refs

uniq.c (1581B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <unistd.h>
      6 
      7 #include "text.h"
      8 #include "util.h"
      9 
     10 static void uniqline(char *);
     11 static void uniq(FILE *, const char *);
     12 static void uniqfinish(void);
     13 
     14 static const char *countfmt = "";
     15 static int dflag = 0;
     16 static int uflag = 0;
     17 
     18 static char *prevline = NULL;
     19 static long prevlinecount = 0;
     20 
     21 static void
     22 usage(void)
     23 {
     24 	eprintf("usage: %s [-cdiu] [input]]\n", argv0);
     25 }
     26 
     27 int
     28 main(int argc, char *argv[])
     29 {
     30 	FILE *fp;
     31 
     32 	ARGBEGIN {
     33 	case 'i':
     34 		eprintf("not implemented\n");
     35 	case 'c':
     36 		countfmt = "%7ld ";
     37 		break;
     38 	case 'd':
     39 		dflag = 1;
     40 		break;
     41 	case 'u':
     42 		uflag = 1;
     43 		break;
     44 	default:
     45 		usage();
     46 	} ARGEND;
     47 
     48 	if (argc == 0) {
     49 		uniq(stdin, "<stdin>");
     50 	} else if (argc == 1) {
     51 		if (!(fp = fopen(argv[0], "r")))
     52 			eprintf("fopen %s:", argv[0]);
     53 		uniq(fp, argv[0]);
     54 		fclose(fp);
     55 	} else
     56 		usage();
     57 	uniqfinish();
     58 
     59 	return 0;
     60 }
     61 
     62 static void
     63 uniqline(char *l)
     64 {
     65 	int linesequel = (!l || !prevline)
     66 		? l == prevline
     67 		: !strcmp(l, prevline);
     68 
     69 	if (linesequel) {
     70 		++prevlinecount;
     71 		return;
     72 	}
     73 
     74 	if (prevline) {
     75 		if ((prevlinecount == 1 && !dflag) ||
     76 		    (prevlinecount != 1 && !uflag)) {
     77 			printf(countfmt, prevlinecount);
     78 			fputs(prevline, stdout);
     79 		}
     80 		free(prevline);
     81 		prevline = NULL;
     82 	}
     83 
     84 	if (l)
     85 		prevline = estrdup(l);
     86 	prevlinecount = 1;
     87 }
     88 
     89 static void
     90 uniq(FILE *fp, const char *str)
     91 {
     92 	char *buf = NULL;
     93 	size_t size = 0;
     94 
     95 	while (getline(&buf, &size, fp) != -1)
     96 		uniqline(buf);
     97 }
     98 
     99 static void
    100 uniqfinish(void)
    101 {
    102 	uniqline(NULL);
    103 }