16ae1554aSColin Percival /*- 26ae1554aSColin Percival * Copyright (c) 1989, 1993 36ae1554aSColin Percival * The Regents of the University of California. All rights reserved. 46ae1554aSColin Percival * 56ae1554aSColin Percival * This code is derived from software contributed to Berkeley by 66ae1554aSColin Percival * Ken Arnold. 76ae1554aSColin Percival * 86ae1554aSColin Percival * Redistribution and use in source and binary forms, with or without 96ae1554aSColin Percival * modification, are permitted provided that the following conditions 106ae1554aSColin Percival * are met: 116ae1554aSColin Percival * 1. Redistributions of source code must retain the above copyright 126ae1554aSColin Percival * notice, this list of conditions and the following disclaimer. 136ae1554aSColin Percival * 2. Redistributions in binary form must reproduce the above copyright 146ae1554aSColin Percival * notice, this list of conditions and the following disclaimer in the 156ae1554aSColin Percival * documentation and/or other materials provided with the distribution. 166ae1554aSColin Percival * 3. Neither the name of the University nor the names of its contributors 176ae1554aSColin Percival * may be used to endorse or promote products derived from this software 186ae1554aSColin Percival * without specific prior written permission. 196ae1554aSColin Percival * 206ae1554aSColin Percival * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 216ae1554aSColin Percival * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 226ae1554aSColin Percival * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 236ae1554aSColin Percival * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 246ae1554aSColin Percival * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 256ae1554aSColin Percival * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 266ae1554aSColin Percival * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 276ae1554aSColin Percival * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 286ae1554aSColin Percival * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 296ae1554aSColin Percival * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 306ae1554aSColin Percival * SUCH DAMAGE. 316ae1554aSColin Percival */ 326ae1554aSColin Percival 336ae1554aSColin Percival #if 0 346ae1554aSColin Percival #ifndef lint 356ae1554aSColin Percival static const char copyright[] = 366ae1554aSColin Percival "@(#) Copyright (c) 1989, 1993\n\ 376ae1554aSColin Percival The Regents of the University of California. All rights reserved.\n"; 386ae1554aSColin Percival #endif /* not lint */ 396ae1554aSColin Percival 406ae1554aSColin Percival #ifndef lint 416ae1554aSColin Percival static const char sccsid[] = "@(#)strfile.c 8.1 (Berkeley) 5/31/93"; 426ae1554aSColin Percival #endif /* not lint */ 436ae1554aSColin Percival #endif 446ae1554aSColin Percival #include <sys/cdefs.h> 456ae1554aSColin Percival __FBSDID("$FreeBSD$"); 466ae1554aSColin Percival 476ae1554aSColin Percival #include <sys/param.h> 486ae1554aSColin Percival #include <sys/endian.h> 496ae1554aSColin Percival #include <ctype.h> 506ae1554aSColin Percival #include <locale.h> 516ae1554aSColin Percival #include <stdbool.h> 526ae1554aSColin Percival #include <stdio.h> 536ae1554aSColin Percival #include <stdlib.h> 546ae1554aSColin Percival #include <string.h> 556ae1554aSColin Percival #include <time.h> 566ae1554aSColin Percival #include <unistd.h> 576ae1554aSColin Percival 586ae1554aSColin Percival #include "strfile.h" 596ae1554aSColin Percival 606ae1554aSColin Percival /* 616ae1554aSColin Percival * This program takes a file composed of strings separated by 626ae1554aSColin Percival * lines starting with two consecutive delimiting character (default 636ae1554aSColin Percival * character is '%') and creates another file which consists of a table 646ae1554aSColin Percival * describing the file (structure from "strfile.h"), a table of seek 656ae1554aSColin Percival * pointers to the start of the strings, and the strings, each terminated 666ae1554aSColin Percival * by a null byte. Usage: 676ae1554aSColin Percival * 686ae1554aSColin Percival * % strfile [-iorsx] [ -cC ] sourcefile [ datafile ] 696ae1554aSColin Percival * 706ae1554aSColin Percival * C - Allow comments marked by a double delimiter at line's beginning 716ae1554aSColin Percival * c - Change delimiting character from '%' to 'C' 726ae1554aSColin Percival * s - Silent. Give no summary of data processed at the end of 736ae1554aSColin Percival * the run. 746ae1554aSColin Percival * o - order the strings in alphabetic order 756ae1554aSColin Percival * i - if ordering, ignore case 766ae1554aSColin Percival * r - randomize the order of the strings 776ae1554aSColin Percival * x - set rotated bit 786ae1554aSColin Percival * 796ae1554aSColin Percival * Ken Arnold Sept. 7, 1978 -- 806ae1554aSColin Percival * 816ae1554aSColin Percival * Added ordering options. 826ae1554aSColin Percival */ 836ae1554aSColin Percival 846ae1554aSColin Percival #define STORING_PTRS (Oflag || Rflag) 856ae1554aSColin Percival #define CHUNKSIZE 512 866ae1554aSColin Percival 876ae1554aSColin Percival #define ALLOC(ptr, sz) do { \ 886ae1554aSColin Percival if (ptr == NULL) \ 896ae1554aSColin Percival ptr = malloc(CHUNKSIZE * sizeof(*ptr)); \ 906ae1554aSColin Percival else if (((sz) + 1) % CHUNKSIZE == 0) \ 916ae1554aSColin Percival ptr = realloc(ptr, ((sz) + CHUNKSIZE) * sizeof(*ptr)); \ 926ae1554aSColin Percival if (ptr == NULL) { \ 936ae1554aSColin Percival fprintf(stderr, "out of space\n"); \ 946ae1554aSColin Percival exit(1); \ 956ae1554aSColin Percival } \ 966ae1554aSColin Percival } while (0) 976ae1554aSColin Percival 986ae1554aSColin Percival typedef struct { 996ae1554aSColin Percival int first; 1006ae1554aSColin Percival off_t pos; 1016ae1554aSColin Percival } STR; 1026ae1554aSColin Percival 1036ae1554aSColin Percival static char *Infile = NULL, /* input file name */ 1046ae1554aSColin Percival Outfile[MAXPATHLEN] = "", /* output file name */ 1056ae1554aSColin Percival Delimch = '%'; /* delimiting character */ 1066ae1554aSColin Percival 1076ae1554aSColin Percival static int Cflag = false; /* embedded comments */ 1086ae1554aSColin Percival static int Sflag = false; /* silent run flag */ 1096ae1554aSColin Percival static int Oflag = false; /* ordering flag */ 1106ae1554aSColin Percival static int Iflag = false; /* ignore case flag */ 1116ae1554aSColin Percival static int Rflag = false; /* randomize order flag */ 1126ae1554aSColin Percival static int Xflag = false; /* set rotated bit */ 1136ae1554aSColin Percival static uint32_t Num_pts = 0; /* number of pointers/strings */ 1146ae1554aSColin Percival 1156ae1554aSColin Percival static off_t *Seekpts; 1166ae1554aSColin Percival 1176ae1554aSColin Percival static FILE *Sort_1, *Sort_2; /* pointers for sorting */ 1186ae1554aSColin Percival 1196ae1554aSColin Percival static STRFILE Tbl; /* statistics table */ 1206ae1554aSColin Percival 1216ae1554aSColin Percival static STR *Firstch; /* first chars of each string */ 1226ae1554aSColin Percival 1236ae1554aSColin Percival static void add_offset(FILE *, off_t); 1246ae1554aSColin Percival static int cmp_str(const void *, const void *); 1256ae1554aSColin Percival static int stable_collate_range_cmp(int, int); 1266ae1554aSColin Percival static void do_order(void); 1276ae1554aSColin Percival static void getargs(int, char **); 1286ae1554aSColin Percival static void randomize(void); 129*a1b6427aSAlfonso Gregory static void usage(void) __dead2; 1306ae1554aSColin Percival 1316ae1554aSColin Percival /* 1326ae1554aSColin Percival * main: 1336ae1554aSColin Percival * Drive the sucker. There are two main modes -- either we store 1346ae1554aSColin Percival * the seek pointers, if the table is to be sorted or randomized, 1356ae1554aSColin Percival * or we write the pointer directly to the file, if we are to stay 1366ae1554aSColin Percival * in file order. If the former, we allocate and re-allocate in 1376ae1554aSColin Percival * CHUNKSIZE blocks; if the latter, we just write each pointer, 1386ae1554aSColin Percival * and then seek back to the beginning to write in the table. 1396ae1554aSColin Percival */ 1406ae1554aSColin Percival int 1416ae1554aSColin Percival main(int ac, char *av[]) 1426ae1554aSColin Percival { 1436ae1554aSColin Percival char *sp, *nsp, dc; 1446ae1554aSColin Percival FILE *inf, *outf; 1456ae1554aSColin Percival off_t last_off, pos, *p; 1466ae1554aSColin Percival size_t length; 1476ae1554aSColin Percival int first; 1486ae1554aSColin Percival uint32_t cnt; 1496ae1554aSColin Percival STR *fp; 1506ae1554aSColin Percival static char string[257]; 1516ae1554aSColin Percival 1526ae1554aSColin Percival setlocale(LC_ALL, ""); 1536ae1554aSColin Percival 1546ae1554aSColin Percival getargs(ac, av); /* evalute arguments */ 1556ae1554aSColin Percival dc = Delimch; 1566ae1554aSColin Percival if ((inf = fopen(Infile, "r")) == NULL) { 1576ae1554aSColin Percival perror(Infile); 1586ae1554aSColin Percival exit(1); 1596ae1554aSColin Percival } 1606ae1554aSColin Percival 1616ae1554aSColin Percival if ((outf = fopen(Outfile, "w")) == NULL) { 1626ae1554aSColin Percival perror(Outfile); 1636ae1554aSColin Percival exit(1); 1646ae1554aSColin Percival } 1656ae1554aSColin Percival if (!STORING_PTRS) 1666ae1554aSColin Percival fseek(outf, (long)sizeof(Tbl), SEEK_SET); 1676ae1554aSColin Percival 1686ae1554aSColin Percival /* 1696ae1554aSColin Percival * Write the strings onto the file 1706ae1554aSColin Percival */ 1716ae1554aSColin Percival 1726ae1554aSColin Percival Tbl.str_longlen = 0; 1736ae1554aSColin Percival Tbl.str_shortlen = 0xffffffff; 1746ae1554aSColin Percival Tbl.str_delim = dc; 1756ae1554aSColin Percival Tbl.str_version = VERSION; 1766ae1554aSColin Percival first = Oflag; 1776ae1554aSColin Percival add_offset(outf, ftello(inf)); 1786ae1554aSColin Percival last_off = 0; 1796ae1554aSColin Percival do { 1806ae1554aSColin Percival sp = fgets(string, 256, inf); 1816ae1554aSColin Percival if (sp == NULL || (sp[0] == dc && sp[1] == '\n')) { 1826ae1554aSColin Percival pos = ftello(inf); 1836ae1554aSColin Percival length = (size_t)(pos - last_off) - 1846ae1554aSColin Percival (sp != NULL ? strlen(sp) : 0); 1856ae1554aSColin Percival last_off = pos; 1866ae1554aSColin Percival if (length == 0) 1876ae1554aSColin Percival continue; 1886ae1554aSColin Percival add_offset(outf, pos); 1896ae1554aSColin Percival if ((size_t)Tbl.str_longlen < length) 1906ae1554aSColin Percival Tbl.str_longlen = length; 1916ae1554aSColin Percival if ((size_t)Tbl.str_shortlen > length) 1926ae1554aSColin Percival Tbl.str_shortlen = length; 1936ae1554aSColin Percival first = Oflag; 1946ae1554aSColin Percival } 1956ae1554aSColin Percival else if (first) { 1966ae1554aSColin Percival for (nsp = sp; !isalnum((unsigned char)*nsp); nsp++) 1976ae1554aSColin Percival continue; 1986ae1554aSColin Percival ALLOC(Firstch, Num_pts); 1996ae1554aSColin Percival fp = &Firstch[Num_pts - 1]; 2006ae1554aSColin Percival if (Iflag && isupper((unsigned char)*nsp)) 2016ae1554aSColin Percival fp->first = tolower((unsigned char)*nsp); 2026ae1554aSColin Percival else 2036ae1554aSColin Percival fp->first = *nsp; 2046ae1554aSColin Percival fp->pos = Seekpts[Num_pts - 1]; 2056ae1554aSColin Percival first = false; 2066ae1554aSColin Percival } 2076ae1554aSColin Percival } while (sp != NULL); 2086ae1554aSColin Percival 2096ae1554aSColin Percival /* 2106ae1554aSColin Percival * write the tables in 2116ae1554aSColin Percival */ 2126ae1554aSColin Percival 2136ae1554aSColin Percival fclose(inf); 2146ae1554aSColin Percival Tbl.str_numstr = Num_pts - 1; 2156ae1554aSColin Percival 2166ae1554aSColin Percival if (Cflag) 2176ae1554aSColin Percival Tbl.str_flags |= STR_COMMENTS; 2186ae1554aSColin Percival 2196ae1554aSColin Percival if (Oflag) 2206ae1554aSColin Percival do_order(); 2216ae1554aSColin Percival else if (Rflag) 2226ae1554aSColin Percival randomize(); 2236ae1554aSColin Percival 2246ae1554aSColin Percival if (Xflag) 2256ae1554aSColin Percival Tbl.str_flags |= STR_ROTATED; 2266ae1554aSColin Percival 2276ae1554aSColin Percival if (!Sflag) { 2286ae1554aSColin Percival printf("\"%s\" created\n", Outfile); 2296ae1554aSColin Percival if (Num_pts == 2) 2306ae1554aSColin Percival puts("There was 1 string"); 2316ae1554aSColin Percival else 2326ae1554aSColin Percival printf("There were %u strings\n", Num_pts - 1); 2336ae1554aSColin Percival printf("Longest string: %u byte%s\n", Tbl.str_longlen, 2346ae1554aSColin Percival Tbl.str_longlen == 1 ? "" : "s"); 2356ae1554aSColin Percival printf("Shortest string: %u byte%s\n", Tbl.str_shortlen, 2366ae1554aSColin Percival Tbl.str_shortlen == 1 ? "" : "s"); 2376ae1554aSColin Percival } 2386ae1554aSColin Percival 2396ae1554aSColin Percival rewind(outf); 2406ae1554aSColin Percival Tbl.str_version = htobe32(Tbl.str_version); 2416ae1554aSColin Percival Tbl.str_numstr = htobe32(Tbl.str_numstr); 2426ae1554aSColin Percival Tbl.str_longlen = htobe32(Tbl.str_longlen); 2436ae1554aSColin Percival Tbl.str_shortlen = htobe32(Tbl.str_shortlen); 2446ae1554aSColin Percival Tbl.str_flags = htobe32(Tbl.str_flags); 2456ae1554aSColin Percival fwrite((char *)&Tbl, sizeof(Tbl), 1, outf); 2466ae1554aSColin Percival if (STORING_PTRS) { 2476ae1554aSColin Percival for (p = Seekpts, cnt = Num_pts; cnt--; ++p) 2486ae1554aSColin Percival *p = htobe64(*p); 2496ae1554aSColin Percival fwrite(Seekpts, sizeof(*Seekpts), (size_t)Num_pts, outf); 2506ae1554aSColin Percival } 2516ae1554aSColin Percival fclose(outf); 2526ae1554aSColin Percival exit(0); 2536ae1554aSColin Percival } 2546ae1554aSColin Percival 2556ae1554aSColin Percival /* 2566ae1554aSColin Percival * This routine evaluates arguments from the command line 2576ae1554aSColin Percival */ 2586ae1554aSColin Percival void 2596ae1554aSColin Percival getargs(int argc, char **argv) 2606ae1554aSColin Percival { 2616ae1554aSColin Percival int ch; 2626ae1554aSColin Percival 2636ae1554aSColin Percival while ((ch = getopt(argc, argv, "Cc:iorsx")) != -1) 2646ae1554aSColin Percival switch(ch) { 2656ae1554aSColin Percival case 'C': /* embedded comments */ 2666ae1554aSColin Percival Cflag++; 2676ae1554aSColin Percival break; 2686ae1554aSColin Percival case 'c': /* new delimiting char */ 2696ae1554aSColin Percival Delimch = *optarg; 2706ae1554aSColin Percival if (!isascii(Delimch)) { 2716ae1554aSColin Percival printf("bad delimiting character: '\\%o\n'", 2726ae1554aSColin Percival (unsigned char)Delimch); 2736ae1554aSColin Percival } 2746ae1554aSColin Percival break; 2756ae1554aSColin Percival case 'i': /* ignore case in ordering */ 2766ae1554aSColin Percival Iflag++; 2776ae1554aSColin Percival break; 2786ae1554aSColin Percival case 'o': /* order strings */ 2796ae1554aSColin Percival Oflag++; 2806ae1554aSColin Percival break; 2816ae1554aSColin Percival case 'r': /* randomize pointers */ 2826ae1554aSColin Percival Rflag++; 2836ae1554aSColin Percival break; 2846ae1554aSColin Percival case 's': /* silent */ 2856ae1554aSColin Percival Sflag++; 2866ae1554aSColin Percival break; 2876ae1554aSColin Percival case 'x': /* set the rotated bit */ 2886ae1554aSColin Percival Xflag++; 2896ae1554aSColin Percival break; 2906ae1554aSColin Percival case '?': 2916ae1554aSColin Percival default: 2926ae1554aSColin Percival usage(); 2936ae1554aSColin Percival } 2946ae1554aSColin Percival argv += optind; 2956ae1554aSColin Percival 2966ae1554aSColin Percival if (*argv) { 2976ae1554aSColin Percival Infile = *argv; 298777c9f5aSMark Johnston if (*++argv) { 299777c9f5aSMark Johnston if (strlcpy(Outfile, *argv, sizeof(Outfile)) >= 300777c9f5aSMark Johnston sizeof(Outfile)) { 301777c9f5aSMark Johnston fprintf(stderr, 302777c9f5aSMark Johnston "output_file path is too long\n"); 303777c9f5aSMark Johnston exit(1); 304777c9f5aSMark Johnston } 305777c9f5aSMark Johnston } 3066ae1554aSColin Percival } 3076ae1554aSColin Percival if (!Infile) { 3086ae1554aSColin Percival puts("No input file name"); 3096ae1554aSColin Percival usage(); 3106ae1554aSColin Percival } 3116ae1554aSColin Percival if (*Outfile == '\0') { 312777c9f5aSMark Johnston if ((size_t)snprintf(Outfile, sizeof(Outfile), "%s.dat", 313777c9f5aSMark Johnston Infile) >= sizeof(Outfile)) { 314777c9f5aSMark Johnston fprintf(stderr, 315777c9f5aSMark Johnston "generated output_file path is too long\n"); 316777c9f5aSMark Johnston exit(1); 317777c9f5aSMark Johnston } 3186ae1554aSColin Percival } 3196ae1554aSColin Percival } 3206ae1554aSColin Percival 3216ae1554aSColin Percival void 3226ae1554aSColin Percival usage(void) 3236ae1554aSColin Percival { 3246ae1554aSColin Percival fprintf(stderr, 3256ae1554aSColin Percival "strfile [-Ciorsx] [-c char] source_file [output_file]\n"); 3266ae1554aSColin Percival exit(1); 3276ae1554aSColin Percival } 3286ae1554aSColin Percival 3296ae1554aSColin Percival /* 3306ae1554aSColin Percival * add_offset: 3316ae1554aSColin Percival * Add an offset to the list, or write it out, as appropriate. 3326ae1554aSColin Percival */ 3336ae1554aSColin Percival void 3346ae1554aSColin Percival add_offset(FILE *fp, off_t off) 3356ae1554aSColin Percival { 3366ae1554aSColin Percival off_t beoff; 3376ae1554aSColin Percival 3386ae1554aSColin Percival if (!STORING_PTRS) { 3396ae1554aSColin Percival beoff = htobe64(off); 3406ae1554aSColin Percival fwrite(&beoff, 1, sizeof(beoff), fp); 3416ae1554aSColin Percival } else { 3426ae1554aSColin Percival ALLOC(Seekpts, Num_pts + 1); 3436ae1554aSColin Percival Seekpts[Num_pts] = off; 3446ae1554aSColin Percival } 3456ae1554aSColin Percival Num_pts++; 3466ae1554aSColin Percival } 3476ae1554aSColin Percival 3486ae1554aSColin Percival /* 3496ae1554aSColin Percival * do_order: 3506ae1554aSColin Percival * Order the strings alphabetically (possibly ignoring case). 3516ae1554aSColin Percival */ 3526ae1554aSColin Percival void 3536ae1554aSColin Percival do_order(void) 3546ae1554aSColin Percival { 3556ae1554aSColin Percival uint32_t i; 3566ae1554aSColin Percival off_t *lp; 3576ae1554aSColin Percival STR *fp; 3586ae1554aSColin Percival 3596ae1554aSColin Percival Sort_1 = fopen(Infile, "r"); 3606ae1554aSColin Percival Sort_2 = fopen(Infile, "r"); 3616ae1554aSColin Percival qsort(Firstch, (size_t)Tbl.str_numstr, sizeof(*Firstch), cmp_str); 3626ae1554aSColin Percival i = Tbl.str_numstr; 3636ae1554aSColin Percival lp = Seekpts; 3646ae1554aSColin Percival fp = Firstch; 3656ae1554aSColin Percival while (i--) 3666ae1554aSColin Percival *lp++ = fp++->pos; 3676ae1554aSColin Percival fclose(Sort_1); 3686ae1554aSColin Percival fclose(Sort_2); 3696ae1554aSColin Percival Tbl.str_flags |= STR_ORDERED; 3706ae1554aSColin Percival } 3716ae1554aSColin Percival 3726ae1554aSColin Percival static int 3736ae1554aSColin Percival stable_collate_range_cmp(int c1, int c2) 3746ae1554aSColin Percival { 3756ae1554aSColin Percival static char s1[2], s2[2]; 3766ae1554aSColin Percival int ret; 3776ae1554aSColin Percival 3786ae1554aSColin Percival s1[0] = c1; 3796ae1554aSColin Percival s2[0] = c2; 3806ae1554aSColin Percival if ((ret = strcoll(s1, s2)) != 0) 3816ae1554aSColin Percival return (ret); 3826ae1554aSColin Percival return (c1 - c2); 3836ae1554aSColin Percival } 3846ae1554aSColin Percival 3856ae1554aSColin Percival /* 3866ae1554aSColin Percival * cmp_str: 3876ae1554aSColin Percival * Compare two strings in the file 3886ae1554aSColin Percival */ 3896ae1554aSColin Percival int 3906ae1554aSColin Percival cmp_str(const void *s1, const void *s2) 3916ae1554aSColin Percival { 3926ae1554aSColin Percival const STR *p1, *p2; 3936ae1554aSColin Percival int c1, c2, n1, n2, r; 3946ae1554aSColin Percival 3956ae1554aSColin Percival #define SET_N(nf,ch) (nf = (ch == '\n')) 3966ae1554aSColin Percival #define IS_END(ch,nf) (ch == EOF || (ch == (unsigned char)Delimch && nf)) 3976ae1554aSColin Percival 3986ae1554aSColin Percival p1 = (const STR *)s1; 3996ae1554aSColin Percival p2 = (const STR *)s2; 4006ae1554aSColin Percival 4016ae1554aSColin Percival c1 = (unsigned char)p1->first; 4026ae1554aSColin Percival c2 = (unsigned char)p2->first; 4036ae1554aSColin Percival if ((r = stable_collate_range_cmp(c1, c2)) != 0) 4046ae1554aSColin Percival return (r); 4056ae1554aSColin Percival 4066ae1554aSColin Percival fseeko(Sort_1, p1->pos, SEEK_SET); 4076ae1554aSColin Percival fseeko(Sort_2, p2->pos, SEEK_SET); 4086ae1554aSColin Percival 4096ae1554aSColin Percival n1 = false; 4106ae1554aSColin Percival n2 = false; 4116ae1554aSColin Percival while (!isalnum(c1 = getc(Sort_1)) && c1 != '\0' && c1 != EOF) 4126ae1554aSColin Percival SET_N(n1, c1); 4136ae1554aSColin Percival while (!isalnum(c2 = getc(Sort_2)) && c2 != '\0' && c2 != EOF) 4146ae1554aSColin Percival SET_N(n2, c2); 4156ae1554aSColin Percival 4166ae1554aSColin Percival while (!IS_END(c1, n1) && !IS_END(c2, n2)) { 4176ae1554aSColin Percival if (Iflag) { 4186ae1554aSColin Percival if (isupper(c1)) 4196ae1554aSColin Percival c1 = tolower(c1); 4206ae1554aSColin Percival if (isupper(c2)) 4216ae1554aSColin Percival c2 = tolower(c2); 4226ae1554aSColin Percival } 4236ae1554aSColin Percival if ((r = stable_collate_range_cmp(c1, c2)) != 0) 4246ae1554aSColin Percival return (r); 4256ae1554aSColin Percival SET_N(n1, c1); 4266ae1554aSColin Percival SET_N(n2, c2); 4276ae1554aSColin Percival c1 = getc(Sort_1); 4286ae1554aSColin Percival c2 = getc(Sort_2); 4296ae1554aSColin Percival } 4306ae1554aSColin Percival if (IS_END(c1, n1)) 4316ae1554aSColin Percival c1 = 0; 4326ae1554aSColin Percival if (IS_END(c2, n2)) 4336ae1554aSColin Percival c2 = 0; 4346ae1554aSColin Percival 4356ae1554aSColin Percival return (stable_collate_range_cmp(c1, c2)); 4366ae1554aSColin Percival } 4376ae1554aSColin Percival 4386ae1554aSColin Percival /* 4396ae1554aSColin Percival * randomize: 4406ae1554aSColin Percival * Randomize the order of the string table. We must be careful 4416ae1554aSColin Percival * not to randomize across delimiter boundaries. All 4426ae1554aSColin Percival * randomization is done within each block. 4436ae1554aSColin Percival */ 4446ae1554aSColin Percival void 4456ae1554aSColin Percival randomize(void) 4466ae1554aSColin Percival { 4476ae1554aSColin Percival uint32_t cnt, i; 4486ae1554aSColin Percival off_t tmp; 4496ae1554aSColin Percival off_t *sp; 4506ae1554aSColin Percival 4516ae1554aSColin Percival Tbl.str_flags |= STR_RANDOM; 4526ae1554aSColin Percival cnt = Tbl.str_numstr; 4536ae1554aSColin Percival 4546ae1554aSColin Percival /* 4556ae1554aSColin Percival * move things around randomly 4566ae1554aSColin Percival */ 4576ae1554aSColin Percival 4586ae1554aSColin Percival for (sp = Seekpts; cnt > 0; cnt--, sp++) { 4596ae1554aSColin Percival i = arc4random_uniform(cnt); 4606ae1554aSColin Percival tmp = sp[0]; 4616ae1554aSColin Percival sp[0] = sp[i]; 4626ae1554aSColin Percival sp[i] = tmp; 4636ae1554aSColin Percival } 4646ae1554aSColin Percival } 465