home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
SORT.ZIP
/
SORT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-08-27
|
9KB
|
246 lines
/*
An OS/2 sort filter for large files.
Usage: SORT <starting column> <column count>
Written by James L. Dean
August 27, 1988
*/
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define INCL_DOSMEMMGR
#include <os2.h>
#define FALSE 0
#define TRUE 1
typedef struct
{
SEL offset;
SEL segment;
} addr;
typedef union
{
unsigned char *ptr;
addr address;
} string;
typedef struct bin
{
string text;
int text_length;
struct bin *next;
} *bin_ptr;
void main(int,char **);
void main(argc,argv)
int argc;
char *argv[];
{
static int bin_num;
register int byte;
static bin_ptr bin_head [256][2];
static bin_ptr bin_tail [256][2];
static union
{
bin_ptr bin_ptr;
addr address;
} current;
static int column_num;
static int current_column;
static int current_index;
static SEL current_offset;
static int current_pass;
static SEL current_segment;
static int fatal_error;
static bin_ptr next_bin_ptr;
register int next_pass;
static int num_columns;
static SEL num_bytes;
static SEL num_double_words;
static int num_segments;
static SEL segment [1024];
static unsigned char text [32768];
static int text_length;
if (argc < 3)
printf("Usage: SORT <starting column> <column count>\n");
else
{
num_segments=0;
current_offset=(SEL) 32768;
for (bin_num=0; bin_num < 256; bin_num++)
{
bin_head[bin_num][0]=NULL;
bin_tail[bin_num][0]=NULL;
}
current_column=atoi(argv[1]);
num_columns=atoi(argv[2]);
current_column+=num_columns-1;
current_index=current_column-1;
byte=(int) ' ';
fatal_error=FALSE;
while ((byte != EOF) && (! fatal_error))
{
text_length=0;
byte=(int) ' ';
while ((byte != (int) '\n')
&& (byte != EOF)
&& (! fatal_error))
{
byte=getchar();
if ((byte != (int) '\n') && (byte != EOF))
{
text[text_length]=(unsigned char) byte;
if (text_length == 32767)
{
fatal_error=TRUE;
printf("Fatal error: line exceeds 32767 bytes.\n");
}
else
text_length++;
}
}
if ((! fatal_error) && (byte != EOF))
{
text[text_length]=(unsigned char) '\0';
if (current_offset+(SEL) sizeof(struct bin)
> (SEL) 32768)
{
if (num_segments < 1024)
{
if (DosAllocSeg((USHORT) 32768,(PSEL) ¤t_segment,
(USHORT) 0) == (USHORT APIENTRY) 0)
{
current_offset=(SEL) 0;
segment[num_segments++]=current_segment;
}
else
{
fatal_error=TRUE;
printf("? out of memory\n");
}
}
else
{
fatal_error=TRUE;
printf("? too much to sort\n");
}
}
if (! fatal_error)
{
current.address.segment=current_segment;
current.address.offset=current_offset;
current_offset+=(SEL) sizeof(struct bin);
num_bytes=(SEL) text_length;
num_bytes++;
num_double_words=num_bytes/(SEL) 4;
if (num_bytes != ((SEL) 4)*num_double_words)
{
num_double_words++;
num_bytes=((SEL) 4)*num_double_words;
}
if (current_offset+num_bytes > (SEL) 32768)
{
if (num_segments < 1024)
{
if (DosAllocSeg((USHORT) 32768,
(PSEL) ¤t_segment,(USHORT) 0)
== (USHORT APIENTRY) 0)
{
current_offset=(SEL) 0;
segment[num_segments++]=current_segment;
}
else
{
fatal_error=TRUE;
printf("? out of memory\n");
}
}
else
{
fatal_error=TRUE;
printf("? too much to sort\n");
}
}
if (! fatal_error)
{
current.bin_ptr->text.address.segment=current_segment;
current.bin_ptr->text.address.offset=current_offset;
current_offset+=num_bytes;
strcpy(current.bin_ptr->text.ptr,(char *) &text[0]);
current.bin_ptr->text_length=text_length;
current.bin_ptr->next=NULL;
if (current_column > text_length)
byte=(int) ' ';
else
byte=(int) text[current_index];
if (bin_head[byte][0] == NULL)
bin_head[byte][0]=current.bin_ptr;
else
bin_tail[byte][0]->next=current.bin_ptr;
bin_tail[byte][0]=current.bin_ptr;
}
}
}
}
if (! fatal_error)
{
current_pass=0;
next_pass=1;
for (column_num=2; column_num <= num_columns; column_num++)
{
for (bin_num=0; bin_num < 256; bin_num++)
{
bin_head[bin_num][next_pass]=NULL;
bin_tail[bin_num][next_pass]=NULL;
}
current_index--;
current_column--;
for (bin_num=0; bin_num < 256; bin_num++)
{
current.bin_ptr=bin_head[bin_num][current_pass];
while (current.bin_ptr != NULL)
{
if (current_column > current.bin_ptr->text_length)
byte=(int) ' ';
else
byte=(int) *((current.bin_ptr->text.ptr)+current_index);
if (bin_head[byte][next_pass] == NULL)
bin_head[byte][next_pass]=current.bin_ptr;
else
bin_tail[byte][next_pass]->next=current.bin_ptr;
bin_tail[byte][next_pass]=current.bin_ptr;
next_bin_ptr=current.bin_ptr->next;
current.bin_ptr->next=NULL;
current.bin_ptr=next_bin_ptr;
}
}
current_pass=next_pass;
next_pass=1-next_pass;
}
for (bin_num=0; bin_num < 256; bin_num++)
{
current.bin_ptr=bin_head[bin_num][current_pass];
while (current.bin_ptr != NULL)
{
printf("%s\n",current.bin_ptr->text.ptr);
next_bin_ptr=current.bin_ptr->next;
current.bin_ptr=next_bin_ptr;
}
bin_head[bin_num][current_pass]=NULL;
bin_tail[bin_num][current_pass]=NULL;
}
}
while (num_segments > 0)
DosFreeSeg(segment[--num_segments]);
}
return;
}