[BACK]Return to init.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sort

Annotation of src/usr.bin/sort/init.c, Revision 1.1

1.1     ! millert     1: /*     OpenBSD$        */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 1993
        !             5:  *     The Regents of the University of California.  All rights reserved.
        !             6:  *
        !             7:  * This code is derived from software contributed to Berkeley by
        !             8:  * Peter McIlroy.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer.
        !            15:  * 2. Redistributions in binary form must reproduce the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer in the
        !            17:  *    documentation and/or other materials provided with the distribution.
        !            18:  * 3. All advertising materials mentioning features or use of this software
        !            19:  *    must display the following acknowledgement:
        !            20:  *     This product includes software developed by the University of
        !            21:  *     California, Berkeley and its contributors.
        !            22:  * 4. Neither the name of the University nor the names of its contributors
        !            23:  *    may be used to endorse or promote products derived from this software
        !            24:  *    without specific prior written permission.
        !            25:  *
        !            26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            36:  * SUCH DAMAGE.
        !            37:  */
        !            38:
        !            39: #ifndef lint
        !            40: #if 0
        !            41: static char sccsid[] = "@(#)init.c     8.1 (Berkeley) 6/6/93";
        !            42: #else
        !            43: static char rcsid[] = "$OpenBSD: $";
        !            44: #endif
        !            45: #endif /* not lint */
        !            46:
        !            47: #include "sort.h"
        !            48:
        !            49: #include <ctype.h>
        !            50: #include <string.h>
        !            51:
        !            52: extern struct coldesc clist[(ND+1)*2];
        !            53: extern int ncols;
        !            54: u_char gweights[NBINS];
        !            55:
        !            56: /*
        !            57:  * clist (list of columns which correspond to one or more icol or tcol)
        !            58:  * is in increasing order of columns.
        !            59:  * Fields are kept in increasing order of fields.
        !            60:  */
        !            61:
        !            62: /*
        !            63:  * keep clist in order--inserts a column in a sorted array
        !            64:  */
        !            65: static void
        !            66: insertcol(field)
        !            67:        struct field *field;
        !            68: {
        !            69:        int i;
        !            70:        for (i = 0; i < ncols; i++)
        !            71:                if (field->icol.num <= clist[i].num)
        !            72:                        break;
        !            73:        if (field->icol.num != clist[i].num) {
        !            74:                memmove(clist+i+1, clist+i, sizeof(COLDESC)*(ncols-i));
        !            75:                clist[i].num = field->icol.num;
        !            76:                ncols++;
        !            77:        }
        !            78:        if (field->tcol.num && field->tcol.num != field->icol.num) {
        !            79:                for (i = 0; i < ncols; i++)
        !            80:                        if (field->tcol.num <= clist[i].num)
        !            81:                                break;
        !            82:                if (field->tcol.num != clist[i].num) {
        !            83:                        memmove(clist+i+1, clist+i,sizeof(COLDESC)*(ncols-i));
        !            84:                        clist[i].num = field->tcol.num;
        !            85:                        ncols++;
        !            86:                }
        !            87:        }
        !            88: }
        !            89:
        !            90: /*
        !            91:  * matches fields with the appropriate columns--n^2 but who cares?
        !            92:  */
        !            93: void
        !            94: fldreset(fldtab)
        !            95:        struct field *fldtab;
        !            96: {
        !            97:        int i;
        !            98:        fldtab[0].tcol.p = clist+ncols-1;
        !            99:        for (++fldtab; fldtab->icol.num; ++fldtab) {
        !           100:                for (i = 0; fldtab->icol.num != clist[i].num; i++);
        !           101:                fldtab->icol.p = clist + i;
        !           102:                if (!fldtab->tcol.num)
        !           103:                        continue;
        !           104:                for (i = 0; fldtab->tcol.num != clist[i].num; i++);
        !           105:                fldtab->tcol.p = clist + i;
        !           106:        }
        !           107: }
        !           108:
        !           109: /*
        !           110:  * interprets a column in a -k field
        !           111:  */
        !           112: char *
        !           113: setcolumn(pos, cur_fld, gflag)
        !           114:        char *pos;
        !           115:        struct field *cur_fld;
        !           116:        int gflag;
        !           117: {
        !           118:        struct column *col;
        !           119:        int tmp;
        !           120:        col = cur_fld->icol.num ? (&(*cur_fld).tcol) : (&(*cur_fld).icol);
        !           121:        pos += sscanf(pos, "%d", &(col->num));
        !           122:        while (isdigit(*pos))
        !           123:                pos++;
        !           124:        if (col->num <= 0 && !(col->num == 0 && col == &(cur_fld->tcol)))
        !           125:                errx(2, "field numbers must be positive");
        !           126:        if (*pos == '.') {
        !           127:                if (!col->num)
        !           128:                        errx(2, "cannot indent end of line");
        !           129:                pos += sscanf(++pos, "%d", &(col->indent));
        !           130:                while (isdigit(*pos))
        !           131:                        pos++;
        !           132:                if (&cur_fld->icol == col)
        !           133:                        col->indent--;
        !           134:                if (col->indent < 0)
        !           135:                        errx(2, "illegal offset");
        !           136:        }
        !           137:        if (optval(*pos, cur_fld->tcol.num))
        !           138:                while ((tmp = optval(*pos, cur_fld->tcol.num))) {
        !           139:                        cur_fld->flags |= tmp;
        !           140:                        pos++;
        !           141:        }
        !           142:        if (cur_fld->icol.num == 0)
        !           143:                cur_fld->icol.num = 1;
        !           144:        return (pos);
        !           145: }
        !           146:
        !           147: int
        !           148: setfield(pos, cur_fld, gflag)
        !           149:        char *pos;
        !           150:        struct field *cur_fld;
        !           151:        int gflag;
        !           152: {
        !           153:        static int nfields = 0;
        !           154:        int tmp;
        !           155:        char *setcolumn();
        !           156:        if (++nfields == ND)
        !           157:                errx(2, "too many sort keys. (Limit is %d)", ND-1);
        !           158:        cur_fld->weights = ascii;
        !           159:        cur_fld->mask = alltable;
        !           160:        pos = setcolumn(pos, cur_fld, gflag);
        !           161:        if (*pos == '\0')                       /* key extends to EOL. */
        !           162:                cur_fld->tcol.num = 0;
        !           163:        else {
        !           164:                if (*pos != ',')
        !           165:                        errx(2, "illegal field descriptor");
        !           166:                setcolumn((++pos), cur_fld, gflag);
        !           167:        }
        !           168:        if (!cur_fld->flags)
        !           169:                cur_fld->flags = gflag;
        !           170:        tmp = cur_fld->flags;
        !           171:
        !           172:        /*
        !           173:         * Assign appropriate mask table and weight table.
        !           174:         * If the global weights are reversed, the local field
        !           175:         * must be "re-reversed".
        !           176:         */
        !           177:        if (((tmp & R) ^ (gflag & R)) && tmp & F)
        !           178:                cur_fld->weights = RFtable;
        !           179:        else if (tmp & F)
        !           180:                cur_fld->weights = Ftable;
        !           181:        else if ((tmp & R) ^ (gflag & R))
        !           182:                cur_fld->weights = Rascii;
        !           183:        if (tmp & I)
        !           184:                cur_fld->mask = itable;
        !           185:        else if (tmp & D)
        !           186:                cur_fld->mask = dtable;
        !           187:        cur_fld->flags |= (gflag & (BI | BT));
        !           188:        if (!cur_fld->tcol.indent)      /* BT has no meaning at end of field */
        !           189:                cur_fld->flags &= (D|F|I|N|R|BI);
        !           190:        if (cur_fld->tcol.num && !(!(cur_fld->flags & BI)
        !           191:            && cur_fld->flags & BT) && (cur_fld->tcol.num <= cur_fld->icol.num
        !           192:            && cur_fld->tcol.indent < cur_fld->icol.indent))
        !           193:                errx(2, "fields out of order");
        !           194:        insertcol(cur_fld);
        !           195:        return (cur_fld->tcol.num);
        !           196: }
        !           197:
        !           198: int
        !           199: optval(desc, tcolflag)
        !           200:        int desc, tcolflag;
        !           201: {
        !           202:        switch(desc) {
        !           203:                case 'b':
        !           204:                        if (!tcolflag)
        !           205:                                return(BI);
        !           206:                        else
        !           207:                                return(BT);
        !           208:                case 'd': return(D);
        !           209:                case 'f': return(F);
        !           210:                case 'i': return(I);
        !           211:                case 'n': return(N);
        !           212:                case 'r': return(R);
        !           213:                default:  return(0);
        !           214:        }
        !           215: }
        !           216:
        !           217: void
        !           218: fixit(argc, argv)
        !           219:        int *argc;
        !           220:        char **argv;
        !           221: {
        !           222:        int i, j, v, w, x;
        !           223:        static char vbuf[ND*20], *vpos, *tpos;
        !           224:        vpos = vbuf;
        !           225:
        !           226:        for (i = 1; i < *argc; i++) {
        !           227:                if (argv[i][0] == '+') {
        !           228:                        tpos = argv[i]+1;
        !           229:                        argv[i] = vpos;
        !           230:                        vpos += sprintf(vpos, "-k");
        !           231:                        tpos += sscanf(tpos, "%d", &v);
        !           232:                        while (isdigit(*tpos))
        !           233:                                tpos++;
        !           234:                        vpos += sprintf(vpos, "%d", v+1);
        !           235:                        if (*tpos == '.') {
        !           236:                                tpos += sscanf(++tpos, "%d", &x);
        !           237:                                vpos += sprintf(vpos, ".%d", x+1);
        !           238:                        }
        !           239:                        while (*tpos)
        !           240:                                *vpos++ = *tpos++;
        !           241:                        vpos += sprintf(vpos, ",");
        !           242:                        if (argv[i+1] &&
        !           243:                            argv[i+1][0] == '-' && isdigit(argv[i+1][1])) {
        !           244:                                tpos = argv[i+1] + 1;
        !           245:                                tpos += sscanf(tpos, "%d", &w);
        !           246:                                while (isdigit(*tpos))
        !           247:                                        tpos++;
        !           248:                                x = 0;
        !           249:                                if (*tpos == '.') {
        !           250:                                        tpos += sscanf(++tpos, "%d", &x);
        !           251:                                        while (isdigit(*tpos))
        !           252:                                                tpos++;
        !           253:                                }
        !           254:                                if (x) {
        !           255:                                        vpos += sprintf(vpos, "%d", w+1);
        !           256:                                        vpos += sprintf(vpos, ".%d", x);
        !           257:                                } else
        !           258:                                        vpos += sprintf(vpos, "%d", w);
        !           259:                                while (*tpos)
        !           260:                                        *vpos++ = *tpos++;
        !           261:                                for (j= i+1; j < *argc; j++)
        !           262:                                        argv[j] = argv[j+1];
        !           263:                                *argc -= 1;
        !           264:                        }
        !           265:                }
        !           266:        }
        !           267: }
        !           268:
        !           269: /*
        !           270:  * ascii, Rascii, Ftable, and RFtable map
        !           271:  * REC_D -> REC_D;  {not REC_D} -> {not REC_D}.
        !           272:  * gweights maps REC_D -> (0 or 255); {not REC_D} -> {not gweights[REC_D]}.
        !           273:  * Note: when sorting in forward order, to encode character zero in a key,
        !           274:  * use \001\001; character 1 becomes \001\002.  In this case, character 0
        !           275:  * is reserved for the field delimiter.  Analagously for -r (fld_d = 255).
        !           276:  * Note: this is only good for ASCII sorting.  For different LC 's,
        !           277:  * all bets are off.  See also num_init in number.c
        !           278:  */
        !           279: void
        !           280: settables(gflags)
        !           281:        int gflags;
        !           282: {
        !           283:        u_char *wts;
        !           284:        int i, incr;
        !           285:        for (i=0; i < 256; i++) {
        !           286:                ascii[i] = i;
        !           287:                if (i > REC_D && i < 255 - REC_D+1)
        !           288:                        Rascii[i] = 255 - i + 1;
        !           289:                else
        !           290:                        Rascii[i] = 255 - i;
        !           291:                if (islower(i)) {
        !           292:                        Ftable[i] = Ftable[i- ('a' -'A')];
        !           293:                        RFtable[i] = RFtable[i - ('a' - 'A')];
        !           294:                } else if (REC_D>= 'A' && REC_D < 'Z' && i < 'a' && i > REC_D) {
        !           295:                        Ftable[i] = i + 1;
        !           296:                        RFtable[i] = Rascii[i] - 1;
        !           297:                } else {
        !           298:                        Ftable[i] = i;
        !           299:                        RFtable[i] = Rascii[i];
        !           300:                }
        !           301:                alltable[i] = 1;
        !           302:                if (i == '\n' || isprint(i))
        !           303:                        itable[i] = 1;
        !           304:                else itable[i] = 0;
        !           305:                if (i == '\n' || i == '\t' || i == ' ' || isalnum(i))
        !           306:                        dtable[i] = 1;
        !           307:                else dtable[i] = 0;
        !           308:        }
        !           309:        Rascii[REC_D] = RFtable[REC_D] = REC_D;
        !           310:        if (REC_D >= 'A' && REC_D < 'Z')
        !           311:                ++Ftable[REC_D + ('a' - 'A')];
        !           312:        if (gflags & R && (!(gflags & F) || !SINGL_FLD))
        !           313:                wts = Rascii;
        !           314:        else if (!(gflags & F) || !SINGL_FLD)
        !           315:                wts = ascii;
        !           316:        else if (gflags & R)
        !           317:                wts = RFtable;
        !           318:        else
        !           319:                wts = Ftable;
        !           320:        memmove(gweights, wts, sizeof(gweights));
        !           321:        incr = (gflags & R) ? -1 : 1;
        !           322:        for (i = 0; i < REC_D; i++)
        !           323:                gweights[i] += incr;
        !           324:        gweights[REC_D] = ((gflags & R) ? 255 : 0);
        !           325:        if (SINGL_FLD && gflags & F) {
        !           326:                for (i = 0; i < REC_D; i++) {
        !           327:                        ascii[i] += incr;
        !           328:                        Rascii[i] += incr;
        !           329:                }
        !           330:                ascii[REC_D] = Rascii[REC_D] = gweights[REC_D];
        !           331:        }
        !           332: }