
/*    sortham
      o  determine size of input file.
      o  assume a worst case with lines containing only 1 x 2 call signs.
      o  alloc a memory buffer big enough to hold the input file.
      o  alloc a memory buffer big enough to hold a pointer to each line.
      o  call manx's quicksort to do the work.
*/

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

static	 char  *VERSION="$VER: sortham 1.0 Vince Herried KA8CTE (30.05.92)";

static	 char *buf=NULL,*pbuf=NULL,**p,line[256];
static	 FILE  *input=NULL,*output=NULL;

void cleanup(void);

int fsize (char *name)

{
   struct stat stbuf;

   if ( stat(name,&stbuf) == -1 )
   {
      fprintf(stderr,"SRTH001E: can't access %s\n",name);
      return(-1);
   } /* if stat(name,&stbuf) */

/*   if ( (stbuf.st_mode & S_IFMT) == S_IFDIR )
   {

   } /* if (stbuf.st_mode */
   return(stbuf.st_size);
} /* fsize () */

cmp (char **a,char **b)
{
   char  ta[7],tb[7];
   char  *x;
   int	 i,j;

   strcpy(ta,"      "); /* initialize work strings */
   strcpy(tb,"      "); /* ditto */

   /* look for the digit (assumes U. S. format call sign) */
   /* build sort key with prefix stuck on the end     */

   x = *a;
   for (i = 0; i<2;i++ )
   {
      if ( isdigit(*x) ) break;
      ta[i+4] = toupper(*x);
      x++;
   } /* for  */

   ta[0]=toupper(*x);
   i++;
   x++;
   j = 1;
   for (;i < 6;i++ )
   {
      if ( ! isalpha(*x) ) break;
      ta[j] = toupper(*x);
      j++;
      x++;
   } /* for  */

   x = *b;
   for (i = 0; i<2;i++ )
   {
      if ( isdigit(*x) ) break;
      tb[i+4] = toupper(*x);
      x++;
   } /* for  */

   tb[0]=toupper(*x);
   i++;
   x++;
   j = 1;
   for (;i < 6;i++ )
   {
      if ( ! isalpha(*x) ) break;
      tb[j] = toupper(*x);
      j++;
      x++;
   } /* for  */

#if DEBUG
   pprintf(stderr,"SRTH002I - ta =%s, tb =%s\n",ta,tb);
#endif

   return strcmp(ta,tb);

} /* cmp () */


void cleanup ()

{
   if ( !buf )
   {
      free(buf);
   } /* if !buf */

   if ( !pbuf )
   {
      free(pbuf);
   } /* if !pbuf */

   if ( !input )
   {
      fclose(input);
   } /* if !input */

   if ( !output )
   {
      fclose(output);
   } /* if !output */

   exit(0);

} /* cleanup () */



int main (int argc,char **argv)
{
   int	 size,i,numlines,numptrs,cmp();
   int	 buf_used,ptrs_used;

   if ( argc != 3 )     /* default: current directory */
   {
      fprintf(stderr,"sortham Version 1.0 05/30/92 Vince Herried KA8CTE\n"
      "purpose: sort input based on amateur call signs starting in column 1\n"
      "usage: sortham inputfilename outputfilename\n");
      exit(1);
   } /* if argc */

   size=fsize(*++argv);      /* find size of the input file */

   size += size/5;	     /* increase size because I add a \0 at end   */
			     /* of each line. This value assumes an avg  */
			     /* line length of 5 (eg 1 X 2 calls).        */
			     /* With longer call signs less space is required */

   if ( size < 512 )         /* fix problems with small files              */
   {
      size = 512;
   } /* if size */


   input=fopen(*argv,"r");
   if ( input == NULL )
   {
      fprintf(stderr,"SRTH003E - open failed for %s\n",*argv);
      cleanup();
   } /* if input=fopen(*argv,"r") */

   argv++;

   output=fopen(*argv,"w");
   if ( output == NULL )
   {
      fprintf(stderr,"open failed for %s\n",*argv);
      cleanup();
   } /* if input=fopen(*argv,"w") */

   if ( size < 0 )
   {
      cleanup();               /* not a file, exit */
   } /* if size */

   if ( !(buf = (char *) malloc(size)) )
   {
      fprintf(stderr,"SRTH004E - Unable to allocate memory for data buffer!\n");
      cleanup();
   } /* if !(buf */

   if ( !(pbuf = (char *) malloc(size)) )
   {
      fprintf(stderr,"SRTH005E - Unable to allocate memory for pointer buffer!\n");
      cleanup();
   } /* if !(pbuf */

   p=pbuf;
   *p=buf;

   buf_used=0;			    /* amount of buffer used so far  */
   ptrs_used=0; 		    /* number of pointers used so far*/


   for (numlines=0;!feof(input);++numlines)
   {

      fgets(line,255,input);

      buf_used += strlen(line) +1;

      if ( buf_used >= size )
      {
	 fprintf(stderr,"SRTH006E - oops it doesn't fit!\n");
	 cleanup();

      } /* if buf_used */


      ptrs_used++;

      if ( ptrs_used >= size/4 )
      {
	 fprintf(stderr,"SRTH007E - oops not enough room in the pointer buffer!\n");
	 cleanup();
      } /* if ptrs_used */



      strcpy(*p,line);

      *++p   =	*p;

      *p   =  *p + strlen(line) +1;

   } /* for  */

   numlines--;

   fclose(input);
   input=NULL;

   qsort(pbuf,numlines,sizeof(char *),cmp);

   p=pbuf;

   for (i = 0;i<numlines;++i)
   {
      fprintf(output,"%s",*p++);
   } /* for  */

   cleanup();
   return(0);
} /* main () */


