don't bother using prototypes if it's not ANSI C; breaks gcc -traditional
[unix-history] / usr / src / games / fortune / strfile / strfile.c
index f428976..014494d 100644 (file)
@@ -1,11 +1,38 @@
-/* $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      <stdio.h>
 # include      <ctype.h>
-# include      <sys/types.h>
-# include      <sys/param.h>
 # include      "strfile.h"
 # include      "strfile.h"
-# include      "random.h"
 
 # ifndef MAXPATHLEN
 # define       MAXPATHLEN      1024
 
 # 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
  * 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:
  *
  * 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.
  *     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
  *     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 --
  *
  *
  *             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.
  */
 
  *     Added ordering options.
  */
 
@@ -73,24 +94,14 @@ typedef struct {
 
 char   *Infile         = NULL,         /* input file name */
        Outfile[MAXPATHLEN] = "",       /* output file name */
 
 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    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;
 
 
 off_t  *Seekpts;
 
@@ -119,8 +130,8 @@ char        **av;
 {
        register char           *sp, dc;
        register FILE           *inf, *outf;
 {
        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];
        register char           *nsp;
        register STR            *fp;
        static char             string[257];
@@ -129,12 +140,12 @@ char      **av;
        dc = Delimch;
        if ((inf = fopen(Infile, "r")) == NULL) {
                perror(Infile);
        dc = Delimch;
        if ((inf = fopen(Infile, "r")) == NULL) {
                perror(Infile);
-               exit(-1);
+               exit(1);
        }
 
        if ((outf = fopen(Outfile, "w")) == NULL) {
                perror(Outfile);
        }
 
        if ((outf = fopen(Outfile, "w")) == NULL) {
                perror(Outfile);
-               exit(-1);
+               exit(1);
        }
        if (!STORING_PTRS)
                (void) fseek(outf, sizeof Tbl, 0);
        }
        if (!STORING_PTRS)
                (void) fseek(outf, sizeof Tbl, 0);
@@ -146,37 +157,36 @@ char      **av;
        Tbl.str_longlen = 0;
        Tbl.str_shortlen = (unsigned int) 0xffffffff;
        Tbl.str_delim = dc;
        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 {
        first = Oflag;
        add_offset(outf, ftell(inf));
        last_off = 0;
        do {
-               if (Num_pts > 508)
-                       atoi("1");
                sp = fgets(string, 256, inf);
                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);
                        pos = ftell(inf);
-                       add_offset(outf, pos);
                        length = pos - last_off - strlen(sp);
                        last_off = 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;
                }
                        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);
 
                }
        } while (sp != NULL);
 
@@ -185,103 +195,104 @@ char    **av;
         */
 
        (void) fclose(inf);
         */
 
        (void) fclose(inf);
-       Tbl.str_numstr = Num_pts - 1;
 
        if (Oflag)
                do_order();
        else if (Rflag)
                randomize();
 
 
        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
 
        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");
                       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");
        }
                       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);
        exit(0);
-       /* NOTREACHED */
 }
 
 /*
  *     This routine evaluates arguments from the command line
  */
 }
 
 /*
  *     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) {
        if (!Infile) {
-               bad++;
                puts("No input file name");
                puts("No input file name");
+               usage();
        }
        }
-       if (*Outfile == '\0' && !bad) {
+       if (*Outfile == '\0') {
                (void) strcpy(Outfile, Infile);
                (void) strcat(Outfile, ".dat");
        }
                (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);
 }
 
 /*
 }
 
 /*
@@ -292,9 +303,12 @@ add_offset(fp, off)
 FILE   *fp;
 off_t  off;
 {
 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;
        }
                ALLOC(Seekpts, Num_pts + 1);
                Seekpts[Num_pts] = off;
        }
@@ -383,8 +397,6 @@ STR *p1, *p2;
                }
                if (c1 != c2)
                        return c1 - c2;
                }
                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);
                SET_N(n1, c1);
                SET_N(n2, c2);
                c1 = getc(Sort_1);
@@ -410,6 +422,8 @@ randomize()
        register off_t  *sp;
        extern time_t   time();
 
        register off_t  *sp;
        extern time_t   time();
 
+       srandom((int)(time((time_t *) NULL) + getpid()));
+
        Tbl.str_flags |= STR_RANDOM;
        cnt = Tbl.str_numstr;
 
        Tbl.str_flags |= STR_RANDOM;
        cnt = Tbl.str_numstr;
 
@@ -418,7 +432,7 @@ randomize()
         */
 
        for (sp = Seekpts; cnt > 0; cnt--, sp++) {
         */
 
        for (sp = Seekpts; cnt > 0; cnt--, sp++) {
-               i = rnd((long) cnt);
+               i = random() % cnt;
                tmp = sp[0];
                sp[0] = sp[i];
                sp[i] = tmp;
                tmp = sp[0];
                sp[0] = sp[i];
                sp[i] = tmp;