tscroll.c revision 1.9 1 /* $NetBSD: tscroll.c,v 1.9 2000/04/27 00:27:56 jdc Exp $ */
2
3 /*-
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #include <stdarg.h>
38
39 #ifndef lint
40 #if 0
41 static char sccsid[] = "@(#)tscroll.c 8.4 (Berkeley) 7/27/94";
42 #else
43 __RCSID("$NetBSD: tscroll.c,v 1.9 2000/04/27 00:27:56 jdc Exp $");
44 #endif
45 #endif /* not lint */
46
47 #include "curses.h"
48 #include "curses_private.h"
49
50 #define MAXRETURNSIZE 64
51
52 char *
53 __tscroll(const char *cap, int n1, int n2)
54 {
55 return (__parse_cap(cap, n1, n2));
56 }
57
58 /*
59 * Routines to parse capabilities. Derived from tgoto.c in termcap(3)
60 * library. Cap is a string containing printf type escapes to allow
61 * scrolling. The following escapes are defined for substituting n:
62 *
63 * %d as in printf
64 * %2 like %2d
65 * %3 like %3d
66 * %. gives %c hacking special case characters
67 * %+x like %c but adding x first
68 *
69 * The codes below affect the state but don't use up a value.
70 *
71 * %>xy if value > x add y
72 * %i increments n
73 * %% gives %
74 * %B BCD (2 decimal digits encoded in one byte)
75 * %D Delta Data (backwards bcd)
76 *
77 * all other characters are ``self-inserting''.
78 *
79 * XXX:
80 * %r reverse order of two parameters
81 * is also defined but we don't support it (yet).
82 */
83 char *
84 #if __STDC__
85 __parse_cap (char const *cap, ...)
86 #else
87 __parse_cap (cap, va_alist)
88 const char *cap;
89 va_dcl
90 #endif
91 {
92 va_list ap;
93 static char result[MAXRETURNSIZE];
94 int c, n;
95 char *dp;
96 int have_input;
97
98 #if __STDC__
99 va_start (ap, cap);
100 #else
101 va_start(ap);
102 #endif
103 n = 0; /* XXX gcc -Wuninitialized */
104
105 if (cap == NULL)
106 goto err;
107 #ifdef DEBUG
108 {
109 int i;
110
111 __CTRACE("__parse_cap: cap = ");
112 for (i = 0; i < strlen(cap); i++)
113 __CTRACE("%s", unctrl(cap[i]));
114 __CTRACE("\n");
115 }
116 #endif
117 have_input = 0;
118 for (dp = result; (c = *cap++) != '\0';) {
119 if (c != '%') {
120 *dp++ = c;
121 continue;
122 }
123 switch (c = *cap++) {
124 case 'n':
125 if (!have_input) {
126 n = va_arg (ap, int);
127 have_input = 1;
128 #ifdef DEBUG
129 __CTRACE ("__parse_cap: %%n, val = %d\n", n);
130 #endif
131 }
132 n ^= 0140;
133 continue;
134 case 'd':
135 if (!have_input) {
136 n = va_arg (ap, int);
137 have_input = 1;
138 #ifdef DEBUG
139 __CTRACE ("__parse_cap: %%d, val = %d\n", n);
140 #endif
141 }
142 if (n < 10)
143 goto one;
144 if (n < 100)
145 goto two;
146 /* FALLTHROUGH */
147 case '3':
148 if (!have_input) {
149 n = va_arg (ap, int);
150 have_input = 1;
151 #ifdef DEBUG
152 __CTRACE ("__parse_cap: %%3, val = %d\n", n);
153 #endif
154 }
155 *dp++ = (n / 100) | '0';
156 n %= 100;
157 /* FALLTHROUGH */
158 case '2':
159 if (!have_input) {
160 n = va_arg (ap, int);
161 have_input = 1;
162 #ifdef DEBUG
163 __CTRACE ("__parse_cap: %%2, val = %d\n", n);
164 #endif
165 }
166 two: *dp++ = n / 10 | '0';
167 one: *dp++ = n % 10 | '0';
168 have_input = 0;
169 continue;
170 case '>':
171 if (!have_input) {
172 n = va_arg (ap, int);
173 have_input = 1;
174 #ifdef DEBUG
175 __CTRACE ("__parse_cap: %%>, val = %d\n", n);
176 #endif
177 }
178 if (n > *cap++)
179 n += *cap++;
180 else
181 cap++;
182 continue;
183 case '+':
184 if (!have_input) {
185 n = va_arg (ap, int);
186 have_input = 1;
187 #ifdef DEBUG
188 __CTRACE ("__parse_cap: %%+, val = %d\n", n);
189 #endif
190 }
191 n += *cap++;
192 /* FALLTHROUGH */
193 case '.':
194 if (!have_input) {
195 n = va_arg (ap, int);
196 have_input = 1;
197 #ifdef DEBUG
198 __CTRACE ("__parse_cap: %%., val = %d\n", n);
199 #endif
200 }
201 *dp++ = n;
202 have_input = 0;
203 continue;
204 case 'i':
205 if (!have_input) {
206 n = va_arg (ap, int);
207 have_input = 1;
208 #ifdef DEBUG
209 __CTRACE ("__parse_cap: %%i, val = %d\n", n);
210 #endif
211 }
212 n++;
213 continue;
214 case '%':
215 *dp++ = c;
216 continue;
217 case 'B':
218 if (!have_input) {
219 n = va_arg (ap, int);
220 have_input = 1;
221 #ifdef DEBUG
222 __CTRACE ("__parse_cap: %%B, val = %d\n", n);
223 #endif
224 }
225 n = (n / 10 << 4) + n % 10;
226 continue;
227 case 'D':
228 if (!have_input) {
229 n = va_arg (ap, int);
230 have_input = 1;
231 #ifdef DEBUG
232 __CTRACE ("__parse_cap: %%D, val = %d\n", n);
233 #endif
234 }
235 n = n - 2 * (n % 16);
236 continue;
237 /*
238 * XXX
239 * System V terminfo files have lots of extra gunk.
240 * The only other one we've seen in capability strings
241 * is %pN, and it seems to work okay if we ignore it.
242 */
243 case 'p':
244 ++cap;
245 continue;
246 default:
247 goto err;
248 }
249 }
250 *dp = '\0';
251 va_end (ap);
252 return (result);
253
254 err: va_end (ap);
255 return ((char *) "\0");
256 }
257