home *** CD-ROM | disk | FTP | other *** search
- /*
- Wc - Text statistics
-
- Original effort by Fabio Rossetti. Inspired by the wc program
- by Gary Brant found on <>< 179 and the WC utility found
- in the Lattice C 5.0 package.
-
- (c) 1989 by Fabio Rossetti
-
- To compile under Lattice C v5.0x use:
-
- lc -O -v -cus wc
- blink lib:cres.o wc.o to wc lib lib:a.lib lib:lc.lib sd nd
-
- */
-
- #include <ctype.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/libraries.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/arpbase.h>
- #include <arpfunctions.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
-
- #define NARGS 3
-
- LONG argc;
- STRPTR argv[NARGS];
-
- #define FILS argv[0]
- #define PRINT argv[1]
- #define CHECK argv[2]
-
- struct ArpBase *ArpBase=NULL;
- struct Process *Pr;
-
- /* file stuff */
- #define BFSIZE 4096
- BPTR fh=NULL;
- TEXT *Buf;
-
- /* flag to signal if only a file is found, affects output */
- BOOL Single = TRUE;
-
- /* extended AnchorPath structure (full path needed) */
- struct UAnchor {
- struct AnchorPath AP;
- TEXT Bf[255];
- };
-
- struct UAnchor *Anchor;
- struct DirectoryEntry *De,*FileList=NULL;
-
- /* shutdown routine */
- VOID Cleanup(r1,r2)
- LONG r1,r2;
- {
- if (FileList) FreeDAList(FileList);
- if (Anchor) FreeAnchorChain((struct AnchorPath *)Anchor);
- if (fh) Close(fh);
- if (ArpBase) CloseLibrary((struct Library *)ArpBase);
- Pr->pr_Result2 = r2;
- exit(r1);
- }
-
- /* Conversion table for checksum */
- TEXT *Ascii =
- "!@#$%^&*()_+1234567890-=qwertyuiop[]asdfghjkl;'`\\zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"~|ZXCVBNM<>?";
-
- /* A Lattice Wc compatible way to assign a unique numeric value to an ASCII char */
- Code(c)
- TEXT c;
- {
- REGISTER BYTE i=0;
- REGISTER TEXT *pos=Ascii;
- while (*pos != NULL) {
- if(*pos++ == c) return(i+1);
- else i++;
- }
- return(0);
- }
-
- /* perform statistics on the opened file Name-d */
- VOID Wc(filhand,Name)
- BPTR filhand;
- TEXT *Name;
-
- {
-
-
- REGISTER TEXT c;
- BOOL inword=FALSE,inpword=FALSE;
- REGISTER ULONG i,
- nc=0, /* number of chars */
- na=0, /* number of alpha chars */
- asnum=0,/* 1st part of checksum, sum of printable chars */
- sum=0; /* 2nd part of checksum, sum perf'd by Code() */
- ULONG nl=0, /* number of lines */
- nw=0, /* number of words of alpha chars */
- np=0, /* number of words of printable chars */
- count,
- awl; /* average word lenght */
-
-
-
- while (count = Read(filhand,Buf,BFSIZE)) {
-
- /* CTRL C ? */
- if (SetSignal(0,0) & SIGBREAKF_CTRL_C) {
- Puts("***Break");
- Cleanup(RETURN_WARN,NULL);
- }
-
- for (i = 0; i < count; i++) {
-
- c = *(Buf+i);
-
- /* filter non-printable chars */
- if (PRINT)
- if ( !isprint(c) && !isspace(c) ) continue;
-
- /* perform chexsum */
- if (CHECK)
- if (isprint(c)) {
- ++asnum;
- if(!isspace(c)) sum+=Code(c);
- }
- ++nc;
-
- /* a line */
- if (c == '\n') ++nl;
-
- if (isalpha(c)) ++na;
-
- /* count words e pwords */
- if (isspace(c))
- {
- inword = FALSE;
- inpword = FALSE;
- }
-
- else {
- if (inword == FALSE)
- {
- inword = TRUE;
- if (isalpha(c)) ++nw;
- }
- if (inpword == FALSE)
- {
- inpword = TRUE;
- if ((isprint(c))) ++np;
- }
- }
- }
- }
-
- /* calculate average word lenght */
- if (!nw) awl = 0;
- else awl = ((na % nw) > (nw / 2)) ? ((na/nw)+1) : (na/nw);
-
- /* output results, table form if more than one file */
- if (Single) {
- Printf(" Characters : %ld\n",nc);
- Printf("Alpha Characters : %ld\n",na);
- Printf(" Words : %ld\n",nw);
- Printf("Avr. Word Lenght : %ld\n",awl);
- Printf(" PWords : %ld\n",np);
- Printf(" Lines : %ld\n",nl);
- if(CHECK) Printf("\n Checksum : %ld %ld\n",asnum,sum);
- }
- else
- {
- if(CHECK) Printf("%7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %s\n",
- nc,na,nw,awl,np,nl,asnum,sum,Name);
- else Printf("%7ld %7ld %7ld %7ld %7ld %7ld %s\n",
- nc,na,nw,awl,np,nl,Name);
- }
- }
-
-
- /* Trick to keep code down to size */
- VOID MemCleanup()
- {
- }
- /* as above */
-
- VOID _main(Line)
- STRPTR Line;
-
- {
-
-
- BOOL Result;
- TEXT **ArV;
- LONG i=0;
-
- Pr = (struct Process*)FindTask(NULL);
-
- if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
- Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY);
-
- /* parse command line */
- for (argc=0;argc < NARGS ;++argc)
- argv[argc] = (STRPTR) NULL;
-
- while(*Line > ' ')
- ++Line;
-
- if((argc = GADS(++Line,
- strlen(Line),
- "Usage: Wc [Pattern] [PRINT=P] [CHECK=C]",
- argv,
- "Files/...,PRINT=P/S,CHECK=C/S" )) < 0)
- {
- Puts(FILS);
- Cleanup(RETURN_WARN,NULL);
- }
-
-
- /* get buffer for file */
- if (!(Buf = ArpAllocMem(BFSIZE,MEMF_CLEAR))) {
- Puts("Error: no memory");
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE);
- }
- if (!(FILS)) {
- Wc(Input(),NULL);
- Cleanup(NULL,NULL);
- }
-
-
-
- /* Allocate space for anchorpath */
- if ( Anchor = (struct UAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) )
- {
- Anchor->AP.ap_Length = 255;
- Anchor->AP.ap_BreakBits = SIGBREAKF_CTRL_C; /* stop if ^C */
- }
- else
- {
- Puts("Error: no memory");
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE);
- }
- ArV = (TEXT **) FILS;
-
- while (ArV[i] != NULL) {
-
- /* examine files specified by pattern */
- Result = FindFirst(ArV[i],(struct AnchorPath *)Anchor);
-
- while ( Result == 0 )
- {
- if (Anchor->AP.ap_Info.fib_DirEntryType < 0) {
-
- /* add filename to ordered DAList */
- if ( !(De=AddDANode(Anchor->AP.ap_Buf,
- &FileList, 0L, 0L)))
- {
- Puts("Error: no memory");
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE);
- }
- }
-
- Result = FindNext((struct AnchorPath*) Anchor );
- }
- if (Result != ERROR_NO_MORE_ENTRIES) {
- switch(Result)
- {
- case ERROR_OBJECT_NOT_FOUND:
- Printf("Error:Can't find %s\n",ArV[i]);
- break;
-
- case ERROR_BREAK:
- Puts("***Break");
- break;
-
- default:
- Puts("Error");
- }
- Cleanup(RETURN_ERROR,Result);
-
- }
-
- i++;
- }
-
-
-
- De = FileList;
-
- if ((De->de_Next)) {
- Single = FALSE;
- if(CHECK){
- Puts(" Chars Alpha Words A.W.L. PWords Lines Checksum FileName");
- Puts("--------------------------------------------------------------------------");
- }
- else {
- Puts(" Chars Alpha Words A.W.L. PWords Lines FileName");
- Puts("----------------------------------------------------------");
- }
- }
- while (De) {
-
- if (!(fh = Open(De->de_Name,MODE_OLDFILE)))
- {
- Puts(De->de_Name);
- Puts("Error:");
- Pr->pr_Result2 = ERROR_OBJECT_NOT_FOUND;
- exit(RETURN_ERROR);
- }
- else
- {
- Wc(fh,BaseName(De->de_Name));
- Close(fh);
- }
-
- De = De->de_Next;
-
- }
-
- fh = NULL;
- Cleanup(NULL,NULL);
-
- }
-