Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
[bpt/emacs.git] / lib-src / yow.c
CommitLineData
701570d7
RS
1/*
2 * yow.c
177c0ea7 3 *
bc851190
RS
4 * Print a quotation from Zippy the Pinhead.
5 * Qux <Kaufman-David@Yale> March 6, 1986
c76d4b42
RS
6 *
7 * This file is in the public domain because the author published it
8 * with no copyright notice before the US signed the Bern Convention.
177c0ea7 9 *
701570d7 10 * With dynamic memory allocation.
bc851190
RS
11 */
12
2f8fe2f4
PJ
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
701570d7
RS
17#include <stdio.h>
18#include <ctype.h>
076a0ff7
DL
19#ifdef TIME_WITH_SYS_TIME
20#include <sys/time.h>
21#include <time.h>
22#else
23#ifdef HAVE_SYS_TIME_H
24#include <sys/time.h>
25#else
26#include <time.h>
27#endif
28#endif
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
32#include "epaths.h" /* For PATH_DATA. */
701570d7
RS
33
34#define BUFSIZE 80
bc851190 35#define SEP '\0'
701570d7
RS
36
37#ifndef YOW_FILE
bc851190 38#define YOW_FILE "yow.lines"
701570d7 39#endif
bc851190 40
35ebc5cf
RS
41#ifdef MSDOS
42#define rootrelativepath(rel) \
43({\
44 static char res[BUFSIZE], *p;\
45 strcpy (res, argv[0]);\
46 p = res + strlen (res);\
47 while (p != res && *p != '/' && *p != '\\' && *p != ':') p--;\
48 strcpy (p + 1, "../");\
49 strcpy (p + 4, rel);\
50 &res;})
51#endif
52
b3dcbddb
DM
53void yow();
54void setup_yow();
55
340ff9de 56int
bc851190
RS
57main (argc, argv)
58 int argc;
59 char *argv[];
60{
61 FILE *fp;
62 char file[BUFSIZ];
bc851190
RS
63
64 if (argc > 2 && !strcmp (argv[1], "-f"))
65 strcpy (file, argv[2]);
66 else
67#ifdef vms
4bcffd8e 68 sprintf (file, "%s%s", PATH_DATA, YOW_FILE);
bc851190 69#else
4bcffd8e 70 sprintf (file, "%s/%s", PATH_DATA, YOW_FILE);
bc851190
RS
71#endif
72
73 if ((fp = fopen(file, "r")) == NULL) {
b3dcbddb 74 fprintf(stderr, "yow: ");
bc851190 75 perror(file);
65396510 76 exit(EXIT_FAILURE);
bc851190
RS
77 }
78
79 /* initialize random seed */
5a13a7ec 80 srand((int) (getpid() + time((time_t *) 0)));
bc851190 81
701570d7 82 setup_yow(fp);
bc851190
RS
83 yow(fp);
84 fclose(fp);
65396510 85 return EXIT_SUCCESS;
bc851190
RS
86}
87
701570d7
RS
88static long len = -1;
89static long header_len;
90
91#define AVG_LEN 40 /* average length of a quotation */
92
93/* Sets len and header_len */
94void
95setup_yow(fp)
96 FILE *fp;
97{
98 int c;
99
100 /* Get length of file */
101 /* Because the header (stuff before the first SEP) can be very long,
102 * thus biasing our search in favor of the first quotation in the file,
103 * we explicitly skip that. */
104 while ((c = getc(fp)) != SEP) {
105 if (c == EOF) {
b3dcbddb 106 fprintf(stderr, "yow: file contains no separators\n");
701570d7
RS
107 exit(2);
108 }
109 }
110 header_len = ftell(fp);
111 if (header_len > AVG_LEN)
112 header_len -= AVG_LEN; /* allow the first quotation to appear */
177c0ea7 113
701570d7 114 if (fseek(fp, 0L, 2) == -1) {
b3dcbddb 115 perror("yow");
65396510 116 exit(EXIT_FAILURE);
701570d7
RS
117 }
118 len = ftell(fp) - header_len;
119}
120
121
122/* go to a random place in the file and print the quotation there */
bc851190
RS
123void
124yow (fp)
125 FILE *fp;
126{
bc851190
RS
127 long offset;
128 int c, i = 0;
701570d7
RS
129 char *buf;
130 unsigned int bufsize;
bc851190 131
701570d7 132 offset = rand() % len + header_len;
bc851190 133 if (fseek(fp, offset, 0) == -1) {
b3dcbddb 134 perror("yow");
65396510 135 exit(EXIT_FAILURE);
bc851190
RS
136 }
137
138 /* Read until SEP, read next line, print it.
eb8c3be9 139 (Note that we will never print anything before the first separator.)
bc851190
RS
140 If we hit EOF looking for the first SEP, just recurse. */
141 while ((c = getc(fp)) != SEP)
142 if (c == EOF) {
143 yow(fp);
144 return;
145 }
146
147 /* Skip leading whitespace, then read in a quotation.
148 If we hit EOF before we find a non-whitespace char, recurse. */
149 while (isspace(c = getc(fp)))
150 ;
151 if (c == EOF) {
152 yow(fp);
153 return;
154 }
701570d7
RS
155
156 bufsize = BUFSIZE;
9fc08e73 157 buf = (char *) malloc(bufsize);
701570d7 158 if (buf == (char *)0) {
b3dcbddb 159 fprintf(stderr, "yow: virtual memory exhausted\n");
701570d7
RS
160 exit (3);
161 }
162
bc851190
RS
163 buf[i++] = c;
164 while ((c = getc(fp)) != SEP && c != EOF) {
165 buf[i++] = c;
177c0ea7 166
701570d7 167 if (i == bufsize-1) {
bc851190 168 /* Yow! Is this quotation too long yet? */
701570d7 169 bufsize *= 2;
9fc08e73 170 buf = (char *) realloc(buf, bufsize);
701570d7 171 if (buf == (char *)0) {
b3dcbddb 172 fprintf(stderr, "yow: virtual memory exhausted\n");
701570d7
RS
173 exit (3);
174 }
175 }
bc851190
RS
176 }
177 buf[i++] = 0;
178 printf("%s\n", buf);
179}
180
ab5796a9
MB
181/* arch-tag: e40fc0df-bafb-4001-af24-5c883d1c685e
182 (do not change this comment) */
65396510
TTN
183
184/* yow.c ends here */