# HG changeset patch # User Richard M. Stallman # Date 631300530 0 # Node ID 71b3e30e0dd4c2f94aaa7089bc69cd8ce92e749c # Parent 467ee6fe6503b381e8e37114ab063ce12232f26e *** empty log message *** diff -r 467ee6fe6503 -r 71b3e30e0dd4 lib-src/yow.c --- a/lib-src/yow.c Mon Dec 11 04:58:09 1989 +0000 +++ b/lib-src/yow.c Tue Jan 02 17:15:30 1990 +0000 @@ -1,17 +1,22 @@ -#include -#include -#include "../src/paths.h" - -/* zippy.c +/* + * yow.c * * Print a quotation from Zippy the Pinhead. * Qux March 6, 1986 * + * With dynamic memory allocation. */ -#define BUFSIZE 2000 +#include +#include +#include "../src/paths.h" /* For PATH_EXEC. */ + +#define BUFSIZE 80 #define SEP '\0' + +#ifndef YOW_FILE #define YOW_FILE "yow.lines" +#endif main (argc, argv) int argc; @@ -19,7 +24,7 @@ { FILE *fp; char file[BUFSIZ]; - void yow(); + void yow(), setup_yow(); if (argc > 2 && !strcmp (argv[1], "-f")) strcpy (file, argv[2]); @@ -38,29 +43,58 @@ /* initialize random seed */ srand((int) (getpid() + time((long *) 0))); + setup_yow(fp); yow(fp); fclose(fp); exit(0); } +static long len = -1; +static long header_len; + +#define AVG_LEN 40 /* average length of a quotation */ + +/* Sets len and header_len */ +void +setup_yow(fp) + FILE *fp; +{ + int c; + + /* Get length of file */ + /* Because the header (stuff before the first SEP) can be very long, + * thus biasing our search in favor of the first quotation in the file, + * we explicitly skip that. */ + while ((c = getc(fp)) != SEP) { + if (c == EOF) { + fprintf(stderr, "File contains no separators.\n"); + exit(2); + } + } + header_len = ftell(fp); + if (header_len > AVG_LEN) + header_len -= AVG_LEN; /* allow the first quotation to appear */ + + if (fseek(fp, 0L, 2) == -1) { + perror("fseek 1"); + exit(1); + } + len = ftell(fp) - header_len; +} + + +/* go to a random place in the file and print the quotation there */ void yow (fp) FILE *fp; { - static long len = -1; long offset; int c, i = 0; - char buf[BUFSIZE]; + char *buf; + unsigned int bufsize; + char *malloc(), *realloc(); - /* Get length of file, go to a random place in it */ - if (len == -1) { - if (fseek(fp, 0, 2) == -1) { - perror("fseek 1"); - exit(1); - } - len = ftell(fp); - } - offset = rand() % len; + offset = rand() % len + header_len; if (fseek(fp, offset, 0) == -1) { perror("fseek 2"); exit(1); @@ -83,13 +117,27 @@ yow(fp); return; } + + bufsize = BUFSIZE; + buf = malloc(bufsize); + if (buf == (char *)0) { + fprintf(stderr, "can't allocate any memory\n"); + exit (3); + } + buf[i++] = c; while ((c = getc(fp)) != SEP && c != EOF) { buf[i++] = c; - - if (i == BUFSIZ-1) + + if (i == bufsize-1) { /* Yow! Is this quotation too long yet? */ - break; + bufsize *= 2; + buf = realloc(buf, bufsize); + if (buf == (char *)0) { + fprintf(stderr, "can't allocate more memory\n"); + exit (3); + } + } } buf[i++] = 0; printf("%s\n", buf);