/****************************************************************************** * * * sortmain.c version 1.0 of 22 Januari 1989 (C) L.J.M. de Wit 1989 * * * * This software may be used and distributed freely if not used commercially * * and the originator (me) is mentioned in the source (just leave this 9 line * * header intact). * * * ****************************************************************************** * * sortmain.c: main module for sort */ #include #include #include "sortmain.h" #include "sortcomp.h" #include "sortfile.h" typedef struct key { /* Sort key structure */ int (*cmp)(); /* Comparision routine */ int bfld; /* Begin field no. */ int bchar; /* Begin char no. */ int echar; /* End char no. */ int flds; /* # of fields (efld-bfld) */ int bis0; /* bfld == bchar == 0 */ int eis0; /* efld == echar == 0 */ struct key *next; /* Next sort key ptr. */ } key; int options = 0; /* Global sort type flag */ long _mneed = 40000; /* Memory occupied by prog */ static char sepchar = ' '; /* Field separator char */ static key firstkey; /* First key used */ static int compar(); /* Standard compare routine */ static int compb0(), compe0(), compbe(); /* Special cases of compar()*/ static int bdfinr(); /* Get 'bdfinr' options */ static char *(*fieldfunc)(); static char *getsepfld(), *getspafld(); /* Search field + offset */ static int (*getcmp())(); extern void allsort(); main(argc,argv) int argc; char **argv; { int i, qualif; char *s; char *outfile = (char *)0; /* Result file (stdout) */ key *keyp, *keyn; int (*compfunc)(); /* Routine used to compare */ int nkeys = 0; /* No. of keys to be used */ settemp("\\tmp"); /* Set default temp dir */ initlookup(); /* Initialize lookup arrays */ for (i = 1; i < argc && (*argv[i] == '-' || *argv[i] == '+'); i++) { /* Handle commandline flags */ s = argv[i]; if (*s++ == ' HBO€pÏÏÏÏÏÏÏÏÏÏÏÏ‚ÏÃÀ„OÀ@OÈÇÈB@=•–“22·7º2¹9º24·8:º…192°µ… compfunc = firstkey.cmp; } else { compfunc = compb0; } } else { if (firstkey.eis0) { compfunc = compe0; } else { compfunc = compbe; } } } else { compfunc = compar; } allsort(argv+i,outfile, compfunc); } static int (*getcmp(flags, unbounded))() int flags, unbounded; { /* DICTORDER, IGNBLANK, FOLDUPPER, REVERSE, unbounded */ static int (*cmparr[])() = { /* All 48 other cases */ c_a, c_au, c_ar, c_aru, c_af, c_afu, c_afr, c_afru, c_ab, c_abu, c_abr, c_abru, c_abf, c_abfu, c_abfr, c_abfru, c_d, c_du, c_dr, c_dru, c_df, c_dfu, c_dfr, c_dfru, c_db, c_dbu, c_dbr, c_dbru, c_dbf, c_dbfu, c_dbfr, c_dbfru, c_i, c_iu, c_ir, c_iru, c_if, c_ifu, c_ifr, c_ifru, c_ib, c_ibu, c_ibr, c_ibru, c_ibf, c_ibfu, c_ibfr, c_ibfru, }; if (flags & NUMERIC) { /* Numeric sort */ return (flags & REVERSE) ? c_nr : c_n; } return cmparr[unbounded + ((flags & REVERSE) ? 2 : 0) + ((flags & FOLDUPPER) ? 4 : 0) + ((flags & IGNBLANK) ? 8 : 0) + ((flags & DICTORDER) ? 16 : (flags & IGNONPRINT) ? 32 : 0)]; } static int bdfinr(c) /* Get 'bdfinr' options */ char c; { switch (c) { case 'b': /* Ignore leading blanks */ return IGNBLANK; case 'd': /* Dictionary order */ return DICTORDER; case 'f': /* Fold ucase to lcase */ return FOLDUPPER; case 'i': /* Ignore nonprinting chars */ return IGNONPRINT; case 'n': /* Numeric sort */ return NUMERIC; case 'r': /* Reverse comparision */ return REVERSE; default: /* Other flags */ return 0; } } static int compar(s,t) /* Gen.compare for all keys */ char *s, *t; /* Strings to be compared */ { register key *keyp = &firstkey; /* Start with key firstkey */ register int result; /* Result of comparision */ register char *bs, *bt; /* Begin pos within strings */ do { if (keyp->bis0) { /* Avoid function call */ bs = s; bt = t; } else { bs = (*fieldfunc)(s,keyp->bfld,keyp->bchar); bt = (*fieldfunc)(t,keyp->bfld,keyp->bchar); } if (keyp->eis0) { /* Unbounded end; */ result = (*keyp->cmp)(bs,bt); /* Avoid end calculation */ } else { result = (*keyp->cmp)(bs,bt, (*bs == '\0') ? bs : (*fieldfunc)(bs-keyp->bchar,keyp->flds,keyp->echar), (*bt == '\0') ? bt : (*fieldfunc)(bt-keyp->bchar,keyp->flds,keyp->echar)); } } while (result == 0 /* Strings compare equal */ && (keyp = keyp->next) != (key *)0) ; /* and more keys to consider*/ return result; } static int compb0(bs,bt) /* Compare for 1 bis0 key */ register char *bs, *bt; /* Strings to be compared */ { register key *keyp = &firstkey; /* For efficiency only */ return (*keyp->cmp)(bs,bt, (*fieldfunc)(bs,keyp->flds,keyp->echar), (*fieldfunc)(bt,keyp->flds,keyp->echar)); } static int compe0(bs,bt) /* Compare for 1 eis0 key */ register char *bs, *bt; /* Strings to be compared */ { register key *keyp = &firstkey; /* For efficiency only */ return (*keyp->cmp)((*fieldfunc)(bs,keyp->bfld,keyp->bchar), (*fieldfunc)(bt,keyp->bfld,keyp->bchar)); } static int compbe(bs,bt) /* Compare for 1 bounded key*/ register char *bs, *bt; /* Strings to be compared */ { register key *keyp = &firstkey; /* For efficiency only */ bs = (*fieldfunc)(bs,keyp->bfld,keyp->bchar); bt = (*fieldfunc)(bt,keyp->bfld,keyp->bchar); return (*keyp->cmp)(bs,bt, (*bs == '\0') ? bs : (*fieldfunc)(bs-keyp->bchar,keyp->flds,keyp->echar), (*bt == '\0') ? bt : (*fieldfunc)(bt-keyp->bchar,keyp->flds,keyp->echar)); } static char *getsepfld(s,field,ch) /* Get position of field */ register char *s; /* String to consider */ register int field, ch; /* Field no. and offset cnt */ { /* Separator was specified */ register char sc = sepchar; if (field > 0) { for ( ; *s != '\0'; ) { if (*s++ == sc && --field == 0) { /* Count 'field' separators */ break; } } } for ( ; ch-- != 0; ) { /* Go ch characters further */ if (*s++ == '\0') { return --s; /* but not past '\0' */ } } return s; } static char *getspafld(s,field,ch) /* Get position of field */ register char *s; /* String to consider */ register int field, ch; /* Field no. and offset cnt */ { /* No separator; is blanks */ if (field > 0) { for ( ; *s != '\0'; s++) { if (wspace(*s)) { do { s++; } while (wspace(*s)) ; if (--field == 0) { break; } } } } for ( ; ch-- != 0; ) { /* Go ch characters further */ if (*s++ == '\0') { return --s; /* But not past '\0' */ } } return s; } void error(format,arg) /* Display a formatted */ char *format, *arg; /* error message and exit */ { fprintf(stderr,"sort: "); fprintf(stderr,format,arg); exit(1); }