home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / telix / t310sort.arc / TLXSORT.C < prev    next >
C/C++ Source or Header  |  1988-10-19  |  5KB  |  236 lines

  1. /**
  2.  *
  3.  *  Module:       tlxsort.c
  4.  *  Version:      1.1
  5.  *  Description:  sort Telix 3.0-3.1 phone directories
  6.  *  Author:       Paul Roub
  7.  *
  8.  *  Revision History:
  9.  *     7-13-88 :  created
  10.  *    10-12-88 :  eliminated bug in sort function
  11.  *                now ignores leading blanks and/or 'the' when sorting
  12.  *                added '-d' switch to delete null entries
  13.  *
  14.  *      This program and its sources are Copyright (C) 1988 by Paul Roub
  15.  *      and may not be sold for profit without the express written
  16.  *      consent of the author.  Redistribute them (in their entirety) as
  17.  *      you wish,  provided no fee is charged and all materials are
  18.  *      present and unmodified.
  19.  *
  20. **/
  21.  
  22. /*<f>*/
  23. #include  <ctype.h>
  24. #include  <malloc.h>
  25. #include  <stdio.h>
  26. #include  <stdlib.h>
  27. #include  <string.h>
  28.  
  29. #include  "tlx30.h"
  30. #include  "tlxsort.h"
  31.  
  32.  
  33. void      main( int argc, char **argv );
  34. int       fon_compare(const void *elem1, const void *elem2);
  35.  
  36. static  char      *InName  = "telix.fon";
  37. static  char      *OutName = "telix.fon";
  38. static  char      Umsg[]   = "usage: tlxsort [-d] [input file name] [output file name]";
  39.  
  40.  
  41. /*<f>*/
  42. /**
  43.  *
  44.  *  Function:     void main()
  45.  *  Description:  tlxsort main routine
  46.  *  Returns:      nothing
  47.  *
  48. **/
  49. void main(argc, argv)
  50. int       argc;
  51. char      **argv;
  52. {
  53.   fon_header *th;
  54.   fon_entry *te, *ke;
  55.   int     keep_count, ncount;
  56.   char    *name;
  57.   int     del_switch;
  58.  
  59.   printf("TlxSort v1.1 -- Copyright (C) 1988 by Paul Roub\n\n");
  60.  
  61.   if (argc > 4)
  62.     quitf(Umsg);
  63.  
  64.   --argc;
  65.   ++argv;
  66.  
  67.   if (argc && (**argv == '-'))
  68.   {
  69.     ++*argv;
  70.  
  71.     if (tolower(**argv) == 'd')
  72.     {
  73.       del_switch = 1;
  74.       --argc;
  75.       ++argv;
  76.     }
  77.     else
  78.       quitf(Umsg);
  79.   }
  80.  
  81.   if (argc)
  82.   {
  83.     InName = *argv;
  84.     argc--;
  85.     argv++;
  86.   }
  87.  
  88.   if (argc)
  89.   {
  90.     OutName = *argv;
  91.     argc--;
  92.     argv++;
  93.   }
  94.  
  95.   printf("Sorting %s to %s...\n", InName, OutName);
  96.  
  97.     ReadFonFile(InName, &th, &te);
  98.  
  99.   qsort(te, (size_t)th->num_entries, sizeof(fon_entry), fon_compare);
  100.  
  101.   if (del_switch)
  102.   {
  103.     keep_count = 0;
  104.     ke = te;
  105.  
  106.     while (keep_count < th->num_entries)
  107.     {
  108.       name = ke->name;
  109.       ncount = 0;
  110.  
  111.       while (isspace(*name) && (ncount < 25))
  112.       {
  113.         name++;
  114.         ncount++;
  115.       }
  116.  
  117.       /*
  118.        *  if we've found ONE blank entry,  then all successive entries
  119.        *  must also be blank,  so only keep the non-blanks we've seen
  120.        *  so far
  121.        */
  122.       if ((ncount == 25) || (! *name))
  123.         break;
  124.       else
  125.       {
  126.         ke++;
  127.         keep_count++;
  128.       }
  129.     }
  130.  
  131.     th->num_entries = keep_count;
  132.   }
  133.  
  134.   WriteFonFile(OutName, th, te);
  135.  
  136.   free(th);
  137.   free(te);
  138.  
  139.   printf("%u entries written.\n", th->num_entries);
  140.  
  141.   exit(0);
  142. }
  143.  
  144.  
  145. /*<f>*/
  146. /**
  147.  *
  148.  *  Function:     int fon_compare()
  149.  *  Description:  comparison routines used by qsort - sorts files by
  150.  *                name - note the exception:  if a one file has a
  151.  *                blank name (""),  it goes after the other,
  152.  *                regardless.
  153.  *                ignores leading "the's" and blanks
  154.  *  Returns:      -1 if first should come before second
  155.  *                0 if first and second sort the same
  156.  *                1 if first should come after second
  157.  *
  158. **/
  159. int fon_compare(elem1, elem2)
  160. const void *elem1, *elem2;
  161. {
  162.   char      *name1, *name2;
  163.   int       len1, len2;
  164.   char      compbuf1[26], compbuf2[26];
  165.  
  166.   /*
  167.    *  isolate the names for readability
  168.    */
  169.   name1 = ((fon_entry *)elem1)->name;
  170.   name2 = ((fon_entry *)elem2)->name;
  171.  
  172.   /*
  173.    *  eliminame leading blanks
  174.    */
  175.   for (len1 = 0; isspace(*name1) && len1 < 25; len1++, name1++)
  176.     ;
  177.  
  178.   for (len2 = 0; isspace(*name2) && len2 < 25; len2++, name2++)
  179.     ;
  180.  
  181.  
  182.   /*
  183.    *  bypass leading the's
  184.    */
  185.   if (! strnicmp(name1, "the", 3))
  186.   {
  187.     name1 += 3;
  188.     len1 += 3;
  189.   }
  190.  
  191.   if (! strnicmp(name2, "the", 3))
  192.   {
  193.     name2 += 3;
  194.     len2 += 3;
  195.   }
  196.  
  197.   /*
  198.    *  eliminame leading blanks following "the"
  199.    */
  200.   while (isspace(*name1) && len1 < 25)
  201.   {
  202.     len1++;
  203.     name1++;
  204.   }
  205.  
  206.   while (isspace(*name2) && len2 < 25)
  207.   {
  208.     len2++;
  209.     name2++;
  210.   }
  211.  
  212.   /*
  213.    *  if we've hit a 0 or blanked past 25,  it's a null entry,
  214.    *  so it goes after anything
  215.    */
  216.   if ((! *name1) || (len1 >= 25))
  217.     return(1);
  218.  
  219.   if ((! *name2) || (len2 >= 25))
  220.     return(-1);
  221.  
  222.  
  223.   /*
  224.    *  else do a case insensitive compare,  using whatever's left
  225.    *  of each after blank- and 'the'- stripping
  226.    */
  227.   memset(compbuf1, 0, sizeof(compbuf1));
  228.   memset(compbuf2, 0, sizeof(compbuf2));
  229.  
  230.   strncpy(compbuf1, name1, 25 - len1);
  231.   strncpy(compbuf2, name2, 25 - len2);
  232.  
  233.   return(stricmp(compbuf1, compbuf2));
  234. }
  235.  
  236.