home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / SORT.ZIP / SORT.C < prev    next >
C/C++ Source or Header  |  1988-08-27  |  9KB  |  246 lines

  1. /*  
  2.      An OS/2 sort filter for large files.
  3.  
  4.      Usage:  SORT <starting column> <column count>
  5.  
  6.      Written by James L. Dean
  7.                 August 27, 1988
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <math.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #define INCL_DOSMEMMGR
  16. #include <os2.h>
  17.  
  18. #define FALSE 0
  19. #define TRUE 1
  20.  
  21. typedef struct
  22.          {
  23.            SEL offset;
  24.            SEL segment;
  25.          } addr;
  26.  
  27. typedef union
  28.           {
  29.             unsigned char *ptr;
  30.             addr          address;
  31.           } string;
  32.  
  33. typedef struct bin
  34.                  {
  35.                    string        text;
  36.                    int           text_length;
  37.                    struct bin    *next;
  38.                  } *bin_ptr;
  39.  
  40. void main(int,char **);
  41.  
  42. void main(argc,argv)
  43.  int  argc;
  44.  char *argv[];
  45.   {
  46.     static   int           bin_num;
  47.     register int           byte;
  48.     static   bin_ptr       bin_head [256][2];
  49.     static   bin_ptr       bin_tail [256][2];
  50.     static   union
  51.                {
  52.                  bin_ptr bin_ptr;
  53.                  addr    address;
  54.                }           current;
  55.     static   int           column_num;
  56.     static   int           current_column;
  57.     static   int           current_index;
  58.     static   SEL           current_offset;
  59.     static   int           current_pass;
  60.     static   SEL           current_segment;
  61.     static   int           fatal_error;
  62.     static   bin_ptr       next_bin_ptr;
  63.     register int           next_pass;
  64.     static   int           num_columns;
  65.     static   SEL           num_bytes;
  66.     static   SEL           num_double_words;
  67.     static   int           num_segments;
  68.     static   SEL           segment [1024];
  69.     static   unsigned char text [32768];
  70.     static   int           text_length;
  71.  
  72.     if (argc < 3)
  73.       printf("Usage:  SORT <starting column> <column count>\n");
  74.     else
  75.       {
  76.         num_segments=0;
  77.         current_offset=(SEL) 32768;
  78.         for (bin_num=0; bin_num < 256; bin_num++)
  79.           {
  80.             bin_head[bin_num][0]=NULL;
  81.             bin_tail[bin_num][0]=NULL;
  82.           }
  83.         current_column=atoi(argv[1]);
  84.         num_columns=atoi(argv[2]);
  85.         current_column+=num_columns-1;
  86.         current_index=current_column-1;
  87.         byte=(int) ' ';
  88.         fatal_error=FALSE;
  89.         while ((byte != EOF) && (! fatal_error))
  90.           {
  91.             text_length=0;
  92.             byte=(int) ' ';
  93.             while ((byte != (int) '\n')
  94.             &&     (byte != EOF)
  95.             &&     (! fatal_error))
  96.               {
  97.                 byte=getchar();
  98.                 if ((byte != (int) '\n') && (byte != EOF))
  99.                   {
  100.                     text[text_length]=(unsigned char) byte;
  101.                     if (text_length == 32767)
  102.                       {
  103.                         fatal_error=TRUE;
  104.                         printf("Fatal error:  line exceeds 32767 bytes.\n");
  105.                       }
  106.                     else
  107.                       text_length++;
  108.                   }
  109.               }
  110.             if ((! fatal_error) && (byte != EOF))
  111.               {
  112.                 text[text_length]=(unsigned char) '\0';
  113.                 if (current_offset+(SEL) sizeof(struct bin) 
  114.                  > (SEL) 32768)
  115.                   {
  116.                     if (num_segments < 1024)
  117.                       {
  118.                         if (DosAllocSeg((USHORT) 32768,(PSEL) ¤t_segment,
  119.                          (USHORT) 0) == (USHORT APIENTRY) 0)
  120.                           {
  121.                             current_offset=(SEL) 0;
  122.                             segment[num_segments++]=current_segment;
  123.                           }
  124.                         else
  125.                           {
  126.                             fatal_error=TRUE;
  127.                             printf("? out of memory\n");
  128.                           }
  129.                       }
  130.                     else
  131.                       {
  132.                         fatal_error=TRUE;
  133.                         printf("? too much to sort\n");
  134.                       }
  135.                   }
  136.                 if (! fatal_error)
  137.                   {
  138.                     current.address.segment=current_segment;
  139.                     current.address.offset=current_offset;
  140.                     current_offset+=(SEL) sizeof(struct bin);
  141.                     num_bytes=(SEL) text_length;
  142.                     num_bytes++;
  143.                     num_double_words=num_bytes/(SEL) 4;
  144.                     if (num_bytes != ((SEL) 4)*num_double_words)
  145.                       {
  146.                         num_double_words++;
  147.                         num_bytes=((SEL) 4)*num_double_words;
  148.                       }
  149.                     if (current_offset+num_bytes > (SEL) 32768)
  150.                       {
  151.                         if (num_segments < 1024)
  152.                           {
  153.                             if (DosAllocSeg((USHORT) 32768,
  154.                              (PSEL) ¤t_segment,(USHORT) 0)
  155.                              == (USHORT APIENTRY) 0)
  156.                               {
  157.                                 current_offset=(SEL) 0;
  158.                                 segment[num_segments++]=current_segment;
  159.                               }
  160.                             else
  161.                               {
  162.                                 fatal_error=TRUE;
  163.                                 printf("? out of memory\n");
  164.                               }
  165.                           }
  166.                         else
  167.                           {
  168.                             fatal_error=TRUE;
  169.                             printf("? too much to sort\n");
  170.                           }
  171.                       }
  172.                     if (! fatal_error)
  173.                       {
  174.                         current.bin_ptr->text.address.segment=current_segment;
  175.                         current.bin_ptr->text.address.offset=current_offset;
  176.                         current_offset+=num_bytes;
  177.                         strcpy(current.bin_ptr->text.ptr,(char *) &text[0]);
  178.                         current.bin_ptr->text_length=text_length;
  179.                         current.bin_ptr->next=NULL;
  180.                         if (current_column > text_length)
  181.                           byte=(int) ' ';
  182.                         else
  183.                           byte=(int) text[current_index];
  184.                         if (bin_head[byte][0] == NULL)
  185.                           bin_head[byte][0]=current.bin_ptr;
  186.                         else
  187.                           bin_tail[byte][0]->next=current.bin_ptr;  
  188.                         bin_tail[byte][0]=current.bin_ptr;  
  189.                       }
  190.                   }
  191.               }
  192.           }                
  193.         if (! fatal_error)
  194.           {
  195.             current_pass=0;
  196.             next_pass=1;
  197.             for (column_num=2; column_num <= num_columns; column_num++)
  198.               {
  199.                 for (bin_num=0; bin_num < 256; bin_num++)
  200.                   {
  201.                     bin_head[bin_num][next_pass]=NULL;
  202.                     bin_tail[bin_num][next_pass]=NULL;
  203.                   }
  204.                 current_index--;
  205.                 current_column--;
  206.                 for (bin_num=0; bin_num < 256; bin_num++)
  207.                   {
  208.                     current.bin_ptr=bin_head[bin_num][current_pass];
  209.                     while (current.bin_ptr != NULL)
  210.                       {
  211.                         if (current_column > current.bin_ptr->text_length)
  212.                           byte=(int) ' ';
  213.                         else
  214.                           byte=(int) *((current.bin_ptr->text.ptr)+current_index);
  215.                         if (bin_head[byte][next_pass] == NULL)
  216.                           bin_head[byte][next_pass]=current.bin_ptr;
  217.                         else
  218.                           bin_tail[byte][next_pass]->next=current.bin_ptr;  
  219.                         bin_tail[byte][next_pass]=current.bin_ptr;  
  220.                         next_bin_ptr=current.bin_ptr->next;
  221.                         current.bin_ptr->next=NULL;
  222.                         current.bin_ptr=next_bin_ptr;
  223.                       }
  224.                   }
  225.                 current_pass=next_pass;
  226.                 next_pass=1-next_pass;
  227.               }
  228.             for (bin_num=0; bin_num < 256; bin_num++)
  229.               {
  230.                 current.bin_ptr=bin_head[bin_num][current_pass];
  231.                 while (current.bin_ptr != NULL)
  232.                   {
  233.                     printf("%s\n",current.bin_ptr->text.ptr);
  234.                     next_bin_ptr=current.bin_ptr->next;
  235.                     current.bin_ptr=next_bin_ptr;
  236.                   }
  237.                 bin_head[bin_num][current_pass]=NULL;
  238.                 bin_tail[bin_num][current_pass]=NULL;
  239.               }
  240.           }
  241.         while (num_segments > 0)
  242.           DosFreeSeg(segment[--num_segments]);
  243.       }
  244.     return;
  245.   }
  246.