]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.topl.c
sprintf -> snprintf, plus some use of strlcpy/strlcat where appropriate
[bsdgames-darwin.git] / hack / hack.topl.c
1 /* $NetBSD: hack.topl.c,v 1.10 2009/06/07 20:13:18 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 /*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 #include <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.topl.c,v 1.10 2009/06/07 20:13:18 dholland Exp $");
67 #endif /* not lint */
68
69 #include <stdlib.h>
70 #include "hack.h"
71 #include "extern.h"
72
73 char toplines[BUFSZ];
74 xchar tlx, tly; /* set by pline; used by addtopl */
75
76 struct topl {
77 struct topl *next_topl;
78 char *topl_text;
79 } *old_toplines, *last_redone_topl;
80 #define OTLMAX 20 /* max nr of old toplines remembered */
81
82 int
83 doredotopl(void)
84 {
85 if (last_redone_topl)
86 last_redone_topl = last_redone_topl->next_topl;
87 if (!last_redone_topl)
88 last_redone_topl = old_toplines;
89 if (last_redone_topl) {
90 (void) strcpy(toplines, last_redone_topl->topl_text);
91 }
92 redotoplin();
93 return (0);
94 }
95
96 void
97 redotoplin(void)
98 {
99 home();
100 if (strchr(toplines, '\n'))
101 cl_end();
102 putstr(toplines);
103 cl_end();
104 tlx = curx;
105 tly = cury;
106 flags.toplin = 1;
107 if (tly > 1)
108 more();
109 }
110
111 void
112 remember_topl(void)
113 {
114 struct topl *tl;
115 int cnt = OTLMAX;
116 if (last_redone_topl &&
117 !strcmp(toplines, last_redone_topl->topl_text))
118 return;
119 if (old_toplines &&
120 !strcmp(toplines, old_toplines->topl_text))
121 return;
122 last_redone_topl = 0;
123 tl = (struct topl *)
124 alloc((unsigned) (strlen(toplines) + sizeof(struct topl) + 1));
125 tl->next_topl = old_toplines;
126 tl->topl_text = (char *) (tl + 1);
127 (void) strcpy(tl->topl_text, toplines);
128 old_toplines = tl;
129 while (cnt && tl) {
130 cnt--;
131 tl = tl->next_topl;
132 }
133 if (tl && tl->next_topl) {
134 free((char *) tl->next_topl);
135 tl->next_topl = 0;
136 }
137 }
138
139 void
140 addtopl(const char *s)
141 {
142 curs(tlx, tly);
143 if (tlx + (int)strlen(s) > CO)
144 putsym('\n');
145 putstr(s);
146 tlx = curx;
147 tly = cury;
148 flags.toplin = 1;
149 }
150
151 /* s = allowed chars besides space/return */
152 void
153 xmore(const char *s)
154 {
155 if (flags.toplin) {
156 curs(tlx, tly);
157 if (tlx + 8 > CO)
158 putsym('\n'), tly++;
159 }
160 if (flags.standout)
161 standoutbeg();
162 putstr("--More--");
163 if (flags.standout)
164 standoutend();
165
166 xwaitforspace(s);
167 if (flags.toplin && tly > 1) {
168 home();
169 cl_end();
170 docorner(1, tly - 1);
171 }
172 flags.toplin = 0;
173 }
174
175 void
176 more(void)
177 {
178 xmore("");
179 }
180
181 void
182 cmore(const char *s)
183 {
184 xmore(s);
185 }
186
187 void
188 clrlin(void)
189 {
190 if (flags.toplin) {
191 home();
192 cl_end();
193 if (tly > 1)
194 docorner(1, tly - 1);
195 remember_topl();
196 }
197 flags.toplin = 0;
198 }
199
200 void
201 pline(const char *fmt, ...)
202 {
203 va_list ap;
204
205 va_start(ap, fmt);
206 vpline(fmt, ap);
207 va_end(ap);
208 }
209
210 void
211 vpline(const char *line, va_list ap)
212 {
213 char pbuf[BUFSZ];
214 char *bp = pbuf, *tl;
215 int n, n0;
216
217 if (!line || !*line)
218 return;
219 if (!strchr(line, '%'))
220 (void) strlcpy(pbuf, line, sizeof(pbuf));
221 else
222 (void) vsnprintf(pbuf, sizeof(pbuf), line, ap);
223 if (flags.toplin == 1 && !strcmp(pbuf, toplines))
224 return;
225 nscr(); /* %% */
226
227 /* If there is room on the line, print message on same line */
228 /* But messages like "You die..." deserve their own line */
229 n0 = strlen(bp);
230 if (flags.toplin == 1 && tly == 1 &&
231 n0 + (int)strlen(toplines) + 3 < CO - 8 && /* leave room for
232 * --More-- */
233 strncmp(bp, "You ", 4)) {
234 (void) strcat(toplines, " ");
235 (void) strcat(toplines, bp);
236 tlx += 2;
237 addtopl(bp);
238 return;
239 }
240 if (flags.toplin == 1)
241 more();
242 remember_topl();
243 toplines[0] = 0;
244 while (n0) {
245 if (n0 >= CO) {
246 /* look for appropriate cut point */
247 n0 = 0;
248 for (n = 0; n < CO; n++)
249 if (bp[n] == ' ')
250 n0 = n;
251 if (!n0)
252 for (n = 0; n < CO - 1; n++)
253 if (!letter(bp[n]))
254 n0 = n;
255 if (!n0)
256 n0 = CO - 2;
257 }
258 (void) strncpy((tl = eos(toplines)), bp, n0);
259 tl[n0] = 0;
260 bp += n0;
261
262 /* remove trailing spaces, but leave one */
263 while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ')
264 tl[--n0] = 0;
265
266 n0 = strlen(bp);
267 if (n0 && tl[0])
268 (void) strcat(tl, "\n");
269 }
270 redotoplin();
271 }
272
273 void
274 putsym(int c1)
275 {
276 char c = c1; /* XXX this hack prevents .o diffs -- remove later */
277
278 switch (c) {
279 case '\b':
280 backsp();
281 return;
282 case '\n':
283 curx = 1;
284 cury++;
285 if (cury > tly)
286 tly = cury;
287 break;
288 default:
289 if (curx == CO)
290 putsym('\n'); /* 1 <= curx <= CO; avoid CO */
291 else
292 curx++;
293 }
294 (void) putchar(c);
295 }
296
297 void
298 putstr(const char *s)
299 {
300 while (*s)
301 putsym(*s++);
302 }