|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Case Larsen. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)uniq.c 5.2 (Berkeley) 6/1/90"; ! 31: #endif /* not lint */ ! 32: ! 33: #include <stdio.h> ! 34: #include <ctype.h> ! 35: ! 36: int cflag, dflag, uflag; ! 37: int numchars, numfields, repeats; ! 38: ! 39: #define MAXLINELEN (2048 + 1) ! 40: ! 41: main (argc,argv) ! 42: int argc; ! 43: char **argv; ! 44: { ! 45: extern int optind; ! 46: FILE *ifp, *ofp, *file(); ! 47: int ch; ! 48: register char *t1, *t2; ! 49: char *prevline, *thisline, *malloc(), *skip(); ! 50: ! 51: while ((ch = getopt(argc, argv, "-cdu123456789")) != EOF) ! 52: switch (ch) { ! 53: case '-': ! 54: --optind; ! 55: goto done; ! 56: case 'c': ! 57: cflag = 1; ! 58: break; ! 59: case 'd': ! 60: dflag = 1; ! 61: break; ! 62: case 'u': ! 63: uflag = 1; ! 64: break; ! 65: /* ! 66: * since -n is a valid option that could be picked up by ! 67: * getopt, but is better handled by the +n and -n code, we ! 68: * break out. ! 69: */ ! 70: case '1': case '2': case '3': case '4': ! 71: case '5': case '6': case '7': case '8': case '9': ! 72: --optind; ! 73: goto done; ! 74: case '?': ! 75: default: ! 76: usage(); ! 77: } ! 78: ! 79: done: argc -= optind; ! 80: argv +=optind; ! 81: ! 82: /* if no flags are set, default is -d -u */ ! 83: if (cflag) { ! 84: if (dflag || uflag) ! 85: usage(); ! 86: } else if (!dflag && !uflag) ! 87: dflag = uflag = 1; ! 88: ! 89: /* because of the +, getopt is messed up */ ! 90: for (; **argv == '+' || **argv == '-'; ++argv, --argc) ! 91: switch (**argv) { ! 92: case '+': ! 93: if ((numchars = atoi(*argv + 1)) < 0) ! 94: goto negerr; ! 95: break; ! 96: case '-': ! 97: if ((numfields = atoi(*argv + 1)) < 0) { ! 98: negerr: (void)fprintf(stderr, ! 99: "uniq: negative field/char skip value.\n"); ! 100: usage(); ! 101: } ! 102: break; ! 103: } ! 104: ! 105: switch(argc) { ! 106: case 0: ! 107: ifp = stdin; ! 108: ofp = stdout; ! 109: break; ! 110: case 1: ! 111: ifp = file(argv[0], "r"); ! 112: ofp = stdout; ! 113: break; ! 114: case 2: ! 115: ifp = file(argv[0], "r"); ! 116: ofp = file(argv[1], "w"); ! 117: break; ! 118: default: ! 119: usage(); ! 120: } ! 121: ! 122: prevline = malloc(MAXLINELEN); ! 123: thisline = malloc(MAXLINELEN); ! 124: (void)fgets(prevline, MAXLINELEN, ifp); ! 125: ! 126: while (fgets(thisline, MAXLINELEN, ifp)) { ! 127: /* if requested get the chosen fields + character offsets */ ! 128: if (numfields || numchars) { ! 129: t1 = skip(thisline); ! 130: t2 = skip(prevline); ! 131: } else { ! 132: t1 = thisline; ! 133: t2 = prevline; ! 134: } ! 135: ! 136: /* if different, print; set previous to new value */ ! 137: if (strcmp(t1, t2)) { ! 138: show(ofp, prevline); ! 139: t1 = prevline; ! 140: prevline = thisline; ! 141: thisline = t1; ! 142: repeats = 0; ! 143: } ! 144: else ! 145: ++repeats; ! 146: } ! 147: show(ofp, prevline); ! 148: exit(0); ! 149: } ! 150: ! 151: /* ! 152: * show -- ! 153: * output a line depending on the flags and number of repetitions ! 154: * of the line. ! 155: */ ! 156: show(ofp, str) ! 157: FILE *ofp; ! 158: char *str; ! 159: { ! 160: if (cflag) ! 161: (void)fprintf(ofp, "%4d %s", repeats + 1, str); ! 162: if (dflag && repeats || uflag && !repeats) ! 163: (void)fprintf(ofp, "%s", str); ! 164: } ! 165: ! 166: char * ! 167: skip(str) ! 168: register char *str; ! 169: { ! 170: register int infield, nchars, nfields; ! 171: ! 172: for (nfields = numfields, infield = 0; nfields && *str; ++str) ! 173: if (isspace(*str)) { ! 174: if (infield) { ! 175: infield = 0; ! 176: --nfields; ! 177: } ! 178: } else if (!infield) ! 179: infield = 1; ! 180: for (nchars = numchars; nchars-- && *str; ++str); ! 181: return(str); ! 182: } ! 183: ! 184: FILE * ! 185: file(name, mode) ! 186: char *name, *mode; ! 187: { ! 188: FILE *fp; ! 189: ! 190: if (!(fp = fopen(name, mode))) { ! 191: (void)fprintf(stderr, "uniq: can't open %s.\n", name); ! 192: exit(1); ! 193: } ! 194: return(fp); ! 195: } ! 196: ! 197: usage() ! 198: { ! 199: (void)fprintf(stderr, ! 200: "usage: uniq [-c | -du] [- #fields] [+ #chars] [input [output]]\n"); ! 201: exit(1); ! 202: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.