koreth@ssyx.ucsc.edu (Steven Grimm) (02/25/89)
Submitted-by: leo@philmds.dts.philips.nl (Leo de Wit)
Posting-number: Volume 2, Issue 18
Archive-name: sort/part02
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file sortcomp.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> sortcomp.c
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else if (isdict(*bt)) {
X --bt; /* Effectively skip *bs */
X } /* (else: skip both) */
X }
X }
X for ( ; bs < es; ) { /* Skip any more */
X if (isdict(*++bs)) { /* non-dict chars in bs */
X --bs;
X break;
X }
X }
X for ( ; bt < et; ) { /* Skip any more */
X if (isdict(*++bt)) { /* non-dict chars in bt */
X --bt;
X break;
X }
X }
X
X return (et - bt) - (es - bs);
X}
X
Xint c_if(bs,bt,es,et) /* Normalized/Fold */
Xregister char *bs, *bt;
Xregister char *es, *et;
X{
X --bs; --bt; --es; --et;
X for ( ; bs < es && bt < et; ) {
X if (fold[*++bs] != fold[*++bt]) { /* Increment & compare */
X if (isnorm(*bs)) {
X if (isnorm(*bt)) {
X return fold[*bs] - fold[*bt];
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else if (isnorm(*bt)) {
X --bt; /* Effectively skip *bs */
X } /* (else: skip both) */
X }
X }
X for ( ; bs < es; ) { /* Skip any more */
X if (isnorm(*++bs)) { /* non-norm chars in bs */
X --bs;
X break;
X }
X }
X for ( ; bt < et; ) { /* Skip any more */
X if (isnorm(*++bt)) { /* non-norm chars in bt */
X --bt;
X break;
X }
X }
X
X return (et - bt) - (es - bs);
X}
X
Xint c_i(bs,bt,es,et) /* Normalized order */
Xregister char *bs, *bt;
Xregister char *es, *et;
X{
X --bs; --bt; --es; --et;
X for ( ; bs < es && bt < et; ) {
X if (*++bs != *++bt) { /* Increment & compare */
X if (isnorm(*bs)) {
X if (isnorm(*bt)) {
X return fold[*bs] - fold[*bt];
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else if (isnorm(*bt)) {
X --bt; /* Effectively skip *bs */
X } /* (else: skip both) */
X }
X }
X for ( ; bs < es; ) { /* Skip any more */
X if (isnorm(*++bs)) { /* non-norm chars in bs */
X --bs;
X break;
X }
X }
X for ( ; bt < et; ) { /* Skip any more */
X if (isnorm(*++bt)) { /* non-norm chars in bt */
X --bt;
X break;
X }
X }
X
X return (et - bt) - (es - bs);
X}
X
Xint c_af(bs,bt,es,et) /* Fold */
Xregister char *bs, *bt;
Xregister char *es, *et;
X{
X register short minlen;
X
X minlen = ((es - bs) <= (et - bt)) ? (es - bs) : (et - bt);
X if (minlen == 0) {
X return (es - bs) - (et - bt);
X }
X
X if (fold[*bs] == fold[*bt]) {
X for ( ; --minlen != 0 && fold[*++bs] == fold[*++bt]; ) ;
X if (minlen == 0) {
X return 0;
X }
X }
X
X return fold[*bs] - fold[*bt];
X}
X
Xint c_dfu(bs,bt) /* Dictionary/Fold */
Xregister char *bs, *bt;
X{
X register char *fld = fold;
X
X --bs; --bt;
X do {
X while (fld[*++bs] == fld[*++bt] && *bt) ; /* Skip equal ones */
X if (!*bt || !*bs) break; /* Stop on '\0' */
X if (isdict(*bs)) {
X if (isdict(*bt)) {
X break; /* Difference found */
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else {
X if (isdict(*bt)) {
X --bt; /* Effectively skip *bs */
X }
X } /* (else: skip both) */
X } while (1);
X
X return fld[*bs] - fld[*bt];
X}
X
Xint c_du(bs,bt) /* Dictionary */
Xregister char *bs, *bt;
X{
X --bs; --bt;
X do {
X while (*++bs == *++bt && *bt) ; /* Skip equal ones */
X if (!*bt || !*bs) break; /* Stop on '\0' */
X if (isdict(*bs)) {
X if (isdict(*bt)) {
X break; /* Difference found */
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else {
X if (isdict(*bt)) {
X --bt; /* Effectively skip *bs */
X }
X } /* (else: skip both) */
X } while (1);
X
X return *bs - *bt;
X}
X
Xint c_ifu(bs,bt) /* Normalized/Fold */
Xregister char *bs, *bt;
X{
X register char *fld = fold;
X
X --bs; --bt;
X do {
X while (fld[*++bs] == fld[*++bt] && *bt) ; /* Skip equal ones */
X if (!*bt || !*bs) break; /* Stop on '\0' */
X if (isnorm(*bs)) {
X if (isnorm(*bt)) {
X break; /* Difference found */
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else {
X if (isnorm(*bt)) {
X --bt; /* Effectively skip *bs */
X }
X } /* (else: skip both) */
X } while (1);
X
X return fld[*bs] - fld[*bt];
X}
X
Xint c_iu(bs,bt) /* Normalized */
Xregister char *bs, *bt;
X{
X --bs; --bt;
X do {
X while (*++bs == *++bt && *bt) ; /* Skip equal ones */
X if (!*bt || !*bs) break; /* Stop on '\0' */
X if (isnorm(*bs)) {
X if (isnorm(*bt)) {
X break; /* Difference found */
X } else {
X --bs; /* Effectively skip *bt */
X }
X } else {
X if (isnorm(*bt)) {
X --bt; /* Effectively skip *bs */
X }
X } /* (else: skip both) */
X } while (1);
X
X return *bs - *bt;
X}
X
Xint c_afu(bs,bt) /* Fold */
Xregister char *bs, *bt;
X{
X register char *fld = fold;
X
X if (fld[*bs] == fld[*bt] && *bt) {
X for ( ; fld[*++bs] == fld[*++bt] && *bt; ) ;
X }
X
X return fld[*bs] - fld[*bt];
X}
X
X#ifndef M68000
X/* using asm if 68000 */
X
Xint c_dbfr(bs,bt,es,et) /* Dict/Blank/Fold/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_df(bt,bs,et,es);
X}
X
Xint c_dbf(bs,bt,es,et) /* Dictionary/Blank/Fold */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_df(bs,bt,es,et);
X}
X
Xint c_dbr(bs,bt,es,et) /* Dictionary/Blank/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_d(bt,bs,et,es);
X}
X
Xint c_db(bs,bt,es,et) /* Dictionary/Blank */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_d(bs,bt,es,et);
X}
X
Xint c_dfr(bs,bt,es,et) /* Dictionary/Fold/Reverse */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_df(bt,bs,et,es);
X}
X
Xint c_dr(bs,bt,es,et) /* Dictionary/Reversed */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_d(bt,bs,et,es);
X}
X
Xint c_ibfr(bs,bt,es,et) /* Norm/Blank/Fold/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_if(bt,bs,et,es);
X}
X
Xint c_ibf(bs,bt,es,et) /* Normalized/Blank/Fold */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_if(bs,bt,es,et);
X}
X
Xint c_ibr(bs,bt,es,et) /* Normalized/Blank/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_i(bt,bs,et,es);
X}
X
Xint c_ib(bs,bt,es,et) /* Normalized/Blank */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_i(bs,bt,es,et);
X}
X
Xint c_ifr(bs,bt,es,et) /* Normalized/Fold/Reverse */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_if(bt,bs,et,es);
X}
X
Xint c_ir(bs,bt,es,et) /* Normalized/Reversed */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_i(bt,bs,et,es);
X}
X
Xint c_abfr(bs,bt,es,et) /* Blank/Fold/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_af(bt,bs,et,es);
X}
X
Xint c_abf(bs,bt,es,et) /* Blank/Fold */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_af(bs,bt,es,et);
X}
X
Xint c_abr(bs,bt,es,et) /* Blank/Reverse */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_a(bt,bs,et,es);
X}
X
Xint c_ab(bs,bt,es,et) /* Blank */
Xregister char *bs, *bt;
Xchar *es, *et;
X{
X SKIPSPACE(bs,bt);
X return c_a(bs,bt,es,et);
X}
X
Xint c_afr(bs,bt,es,et) /* Fold/Reverse */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_af(bt,bs,et,es);
X}
X
Xint c_ar(bs,bt,es,et) /* Reverse */
Xchar *bs, *bt;
Xchar *es, *et;
X{
X return c_a(bt,bs,et,es);
X}
X
X/* Unbounded comparisions start here */
X
Xint c_dbfru(bs,bt) /* Dict/Blank/Fold/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_dfu(bt,bs);
X}
X
Xint c_dbfu(bs,bt) /* Dictionary/Blank/Fold */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_dfu(bs,bt);
X}
X
Xint c_dbru(bs,bt) /* Dictionary/Blank/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_du(bt,bs);
X}
X
Xint c_dbu(bs,bt) /* Dictionary/Blank */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_du(bs,bt);
X}
X
Xint c_dfru(bs,bt) /* Dictionary/Fold/Reverse */
Xchar *bs, *bt;
X{
X return c_dfu(bt,bs);
X}
X
Xint c_dru(bs,bt) /* Dictionary/Reverse */
Xchar *bs, *bt;
X{
X return c_du(bt,bs);
X}
X
Xint c_ibfru(bs,bt) /* Norm/Blank/Fold/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_ifu(bt,bs);
X}
X
Xint c_ibfu(bs,bt) /* Normalized/Blank/Fold */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_ifu(bs,bt);
X}
X
Xint c_ibru(bs,bt) /* Normalized/Blank/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_iu(bt,bs);
X}
X
Xint c_ibu(bs,bt) /* Normalized/Blank */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_iu(bs,bt);
X}
X
Xint c_ifru(bs,bt) /* Normalized/Fold/Reverse */
Xchar *bs, *bt;
X{
X return c_ifu(bt,bs);
X}
X
Xint c_iru(bs,bt) /* Normalized/Reverse */
Xchar *bs, *bt;
X{
X return c_iu(bt,bs);
X}
X
Xint c_abfru(bs,bt) /* Blank/Fold/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_afu(bt,bs);
X}
X
Xint c_abfu(bs,bt) /* Blank/Fold */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_afu(bs,bt);
X}
X
Xint c_abru(bs,bt) /* Blank/Reverse */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_au(bt,bs);
X}
X
Xint c_abu(bs,bt) /* Blank */
Xregister char *bs, *bt;
X{
X SKIPSPACE(bs,bt);
X return c_au(bs,bt);
X}
X
Xint c_afru(bs,bt) /* Fold/Reverse */
Xregister char *bs, *bt;
X{
X register char *fld = fold;
X
X if (fld[*bs] == fld[*bt] && *bt) {
X for ( ; fld[*++bs] == fld[*++bt] && *bt; ) ;
X }
X
X return fld[*bt] - fld[*bs];
X}
X
Xint c_aru(bs,bt) /* Reverse */
Xregister char *bs, *bt;
X{
X if (*bs == *bt && *bt) {
X for ( ; *++bs == *++bt && *bt; ) ;
X }
X
X return *bt - *bs;
X}
X
Xint c_au(bs,bt) /* Ordinary sort */
Xregister char *bs, *bt;
X{
X if (*bs == *bt && *bs) { /* Compare & skip eq. chars */
X while (*++bs == *++bt && *bs) ; /* Compare & skip eq. chars */
X }
X
X return *bs - *bt;
X}
X
Xint c_a(bs,bt,es,et) /* Ordinary sort */
Xregister char *bs, *bt;
Xregister char *es, *et;
X{
X register short minlen;
X
X minlen = ((es - bs) <= (et - bt)) ? (es - bs) : (et - bt);
X if (minlen == 0) {
X return (es - bs) - (et - bt);
X }
X
X if (*bs == *bt) {
X for ( ; --minlen != 0 && *++bs == *++bt; ) ;
X if (minlen == 0) {
X return 0;
X }
X }
X
X return *bs - *bt;
X}
X#endif not MC68000
SHAR_EOF
chmod 0600 sortcomp.c || echo "restore of sortcomp.c fails"
sed 's/^X//' << 'SHAR_EOF' > sortcomp.h &&
X/******************************************************************************
X * *
X * sortcomp.h version 1.0 of 22 Januari 1989 (C) L.J.M. de Wit 1989 *
X * *
X * This software may be used and distributed freely if not used commercially *
X * and the originator (me) is mentioned in the source (just leave this 9 line *
X * header intact). *
X * *
X ******************************************************************************
X *
X * sortcomp.h: header for sortcomp.c's external definitions
X */
X
Xextern int c_nr(), c_n(), /* the various compare funcs*/
X c_dbfr(), c_dbf(), c_dbr(), c_db(),
X c_dfr(), c_df(), c_dr(), c_d(),
X c_ibfr(), c_ibf(), c_ibr(), c_ib(),
X c_ifr(), c_if(), c_ir(), c_i(),
X c_abfr(), c_abf(), c_abr(), c_ab(),
X c_afr(), c_af(), c_ar(), c_a(),
X c_dbfru(), c_dbfu(), c_dbru(), c_dbu(),
X c_dfru(), c_dfu(), c_dru(), c_du(),
X c_ibfru(), c_ibfu(), c_ibru(), c_ibu(),
X c_ifru(), c_ifu(), c_iru(), c_iu(),
X c_abfru(), c_abfu(), c_abru(), c_abu(),
X c_afru(), c_afu(), c_aru(), c_au();
X
Xextern void initlookup(); /* Initialize lookup tables */
SHAR_EOF
chmod 0600 sortcomp.h || echo "restore of sortcomp.h fails"
sed 's/^X//' << 'SHAR_EOF' > sortfile.c &&
X/******************************************************************************
X * *
X * sortfile.c version 1.0 of 1 Januari 1989 (C) L.J.M. de Wit 1989 *
X * *
X * This software may be used and distributed freely if not used commercially *
X * and the originator (me) is mentioned in the source (just leave this 9 line *
X * header intact). *
X * *
X ******************************************************************************
X *
X * sortfile.c: stdio replacement for Atari ST
X *
X * This replacement is added both to speed up the normal stdio offered by
X * Lattice C, and to repair a bug with open() (fopen() ?) that is in the
X * standard library (version 3.03: try opening & closing 20 files, your
X * program bombs when you try to open a new file, even though the old ones
X * have been closed).
X *
X * Note that this package is not complete (no flushbuf, filbuf, printf etc.)
X * but this wasn't the intent anyway; furthermore, the allocation of buffers
X * takes place when a file is opened, rather than when it is first read/written
X * (as in a standard stdio package).
X */
X
X#include <stdio.h>
X#include <osbind.h>
X#include <fcntl.h>
X#include "sortmain.h"
X#include "sortfile.h"
X
X#undef Fwrite
X#define Fwrite fixwrite /* Fix for Fwrite bug */
X
Xstatic int buflen; /* Default buffer length */
X
Xstatic int lopen();
Xstatic int fixwrite();
X
X#ifdef BESTIO
X
Xvoid bestio(size) /* Initializes stdin/stdout */
Xint size;
X{
X char *iobuffer[2]; /* stdin/stdout buffer ptrs */
X
X buflen = size;
X iobuffer[0] = (char *)Malloc(buflen);
X iobuffer[1] = (char *)Malloc(buflen);
X if (iobuffer[0] == (char *)-1 || iobuffer[1] == (char *)-1) {
X error("memory allocation failed\n",(char *)0);
X }
X stdin->_ptr = stdin->_base = iobuffer[0];
X stdin->_rcnt = buflen;
X stdin->_flag = _IOREAD;
X stdin->_file = 0;
X stdin->_size = buflen;
X
X stdout->_ptr = stdout->_base = iobuffer[1];
X stdout->_wcnt = buflen;
X stdout->_flag = _IOWRT;
X stdout->_file = 1;
X stdout->_size = buflen;
X}
X
Xvoid exit(code) /* Replaces standard exit */
Xint code;
X{
X int i;
X
X for (i = 0; i < _NFILE; i++) {
X if (_iob[i]._flag != 0) { /* Stclose any open files */
X stclose(_iob+i);
X }
X }
X _exit(code); /* and _exit */
X}
X
X#else NOT BESTIO
X
Xint _fmode = 0x8000; /* No translation, for speed*/
X
X#endif BESTIO
X
XFILE *stopen(filename,mode) /* Replaces fopen() */
Xchar *filename, *mode;
X{
X FILE *fp;
X int desc;
X int flag;
X int i;
X
X for (i = 0; i < _NFILE; i++) { /* Find first free entry */
X if (_iob[i]._flag == 0) {
X break;
X }
X }
X if (i < _NFILE) {
X fp = _iob + i; /* First free */
X } else {
X return (FILE *)0; /* All occupied */
X }
X
X if (!strcmp(mode,"w")) { /* Mode "w": write */
X desc = lopen(filename,O_WRONLY|O_CREAT|O_TRUNC);
X flag = _IOWRT;
X } else if (!strcmp(mode,"r")) { /* Mode "r": read */
X desc = lopen(filename,O_RDONLY);
X flag = _IOREAD;
X } else { /* Unknown mode */
X return (FILE *)0;
X }
X
X if (desc < 0) {
X return (FILE *)0; /* Lopen failed */
X } else {
X fp->_rcnt = fp->_wcnt = fp->_size = 0;
X fp->_ptr = fp->_base = (char *)0;
X fp->_file = desc;
X fp->_flag = flag;
X }
X
X return fp;
X}
X
Xint stclose(fp) /* Replaces fclose() */
XFILE *fp;
X{
X int retco;
X
X if (fp->_flag & (_IORW|_IOWRT)) {
X stflush(fp); /* Flush an output stream */
X }
X retco = Fclose(fp->_file); /* Close file */
X if (fp->_base != (char *)0) {
X retco |= Mfree(fp->_base); /* Free allocated buffer */
X }
X fp->_base = (char *)0;
X fp->_flag = 0; /* Indicate entry is free */
X
X return retco;
X}
X
Xint stflush(fp)
XFILE *fp;
X{
X if (fp->_size > fp->_wcnt) { /* Any data to be flushed ? */
X Fwrite(fp->_file,fp->_size-fp->_wcnt,fp->_base); /* Write it */
X fp->_ptr = fp->_base; /* re-init ptr */
X fp->_wcnt = fp->_size; /* and _wcnt */
X }
X}
X
Xvoid stbuffer(fp,buf,size)
XFILE *fp;
Xchar *buf;
Xint size;
X{
X fp->_ptr = fp->_base = buf;
X fp->_size = size;
X fp->_wcnt = size;
X fp->_rcnt = 0;
X}
X
Xchar *stgets(inbuf,size,fp) /* Replaces fgets() */
Xchar *inbuf;
Xregister int size;
Xregister FILE *fp;
X{
X register int todo, i, ntoread;
X register char *s, *t;
X
X if (fp->_base == (char *)0) {
X s = (char *)Malloc(buflen); /* Allocate buffer */
X stbuffer(fp,s,buflen);
X }
X if (size-- <= 0 || feof(fp)) { /* One for the '\0' */
X return (char *)0;
X }
X
X t = inbuf;
X s = fp->_ptr;
X ntoread = fp->_rcnt;
X
X for ( ; ; ) {
X todo = min(size,ntoread);
X for (i = 0; i < todo; i++) {
X if ((*t++ = *s++) == '\n') { /* Had a newline */
X i++;
X *t = '\0'; /* 0-terminate line */
X fp->_ptr = s;
X fp->_rcnt = ntoread - i;
X return inbuf;
X }
X }
X if ((size -= todo) <= 0) { /* All read */
X break;
X }
X ntoread = Fread(fp->_file,fp->_size,fp->_base); /* Read a buffer */
X s = fp->_base; /* Re-init ptr */
X if (ntoread <= 0) {
X fp->_flag |= _IOEOF;
X return (char *)0; /* End-of-file */
X }
X }
X fp->_rcnt = ntoread - todo;
X fp->_ptr = s;
X *t = '\0';
X return inbuf;
X}
X
Xvoid stputs(inbuf,fp) /* Replaces fputs() */
Xchar *inbuf;
Xregister FILE *fp;
X{
X register int i, ntowrite;
X register char *s, *t;
X
X if (fp->_base == (char *)0) {
X s = (char *)Malloc(buflen); /* Allocate buffer */
X stbuffer(fp,s,buflen);
X }
X s = inbuf;
X t = fp->_ptr;
X ntowrite = fp->_wcnt;
X
X for ( ; ; ) {
X for (i = 0; i < ntowrite; i++) {
X if (*s == '\0') { /* Found 0 terminator */
X break;
X }
X *t++ = *s++;
X }
X if (*s == '\0') {
X fp->_wcnt = ntowrite - i;
X fp->_ptr = t;
X return;
X }
X Fwrite(fp->_file,t - fp->_base,fp->_base); /* Write a buffer */
X ntowrite = fp->_size;
X t = fp->_base; /* Re-init ptr */
X }
X}
X
Xstatic int lopen(filename,mode) /* Simple open() replacement*/
Xchar *filename;
Xint mode;
X{
X int fd;
X
X if (!(mode & O_TRUNC)) {
X fd = Fopen(filename,mode & (O_WRONLY|O_RDWR)); /* Open file */
X }
X
X if ((mode & O_TRUNC) || ((fd < 0) && (mode & O_CREAT))) {
X fd = Fcreate(filename,!(mode & (O_WRONLY|O_RDWR))); /* Create file */
X }
X
X return fd;
X}
X
Xstatic int fixwrite(fd,len,buf)
Xint fd, len;
Xchar *buf;
X{
X int total, piece = 0;
X char *top;
X
X if (fd != 1) {
X return gemdos(0x40,fd,len,buf);
X }
X for (total = 0, top = buf + len; len > 0; buf += piece, len -= piece) {
X if ((piece = len) > 32767) {
X piece = 32256;
X }
X total += gemdos(0x40,fd,piece,buf);
X }
X return total;
X}
SHAR_EOF
chmod 0600 sortfile.c || echo "restore of sortfile.c fails"
sed 's/^X//' << 'SHAR_EOF' > sortfile.h &&
X/******************************************************************************
X * *
X * sortfile.h version 1.0 of 22 Januari 1989 (C) L.J.M. de Wit 1989 *
X * *
X * This software may be used and distributed freely if not used commercially *
X * and the originator (me) is mentioned in the source (just leave this 9 line *
X * header intact). *
X * *
X ******************************************************************************
X *
X * sortfile.h: external definitions for the sortfile stdio package.
X *
X * To enable the speeded up std I/O routines, the BESTIO symbol must be
X * #define'd (with -dBESTIO in the LC1 compilation phase when using Lattice C)
X * and sortfile used when linking.
X * To use the standard stdio package, don't define BESTIO and don't link with
X * sortfile.
X */
X
X#ifdef BESTIO
X
X#define fopen stopen
X#define fgets stgets
X#define fputs stputs
X#define fclose stclose
X#define setbuffer stbuffer
X
Xextern FILE *stopen();
Xextern char *stgets();
Xextern void stputs();
Xextern void stbuffer();
Xextern int stclose();
Xextern void bestio();
Xextern void exit();
X
X#else not BESTIO
X
X#define bestio(s)
X
X#endif BESTIO
SHAR_EOF
chmod 0600 sortfile.h || echo "restore of sortfile.h fails"
sed 's/^X//' << 'SHAR_EOF' > sortmain.c &&
X/******************************************************************************
X * *
X * sortmain.c version 1.0 of 22 Januari 1989 (C) L.J.M. de Wit 1989 *
X * *
X * This software may be used and distributed freely if not used commercially *
X * and the originator (me) is mentioned in the source (just leave this 9 line *
X * header intact). *
X * *
X ******************************************************************************
X *
X * sortmain.c: main module for sort
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "sortmain.h"
X#include "sortcomp.h"
X#include "sortfile.h"
X
Xtypedef struct key { /* Sort key structure */
X int (*cmp)(); /* Comparision routine */
X int bfld; /* Begin field no. */
X int bchar; /* Begin char no. */
X int echar; /* End char no. */
X int flds; /* # of fields (efld-bfld) */
X int bis0; /* bfld == bchar == 0 */
X int eis0; /* efld == echar == 0 */
X struct key *next; /* Next sort key ptr. */
X} key;
X
Xint options = 0; /* Global sort type flag */
Xlong _mneed = 40000; /* Memory occupied by prog */
X
Xstatic char sepchar = ' '; /* Field separator char */
Xstatic key firstkey; /* First key used */
X
Xstatic int compar(); /* Standard compare routine */
Xstatic int compb0(), compe0(), compbe(); /* Special cases of compar()*/
Xstatic int bdfinr(); /* Get 'bdfinr' options */
Xstatic char *(*fieldfunc)();
Xstatic char *getsepfld(), *getspafld(); /* Search field + offset */
Xstatic int (*getcmp())();
Xextern void allsort();
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X int i, qualif;
X char *s;
X char *outfile = (char *)0; /* Result file (stdout) */
X key *keyp, *keyn;
X int (*compfunc)(); /* Routine used to compare */
X int nkeys = 0; /* No. of keys to be used */
X
X settemp("\\tmp"); /* Set default temp dir */
X
X initlookup(); /* Initialize lookup arrays */
X
X for (i = 1; i < argc && (*argv[i] == '-' ||
X *argv[i] == '+'); i++) { /* Handle commandline flags */
X s = argv[i];
X if (*s++ == '-') {
X if (*s == '\0') { /* '-' denotes std input */
X break;
X }
X for ( ; *s != '\0'; ) {
X if (qualif = bdfinr(*s)) { /* *s in (b,d,f,i,n,r) */
X options |= qualif; /* Add it to options */
X s++;
X } else {
X switch (*s++) {
X case 't': /* Field separator char */
X sepchar = *s++;
X break;
X case 'c': /* Don't sort, only check */
X options |= CHECKONLY;
X break;
X case 'm': /* Merge the sorted input */
X options |= MERGEONLY;
X break;
X case 'o': /* Output file */
X options |= OUTFILE;
X s += strlen(s);
X outfile = argv[++i];
X break;
X case 'T': /* Directory for temp files */
X options |= SEPARATOR;
X s += strlen(s);
X settemp(argv[++i]);
X break;
X case 'u': /* Remove duplicate lines */
X options |= UNIQUE;
X break;
X default: /* Invalid option */
X *s = '\0'; /* Null terminate */
X error("invalid option %s\n",--s);
X break;
X }
X }
X }
X } else { /* '+' sort key flag */
X int keyflags = 0, efld = 0;
X
X if (nkeys++ == 0) {
X keyp = &firstkey;
X } else {
X keyp = (key *)malloc(sizeof(key));/* Create the (next) key */
X if (keyp == (key *)0) {
X error("memory allocation failed\n",(char *)0);
X }
X for (keyn = &firstkey; keyn->next != (key *)0;
X keyn = keyn->next) ;
X keyn->next = keyp;
X }
X keyp->next = (key *)0;
X keyp->bfld = atoi(s); /* Get key's start field no.*/
X for ( ; isdigit(*s); s++) ;
X if (*s == '.') {
X keyp->bchar = atoi(++s); /* Get char offset for field*/
X for ( ; isdigit(*s); s++) ;
X } else {
X keyp->bchar = 0; /* 0 is default */
X }
X for ( ; *s != '\0'; s++) { /* 'bdfinr' flags for key */
X if (qualif = bdfinr(*s)) {
X keyflags |= qualif; /* Add flag */
X } else {
X s[1] = '\0';
X error("invalid option %s\n",s);
X }
X }
X if (i + 1 < argc && argv[i+1][0] == '-' /* End field specified */
X && (argv[i+1][1] == '.' || isdigit(argv[i+1][1]))) {
X s = argv[++i] + 1;
X efld = atoi(s); /* Get key's end field no. */
X for ( ; isdigit(*s); s++) ;
X if (*s == '.') {
X keyp->echar = atoi(++s); /* Get char offset for field*/
X for ( ; isdigit(*s); s++) ;
X } else {
X keyp->echar = 0; /* 0 is default */
X }
X for ( ; *s != '\0'; s++) { /* 'bdfinr' flags for key */
X if (qualif = bdfinr(*s)) {
X keyflags |= qualif; /* add flag */
X } else {
X s[1] = '\0';
X error("invalid option %s\n",s);
X }
X }
X } else {
X efld = keyp->echar = 0;
X }
X if (keyflags == 0) { /* If no field flags */
X keyflags = options; /* Take global ones */
X }
X keyp->flds = efld - keyp->bfld;
X keyp->bis0 = keyp->bfld == 0 && keyp->bchar == 0;
X keyp->eis0 = efld == 0 && keyp->echar == 0;
X keyp->cmp = getcmp(keyflags,keyp->eis0);
X }
X }
X
X bestio(2048); /* Possibly initiate bestio */
X
X if (nkeys == 0) { /* No key specified */
X nkeys++;
X firstkey.next = (key *)0;
X firstkey.cmp = getcmp(options,1);
X firstkey.bfld = 0;
X firstkey.bchar = 0;
X firstkey.echar = 0;
X firstkey.flds = 0;
X firstkey.bis0 = 1;
X firstkey.eis0 = 1;
X }
X
X fieldfunc = (options & SEPARATOR) ? getsepfld : getspafld;
X
X if (nkeys == 1) { /* One key only */
X if (firstkey.bis0) {
X if (firstkey.eis0) {
X compfunc = firstkey.cmp;
X } else {
X compfunc = compb0;
X }
X } else {
X if (firstkey.eis0) {
X compfunc = compe0;
X } else {
X compfunc = compbe;
X }
X }
X } else {
X compfunc = compar;
X }
X allsort(argv+i,outfile, compfunc);
X}
X
Xstatic int (*getcmp(flags, unbounded))()
Xint flags, unbounded;
X{
X /* DICTORDER, IGNBLANK, FOLDUPPER, REVERSE, unbounded */
X static int (*cmparr[])() = { /* All 48 other cases */
X c_a, c_au, c_ar, c_aru,
X c_af, c_afu, c_afr, c_afru,
X c_ab, c_abu, c_abr, c_abru,
X c_abf, c_abfu, c_abfr, c_abfru,
X c_d, c_du, c_dr, c_dru,
X c_df, c_dfu, c_dfr, c_dfru,
X c_db, c_dbu, c_dbr, c_dbru,
X c_dbf, c_dbfu, c_dbfr, c_dbfru,
X c_i, c_iu, c_ir, c_iru,
X c_if, c_ifu, c_ifr, c_ifru,
X c_ib, c_ibu, c_ibr, c_ibru,
X c_ibf, c_ibfu, c_ibfr, c_ibfru,
X };
X
X if (flags & NUMERIC) { /* Numeric sort */
X return (flags & REVERSE) ? c_nr : c_n;
X }
X
X return cmparr[unbounded +
X ((flags & REVERSE) ? 2 : 0) +
X ((flags & FOLDUPPER) ? 4 : 0) +
X ((flags & IGNBLANK) ? 8 : 0) +
X ((flags & DICTORDER) ? 16 :
X (flags & IGNONPRINT) ? 32 : 0)];
X}
X
Xstatic int bdfinr(c) /* Get 'bdfinr' options */
Xchar c;
X{
X switch (c) {
X case 'b': /* Ignore leading blanks */
X return IGNBLANK;
X case 'd': /* Dictionary order */
X return DICTORDER;
X case 'f': /* Fold ucase to lcase */
X return FOLDUPPER;
X case 'i': /* Ignore nonprinting chars */
X return IGNONPRINT;
X case 'n': /* Numeric sort */
X return NUMERIC;
X case 'r': /* Reverse comparision */
X return REVERSE;
X default: /* Other flags */
X return 0;
X }
X}
X
Xstatic int compar(s,t) /* Gen.compare for all keys */
Xchar *s, *t; /* Strings to be compared */
X{
X register key *keyp = &firstkey; /* Start with key firstkey */
X register int result; /* Result of comparision */
X register char *bs, *bt; /* Begin pos within strings */
X
X do {
X if (keyp->bis0) { /* Avoid function call */
X bs = s;
X bt = t;
X } else {
X bs = (*fieldfunc)(s,keyp->bfld,keyp->bchar);
X bt = (*fieldfunc)(t,keyp->bfld,keyp->bchar);
X }
X if (keyp->eis0) { /* Unbounded end; */
X result = (*keyp->cmp)(bs,bt); /* Avoid end calculation */
X } else {
X result = (*keyp->cmp)(bs,bt,
X (*bs == '\0') ? bs :
X (*fieldfunc)(bs-keyp->bchar,keyp->flds,keyp->echar),
X (*bt == '\0') ? bt :
X (*fieldfunc)(bt-keyp->bchar,keyp->flds,keyp->echar));
X }
X } while (result == 0 /* Strings compare equal */
X && (keyp = keyp->next) != (key *)0) ; /* and more keys to consider*/
X
X return result;
X}
X
Xstatic int compb0(bs,bt) /* Compare for 1 bis0 key */
Xregister char *bs, *bt; /* Strings to be compared */
X{
X register key *keyp = &firstkey; /* For efficiency only */
X
X return (*keyp->cmp)(bs,bt,
X (*fieldfunc)(bs,keyp->flds,keyp->echar),
X (*fieldfunc)(bt,keyp->flds,keyp->echar));
X}
X
Xstatic int compe0(bs,bt) /* Compare for 1 eis0 key */
Xregister char *bs, *bt; /* Strings to be compared */
X{
X register key *keyp = &firstkey; /* For efficiency only */
X
X return (*keyp->cmp)((*fieldfunc)(bs,keyp->bfld,keyp->bchar),
X (*fieldfunc)(bt,keyp->bfld,keyp->bchar));
X}
X
Xstatic int compbe(bs,bt) /* Compare for 1 bounded key*/
Xregister char *bs, *bt; /* Strings to be compared */
X{
X register key *keyp = &firstkey; /* For efficiency only */
X
X bs = (*fieldfunc)(bs,keyp->bfld,keyp->bchar);
X bt = (*fieldfunc)(bt,keyp->bfld,keyp->bchar);
X return (*keyp->cmp)(bs,bt,
X (*bs == '\0') ? bs :
X (*fieldfunc)(bs-keyp->bchar,keyp->flds,keyp->echar),
X (*bt == '\0') ? bt :
X (*fieldfunc)(bt-keyp->bchar,keyp->flds,keyp->echar));
X}
X
Xstatic char *getsepfld(s,field,ch) /* Get position of field */
Xregister char *s; /* String to consider */
Xregister int field, ch; /* Field no. and offset cnt */
X{ /* Separator was specified */
X register char sc = sepchar;
X
X if (field > 0) {
X for ( ; *s != '\0'; ) {
X if (*s++ == sc && --field == 0) { /* Count 'field' separators */
X break;
X }
X }
X }
X for ( ; ch-- != 0; ) { /* Go ch characters further */
X if (*s++ == '\0') {
X return --s; /* but not past '\0' */
X }
X }
X return s;
X}
X
Xstatic char *getspafld(s,field,ch) /* Get position of field */
Xregister char *s; /* String to consider */
Xregister int field, ch; /* Field no. and offset cnt */
X{ /* No separator; is blanks */
X if (field > 0) {
X for ( ; *s != '\0'; s++) {
X if (wspace(*s)) {
X do {
X s++;
X } while (wspace(*s)) ;
X if (--field == 0) {
X break;
X }
X }
X }
X }
X for ( ; ch-- != 0; ) { /* Go ch characters further */
X if (*s++ == '\0') {
X return --s; /* But not past '\0' */
X }
X }
X return s;
X}
X
Xvoid error(format,arg) /* Display a formatted */
Xchar *format, *arg; /* error message and exit */
X{
X fprintf(stderr,"sort: ");
X fprintf(stderr,format,arg);
X exit(1);
X}
SHAR_EOF
chmod 0600 sortmain.c || echo "restore of sortmain.c fails"
sed 's/^X//' << 'SHAR_EOF' > sortmain.h &&
X/******************************************************************************
X * *
X * sortmain.h version 1.0 of 22 Januari 1989 (C) L.J.M. de Wit 1989 *
X * *
X * This software may be used and distributed freely if not used commercially *
X * and the originator (me) is mentioned in the source (just leave this 9 line *
X * header intact). *
X * *
X ******************************************************************************
X *
X * sortmain.h: external definitions & symbols for sortmain
X */
X
X#define IGNBLANK 0x001 /* Ignore leading blanks */
X#define DICTORDER 0x002 /* Dictionary order */
X#define FOLDUPPER 0x004 /* Fold ucase to lcase */
X#define IGNONPRINT 0x008 /* Ignore non-printing chars*/
X#define NUMERIC 0x010 /* Interpret as numeric */
X#define REVERSE 0x020 /* Reverse result */
X
X#define CHECKONLY 0x040 /* Don't sort; check only */
X#define MERGEONLY 0x080 /* Merge; input is sorted */
X#define OUTFILE 0x100 /* Output was specified */
X#define UNIQUE 0x200 /* Remove identical lines */
X#define SEPARATOR 0x400 /* Separator was specified */
X
X#define wspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
X
Xextern int options; /* Global sort flags */
X
Xextern void error(); /* Display error msg & exit */
SHAR_EOF
chmod 0600 sortmain.h || echo "restore of sortmain.h fails"
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0