1 /*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)tscroll.c 8.4 (Berkeley) 07/27/94";
10 #endif /* not lint */
11
12 #include "curses.h"
13
14 #define MAXRETURNSIZE 64
15
16 /*
17 * Routine to perform scrolling. Derived from tgoto.c in tercamp(3)
18 * library. Cap is a string containing printf type escapes to allow
19 * scrolling. The following escapes are defined for substituting n:
20 *
21 * %d as in printf
22 * %2 like %2d
23 * %3 like %3d
24 * %. gives %c hacking special case characters
25 * %+x like %c but adding x first
26 *
27 * The codes below affect the state but don't use up a value.
28 *
29 * %>xy if value > x add y
30 * %i increments n
31 * %% gives %
32 * %B BCD (2 decimal digits encoded in one byte)
33 * %D Delta Data (backwards bcd)
34 *
35 * all other characters are ``self-inserting''.
36 */
37 char *
__tscroll(cap,n1,n2)38 __tscroll(cap, n1, n2)
39 const char *cap;
40 int n1, n2;
41 {
42 static char result[MAXRETURNSIZE];
43 int c, n;
44 char *dp;
45
46 if (cap == NULL)
47 goto err;
48 for (n = n1, dp = result; (c = *cap++) != '\0';) {
49 if (c != '%') {
50 *dp++ = c;
51 continue;
52 }
53 switch (c = *cap++) {
54 case 'n':
55 n ^= 0140;
56 continue;
57 case 'd':
58 if (n < 10)
59 goto one;
60 if (n < 100)
61 goto two;
62 /* FALLTHROUGH */
63 case '3':
64 *dp++ = (n / 100) | '0';
65 n %= 100;
66 /* FALLTHROUGH */
67 case '2':
68 two: *dp++ = n / 10 | '0';
69 one: *dp++ = n % 10 | '0';
70 n = n2;
71 continue;
72 case '>':
73 if (n > *cap++)
74 n += *cap++;
75 else
76 cap++;
77 continue;
78 case '+':
79 n += *cap++;
80 /* FALLTHROUGH */
81 case '.':
82 *dp++ = n;
83 continue;
84 case 'i':
85 n++;
86 continue;
87 case '%':
88 *dp++ = c;
89 continue;
90 case 'B':
91 n = (n / 10 << 4) + n % 10;
92 continue;
93 case 'D':
94 n = n - 2 * (n % 16);
95 continue;
96 /*
97 * XXX
98 * System V terminfo files have lots of extra gunk.
99 * The only one we've seen in scrolling strings is
100 * %pN, and it seems to work okay if we ignore it.
101 */
102 case 'p':
103 ++cap;
104 continue;
105 default:
106 goto err;
107 }
108 }
109 *dp = '\0';
110 return (result);
111
112 err: return("curses: __tscroll failed");
113 }
114