Annotation of src/usr.bin/sort/init.c, Revision 1.3
1.3 ! millert 1: /* $OpenBSD$ */
1.1 millert 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
1.3 ! millert 43: static char rcsid[] = "$OpenBSD: init.c,v 1.2 1997/06/16 02:21:56 millert Exp $";
1.1 millert 44: #endif
45: #endif /* not lint */
46:
47: #include "sort.h"
48:
49: #include <ctype.h>
50: #include <string.h>
51:
1.3 ! millert 52: extern struct coldesc *clist;
1.1 millert 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) {
1.2 millert 100: for (i = 0; fldtab->icol.num != clist[i].num; i++)
101: ;
1.1 millert 102: fldtab->icol.p = clist + i;
103: if (!fldtab->tcol.num)
104: continue;
1.2 millert 105: for (i = 0; fldtab->tcol.num != clist[i].num; i++)
106: ;
1.1 millert 107: fldtab->tcol.p = clist + i;
108: }
109: }
110:
111: /*
112: * interprets a column in a -k field
113: */
114: char *
115: setcolumn(pos, cur_fld, gflag)
116: char *pos;
117: struct field *cur_fld;
118: int gflag;
119: {
120: struct column *col;
121: int tmp;
1.2 millert 122:
1.1 millert 123: col = cur_fld->icol.num ? (&(*cur_fld).tcol) : (&(*cur_fld).icol);
124: pos += sscanf(pos, "%d", &(col->num));
125: while (isdigit(*pos))
126: pos++;
127: if (col->num <= 0 && !(col->num == 0 && col == &(cur_fld->tcol)))
128: errx(2, "field numbers must be positive");
129: if (*pos == '.') {
130: if (!col->num)
131: errx(2, "cannot indent end of line");
132: pos += sscanf(++pos, "%d", &(col->indent));
133: while (isdigit(*pos))
134: pos++;
135: if (&cur_fld->icol == col)
136: col->indent--;
137: if (col->indent < 0)
138: errx(2, "illegal offset");
139: }
140: if (optval(*pos, cur_fld->tcol.num))
141: while ((tmp = optval(*pos, cur_fld->tcol.num))) {
142: cur_fld->flags |= tmp;
143: pos++;
144: }
145: if (cur_fld->icol.num == 0)
146: cur_fld->icol.num = 1;
147: return (pos);
148: }
149:
150: int
151: setfield(pos, cur_fld, gflag)
152: char *pos;
153: struct field *cur_fld;
154: int gflag;
155: {
156: int tmp;
157: char *setcolumn();
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)
1.2 millert 205: return (BI);
1.1 millert 206: else
1.2 millert 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);
1.1 millert 214: }
215: }
216:
217: void
218: fixit(argc, argv)
219: int *argc;
220: char **argv;
221: {
222: int i, j, v, w, x;
1.3 ! millert 223: static char *vbuf, *vpos, *tpos;
! 224:
! 225: if ((vpos = vbuf = calloc(ND*20, sizeof(char))) == NULL)
! 226: errx(2, "cannot allocate memory");
1.1 millert 227:
228: for (i = 1; i < *argc; i++) {
229: if (argv[i][0] == '+') {
230: tpos = argv[i]+1;
231: argv[i] = vpos;
232: vpos += sprintf(vpos, "-k");
233: tpos += sscanf(tpos, "%d", &v);
234: while (isdigit(*tpos))
235: tpos++;
236: vpos += sprintf(vpos, "%d", v+1);
237: if (*tpos == '.') {
238: tpos += sscanf(++tpos, "%d", &x);
239: vpos += sprintf(vpos, ".%d", x+1);
240: }
241: while (*tpos)
242: *vpos++ = *tpos++;
243: vpos += sprintf(vpos, ",");
244: if (argv[i+1] &&
245: argv[i+1][0] == '-' && isdigit(argv[i+1][1])) {
246: tpos = argv[i+1] + 1;
247: tpos += sscanf(tpos, "%d", &w);
248: while (isdigit(*tpos))
249: tpos++;
250: x = 0;
251: if (*tpos == '.') {
252: tpos += sscanf(++tpos, "%d", &x);
253: while (isdigit(*tpos))
254: tpos++;
255: }
256: if (x) {
257: vpos += sprintf(vpos, "%d", w+1);
258: vpos += sprintf(vpos, ".%d", x);
259: } else
260: vpos += sprintf(vpos, "%d", w);
261: while (*tpos)
262: *vpos++ = *tpos++;
263: for (j= i+1; j < *argc; j++)
264: argv[j] = argv[j+1];
265: *argc -= 1;
266: }
267: }
268: }
269: }
270:
271: /*
272: * ascii, Rascii, Ftable, and RFtable map
273: * REC_D -> REC_D; {not REC_D} -> {not REC_D}.
274: * gweights maps REC_D -> (0 or 255); {not REC_D} -> {not gweights[REC_D]}.
275: * Note: when sorting in forward order, to encode character zero in a key,
276: * use \001\001; character 1 becomes \001\002. In this case, character 0
277: * is reserved for the field delimiter. Analagously for -r (fld_d = 255).
278: * Note: this is only good for ASCII sorting. For different LC 's,
279: * all bets are off. See also num_init in number.c
280: */
281: void
282: settables(gflags)
283: int gflags;
284: {
285: u_char *wts;
286: int i, incr;
287: for (i=0; i < 256; i++) {
288: ascii[i] = i;
289: if (i > REC_D && i < 255 - REC_D+1)
290: Rascii[i] = 255 - i + 1;
291: else
292: Rascii[i] = 255 - i;
293: if (islower(i)) {
294: Ftable[i] = Ftable[i- ('a' -'A')];
295: RFtable[i] = RFtable[i - ('a' - 'A')];
296: } else if (REC_D>= 'A' && REC_D < 'Z' && i < 'a' && i > REC_D) {
297: Ftable[i] = i + 1;
298: RFtable[i] = Rascii[i] - 1;
299: } else {
300: Ftable[i] = i;
301: RFtable[i] = Rascii[i];
302: }
303: alltable[i] = 1;
304: if (i == '\n' || isprint(i))
305: itable[i] = 1;
306: else itable[i] = 0;
307: if (i == '\n' || i == '\t' || i == ' ' || isalnum(i))
308: dtable[i] = 1;
309: else dtable[i] = 0;
310: }
311: Rascii[REC_D] = RFtable[REC_D] = REC_D;
312: if (REC_D >= 'A' && REC_D < 'Z')
1.2 millert 313: Ftable[REC_D + ('a' - 'A')]++;
1.1 millert 314: if (gflags & R && (!(gflags & F) || !SINGL_FLD))
315: wts = Rascii;
316: else if (!(gflags & F) || !SINGL_FLD)
317: wts = ascii;
318: else if (gflags & R)
319: wts = RFtable;
320: else
321: wts = Ftable;
322: memmove(gweights, wts, sizeof(gweights));
323: incr = (gflags & R) ? -1 : 1;
324: for (i = 0; i < REC_D; i++)
325: gweights[i] += incr;
326: gweights[REC_D] = ((gflags & R) ? 255 : 0);
327: if (SINGL_FLD && gflags & F) {
328: for (i = 0; i < REC_D; i++) {
329: ascii[i] += incr;
330: Rascii[i] += incr;
331: }
332: ascii[REC_D] = Rascii[REC_D] = gweights[REC_D];
333: }
334: }