tscroll.c revision 1.11 1 /* $NetBSD: tscroll.c,v 1.11 2002/06/26 18:14:08 christos 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
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)tscroll.c 8.4 (Berkeley) 7/27/94";
41 #else
42 __RCSID("$NetBSD: tscroll.c,v 1.11 2002/06/26 18:14:08 christos Exp $");
43 #endif
44 #endif /* not lint */
45
46 #include <string.h>
47 #include <stdarg.h>
48 #include "curses.h"
49 #include "curses_private.h"
50
51 #define MAXRETURNSIZE 64
52
53 char *
54 __tscroll(const char *cap, int n1, int n2)
55 {
56 return (__parse_cap(cap, n1, n2));
57 }
58
59 /*
60 * Routines to parse capabilities. Derived from tgoto.c in termcap(3)
61 * library. Cap is a string containing printf type escapes to allow
62 * scrolling. The following escapes are defined for substituting n:
63 *
64 * %d as in printf
65 * %2 like %2d
66 * %3 like %3d
67 * %. gives %c hacking special case characters
68 * %+x like %c but adding x first
69 *
70 * The codes below affect the state but don't use up a value.
71 *
72 * %>xy if value > x add y
73 * %i increments n
74 * %% gives %
75 * %B BCD (2 decimal digits encoded in one byte)
76 * %D Delta Data (backwards bcd)
77 *
78 * all other characters are ``self-inserting''.
79 *
80 * XXX:
81 * %r reverse order of two parameters
82 * is also defined but we don't support it (yet).
83 */
84 char *
85 __parse_cap (char const *cap, ...)
86 {
87 va_list ap;
88 static char result[MAXRETURNSIZE];
89 int c, n;
90 char *dp;
91 int have_input;
92
93 va_start (ap, cap);
94 n = 0; /* XXX gcc -Wuninitialized */
95
96 if (cap == NULL)
97 goto err;
98 #ifdef DEBUG
99 {
100 int i;
101
102 __CTRACE("__parse_cap: cap = ");
103 for (i = 0; i < strlen(cap); i++)
104 __CTRACE("%s", unctrl(cap[i]));
105 __CTRACE("\n");
106 }
107 #endif
108 have_input = 0;
109 for (dp = result; (c = *cap++) != '\0';) {
110 if (c != '%') {
111 *dp++ = c;
112 continue;
113 }
114 switch (c = *cap++) {
115 case 'n':
116 if (!have_input) {
117 n = va_arg (ap, int);
118 have_input = 1;
119 #ifdef DEBUG
120 __CTRACE ("__parse_cap: %%n, val = %d\n", n);
121 #endif
122 }
123 n ^= 0140;
124 continue;
125 case 'd':
126 if (!have_input) {
127 n = va_arg (ap, int);
128 have_input = 1;
129 #ifdef DEBUG
130 __CTRACE ("__parse_cap: %%d, val = %d\n", n);
131 #endif
132 }
133 if (n < 10)
134 goto one;
135 if (n < 100)
136 goto two;
137 /* FALLTHROUGH */
138 case '3':
139 if (!have_input) {
140 n = va_arg (ap, int);
141 have_input = 1;
142 #ifdef DEBUG
143 __CTRACE ("__parse_cap: %%3, val = %d\n", n);
144 #endif
145 }
146 *dp++ = (n / 100) | '0';
147 n %= 100;
148 /* FALLTHROUGH */
149 case '2':
150 if (!have_input) {
151 n = va_arg (ap, int);
152 have_input = 1;
153 #ifdef DEBUG
154 __CTRACE ("__parse_cap: %%2, val = %d\n", n);
155 #endif
156 }
157 two: *dp++ = n / 10 | '0';
158 one: *dp++ = n % 10 | '0';
159 have_input = 0;
160 continue;
161 case '>':
162 if (!have_input) {
163 n = va_arg (ap, int);
164 have_input = 1;
165 #ifdef DEBUG
166 __CTRACE ("__parse_cap: %%>, val = %d\n", n);
167 #endif
168 }
169 if (n > *cap++)
170 n += *cap++;
171 else
172 cap++;
173 continue;
174 case '+':
175 if (!have_input) {
176 n = va_arg (ap, int);
177 have_input = 1;
178 #ifdef DEBUG
179 __CTRACE ("__parse_cap: %%+, val = %d\n", n);
180 #endif
181 }
182 n += *cap++;
183 /* FALLTHROUGH */
184 case '.':
185 if (!have_input) {
186 n = va_arg (ap, int);
187 have_input = 1;
188 #ifdef DEBUG
189 __CTRACE ("__parse_cap: %%., val = %d\n", n);
190 #endif
191 }
192 *dp++ = n;
193 have_input = 0;
194 continue;
195 case 'i':
196 if (!have_input) {
197 n = va_arg (ap, int);
198 have_input = 1;
199 #ifdef DEBUG
200 __CTRACE ("__parse_cap: %%i, val = %d\n", n);
201 #endif
202 }
203 n++;
204 continue;
205 case '%':
206 *dp++ = c;
207 continue;
208 case 'B':
209 if (!have_input) {
210 n = va_arg (ap, int);
211 have_input = 1;
212 #ifdef DEBUG
213 __CTRACE ("__parse_cap: %%B, val = %d\n", n);
214 #endif
215 }
216 n = (n / 10 << 4) + n % 10;
217 continue;
218 case 'D':
219 if (!have_input) {
220 n = va_arg (ap, int);
221 have_input = 1;
222 #ifdef DEBUG
223 __CTRACE ("__parse_cap: %%D, val = %d\n", n);
224 #endif
225 }
226 n = n - 2 * (n % 16);
227 continue;
228 /*
229 * XXX
230 * System V terminfo files have lots of extra gunk.
231 * The only other one we've seen in capability strings
232 * is %pN, and it seems to work okay if we ignore it.
233 */
234 case 'p':
235 ++cap;
236 continue;
237 default:
238 goto err;
239 }
240 }
241 *dp = '\0';
242 va_end (ap);
243 return (result);
244
245 err: va_end (ap);
246 return ((char *) "\0");
247 }
248