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

  1. /*
  2.  * Count - count lines, words, and characters.
  3.  *
  4.  * Version 37.3 =TP= 29-Jan-92
  5.  *
  6.  * Compile with SAS/C 5.10 and link without startup code:
  7.  *      lc -cqfist -v -b0 -rr -O -ms Count
  8.  *      blink Count.o to Count sd sc
  9.  *      protect Count +p
  10.  *
  11.  * Copyright (c) 1992 Torsten Poulin
  12.  *
  13.  * Torsten Poulin
  14.  * Banebrinken 99, 2, lejlighed 77
  15.  * DK 2400  København NV
  16.  * DENMARK
  17.  */
  18.  
  19. /****** English:COUNT *****************************************************
  20. *
  21. *   FORMAT
  22. *       COUNT [[FROM] <names|patterns>] [LINES] [WORDS] [CHARS]
  23. *
  24. *   TEMPLATE
  25. *       FROM/M,LINES/S,WORDS/S,CHARS/S
  26. *
  27. *   PURPOSE
  28. *       To count lines, words, and characters.
  29. *
  30. *   SPECIFICATION
  31. *       Count counts lines, words, and characters in the named files,
  32. *       or in the default input if no names appear.  It also keeps
  33. *       a total count for all named files.  A word is a maximal
  34. *       string of characters delimited by spaces, tabs, or new-lines.
  35. *
  36. *       The switches LINES, WORDS, and CHARS may be used to specify
  37. *       that a subset of lines, words, and characters are to be
  38. *       reported.  If no switches are given Count defaults to
  39. *       all of them.
  40. *
  41. *       When names are specified on the command line, they will be
  42. *       printed along with the counts.
  43. *
  44. ***************************************************************************
  45. *
  46. */
  47. /****** dansk:COUNT *******************************************************
  48. *
  49. *   FORMAT
  50. *       COUNT [[FROM] <navne|mønstre>] [LINES] [WORDS] [CHARS]
  51. *
  52. *   SKABELON
  53. *       FROM/M,LINES/S,WORDS/S,CHARS/S
  54. *
  55. *   FORMÅL
  56. *       At tælle linjer, ord og tegn.
  57. *
  58. *   SPECIFIKATION
  59. *       Count tæller linjer, ord og tegn i de nævnte filer eller fra
  60. *       sit standardinput hvis ingen navne er angivet.  Den laver
  61. *       også en sluttotal for alle filerne.  Et ord er en maksimal
  62. *       tegnfølge afgrænset af blank-, tabulerings- eller
  63. *       ny-linjetegn.
  64. *
  65. *       Kontakterne LINES, WORDS og CHARS kan bruges til at angive
  66. *       at en delmængde af linjer, ord og tegn skal rapporteres.
  67. *       Hvis der ikke angives nogen kontakter antager Count at der
  68. *       menes dem alle sammen.
  69. *
  70. *       Når filnavne angives på kommandolinjen udskrives de sammen
  71. *       med optællingerne.
  72. *
  73. ***************************************************************************
  74. *
  75. */
  76.  
  77.  
  78. #include <exec/types.h>
  79. #include <exec/memory.h>
  80. #include <dos/dos.h>
  81. #include <dos/dosasl.h>
  82. #include <clib/dos_protos.h>
  83. #include <clib/exec_protos.h>
  84. #include <stdio.h>
  85. #include <string.h>
  86.  
  87. #ifdef __SASC
  88. #include <pragmas/dos_pragmas.h>
  89. #include <pragmas/exec_pragmas.h>
  90. #endif
  91.  
  92. #define MAXNAMELEN 256L
  93.  
  94.  
  95. #define TEMPLATE "FROM/M,LINES/S,WORDS/S,CHARS/S"
  96.  
  97. #define OPT_FROM    0
  98. #define OPT_LINES   1
  99. #define OPT_WORDS   2
  100. #define OPT_CHARS   3
  101.  
  102.  
  103. char const *version = "\0$VER: Count 37.3 (29.1.92)\
  104.  ©1989,91,92 Torsten Poulin";
  105.  
  106. static BOOL count(struct Library *, struct DosLibrary *, BPTR, UBYTE *,
  107.                   BOOL, BOOL, BOOL, ULONG *, ULONG *, ULONG *);
  108.  
  109.  
  110. LONG entrypoint(VOID)
  111. {
  112.     struct Library       *SysBase;
  113.     struct DosBase       *DOSBase;
  114.     struct RDArgs        *args;
  115.     struct AnchorPath    *ap;
  116.     LONG                 arg[4];
  117.     LONG                 rc = RETURN_OK;
  118.     UBYTE                **name;
  119.     UBYTE                *filename;
  120.     BPTR                 fp;
  121.     ULONG                tl, tw, tc;
  122.     ULONG                several = 0;
  123.     
  124.     SysBase = *(struct Library **) 4L;
  125.     if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  126.         goto noDOS;
  127.     
  128.     arg[OPT_FROM] = arg[OPT_LINES] = arg[OPT_WORDS] = arg[OPT_CHARS] = 0L;
  129.     tl = tw = tc = 0L;
  130.     
  131.     if(args = ReadArgs(TEMPLATE, arg, NULL))
  132.     {
  133.         if(!arg[OPT_LINES] && !arg[OPT_WORDS] && !arg[OPT_CHARS])
  134.             arg[OPT_LINES] = arg[OPT_WORDS] = arg[OPT_CHARS] = TRUE;
  135.             
  136.         if(arg[OPT_FROM])
  137.         {
  138.             name = (UBYTE **) arg[OPT_FROM];
  139.             for(; *name; name++)
  140.             {
  141.                 UBYTE *dummy;
  142.                 LONG  IsWild;
  143.             
  144.                 /* Is it a pattern? */
  145.                 if(!(dummy = AllocMem(2 * strlen(*name) + 2, MEMF_PUBLIC)))
  146.                 {
  147.                     PrintFault(ERROR_NO_FREE_STORE, "Count");
  148.                     rc = RETURN_FAIL;
  149.                     break;;
  150.                 }
  151.                 IsWild = ParsePattern(*name, dummy, 2 * strlen(*name) + 2);
  152.                 FreeMem(dummy, 2 * strlen(*name) + 2);
  153.                 if(IsWild == -1)
  154.                 {
  155.                     LONG err = IoErr();
  156.                     PrintFault(err, "Count");
  157.                     rc = RETURN_FAIL;
  158.                     break;
  159.                 }
  160.  
  161.                 if(!(ap = AllocMem(sizeof(struct AnchorPath) + MAXNAMELEN,
  162.                                    MEMF_PUBLIC | MEMF_CLEAR)))
  163.                 {
  164.                     PrintFault(ERROR_NO_FREE_STORE, "Count");
  165.                     rc = RETURN_FAIL;
  166.                     break;
  167.                 }
  168.  
  169.                 ap->ap_Strlen = MAXNAMELEN;
  170.  
  171.                 if(!IsWild || MatchFirst(*name, ap) == 0)
  172.                     do
  173.                     {
  174.                         BOOL success;
  175.                         
  176.                         if(IsWild)
  177.                         {
  178.                             filename = ap->ap_Buf;
  179.                             if(ap->ap_Info.fib_DirEntryType > 0)
  180.                                 continue;
  181.                         }
  182.                         else
  183.                             filename = *name;
  184.                             
  185.                         if(!(fp = Open(filename, MODE_OLDFILE)))
  186.                         {
  187.                             LONG err = IoErr();
  188.                             PrintFault(err, filename);
  189.                             continue;
  190.                         }
  191.                         several++;
  192.                         success = count(SysBase, DOSBase, fp, filename,
  193.                                         arg[OPT_LINES],
  194.                                         arg[OPT_WORDS],
  195.                                         arg[OPT_CHARS],
  196.                                         &tl, &tw, &tc);
  197.                         Close(fp);
  198.                         if(!success)
  199.                         {
  200.                             several = 0L;
  201.                             rc = RETURN_WARN;
  202.                             break;
  203.                         }
  204.                     } while(IsWild == 1 && MatchNext(ap) == 0);
  205.                 if(IsWild)
  206.                     MatchEnd(ap);
  207.                 FreeMem(ap, sizeof(struct AnchorPath) + MAXNAMELEN);
  208.  
  209.         }
  210.             if(several > 1)
  211.             {
  212.                 if(arg[OPT_LINES]) VPrintf("%12ld", (LONG *) &tl);
  213.                 if(arg[OPT_WORDS]) VPrintf("%12ld", (LONG *) &tw);
  214.                 if(arg[OPT_CHARS]) VPrintf("%12ld", (LONG *) &tc);
  215.                 PutStr(" total\n");
  216.             }            
  217.         }
  218.         else
  219.             if(!count(SysBase, DOSBase, Input(), NULL,
  220.                       arg[OPT_LINES], arg[OPT_WORDS], arg[OPT_CHARS],
  221.                       &tl, &tw, &tc))
  222.                 rc = RETURN_WARN;
  223.  
  224.         FreeArgs(args);
  225.     }
  226.     else
  227.     {
  228.         LONG err = IoErr();
  229.         PrintFault(err, "Count");
  230.         rc = RETURN_ERROR;
  231.     }
  232.                 
  233.     CloseLibrary((struct DosBase *) DOSBase);
  234.  noDOS:
  235.     return rc;
  236. }
  237.  
  238.  
  239. static BOOL count(struct Library *SysBase, struct DosLibrary *DOSBase,
  240.                   BPTR fp, UBYTE *filename,
  241.                   BOOL lines, BOOL words, BOOL chars,
  242.                   ULONG *tl, ULONG *tw, ULONG *tc)
  243. {
  244.     ULONG   nc, nl, nw;
  245.     BOOL    inword;
  246.     LONG    c;
  247.     register UBYTE breakcheck = 0;
  248.        
  249.     nc = nl = nw = 0L;
  250.     inword = FALSE;
  251.     
  252.     while((c = FGetC(fp)) != -1L)
  253.     {
  254.         if(!(breakcheck -= 4) && SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  255.         {
  256.             PrintFault(ERROR_BREAK, NULL);
  257.             return FALSE;
  258.         }
  259.  
  260.         if(c == '\n')
  261.             nl++;
  262.         nc++;
  263.         if(c == ' ' || c == '\t' || c == '\n') 
  264.             inword = FALSE;
  265.         else if(!inword)
  266.         {
  267.             inword = TRUE;
  268.             nw++;
  269.         }
  270.     }
  271.     
  272.     *tl += nl;
  273.     *tw += nw;
  274.     *tc += nc;
  275.         
  276.     if(lines) VPrintf("%12ld", (LONG *) &nl);
  277.     if(words) VPrintf("%12ld", (LONG *) &nw);
  278.     if(chars) VPrintf("%12ld", (LONG *) &nc);
  279.     if(filename)
  280.     {
  281.         FPutC(Output(), ' ');
  282.         PutStr(filename);
  283.     }
  284.     FPutC(Output(), '\n');
  285.     return TRUE;
  286. }
  287.