#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <functions.h>


void CloseAll(char *s);
int sumfile(char *filename);

char ver[] = "$VER: sum 1.1 (3.4.94) © by Oliver Kaufmann";

char *usage = "usage: sum [-h|-?] [<filepatternlist>] [-p<pos>] [-q]\n\
                -h : show usage\n\
                -? : show usage\n\
 <filepatternlist> : one or more files or filepatterns,\n\
                     if omitted, use stdin as input\n\
           -p<pos> : start at position <pos> in every line\n\
                -q : quiet, do not display verbose information\n";


struct MyAnchorPath {
	struct AChain	*ap_Base;	/* pointer to first anchor */
	struct AChain	*ap_Last;	/* pointer to last anchor */
	LONG	ap_BreakBits;		/* Bits we want to break on */
	LONG	ap_FoundBreak;		/* Bits we broke on. Also returns ERROR_BREAK */
	BYTE	ap_Flags;		/* New use for extra word. */
	BYTE	ap_Reserved;
	WORD	ap_Strlen;		/* This is what ap_Length used to be */
	struct	FileInfoBlock ap_Info;
	UBYTE	ap_Buf[256];		/* Buffer for path name, allocated by user */
};

#define MAXLEN 1024

struct FileInfoBlock *fib;
struct MyAnchorPath myap;
struct AnchorPath *ap;

unsigned long sum=0, n=0;
int pos=0;
int quietflag = 0;
char h[MAXLEN];

void main(int argc, char *argv[])
{
   int i;
   int flcount=0;

   unsigned long sumalt, nalt;

   int patcount = 0;
   char *patfield[256];

   char *filename;

   sum = 0;
   n = 0;
   pos = 0;                                 /* for tar index files pos = 14 */
   
   for(i=1; i<argc; i++) {
      if(*argv[i]=='-')
         switch(*(argv[i]+1)) {
            case 'p' : pos = 0;
                       sscanf(argv[i]+2,"%d", &pos);
                       break;
            case 'q' : quietflag = 1;
                       break;
            case '?' : printf(usage);
                       exit(0);
                       break;
            case 'h' : printf(usage);
                       exit(0);
                       break;
         }
      else
         patfield[patcount++] = argv[i];
   }

   if ( (pos > MAXLEN) || (pos<0) )
      CloseAll("error: <pos> must be [0-255]");


   ap = (struct AnchorPath*)&myap;
   ap->ap_Strlen = 254;
   ap->ap_BreakBits = 0;

   if(patcount == 0)          /* from stdin */
      sumfile("*");
   else
      for( i=0; i<patcount ; i++) {
         if ( MatchFirst(patfield[i], ap) ) {
            printf("no match on %s\n",patfield[i]);
            continue;
         }

         do { 
            fib = &ap->ap_Info;
            if( fib->fib_DirEntryType > 0 )  /* exclude dirs */
               continue;
            sumalt = sum;
            nalt = n;
            if(sumfile(myap.ap_Buf)){      /* name and path */
               flcount++;
               if(!quietflag) {
                  printf("%-32s : %11lu in %7lu lines at column %3d\n",
                         myap.ap_Buf, sum-sumalt, n-nalt, pos);
               }
            }

         } while (!MatchNext(ap));

         MatchEnd(ap);
      }

   if(quietflag)
      printf("%lu\n",sum);
   else {
      printf("-----------------------------------------------------------------------------\n");
      printf("%3d file(s) total                : %11lu in %7lu lines at column %3d\n",
              flcount,sum,n,pos);
   }

   exit(0);
}

int sumfile(char *filename)
{
   unsigned long fs;
   FILE *f=NULL;

   if( (f = fopen(filename, "r")) == NULL) {
     printf("error: file %s not found\n",filename);
     return 0;
   }

   h[pos] = '\0';

   while(fgets(h,MAXLEN,f) != 0) {
      n++;
      fs = 0;
      
      sscanf(&h[pos],"%lu",&fs);
      sum += fs;
      h[pos] = '\0';

   }
   fclose(f);

   return 1;  
}



void CloseAll(char *s)
{
   if(s != NULL)
      printf("%s\n",s);
   exit(5);
}
