da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1992-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * uniq
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Written by David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner"[-n?\n@(#)$Id: uniq (AT&T Research) 2009-11-28 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?uniq - Report or filter out repeated lines in a file]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+DESCRIPTION?\buniq\b reads the input, compares adjacent lines, and "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "writes one copy of each input line on the output. The second "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "and succeeding copies of the repeated adjacent lines are not "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "written.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?If the output file, \aoutfile\a, is not specified, \buniq\b writes "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "to standard output. If no \ainfile\a is given, or if the \ainfile\a "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "is \b-\b, \buniq\b reads from standard input with the start of "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "the file defined as the current offset.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[c:count?Output the number of times each line occurred along with "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[d:repeated|duplicates?Output the first of each duplicate line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[D:all-repeated?Output all duplicate lines as a group with an empty "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "line delimiter specified by \adelimit\a:]:?[delimit:=none]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[n:none?Do not delimit duplicate groups.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[p:prepend?Prepend an empty line before each group.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[s:separate?Separate each group with an empty line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[f:skip-fields]#[fields?\afields\a is the number of fields to skip over "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "before checking for uniqueness. A field is the minimal string matching "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "the BRE \b[[:blank:]]]]*[^[:blank:]]]]*\b. -\anumber\a is equivalent to "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "\b--skip-fields\b=\anumber\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[i:ignore-case?Ignore case in comparisons.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s:skip-chars]#[chars?\achars\a is the number of characters to skip over "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "before checking for uniqueness. If specified along with \b-f\b, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the first \achars\a after the first \afields\a are ignored. If "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the \achars\a specifies more characters than are on the line, "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "an empty string will be used for comparison. +\anumber\a is "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "equivalent to \b--skip-chars\b=\anumber\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[u:unique?Output unique lines.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[w:check-chars]#[chars?\achars\a is the number of characters to compare "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "after skipping any specified fields and characters.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n[infile [outfile]]\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+0?The input file was successfully processed.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+>0?An error occurred.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bsort\b(1), \bgrep\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_FLAG 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define D_FLAG 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define U_FLAG 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CWIDTH 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXCNT 9999
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Compare_f)(const char*, const char*, size_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int uniq(Sfio_t *fdin, Sfio_t *fdout, int fields, int chars, int width, int mode, int* all, Compare_f compare)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register int n, f, outsize=0, mb = mbwide();
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register char *cp, *ep, *mp, *bufp, *outp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *orecp, *sbufp=0, *outbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int reclen,oreclen= -1,count=0,cwidth=0,sep,next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&C_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cwidth = CWIDTH+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bufp = sfgetr(fdin,'\n',0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfvalue(fdin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(bufp = sfgetr(fdin,'\n',SF_LASTR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfvalue(fdin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = memcpy(fmtbuf(n + 1), bufp, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp[n++] = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = bufp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = cp + n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (f = fields)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (f-->0 && cp<ep) /* skip over fields */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (cp<ep && *cp==' ' || *cp=='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (cp<ep && *cp!=' ' && *cp!='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (chars)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (f = chars; f; f--)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner mbchar(cp);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp += chars;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((reclen = n - (cp - bufp)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reclen = 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner cp = bufp + n - 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (width >= 0 && width < reclen)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (mb)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner reclen = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner mp = cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while (reclen < width && mp < ep)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner reclen++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner mbchar(mp);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner reclen = mp - cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner reclen = width;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner reclen = -2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(reclen==oreclen && (!reclen || !(*compare)(cp,orecp,reclen)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!all)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(outsize>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(((mode&D_FLAG)&&count==0) || ((mode&U_FLAG)&&count))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(outp!=sbufp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,outp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cwidth)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(count<9)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(f < CWIDTH-1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f++] = ' ';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f++] = '0' + count + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f] = ' ';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(count<MAXCNT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz count++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = CWIDTH;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f--] = ' ';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f--] = '0' + (count % 10);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (count /= 10);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (f >= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz outp[f--] = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outsize -= (CWIDTH+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(outp!=sbufp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sbufp=fmtbuf(outsize)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(sbufp,outp+CWIDTH+1,outsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,outp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outp = sbufp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outp += CWIDTH+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(fdout,"%4d ",count+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfwrite(fdout,outp,outsize) != outsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count = next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfwrite(fdout,outp,outsize) != outsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*all >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *all = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = all && *all > 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save current record */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(outbuff = sfreserve(fdout, 0, 0)) || (outsize = sfvalue(fdout)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outp = outbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(outsize < n+cwidth+sep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* no room in outp, clear lock and use side buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,outp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sbufp = outp=fmtbuf(outsize=n+cwidth+sep)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outsize = n+cwidth+sep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(outp+cwidth+sep,bufp,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outp[cwidth] = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oreclen = reclen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin orecp = outp+cwidth+sep + (cp-bufp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_uniq(int argc, char** argv, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n, mode=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fields=0, chars=0, width=-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *fpin, *fpout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* all = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Compare_f compare = (Compare_f)memcmp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n = optget(argv, usage)) switch (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= C_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= D_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= D_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch ((int)opt_info.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin all = &sep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin compare = (Compare_f)strncasecmp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= U_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*opt_info.option=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fields = opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chars = opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chars = opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'w':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin width = opt_info.num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(all && (mode&C_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "-c and -D are mutually exclusive");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp = *argv) && (argv++,!streq(cp,"-")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(fpin = sfopen(NiL,cp,"r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"%s: cannot open",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fpin = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp = *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(fpout = sfopen(NiL,cp,"w")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(1),"%s: cannot create",cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fpout = sfstdout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "too many arguments");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors = uniq(fpin,fpout,fields,chars,width,mode,all,compare);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fpin!=sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fpin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fpout!=sfstdout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fpout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(error_info.errors);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin