home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 1 / FFMCD01.bin / bbs / libdisks / d700t799 / disk774.lha / ExtraCmds / src / Unique.c < prev   
Encoding:
C/C++ Source or Header  |  1992-12-05  |  8.0 KB  |  302 lines

  1. /*
  2.  * Unique - AmigaDOS subset of UNIX uniq.
  3.  *
  4.  * Version 1 =TP= 1989 - Generic version (UNIX style); highly portable
  5.  * Version 2 =TP= 1989 - as above.
  6.  * Version 3 (37.3) =TP= 9-Feb-92 - AmigaDOS 2.0 specific version.
  7.  *
  8.  * Compile with SAS/C v5.10b and link without startup code:
  9.  *      lc -cqfist -v -b0 -rr -O -ms Unique
  10.  *      blink Unique.o to Unique sd sc
  11.  *      protect Unique +p
  12.  *
  13.  * Copyright (c) 1989, 1992 Torsten Poulin
  14.  *
  15.  * Torsten Poulin
  16.  * Banebrinken 99, 2, lejlighed 77
  17.  * DK 2400  København NV
  18.  * DENMARK
  19.  */
  20.  
  21. /****** English:UNIQUE ****************************************************
  22. *
  23. *   FORMAT
  24. *       UNIQUE [[FROM] <file>] [[TO] <file>] [REPEATED][UNIQUE][COUNT]
  25. *
  26. *   TEMPLATE
  27. *       FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S
  28. *
  29. *   PURPOSE
  30. *       To report repeated lines in a file.
  31. *
  32. *   SPECIFICATION
  33. *       The command Unique reads the FROM file comparing adjacent
  34. *       lines.  In the normal case, the second and succeeding copies
  35. *       of repeated lines are removed; the remainder is written
  36. *       on the TO file.  Note that repeated lines must be adjacent
  37. *       to be found (see SORT).  If the UNIQUE switch is used, just
  38. *       the lines that are not repeated in the original file are
  39. *       output.  The REPEATED switch specifies that one copy of just
  40. *       the repeated lines is to be written.  The normal mode ouput
  41. *       is the union of the UNIQUE and REPEATED mode outputs.
  42. *
  43. *       The COUNT switch generates an output report with each line
  44. *       preceeded by a count of the number of times it occured.
  45. *
  46. *       If no FROM file is given input is read from the default
  47. *       input;  likewise if no TO file is given output is written
  48. *       to the default output.
  49. *
  50. *   SEE ALSO
  51. *       COMMON, COUNT, SORT
  52. *
  53. *   BUGS
  54. *       Unique will fail to function correctly given input lines
  55. *       longer than 512 characters.
  56. *
  57. *   UNIX EQUIVALENT
  58. *       uniq(BU_CMD)
  59. *
  60. ***************************************************************************
  61. *
  62. */
  63. /****** dansk:UNIQUE ******************************************************
  64. *
  65. *   FORMAT
  66. *       UNIQUE [[FROM] <fil>] [[TO] <fil>] [REPEATED][UNIQUE][COUNT]
  67. *
  68. *   SKABELON
  69. *       FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S
  70. *
  71. *   FORMÅL
  72. *       At rapportere gentagne linjer i en fil.
  73. *
  74. *   SPECIFIKATION
  75. *       Kommandoen Unique læser filen FROM og sammenligner
  76. *       tilstødende linjer.  I det normale tilfælde fjernes den
  77. *       anden og efterfølgende kopier af gentagne linjer.
  78. *       Resten af filen skrives til filen TO.  Bemærk at gentagne
  79. *       linjer skal stå lige efter hinanden for at blive fundet
  80. *       (se SORT).  Hvis kontakten UNIQUE bruges bliver kun de
  81. *       linjer der ikke er gentaget i den oprindelige fil
  82. *       udskrevet.  Kontakten REPEATED angiver at én kopi af kun
  83. *       de gentagne linjer skal udskrives.  Den normale adfærd
  84. *       er at udskrive foreningsmængden af hvad UNIQUE og
  85. *       REPEATED ville producere.
  86. *
  87. *       Kontakten COUNT frembringer en uddatarapport hvor hver
  88. *       linje er foranstillet antallet af gange den forekom.
  89. *
  90. *       Hvis argumentet FROM ikke er angivet, læses inddata fra
  91. *       standardinputtet.  Ligeledes skrives uddata til standard-
  92. *       outputtet hvis argumentet TO er udeladt.
  93. *
  94. *   SE OGSÅ
  95. *       COMMON, COUNT, SORT
  96. *
  97. *   FEJL OG MANGLER
  98. *       Unique vil ikke virke korrekt hvis nogle inddatalinjer
  99. *       er længere end 512 tegn.
  100. *
  101. *   TILSVARENDE I UNIX
  102. *       uniq(BU_CMD)
  103. *
  104. ***************************************************************************
  105. *
  106. */
  107.  
  108.  
  109. #include <exec/types.h>
  110. #include <exec/memory.h>
  111. #include <dos/dos.h>
  112. #include <dos/dosasl.h>
  113. #include <clib/dos_protos.h>
  114. #include <clib/exec_protos.h>
  115. #include <stdio.h>
  116. #include <string.h>
  117.  
  118. #ifdef __SASC
  119. #include <pragmas/dos_pragmas.h>
  120. #include <pragmas/exec_pragmas.h>
  121. #pragma libcall UtilityBase Stricmp A2 9802
  122. #endif
  123.  
  124. /* my include files are for early V36, so ... */
  125. LONG Stricmp(char *, char *);
  126.  
  127. #define MAXLINE (512+1)
  128. #define MAXNAME 50
  129.  
  130. #define TEMPLATE "FROM,TO,REPEATED/S,UNIQUE/S,COUNT/S"
  131.  
  132. #define OPT_FROM   0
  133. #define OPT_TO     1
  134. #define OPT_REPEAT 2
  135. #define OPT_UNIQUE 3
  136. #define OPT_COUNT  4
  137.  
  138. char const *version = "\0$VER: Unique 37.3 (9.2.92) ©1989,92 Torsten Poulin";
  139.  
  140. static BOOL ioerr(struct DosLibrary *DOSBase);
  141. static LONG unique(struct Library *SysBase, struct DosLibrary *DOSBase,
  142.                    struct Library *UtilityBase, BPTR in, BPTR out,
  143.                    BOOL dflag, BOOL uflag, BOOL cflag);
  144.  
  145.  
  146. LONG entrypoint(VOID)
  147. {
  148.     BPTR in, out;
  149.     ULONG err;
  150.     LONG rc = RETURN_OK;
  151.     
  152.     struct Library *SysBase;
  153.     struct DosBase *DOSBase;
  154.     struct Library *UtilityBase;
  155.     struct RDArgs  *args;
  156.     LONG           arg[5];
  157.         
  158.     SysBase = *(struct Library **) 4L;
  159.     if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  160.     {
  161.         rc = RETURN_FAIL;
  162.         goto noDOS;
  163.     }
  164.     if(!(UtilityBase = OpenLibrary("utility.library", 37L)))
  165.     {
  166.         rc = RETURN_FAIL;
  167.         goto noUtility;
  168.     }
  169.     
  170.     arg[OPT_FROM] = arg[OPT_TO] = 
  171.     arg[OPT_REPEAT] = arg[OPT_UNIQUE] = arg[OPT_COUNT] = 0L;
  172.     
  173.     if(args = ReadArgs(TEMPLATE, arg, NULL))
  174.     {
  175.         if(arg[OPT_FROM])
  176.         {
  177.             if(!(in = Open((UBYTE *) arg[OPT_FROM], MODE_OLDFILE)))
  178.             {
  179.                 err = IoErr();
  180.                 PrintFault(err, (UBYTE *) arg[OPT_FROM]);
  181.                 rc = RETURN_ERROR;
  182.                 goto errExit;
  183.             }
  184.         }
  185.         else
  186.             in = Input();
  187.  
  188.         if(arg[OPT_TO])
  189.         {
  190.             if(!(out = Open((UBYTE *) arg[OPT_TO], MODE_NEWFILE)))
  191.             {
  192.                 err = IoErr();
  193.                 PrintFault(err, (UBYTE *) arg[OPT_TO]);
  194.                 rc = RETURN_ERROR;
  195.                 goto errExit;
  196.             }
  197.         }
  198.         else
  199.             out = Output();
  200.         
  201.         rc = unique(SysBase, DOSBase, UtilityBase, in, out,
  202.                     (BOOL) arg[OPT_REPEAT],
  203.                     (BOOL) arg[OPT_UNIQUE],
  204.                     (BOOL) arg[OPT_COUNT]);
  205.  
  206.         if(arg[OPT_FROM])
  207.             Close(in);
  208.         if(arg[OPT_TO])
  209.             Close(out);
  210.  
  211.         FreeArgs(args);
  212.     }
  213.     else
  214.     {
  215.         LONG err = IoErr();
  216.         PrintFault(err, "Unique");
  217.         rc = RETURN_ERROR;
  218.     }
  219.     
  220.  errExit:
  221.     CloseLibrary(UtilityBase);
  222.  noUtility:
  223.     CloseLibrary((struct Library *) DOSBase);
  224.  noDOS:
  225.     return rc;
  226. }
  227.  
  228.  
  229. static LONG unique(struct Library *SysBase, struct DosLibrary *DOSBase,
  230.                    struct Library *UtilityBase, BPTR in, BPTR out,
  231.                    BOOL dflag, BOOL uflag, BOOL cflag)
  232. {
  233.     ULONG count;
  234.     UBYTE prevline[MAXLINE];
  235.     UBYTE nextline[MAXLINE];
  236.     UBYTE *temp;
  237.     UBYTE *prev = prevline;
  238.     UBYTE *next = nextline;
  239.     
  240.     if(dflag && uflag)
  241.         dflag = uflag = FALSE;
  242.  
  243.     count = 1;
  244.     if(FGets(in, prev, MAXLINE) == NULL)
  245.     {
  246.         if(ioerr(DOSBase))
  247.             return RETURN_FAIL;
  248.     }
  249.     else
  250.     {
  251.         while(FGets(in, next, MAXLINE) != NULL)
  252.         {
  253.  
  254.             if(Stricmp(prev, next) == 0)
  255.                 ++count;
  256.             else if((!dflag && !uflag) ||
  257.                     (count == 2 && !uflag) ||
  258.                     (count == 1 && uflag))
  259.             {
  260.                 if(cflag)
  261.                     VFPrintf(out, "%10lu ", (LONG *) &count);
  262.                 FPuts(out, prev);
  263.                 count = 1;
  264.             }
  265.             else
  266.                 count = 1;
  267.             temp = prev;
  268.             prev = next;
  269.             next = temp;
  270.  
  271.             if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  272.             {
  273.                 PrintFault(ERROR_BREAK, NULL);
  274.                 return RETURN_WARN;
  275.             }
  276.         }
  277.         if(ioerr(DOSBase))
  278.             return RETURN_FAIL;
  279.  
  280.         if((!dflag && !uflag) ||
  281.            (count == 2 && !uflag) ||
  282.            (count == 1 && uflag))
  283.         {
  284.             if(cflag)
  285.                 VFPrintf(out, "%10lu ", (LONG *) &count);
  286.             FPuts(out, prev);
  287.         }
  288.     }
  289.     return RETURN_OK;
  290. }
  291.  
  292.  
  293. static BOOL ioerr(struct DosLibrary *DOSBase)
  294. {
  295.     LONG err;
  296.     
  297.     if(!(err = IoErr()))
  298.         return FALSE;
  299.     PrintFault(err, "Unique");
  300.     return TRUE;
  301. }
  302.