(write_c_args): Put `default' in upper case.
[bpt/emacs.git] / lib-src / yow.c
CommitLineData
701570d7
RS
1/*
2 * yow.c
bc851190
RS
3 *
4 * Print a quotation from Zippy the Pinhead.
5 * Qux <Kaufman-David@Yale> March 6, 1986
6 *
701570d7 7 * With dynamic memory allocation.
bc851190
RS
8 */
9
701570d7
RS
10#include <stdio.h>
11#include <ctype.h>
21af68b6 12#include <../src/paths.h> /* For PATH_DATA. */
701570d7
RS
13
14#define BUFSIZE 80
bc851190 15#define SEP '\0'
701570d7
RS
16
17#ifndef YOW_FILE
bc851190 18#define YOW_FILE "yow.lines"
701570d7 19#endif
bc851190
RS
20
21main (argc, argv)
22 int argc;
23 char *argv[];
24{
25 FILE *fp;
26 char file[BUFSIZ];
701570d7 27 void yow(), setup_yow();
bc851190
RS
28
29 if (argc > 2 && !strcmp (argv[1], "-f"))
30 strcpy (file, argv[2]);
31 else
32#ifdef vms
4bcffd8e 33 sprintf (file, "%s%s", PATH_DATA, YOW_FILE);
bc851190 34#else
4bcffd8e 35 sprintf (file, "%s/%s", PATH_DATA, YOW_FILE);
bc851190
RS
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
701570d7 46 setup_yow(fp);
bc851190
RS
47 yow(fp);
48 fclose(fp);
49 exit(0);
50}
51
701570d7
RS
52static long len = -1;
53static long header_len;
54
55#define AVG_LEN 40 /* average length of a quotation */
56
57/* Sets len and header_len */
58void
59setup_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 */
bc851190
RS
87void
88yow (fp)
89 FILE *fp;
90{
bc851190
RS
91 long offset;
92 int c, i = 0;
701570d7
RS
93 char *buf;
94 unsigned int bufsize;
95 char *malloc(), *realloc();
bc851190 96
701570d7 97 offset = rand() % len + header_len;
bc851190
RS
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.
eb8c3be9 104 (Note that we will never print anything before the first separator.)
bc851190
RS
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 }
701570d7
RS
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
bc851190
RS
128 buf[i++] = c;
129 while ((c = getc(fp)) != SEP && c != EOF) {
130 buf[i++] = c;
701570d7
RS
131
132 if (i == bufsize-1) {
bc851190 133 /* Yow! Is this quotation too long yet? */
701570d7
RS
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 }
bc851190
RS
141 }
142 buf[i++] = 0;
143 printf("%s\n", buf);
144}
145