home *** CD-ROM | disk | FTP | other *** search
- /*
- * Unique - AmigaDOS subset of UNIX uniq.
- *
- * Version 1 =TP= 1989 - Generic version (UNIX style); highly portable
- * Version 2 =TP= 1989 - as above.
- * Version 3 (37.3) =TP= 9-Feb-92 - AmigaDOS 2.0 specific version.
- *
- * Compile with SAS/C v5.10b and link without startup code:
- * lc -cqfist -v -b0 -rr -O -ms Unique
- * blink Unique.o to Unique sd sc
- * protect Unique +p
- *
- * Copyright (c) 1989, 1992 Torsten Poulin
- *
- * Torsten Poulin
- * Banebrinken 99, 2, lejlighed 77
- * DK 2400 København NV
- * DENMARK
- */
-
- /****** English:UNIQUE ****************************************************
- *
- * FORMAT
- * UNIQUE [[FROM] <file>] [[TO] <file>] [REPEATED][UNIQUE][COUNT]
- *
- * TEMPLATE
- * FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S
- *
- * PURPOSE
- * To report repeated lines in a file.
- *
- * SPECIFICATION
- * The command Unique reads the FROM file comparing adjacent
- * lines. In the normal case, the second and succeeding copies
- * of repeated lines are removed; the remainder is written
- * on the TO file. Note that repeated lines must be adjacent
- * to be found (see SORT). If the UNIQUE switch is used, just
- * the lines that are not repeated in the original file are
- * output. The REPEATED switch specifies that one copy of just
- * the repeated lines is to be written. The normal mode ouput
- * is the union of the UNIQUE and REPEATED mode outputs.
- *
- * The COUNT switch generates an output report with each line
- * preceeded by a count of the number of times it occured.
- *
- * If no FROM file is given input is read from the default
- * input; likewise if no TO file is given output is written
- * to the default output.
- *
- * SEE ALSO
- * COMMON, COUNT, SORT
- *
- * BUGS
- * Unique will fail to function correctly given input lines
- * longer than 512 characters.
- *
- * UNIX EQUIVALENT
- * uniq(BU_CMD)
- *
- ***************************************************************************
- *
- */
- /****** dansk:UNIQUE ******************************************************
- *
- * FORMAT
- * UNIQUE [[FROM] <fil>] [[TO] <fil>] [REPEATED][UNIQUE][COUNT]
- *
- * SKABELON
- * FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S
- *
- * FORMÅL
- * At rapportere gentagne linjer i en fil.
- *
- * SPECIFIKATION
- * Kommandoen Unique læser filen FROM og sammenligner
- * tilstødende linjer. I det normale tilfælde fjernes den
- * anden og efterfølgende kopier af gentagne linjer.
- * Resten af filen skrives til filen TO. Bemærk at gentagne
- * linjer skal stå lige efter hinanden for at blive fundet
- * (se SORT). Hvis kontakten UNIQUE bruges bliver kun de
- * linjer der ikke er gentaget i den oprindelige fil
- * udskrevet. Kontakten REPEATED angiver at én kopi af kun
- * de gentagne linjer skal udskrives. Den normale adfærd
- * er at udskrive foreningsmængden af hvad UNIQUE og
- * REPEATED ville producere.
- *
- * Kontakten COUNT frembringer en uddatarapport hvor hver
- * linje er foranstillet antallet af gange den forekom.
- *
- * Hvis argumentet FROM ikke er angivet, læses inddata fra
- * standardinputtet. Ligeledes skrives uddata til standard-
- * outputtet hvis argumentet TO er udeladt.
- *
- * SE OGSÅ
- * COMMON, COUNT, SORT
- *
- * FEJL OG MANGLER
- * Unique vil ikke virke korrekt hvis nogle inddatalinjer
- * er længere end 512 tegn.
- *
- * TILSVARENDE I UNIX
- * uniq(BU_CMD)
- *
- ***************************************************************************
- *
- */
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <dos/dosasl.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <stdio.h>
- #include <string.h>
-
- #ifdef __SASC
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/exec_pragmas.h>
- #pragma libcall UtilityBase Stricmp A2 9802
- #endif
-
- /* my include files are for early V36, so ... */
- LONG Stricmp(char *, char *);
-
- #define MAXLINE (512+1)
- #define MAXNAME 50
-
- #define TEMPLATE "FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S"
-
- #define OPT_FROM 0
- #define OPT_TO 1
- #define OPT_REPEAT 2
- #define OPT_UNIQUE 3
- #define OPT_COUNT 4
-
- char const *version = "\0$VER: Unique 37.3 (9.2.92) ©1989,92 Torsten Poulin";
-
- static BOOL ioerr(struct DosLibrary *DOSBase);
- static LONG unique(struct Library *SysBase, struct DosLibrary *DOSBase,
- struct Library *UtilityBase, BPTR in, BPTR out,
- BOOL dflag, BOOL uflag, BOOL cflag);
-
-
- LONG entrypoint(VOID)
- {
- BPTR in, out;
- ULONG err;
- LONG rc = RETURN_OK;
-
- struct Library *SysBase;
- struct DosBase *DOSBase;
- struct Library *UtilityBase;
- struct RDArgs *args;
- LONG arg[5];
-
- SysBase = *(struct Library **) 4L;
- if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto noDOS;
- }
- if(!(UtilityBase = OpenLibrary("utility.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto noUtility;
- }
-
- arg[OPT_FROM] = arg[OPT_TO] =
- arg[OPT_REPEAT] = arg[OPT_UNIQUE] = arg[OPT_COUNT] = 0L;
-
- if(args = ReadArgs(TEMPLATE, arg, NULL))
- {
- if(arg[OPT_FROM])
- {
- if(!(in = Open((UBYTE *) arg[OPT_FROM], MODE_OLDFILE)))
- {
- err = IoErr();
- PrintFault(err, (UBYTE *) arg[OPT_FROM]);
- rc = RETURN_ERROR;
- goto errExit;
- }
- }
- else
- in = Input();
-
- if(arg[OPT_TO])
- {
- if(!(out = Open((UBYTE *) arg[OPT_TO], MODE_NEWFILE)))
- {
- err = IoErr();
- PrintFault(err, (UBYTE *) arg[OPT_TO]);
- rc = RETURN_ERROR;
- goto errExit;
- }
- }
- else
- out = Output();
-
- rc = unique(SysBase, DOSBase, UtilityBase, in, out,
- (BOOL) arg[OPT_REPEAT],
- (BOOL) arg[OPT_UNIQUE],
- (BOOL) arg[OPT_COUNT]);
-
- if(arg[OPT_FROM])
- Close(in);
- if(arg[OPT_TO])
- Close(out);
-
- FreeArgs(args);
- }
- else
- {
- LONG err = IoErr();
- PrintFault(err, "Unique");
- rc = RETURN_ERROR;
- }
-
- errExit:
- CloseLibrary(UtilityBase);
- noUtility:
- CloseLibrary((struct Library *) DOSBase);
- noDOS:
- return rc;
- }
-
-
- static LONG unique(struct Library *SysBase, struct DosLibrary *DOSBase,
- struct Library *UtilityBase, BPTR in, BPTR out,
- BOOL dflag, BOOL uflag, BOOL cflag)
- {
- ULONG count;
- UBYTE prevline[MAXLINE];
- UBYTE nextline[MAXLINE];
- UBYTE *temp;
- UBYTE *prev = prevline;
- UBYTE *next = nextline;
-
- if(dflag && uflag)
- dflag = uflag = FALSE;
-
- count = 1;
- if(FGets(in, prev, MAXLINE) == NULL)
- {
- if(ioerr(DOSBase))
- return RETURN_FAIL;
- }
- else
- {
- while(FGets(in, next, MAXLINE) != NULL)
- {
-
- if(Stricmp(prev, next) == 0)
- ++count;
- else if((!dflag && !uflag) ||
- (count == 2 && !uflag) ||
- (count == 1 && uflag))
- {
- if(cflag)
- VFPrintf(out, "%10lu ", (LONG *) &count);
- FPuts(out, prev);
- count = 1;
- }
- else
- count = 1;
- temp = prev;
- prev = next;
- next = temp;
-
- if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
- {
- PrintFault(ERROR_BREAK, NULL);
- return RETURN_WARN;
- }
- }
- if(ioerr(DOSBase))
- return RETURN_FAIL;
-
- if((!dflag && !uflag) ||
- (count == 2 && !uflag) ||
- (count == 1 && uflag))
- {
- if(cflag)
- VFPrintf(out, "%10lu ", (LONG *) &count);
- FPuts(out, prev);
- }
- }
- return RETURN_OK;
- }
-
-
- static BOOL ioerr(struct DosLibrary *DOSBase)
- {
- LONG err;
-
- if(!(err = IoErr()))
- return FALSE;
- PrintFault(err, "Unique");
- return TRUE;
- }
-