1*84d9c625SLionel Sambuc /* $NetBSD: init.c,v 1.29 2013/10/18 20:47:06 christos Exp $ */
20fbbaa43SLionel Sambuc
30fbbaa43SLionel Sambuc /*-
40fbbaa43SLionel Sambuc * Copyright (c) 2000-2003 The NetBSD Foundation, Inc.
50fbbaa43SLionel Sambuc * All rights reserved.
60fbbaa43SLionel Sambuc *
70fbbaa43SLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation
80fbbaa43SLionel Sambuc * by Ben Harris and Jaromir Dolecek.
90fbbaa43SLionel Sambuc *
100fbbaa43SLionel Sambuc * Redistribution and use in source and binary forms, with or without
110fbbaa43SLionel Sambuc * modification, are permitted provided that the following conditions
120fbbaa43SLionel Sambuc * are met:
130fbbaa43SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
140fbbaa43SLionel Sambuc * notice, this list of conditions and the following disclaimer.
150fbbaa43SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
160fbbaa43SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
170fbbaa43SLionel Sambuc * documentation and/or other materials provided with the distribution.
180fbbaa43SLionel Sambuc *
190fbbaa43SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
200fbbaa43SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
210fbbaa43SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220fbbaa43SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
230fbbaa43SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
240fbbaa43SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
250fbbaa43SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
260fbbaa43SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
270fbbaa43SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
280fbbaa43SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290fbbaa43SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
300fbbaa43SLionel Sambuc */
310fbbaa43SLionel Sambuc
320fbbaa43SLionel Sambuc /*-
330fbbaa43SLionel Sambuc * Copyright (c) 1993
340fbbaa43SLionel Sambuc * The Regents of the University of California. All rights reserved.
350fbbaa43SLionel Sambuc *
360fbbaa43SLionel Sambuc * This code is derived from software contributed to Berkeley by
370fbbaa43SLionel Sambuc * Peter McIlroy.
380fbbaa43SLionel Sambuc *
390fbbaa43SLionel Sambuc * Redistribution and use in source and binary forms, with or without
400fbbaa43SLionel Sambuc * modification, are permitted provided that the following conditions
410fbbaa43SLionel Sambuc * are met:
420fbbaa43SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
430fbbaa43SLionel Sambuc * notice, this list of conditions and the following disclaimer.
440fbbaa43SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
450fbbaa43SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
460fbbaa43SLionel Sambuc * documentation and/or other materials provided with the distribution.
470fbbaa43SLionel Sambuc * 3. Neither the name of the University nor the names of its contributors
480fbbaa43SLionel Sambuc * may be used to endorse or promote products derived from this software
490fbbaa43SLionel Sambuc * without specific prior written permission.
500fbbaa43SLionel Sambuc *
510fbbaa43SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
520fbbaa43SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
530fbbaa43SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
540fbbaa43SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
550fbbaa43SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
560fbbaa43SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
570fbbaa43SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
580fbbaa43SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
590fbbaa43SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
600fbbaa43SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
610fbbaa43SLionel Sambuc * SUCH DAMAGE.
620fbbaa43SLionel Sambuc */
630fbbaa43SLionel Sambuc
640fbbaa43SLionel Sambuc #include "sort.h"
650fbbaa43SLionel Sambuc
66*84d9c625SLionel Sambuc __RCSID("$NetBSD: init.c,v 1.29 2013/10/18 20:47:06 christos Exp $");
670fbbaa43SLionel Sambuc
680fbbaa43SLionel Sambuc #include <ctype.h>
690fbbaa43SLionel Sambuc #include <string.h>
700fbbaa43SLionel Sambuc
710fbbaa43SLionel Sambuc static void insertcol(struct field *);
720fbbaa43SLionel Sambuc static const char *setcolumn(const char *, struct field *);
730fbbaa43SLionel Sambuc
740fbbaa43SLionel Sambuc /*
750fbbaa43SLionel Sambuc * masks of ignored characters.
760fbbaa43SLionel Sambuc */
770fbbaa43SLionel Sambuc static u_char dtable[NBINS], itable[NBINS];
780fbbaa43SLionel Sambuc
790fbbaa43SLionel Sambuc /*
800fbbaa43SLionel Sambuc * parsed key options
810fbbaa43SLionel Sambuc */
820fbbaa43SLionel Sambuc struct coldesc *clist = NULL;
830fbbaa43SLionel Sambuc int ncols = 0;
840fbbaa43SLionel Sambuc
850fbbaa43SLionel Sambuc /*
860fbbaa43SLionel Sambuc * clist (list of columns which correspond to one or more icol or tcol)
870fbbaa43SLionel Sambuc * is in increasing order of columns.
880fbbaa43SLionel Sambuc * Fields are kept in increasing order of fields.
890fbbaa43SLionel Sambuc */
900fbbaa43SLionel Sambuc
910fbbaa43SLionel Sambuc /*
920fbbaa43SLionel Sambuc * keep clist in order--inserts a column in a sorted array
930fbbaa43SLionel Sambuc */
940fbbaa43SLionel Sambuc static void
insertcol(struct field * field)950fbbaa43SLionel Sambuc insertcol(struct field *field)
960fbbaa43SLionel Sambuc {
970fbbaa43SLionel Sambuc int i;
980fbbaa43SLionel Sambuc struct coldesc *p;
990fbbaa43SLionel Sambuc
1000fbbaa43SLionel Sambuc /* Make space for new item */
1010fbbaa43SLionel Sambuc p = realloc(clist, (ncols + 2) * sizeof(*clist));
1020fbbaa43SLionel Sambuc if (!p)
1030fbbaa43SLionel Sambuc err(1, "realloc");
1040fbbaa43SLionel Sambuc clist = p;
1050fbbaa43SLionel Sambuc memset(&clist[ncols], 0, sizeof(clist[ncols]));
1060fbbaa43SLionel Sambuc
1070fbbaa43SLionel Sambuc for (i = 0; i < ncols; i++)
1080fbbaa43SLionel Sambuc if (field->icol.num <= clist[i].num)
1090fbbaa43SLionel Sambuc break;
1100fbbaa43SLionel Sambuc if (field->icol.num != clist[i].num) {
1110fbbaa43SLionel Sambuc memmove(clist+i+1, clist+i, sizeof(COLDESC)*(ncols-i));
1120fbbaa43SLionel Sambuc clist[i].num = field->icol.num;
1130fbbaa43SLionel Sambuc ncols++;
1140fbbaa43SLionel Sambuc }
1150fbbaa43SLionel Sambuc if (field->tcol.num && field->tcol.num != field->icol.num) {
1160fbbaa43SLionel Sambuc for (i = 0; i < ncols; i++)
1170fbbaa43SLionel Sambuc if (field->tcol.num <= clist[i].num)
1180fbbaa43SLionel Sambuc break;
1190fbbaa43SLionel Sambuc if (field->tcol.num != clist[i].num) {
1200fbbaa43SLionel Sambuc memmove(clist+i+1, clist+i,sizeof(COLDESC)*(ncols-i));
1210fbbaa43SLionel Sambuc clist[i].num = field->tcol.num;
1220fbbaa43SLionel Sambuc ncols++;
1230fbbaa43SLionel Sambuc }
1240fbbaa43SLionel Sambuc }
1250fbbaa43SLionel Sambuc }
1260fbbaa43SLionel Sambuc
1270fbbaa43SLionel Sambuc /*
1280fbbaa43SLionel Sambuc * matches fields with the appropriate columns--n^2 but who cares?
1290fbbaa43SLionel Sambuc */
1300fbbaa43SLionel Sambuc void
fldreset(struct field * fldtab)1310fbbaa43SLionel Sambuc fldreset(struct field *fldtab)
1320fbbaa43SLionel Sambuc {
1330fbbaa43SLionel Sambuc int i;
1340fbbaa43SLionel Sambuc
1350fbbaa43SLionel Sambuc fldtab[0].tcol.p = clist + ncols - 1;
1360fbbaa43SLionel Sambuc for (++fldtab; fldtab->icol.num; ++fldtab) {
1370fbbaa43SLionel Sambuc for (i = 0; fldtab->icol.num != clist[i].num; i++)
1380fbbaa43SLionel Sambuc ;
1390fbbaa43SLionel Sambuc fldtab->icol.p = clist + i;
1400fbbaa43SLionel Sambuc if (!fldtab->tcol.num)
1410fbbaa43SLionel Sambuc continue;
1420fbbaa43SLionel Sambuc for (i = 0; fldtab->tcol.num != clist[i].num; i++)
1430fbbaa43SLionel Sambuc ;
1440fbbaa43SLionel Sambuc fldtab->tcol.p = clist + i;
1450fbbaa43SLionel Sambuc }
1460fbbaa43SLionel Sambuc }
1470fbbaa43SLionel Sambuc
1480fbbaa43SLionel Sambuc /*
1490fbbaa43SLionel Sambuc * interprets a column in a -k field
1500fbbaa43SLionel Sambuc */
1510fbbaa43SLionel Sambuc static const char *
setcolumn(const char * pos,struct field * cur_fld)1520fbbaa43SLionel Sambuc setcolumn(const char *pos, struct field *cur_fld)
1530fbbaa43SLionel Sambuc {
1540fbbaa43SLionel Sambuc struct column *col;
1550fbbaa43SLionel Sambuc char *npos;
1560fbbaa43SLionel Sambuc int tmp;
1570fbbaa43SLionel Sambuc col = cur_fld->icol.num ? (&cur_fld->tcol) : (&cur_fld->icol);
1580fbbaa43SLionel Sambuc col->num = (int) strtol(pos, &npos, 10);
1590fbbaa43SLionel Sambuc pos = npos;
1600fbbaa43SLionel Sambuc if (col->num <= 0 && !(col->num == 0 && col == &(cur_fld->tcol)))
1610fbbaa43SLionel Sambuc errx(2, "field numbers must be positive");
1620fbbaa43SLionel Sambuc if (*pos == '.') {
1630fbbaa43SLionel Sambuc if (!col->num)
1640fbbaa43SLionel Sambuc errx(2, "cannot indent end of line");
1650fbbaa43SLionel Sambuc ++pos;
1660fbbaa43SLionel Sambuc col->indent = (int) strtol(pos, &npos, 10);
1670fbbaa43SLionel Sambuc pos = npos;
1680fbbaa43SLionel Sambuc if (&cur_fld->icol == col)
1690fbbaa43SLionel Sambuc col->indent--;
1700fbbaa43SLionel Sambuc if (col->indent < 0)
1710fbbaa43SLionel Sambuc errx(2, "illegal offset");
1720fbbaa43SLionel Sambuc }
1730fbbaa43SLionel Sambuc for(; (tmp = optval(*pos, cur_fld->tcol.num)); pos++)
1740fbbaa43SLionel Sambuc cur_fld->flags |= tmp;
1750fbbaa43SLionel Sambuc if (cur_fld->icol.num == 0)
1760fbbaa43SLionel Sambuc cur_fld->icol.num = 1;
1770fbbaa43SLionel Sambuc return (pos);
1780fbbaa43SLionel Sambuc }
1790fbbaa43SLionel Sambuc
1800fbbaa43SLionel Sambuc int
setfield(const char * pos,struct field * cur_fld,int gflag)1810fbbaa43SLionel Sambuc setfield(const char *pos, struct field *cur_fld, int gflag)
1820fbbaa43SLionel Sambuc {
1830fbbaa43SLionel Sambuc cur_fld->mask = NULL;
1840fbbaa43SLionel Sambuc
1850fbbaa43SLionel Sambuc pos = setcolumn(pos, cur_fld);
1860fbbaa43SLionel Sambuc if (*pos == '\0') /* key extends to EOL. */
1870fbbaa43SLionel Sambuc cur_fld->tcol.num = 0;
1880fbbaa43SLionel Sambuc else {
1890fbbaa43SLionel Sambuc if (*pos != ',')
1900fbbaa43SLionel Sambuc errx(2, "illegal field descriptor");
1910fbbaa43SLionel Sambuc setcolumn((++pos), cur_fld);
1920fbbaa43SLionel Sambuc }
1930fbbaa43SLionel Sambuc if (!cur_fld->flags)
1940fbbaa43SLionel Sambuc cur_fld->flags = gflag;
1950fbbaa43SLionel Sambuc if (REVERSE)
1960fbbaa43SLionel Sambuc /* A local 'r' doesn't invert the global one */
1970fbbaa43SLionel Sambuc cur_fld->flags &= ~R;
1980fbbaa43SLionel Sambuc
1990fbbaa43SLionel Sambuc /* Assign appropriate mask table and weight table. */
2000fbbaa43SLionel Sambuc cur_fld->weights = weight_tables[cur_fld->flags & (R | F)];
2010fbbaa43SLionel Sambuc if (cur_fld->flags & I)
2020fbbaa43SLionel Sambuc cur_fld->mask = itable;
2030fbbaa43SLionel Sambuc else if (cur_fld->flags & D)
2040fbbaa43SLionel Sambuc cur_fld->mask = dtable;
2050fbbaa43SLionel Sambuc
2060fbbaa43SLionel Sambuc cur_fld->flags |= (gflag & (BI | BT));
2070fbbaa43SLionel Sambuc if (!cur_fld->tcol.indent) /* BT has no meaning at end of field */
2080fbbaa43SLionel Sambuc cur_fld->flags &= ~BT;
2090fbbaa43SLionel Sambuc
2100fbbaa43SLionel Sambuc if (cur_fld->tcol.num
2110fbbaa43SLionel Sambuc && !(!(cur_fld->flags & BI) && cur_fld->flags & BT)
2120fbbaa43SLionel Sambuc && (cur_fld->tcol.num <= cur_fld->icol.num
2130fbbaa43SLionel Sambuc /* indent if 0 -> end of field, i.e. okay */
2140fbbaa43SLionel Sambuc && cur_fld->tcol.indent != 0
2150fbbaa43SLionel Sambuc && cur_fld->tcol.indent < cur_fld->icol.indent))
2160fbbaa43SLionel Sambuc errx(2, "fields out of order");
2170fbbaa43SLionel Sambuc
2180fbbaa43SLionel Sambuc insertcol(cur_fld);
2190fbbaa43SLionel Sambuc return (cur_fld->tcol.num);
2200fbbaa43SLionel Sambuc }
2210fbbaa43SLionel Sambuc
2220fbbaa43SLionel Sambuc int
optval(int desc,int tcolflag)2230fbbaa43SLionel Sambuc optval(int desc, int tcolflag)
2240fbbaa43SLionel Sambuc {
2250fbbaa43SLionel Sambuc switch(desc) {
2260fbbaa43SLionel Sambuc case 'b':
2270fbbaa43SLionel Sambuc if (!tcolflag)
2280fbbaa43SLionel Sambuc return BI;
2290fbbaa43SLionel Sambuc else
2300fbbaa43SLionel Sambuc return BT;
2310fbbaa43SLionel Sambuc case 'd': return D;
2320fbbaa43SLionel Sambuc case 'f': return F;
2330fbbaa43SLionel Sambuc case 'i': return I;
2340fbbaa43SLionel Sambuc case 'l': return L;
2350fbbaa43SLionel Sambuc case 'n': return N;
236*84d9c625SLionel Sambuc #if defined(__minix)
237e286ccc0SBen Gras case 'x': return X;
238*84d9c625SLionel Sambuc #endif /* defined(__minix) */
2390fbbaa43SLionel Sambuc case 'r': return R;
2400fbbaa43SLionel Sambuc default: return 0;
2410fbbaa43SLionel Sambuc }
2420fbbaa43SLionel Sambuc }
2430fbbaa43SLionel Sambuc
2440fbbaa43SLionel Sambuc /*
2450fbbaa43SLionel Sambuc * Return true if the options found in ARG, according to the getopt
2460fbbaa43SLionel Sambuc * spec in OPTS, require an additional argv word as an option
2470fbbaa43SLionel Sambuc * argument.
2480fbbaa43SLionel Sambuc */
2490fbbaa43SLionel Sambuc static int
options_need_argument(const char * arg,const char * opts)2500fbbaa43SLionel Sambuc options_need_argument(const char *arg, const char *opts)
2510fbbaa43SLionel Sambuc {
2520fbbaa43SLionel Sambuc size_t pos;
2530fbbaa43SLionel Sambuc const char *s;
2540fbbaa43SLionel Sambuc
2550fbbaa43SLionel Sambuc /*assert(arg[0] == '-');*/
2560fbbaa43SLionel Sambuc
2570fbbaa43SLionel Sambuc pos = 1;
2580fbbaa43SLionel Sambuc while (arg[pos]) {
2590fbbaa43SLionel Sambuc s = strchr(opts, arg[pos]);
2600fbbaa43SLionel Sambuc if (s == NULL) {
2610fbbaa43SLionel Sambuc /* invalid option */
2620fbbaa43SLionel Sambuc return 0;
2630fbbaa43SLionel Sambuc }
2640fbbaa43SLionel Sambuc if (s[1] == ':') {
2650fbbaa43SLionel Sambuc /* option requires argument */
2660fbbaa43SLionel Sambuc if (arg[pos+1] == '\0') {
2670fbbaa43SLionel Sambuc /* no argument in this arg */
2680fbbaa43SLionel Sambuc return 1;
2690fbbaa43SLionel Sambuc }
2700fbbaa43SLionel Sambuc else {
2710fbbaa43SLionel Sambuc /* argument is in this arg; no more options */
2720fbbaa43SLionel Sambuc return 0;
2730fbbaa43SLionel Sambuc }
2740fbbaa43SLionel Sambuc }
2750fbbaa43SLionel Sambuc pos++;
2760fbbaa43SLionel Sambuc }
2770fbbaa43SLionel Sambuc return 0;
2780fbbaa43SLionel Sambuc }
2790fbbaa43SLionel Sambuc
2800fbbaa43SLionel Sambuc /*
2810fbbaa43SLionel Sambuc * Replace historic +SPEC arguments with appropriate -kSPEC.
2820fbbaa43SLionel Sambuc *
2830fbbaa43SLionel Sambuc * The form can be either a single +SPEC or a pair +SPEC -SPEC.
2840fbbaa43SLionel Sambuc * The following -SPEC is not recognized unless it follows
2850fbbaa43SLionel Sambuc * immediately.
2860fbbaa43SLionel Sambuc */
2870fbbaa43SLionel Sambuc void
fixit(int * argc,char ** argv,const char * opts)2880fbbaa43SLionel Sambuc fixit(int *argc, char **argv, const char *opts)
2890fbbaa43SLionel Sambuc {
2900fbbaa43SLionel Sambuc int i, j, sawplus;
2910fbbaa43SLionel Sambuc char *vpos, *tpos, spec[20];
2920fbbaa43SLionel Sambuc int col, indent;
2930fbbaa43SLionel Sambuc
2940fbbaa43SLionel Sambuc sawplus = 0;
2950fbbaa43SLionel Sambuc for (i = 1; i < *argc; i++) {
2960fbbaa43SLionel Sambuc /*
2970fbbaa43SLionel Sambuc * This loop must stop exactly where getopt will stop.
2980fbbaa43SLionel Sambuc * Otherwise it turns e.g. "sort x +3" into "sort x
2990fbbaa43SLionel Sambuc * -k4.1", which will croak if +3 was in fact really a
3000fbbaa43SLionel Sambuc * file name. In order to do this reliably we need to
3010fbbaa43SLionel Sambuc * be able to identify argv words that are option
3020fbbaa43SLionel Sambuc * arguments.
3030fbbaa43SLionel Sambuc */
3040fbbaa43SLionel Sambuc
3050fbbaa43SLionel Sambuc if (!strcmp(argv[i], "--")) {
3060fbbaa43SLionel Sambuc /* End of options; stop. */
3070fbbaa43SLionel Sambuc break;
3080fbbaa43SLionel Sambuc }
3090fbbaa43SLionel Sambuc
3100fbbaa43SLionel Sambuc if (argv[i][0] == '+') {
3110fbbaa43SLionel Sambuc /* +POS argument */
3120fbbaa43SLionel Sambuc sawplus = 1;
3130fbbaa43SLionel Sambuc } else if (argv[i][0] == '-' && sawplus &&
3140fbbaa43SLionel Sambuc isdigit((unsigned char)argv[i][1])) {
3150fbbaa43SLionel Sambuc /* -POS argument */
3160fbbaa43SLionel Sambuc sawplus = 0;
3170fbbaa43SLionel Sambuc } else if (argv[i][0] == '-') {
3180fbbaa43SLionel Sambuc /* other option */
3190fbbaa43SLionel Sambuc sawplus = 0;
3200fbbaa43SLionel Sambuc if (options_need_argument(argv[i], opts)) {
3210fbbaa43SLionel Sambuc /* skip over the argument */
3220fbbaa43SLionel Sambuc i++;
3230fbbaa43SLionel Sambuc }
3240fbbaa43SLionel Sambuc continue;
3250fbbaa43SLionel Sambuc } else {
3260fbbaa43SLionel Sambuc /* not an option at all; stop */
3270fbbaa43SLionel Sambuc sawplus = 0;
3280fbbaa43SLionel Sambuc break;
3290fbbaa43SLionel Sambuc }
3300fbbaa43SLionel Sambuc
3310fbbaa43SLionel Sambuc /*
3320fbbaa43SLionel Sambuc * At this point argv[i] is an old-style spec. The
3330fbbaa43SLionel Sambuc * sawplus flag used by the above loop logic also
3340fbbaa43SLionel Sambuc * tells us if it's a +SPEC or -SPEC.
3350fbbaa43SLionel Sambuc */
3360fbbaa43SLionel Sambuc
3370fbbaa43SLionel Sambuc /* parse spec */
3380fbbaa43SLionel Sambuc tpos = argv[i]+1;
3390fbbaa43SLionel Sambuc col = (int)strtol(tpos, &tpos, 10);
3400fbbaa43SLionel Sambuc if (*tpos == '.') {
3410fbbaa43SLionel Sambuc ++tpos;
3420fbbaa43SLionel Sambuc indent = (int) strtol(tpos, &tpos, 10);
3430fbbaa43SLionel Sambuc } else
3440fbbaa43SLionel Sambuc indent = 0;
3450fbbaa43SLionel Sambuc /* tpos now points to the optional flags */
3460fbbaa43SLionel Sambuc
3470fbbaa43SLionel Sambuc /*
3480fbbaa43SLionel Sambuc * In the traditional form, x.0 means beginning of line;
3490fbbaa43SLionel Sambuc * in the new form, x.0 means end of line. Adjust the
3500fbbaa43SLionel Sambuc * value of INDENT accordingly.
3510fbbaa43SLionel Sambuc */
3520fbbaa43SLionel Sambuc if (sawplus) {
3530fbbaa43SLionel Sambuc /* +POS */
3540fbbaa43SLionel Sambuc col += 1;
3550fbbaa43SLionel Sambuc indent += 1;
3560fbbaa43SLionel Sambuc } else {
3570fbbaa43SLionel Sambuc /* -POS */
3580fbbaa43SLionel Sambuc if (indent > 0)
3590fbbaa43SLionel Sambuc col += 1;
3600fbbaa43SLionel Sambuc }
3610fbbaa43SLionel Sambuc
3620fbbaa43SLionel Sambuc /* make the new style spec */
363*84d9c625SLionel Sambuc (void)snprintf(spec, sizeof(spec), "%d.%d%s", col, indent,
3640fbbaa43SLionel Sambuc tpos);
3650fbbaa43SLionel Sambuc
3660fbbaa43SLionel Sambuc if (sawplus) {
3670fbbaa43SLionel Sambuc /* Replace the +POS argument with new-style -kSPEC */
3680fbbaa43SLionel Sambuc asprintf(&vpos, "-k%s", spec);
3690fbbaa43SLionel Sambuc argv[i] = vpos;
3700fbbaa43SLionel Sambuc } else {
3710fbbaa43SLionel Sambuc /*
3720fbbaa43SLionel Sambuc * Append the spec to the one from the
3730fbbaa43SLionel Sambuc * preceding +POS argument, and remove the
3740fbbaa43SLionel Sambuc * current argv element entirely.
3750fbbaa43SLionel Sambuc */
3760fbbaa43SLionel Sambuc asprintf(&vpos, "%s,%s", argv[i-1], spec);
3770fbbaa43SLionel Sambuc free(argv[i-1]);
3780fbbaa43SLionel Sambuc argv[i-1] = vpos;
3790fbbaa43SLionel Sambuc for (j=i; j < *argc; j++)
3800fbbaa43SLionel Sambuc argv[j] = argv[j+1];
3810fbbaa43SLionel Sambuc *argc -= 1;
3820fbbaa43SLionel Sambuc i--;
3830fbbaa43SLionel Sambuc }
3840fbbaa43SLionel Sambuc }
3850fbbaa43SLionel Sambuc }
3860fbbaa43SLionel Sambuc
3870fbbaa43SLionel Sambuc /*
3880fbbaa43SLionel Sambuc * ascii, Rascii, Ftable, and RFtable map
3890fbbaa43SLionel Sambuc *
3900fbbaa43SLionel Sambuc * Sorting 'weight' tables.
3910fbbaa43SLionel Sambuc * Convert 'ascii' characters into their sort order.
3920fbbaa43SLionel Sambuc * The 'F' variants fold lower case to upper equivalent
3930fbbaa43SLionel Sambuc * The 'R' variants are for reverse sorting.
3940fbbaa43SLionel Sambuc *
3950fbbaa43SLionel Sambuc * The record separator (REC_D) never needs a weight, this frees one
3960fbbaa43SLionel Sambuc * byte value as an 'end of key' marker. This must be 0 for normal
3970fbbaa43SLionel Sambuc * weight tables, and 0xff for reverse weight tables - and is used
3980fbbaa43SLionel Sambuc * to terminate keys so that short keys sort before (after if reverse)
3990fbbaa43SLionel Sambuc * longer keys.
4000fbbaa43SLionel Sambuc *
4010fbbaa43SLionel Sambuc * The field separator has a normal weight - although it cannot occur
4020fbbaa43SLionel Sambuc * within a key unless it is the default (space+tab).
4030fbbaa43SLionel Sambuc *
4040fbbaa43SLionel Sambuc * All other bytes map to the appropriate value for the sort order.
4050fbbaa43SLionel Sambuc * Numeric sorts don't need any tables, they are reversed by negation.
4060fbbaa43SLionel Sambuc *
4070fbbaa43SLionel Sambuc * Global reverse sorts are done by writing the sorted keys in reverse
4080fbbaa43SLionel Sambuc * order - the sort itself is stil forwards.
4090fbbaa43SLionel Sambuc * This means that weights are only ever used when generating keys, any
4100fbbaa43SLionel Sambuc * sort of the original data bytes is always forwards and unweighted.
4110fbbaa43SLionel Sambuc *
4120fbbaa43SLionel Sambuc * Note: this is only good for ASCII sorting. For different LC 's,
4130fbbaa43SLionel Sambuc * all bets are off.
4140fbbaa43SLionel Sambuc *
4150fbbaa43SLionel Sambuc * itable[] and dtable[] are the masks for -i (ignore non-printables)
4160fbbaa43SLionel Sambuc * and -d (only sort blank and alphanumerics).
4170fbbaa43SLionel Sambuc */
4180fbbaa43SLionel Sambuc void
settables(void)4190fbbaa43SLionel Sambuc settables(void)
4200fbbaa43SLionel Sambuc {
4210fbbaa43SLionel Sambuc int i;
4220fbbaa43SLionel Sambuc int next_weight = 1;
4230fbbaa43SLionel Sambuc int rev_weight = 254;
4240fbbaa43SLionel Sambuc
4250fbbaa43SLionel Sambuc ascii[REC_D] = 0;
4260fbbaa43SLionel Sambuc Rascii[REC_D] = 255;
4270fbbaa43SLionel Sambuc Ftable[REC_D] = 0;
4280fbbaa43SLionel Sambuc RFtable[REC_D] = 255;
4290fbbaa43SLionel Sambuc
4300fbbaa43SLionel Sambuc for (i = 0; i < 256; i++) {
4310fbbaa43SLionel Sambuc if (i == REC_D)
4320fbbaa43SLionel Sambuc continue;
4330fbbaa43SLionel Sambuc ascii[i] = next_weight;
4340fbbaa43SLionel Sambuc Rascii[i] = rev_weight;
4350fbbaa43SLionel Sambuc if (Ftable[i] == 0) {
4360fbbaa43SLionel Sambuc Ftable[i] = next_weight;
4370fbbaa43SLionel Sambuc RFtable[i] = rev_weight;
4380fbbaa43SLionel Sambuc Ftable[tolower(i)] = next_weight;
4390fbbaa43SLionel Sambuc RFtable[tolower(i)] = rev_weight;
4400fbbaa43SLionel Sambuc }
4410fbbaa43SLionel Sambuc next_weight++;
4420fbbaa43SLionel Sambuc rev_weight--;
4430fbbaa43SLionel Sambuc
4440fbbaa43SLionel Sambuc if (i == '\n' || isprint(i))
4450fbbaa43SLionel Sambuc itable[i] = 1;
4460fbbaa43SLionel Sambuc
4470fbbaa43SLionel Sambuc if (i == '\n' || i == '\t' || i == ' ' || isalnum(i))
4480fbbaa43SLionel Sambuc dtable[i] = 1;
4490fbbaa43SLionel Sambuc }
4500fbbaa43SLionel Sambuc }
451