Mercurial > emacs
annotate lib-src/yow.c @ 4198:4b43be9f5671
(etags): Depend on ../src/config.h.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 21 Jul 1993 03:29:43 +0000 |
parents | 507f64624555 |
children | 2641ab559aae |
rev | line source |
---|---|
42 | 1 /* |
2 * yow.c | |
12 | 3 * |
4 * Print a quotation from Zippy the Pinhead. | |
5 * Qux <Kaufman-David@Yale> March 6, 1986 | |
6 * | |
42 | 7 * With dynamic memory allocation. |
12 | 8 */ |
9 | |
42 | 10 #include <stdio.h> |
11 #include <ctype.h> | |
443 | 12 #include "../src/paths.h" /* For PATH_DATA. */ |
42 | 13 |
14 #define BUFSIZE 80 | |
12 | 15 #define SEP '\0' |
42 | 16 |
17 #ifndef YOW_FILE | |
12 | 18 #define YOW_FILE "yow.lines" |
42 | 19 #endif |
12 | 20 |
21 main (argc, argv) | |
22 int argc; | |
23 char *argv[]; | |
24 { | |
25 FILE *fp; | |
26 char file[BUFSIZ]; | |
42 | 27 void yow(), setup_yow(); |
12 | 28 |
29 if (argc > 2 && !strcmp (argv[1], "-f")) | |
30 strcpy (file, argv[2]); | |
31 else | |
32 #ifdef vms | |
443 | 33 sprintf (file, "%s%s", PATH_DATA, YOW_FILE); |
12 | 34 #else |
443 | 35 sprintf (file, "%s/%s", PATH_DATA, YOW_FILE); |
12 | 36 #endif |
37 | |
38 if ((fp = fopen(file, "r")) == NULL) { | |
39 perror(file); | |
40 exit(1); | |
41 } | |
42 | |
43 /* initialize random seed */ | |
44 srand((int) (getpid() + time((long *) 0))); | |
45 | |
42 | 46 setup_yow(fp); |
12 | 47 yow(fp); |
48 fclose(fp); | |
49 exit(0); | |
50 } | |
51 | |
42 | 52 static long len = -1; |
53 static long header_len; | |
54 | |
55 #define AVG_LEN 40 /* average length of a quotation */ | |
56 | |
57 /* Sets len and header_len */ | |
58 void | |
59 setup_yow(fp) | |
60 FILE *fp; | |
61 { | |
62 int c; | |
63 | |
64 /* Get length of file */ | |
65 /* Because the header (stuff before the first SEP) can be very long, | |
66 * thus biasing our search in favor of the first quotation in the file, | |
67 * we explicitly skip that. */ | |
68 while ((c = getc(fp)) != SEP) { | |
69 if (c == EOF) { | |
70 fprintf(stderr, "File contains no separators.\n"); | |
71 exit(2); | |
72 } | |
73 } | |
74 header_len = ftell(fp); | |
75 if (header_len > AVG_LEN) | |
76 header_len -= AVG_LEN; /* allow the first quotation to appear */ | |
77 | |
78 if (fseek(fp, 0L, 2) == -1) { | |
79 perror("fseek 1"); | |
80 exit(1); | |
81 } | |
82 len = ftell(fp) - header_len; | |
83 } | |
84 | |
85 | |
86 /* go to a random place in the file and print the quotation there */ | |
12 | 87 void |
88 yow (fp) | |
89 FILE *fp; | |
90 { | |
91 long offset; | |
92 int c, i = 0; | |
42 | 93 char *buf; |
94 unsigned int bufsize; | |
95 char *malloc(), *realloc(); | |
12 | 96 |
42 | 97 offset = rand() % len + header_len; |
12 | 98 if (fseek(fp, offset, 0) == -1) { |
99 perror("fseek 2"); | |
100 exit(1); | |
101 } | |
102 | |
103 /* Read until SEP, read next line, print it. | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
443
diff
changeset
|
104 (Note that we will never print anything before the first separator.) |
12 | 105 If we hit EOF looking for the first SEP, just recurse. */ |
106 while ((c = getc(fp)) != SEP) | |
107 if (c == EOF) { | |
108 yow(fp); | |
109 return; | |
110 } | |
111 | |
112 /* Skip leading whitespace, then read in a quotation. | |
113 If we hit EOF before we find a non-whitespace char, recurse. */ | |
114 while (isspace(c = getc(fp))) | |
115 ; | |
116 if (c == EOF) { | |
117 yow(fp); | |
118 return; | |
119 } | |
42 | 120 |
121 bufsize = BUFSIZE; | |
122 buf = malloc(bufsize); | |
123 if (buf == (char *)0) { | |
124 fprintf(stderr, "can't allocate any memory\n"); | |
125 exit (3); | |
126 } | |
127 | |
12 | 128 buf[i++] = c; |
129 while ((c = getc(fp)) != SEP && c != EOF) { | |
130 buf[i++] = c; | |
42 | 131 |
132 if (i == bufsize-1) { | |
12 | 133 /* Yow! Is this quotation too long yet? */ |
42 | 134 bufsize *= 2; |
135 buf = realloc(buf, bufsize); | |
136 if (buf == (char *)0) { | |
137 fprintf(stderr, "can't allocate more memory\n"); | |
138 exit (3); | |
139 } | |
140 } | |
12 | 141 } |
142 buf[i++] = 0; | |
143 printf("%s\n", buf); | |
144 } | |
145 |