xref: /original-bsd/lib/libcurses/tscroll.c (revision 3b3772fe)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 #ifndef lint
10 static char copyright[] =
11 "@(#) Copyright (c) 1992 The Regents of the University of California.\n\
12  All rights reserved.\n";
13 #endif /* not lint */
14 
15 #ifndef lint
16 static char sccsid[] = "@(#)tscroll.c	5.1 (Berkeley) 10/01/92";
17 #endif /* not lint */
18 
19 #include <stdio.h>
20 
21 #define MAXRETURNSIZE 64
22 
23 /*
24  * Routine to perform scrolling.  Derived from tgoto.c in tercamp(3) library.
25  * Cap is a string containing printf type escapes to allow
26  * scrolling.
27  * The following escapes are defined for substituting n:
28  *
29  *	%d	as in printf
30  *	%2	like %2d
31  *	%3	like %3d
32  *	%.	gives %c hacking special case characters
33  *	%+x	like %c but adding x first
34  *
35  *	The codes below affect the state but don't use up a value.
36  *
37  *	%>xy	if value > x add y
38  *	%i	increments n
39  *	%%	gives %
40  *	%B	BCD (2 decimal digits encoded in one byte)
41  *	%D	Delta Data (backwards bcd)
42  *
43  * all other characters are ``self-inserting''.
44  */
45 char *
46 tscroll(cap, n)
47 	const char *cap;
48 	int n;
49 {
50 	static char result[MAXRETURNSIZE];
51 	register char *dp;
52 	register int c;
53 	char *cp;
54 
55 	if (cap == NULL) {
56 toohard:
57 		/*
58 		 * ``We don't do that under BOZO's big top''
59 		 */
60 		return ("OOPS");
61 	}
62 
63 	cp = (char *) cap;
64 	dp = result;
65 	while (c = *cp++) {
66 		if (c != '%') {
67 			*dp++ = c;
68 			continue;
69 		}
70 		switch (c = *cp++) {
71 		case 'n':
72 			n ^= 0140;
73 			continue;
74 		case 'd':
75 			if (n < 10)
76 				goto one;
77 			if (n < 100)
78 				goto two;
79 			/* fall into... */
80 		case '3':
81 			*dp++ = (n / 100) | '0';
82 			n %= 100;
83 			/* fall into... */
84 		case '2':
85 two:
86 			*dp++ = n / 10 | '0';
87 one:
88 			*dp++ = n % 10 | '0';
89 			continue;
90 		case '>':
91 			if (n > *cp++)
92 				n += *cp++;
93 			else
94 				cp++;
95 			continue;
96 		case '+':
97 			n += *cp++;
98 			/* fall into... */
99 		case '.':
100 			*dp++ = n;
101 			continue;
102 		case 'i':
103 			n++;
104 			continue;
105 		case '%':
106 			*dp++ = c;
107 			continue;
108 
109 		case 'B':
110 			n = (n / 10 << 4) + n % 10;
111 			continue;
112 		case 'D':
113 			n = n - 2 * (n % 16);
114 			continue;
115 		default:
116 			goto toohard;
117 		}
118 	}
119 	*dp = '\0';
120 	return (result);
121 }
122