-/* $Header: strfile.c,v 1.19 89/05/05 16:07:46 arnold Exp $ */
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Arnold.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+#ifndef lint
+static char sccsid[] = "@(#)strfile.c 5.10 (Berkeley) %G%";
+#endif /* not lint */
+
+# include <sys/param.h>
+# include <sys/types.h>
# include <stdio.h>
# include <ctype.h>
-# include <sys/types.h>
-# include <sys/param.h>
# include "strfile.h"
-# include "random.h"
# ifndef MAXPATHLEN
# define MAXPATHLEN 1024
* lines starting with two consecutive delimiting character (default
* character is '%') and creates another file which consists of a table
* describing the file (structure from "strfile.h"), a table of seek
- * pointers to the start of the strings, and the strings, each terinated
+ * pointers to the start of the strings, and the strings, each terminated
* by a null byte. Usage:
*
- * % strfile [ - ] [ -cC ] [ -sv ] [ -oir ] sourcefile [ datafile ]
+ * % strfile [-iorsx] [ -cC ] sourcefile [ datafile ]
*
- * - - Give a usage summary useful for jogging the memory
* c - Change delimiting character from '%' to 'C'
* s - Silent. Give no summary of data processed at the end of
* the run.
- * v - Verbose. Give summary of data processed. (Default)
* o - order the strings in alphabetic order
* i - if ordering, ignore case
* r - randomize the order of the strings
+ * x - set rotated bit
*
* Ken Arnold Sept. 7, 1978 --
*
- * Added method to indicate dividers. A "%-" will cause the address
- * to be added to the structure in one of the pointer elements.
- *
- * Ken Arnold Nov., 1984 --
- *
* Added ordering options.
*/
char *Infile = NULL, /* input file name */
Outfile[MAXPATHLEN] = "", /* output file name */
- Delimch = '%', /* delimiting character */
- *Usage[] = { /* usage summary */
- "usage: strfile [ - ] [ -cC ] [ -sv ] [ -oir ] inputfile [ datafile ]",
- " - - Give this usage summary",
- " c - Replace delimiting character with 'C'",
- " s - Silent. Give no summary",
- " v - Verbose. Give summary. (default)",
- " o - order strings alphabetically",
- " i - ignore case in ordering",
- " r - randomize the order of the strings",
- " Default \"datafile\" is inputfile.dat",
- };
+ Delimch = '%'; /* delimiting character */
int Sflag = FALSE; /* silent run flag */
int Oflag = FALSE; /* ordering flag */
int Iflag = FALSE; /* ignore case flag */
int Rflag = FALSE; /* randomize order flag */
-int Num_pts = 0; /* number of pointers/strings */
+int Xflag = FALSE; /* set rotated bit */
+long Num_pts = 0; /* number of pointers/strings */
off_t *Seekpts;
{
register char *sp, dc;
register FILE *inf, *outf;
- register off_t last_off, length, pos;
- register int first;
+ register off_t last_off, length, pos, *p;
+ register int first, cnt;
register char *nsp;
register STR *fp;
static char string[257];
dc = Delimch;
if ((inf = fopen(Infile, "r")) == NULL) {
perror(Infile);
- exit(-1);
+ exit(1);
}
if ((outf = fopen(Outfile, "w")) == NULL) {
perror(Outfile);
- exit(-1);
+ exit(1);
}
if (!STORING_PTRS)
(void) fseek(outf, sizeof Tbl, 0);
Tbl.str_longlen = 0;
Tbl.str_shortlen = (unsigned int) 0xffffffff;
Tbl.str_delim = dc;
+ Tbl.str_version = VERSION;
first = Oflag;
add_offset(outf, ftell(inf));
last_off = 0;
do {
- if (Num_pts > 508)
- atoi("1");
sp = fgets(string, 256, inf);
- if (sp == NULL || (sp[0] == dc && sp[1] == dc)) {
+ if (sp == NULL || sp[0] == dc && sp[1] == '\n') {
pos = ftell(inf);
- add_offset(outf, pos);
length = pos - last_off - strlen(sp);
last_off = pos;
+ if (!length)
+ continue;
+ add_offset(outf, pos);
if (Tbl.str_longlen < length)
Tbl.str_longlen = length;
if (Tbl.str_shortlen > length)
Tbl.str_shortlen = length;
first = Oflag;
}
- else {
- if (first) {
- for (nsp = sp; !isalnum(*nsp); nsp++)
- continue;
- ALLOC(Firstch, Num_pts);
- fp = &Firstch[Num_pts - 1];
- if (Iflag && isupper(*nsp))
- fp->first = tolower(*nsp);
- else
- fp->first = *nsp;
- fp->pos = Seekpts[Num_pts - 1];
- first = FALSE;
- }
+ else if (first) {
+ for (nsp = sp; !isalnum(*nsp); nsp++)
+ continue;
+ ALLOC(Firstch, Num_pts);
+ fp = &Firstch[Num_pts - 1];
+ if (Iflag && isupper(*nsp))
+ fp->first = tolower(*nsp);
+ else
+ fp->first = *nsp;
+ fp->pos = Seekpts[Num_pts - 1];
+ first = FALSE;
}
} while (sp != NULL);
*/
(void) fclose(inf);
- Tbl.str_numstr = Num_pts - 1;
if (Oflag)
do_order();
else if (Rflag)
randomize();
- (void) fseek(outf, (off_t) 0, 0);
- (void) fwrite((char *) &Tbl, sizeof Tbl, 1, outf);
- if (STORING_PTRS)
- (void) fwrite((char *) Seekpts, sizeof *Seekpts, (int) Num_pts, outf);
- (void) fclose(outf);
+ if (Xflag)
+ Tbl.str_flags |= STR_ROTATED;
if (!Sflag) {
printf("\"%s\" created\n", Outfile);
if (Num_pts == 2)
puts("There was 1 string");
else
- printf("There were %u strings\n", Num_pts - 1);
- printf("Longest string: %u byte%s\n", Tbl.str_longlen,
+ printf("There were %d strings\n", Num_pts - 1);
+ printf("Longest string: %lu byte%s\n", Tbl.str_longlen,
Tbl.str_longlen == 1 ? "" : "s");
- printf("Shortest string: %u byte%s\n", Tbl.str_shortlen,
+ printf("Shortest string: %lu byte%s\n", Tbl.str_shortlen,
Tbl.str_shortlen == 1 ? "" : "s");
}
+
+ (void) fseek(outf, (off_t) 0, 0);
+ Tbl.str_version = htonl(Tbl.str_version);
+ Tbl.str_numstr = htonl(Num_pts - 1);
+ Tbl.str_longlen = htonl(Tbl.str_longlen);
+ Tbl.str_shortlen = htonl(Tbl.str_shortlen);
+ Tbl.str_flags = htonl(Tbl.str_flags);
+ (void) fwrite((char *) &Tbl, sizeof Tbl, 1, outf);
+ if (STORING_PTRS) {
+ for (p = Seekpts, cnt = Num_pts; cnt--; ++p)
+ *p = htonl(*p);
+ (void) fwrite((char *) Seekpts, sizeof *Seekpts, (int) Num_pts, outf);
+ }
+ (void) fclose(outf);
exit(0);
- /* NOTREACHED */
}
/*
* This routine evaluates arguments from the command line
*/
-getargs(ac, av)
-register int ac;
-register char **av;
+getargs(argc, argv)
+int argc;
+char **argv;
{
- register char *sp;
- register int i;
- register int bad, j;
-
- bad = 0;
- for (i = 1; i < ac; i++)
- if (*av[i] == '-' && av[i][1]) {
- for (sp = &av[i][1]; *sp; sp++)
- switch (*sp) {
- case 'c': /* new delimiting char */
- if ((Delimch = *++sp) == '\0') {
- --sp;
- Delimch = *av[++i];
- }
- if (!isascii(Delimch)) {
- printf("bad delimiting character: '\\%o\n'",
- Delimch);
- bad++;
- }
- break;
- case 's': /* silent */
- Sflag++;
- break;
- case 'v': /* verbose */
- Sflag = 0;
- break;
- case 'o': /* order strings */
- Oflag++;
- break;
- case 'i': /* ignore case in ordering */
- Iflag++;
- break;
- case 'r': /* ignore case in ordering */
- Rflag++;
- break;
- default: /* unknown flag */
- bad++;
- printf("bad flag: '%c'\n", *sp);
- break;
- }
- }
- else if (*av[i] == '-') {
- for (j = 0; Usage[j]; j++)
- puts(Usage[j]);
- exit(0);
+ extern char *optarg;
+ extern int optind;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "c:iorsx")) != EOF)
+ switch(ch) {
+ case 'c': /* new delimiting char */
+ Delimch = *optarg;
+ if (!isascii(Delimch)) {
+ printf("bad delimiting character: '\\%o\n'",
+ Delimch);
+ }
+ break;
+ case 'i': /* ignore case in ordering */
+ Iflag++;
+ break;
+ case 'o': /* order strings */
+ Oflag++;
+ break;
+ case 'r': /* randomize pointers */
+ Rflag++;
+ break;
+ case 's': /* silent */
+ Sflag++;
+ break;
+ case 'x': /* set the rotated bit */
+ Xflag++;
+ break;
+ case '?':
+ default:
+ usage();
}
- else if (Infile)
- (void) strcpy(Outfile, av[i]);
- else
- Infile = av[i];
+ argv += optind;
+
+ if (*argv) {
+ Infile = *argv;
+ if (*++argv)
+ (void) strcpy(Outfile, *argv);
+ }
if (!Infile) {
- bad++;
puts("No input file name");
+ usage();
}
- if (*Outfile == '\0' && !bad) {
+ if (*Outfile == '\0') {
(void) strcpy(Outfile, Infile);
(void) strcat(Outfile, ".dat");
}
- if (bad) {
- puts("use \"strfile -\" to get usage");
- exit(-1);
- }
+}
+
+usage()
+{
+ (void) fprintf(stderr,
+ "strfile [-iorsx] [-c char] sourcefile [datafile]\n");
+ exit(1);
}
/*
FILE *fp;
off_t off;
{
- if (!STORING_PTRS)
- fwrite(&off, 1, sizeof off, fp);
- else {
+ off_t net;
+
+ if (!STORING_PTRS) {
+ net = htonl(off);
+ fwrite(&net, 1, sizeof net, fp);
+ } else {
ALLOC(Seekpts, Num_pts + 1);
Seekpts[Num_pts] = off;
}
}
if (c1 != c2)
return c1 - c2;
- if (c1 == '\n' || c2 == '\n')
- atoi("1");
SET_N(n1, c1);
SET_N(n2, c2);
c1 = getc(Sort_1);
register off_t *sp;
extern time_t time();
+ srandom((int)(time((time_t *) NULL) + getpid()));
+
Tbl.str_flags |= STR_RANDOM;
cnt = Tbl.str_numstr;
*/
for (sp = Seekpts; cnt > 0; cnt--, sp++) {
- i = rnd((long) cnt);
+ i = random() % cnt;
tmp = sp[0];
sp[0] = sp[i];
sp[i] = tmp;