1fdd4e1e0SJan Lentfer /****************************************************************************
2*32bb5217SDaniel Fojt  * Copyright 2018-2019,2020 Thomas E. Dickey                                *
3*32bb5217SDaniel Fojt  * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
4fdd4e1e0SJan Lentfer  *                                                                          *
5fdd4e1e0SJan Lentfer  * Permission is hereby granted, free of charge, to any person obtaining a  *
6fdd4e1e0SJan Lentfer  * copy of this software and associated documentation files (the            *
7fdd4e1e0SJan Lentfer  * "Software"), to deal in the Software without restriction, including      *
8fdd4e1e0SJan Lentfer  * without limitation the rights to use, copy, modify, merge, publish,      *
9fdd4e1e0SJan Lentfer  * distribute, distribute with modifications, sublicense, and/or sell       *
10fdd4e1e0SJan Lentfer  * copies of the Software, and to permit persons to whom the Software is    *
11fdd4e1e0SJan Lentfer  * furnished to do so, subject to the following conditions:                 *
12fdd4e1e0SJan Lentfer  *                                                                          *
13fdd4e1e0SJan Lentfer  * The above copyright notice and this permission notice shall be included  *
14fdd4e1e0SJan Lentfer  * in all copies or substantial portions of the Software.                   *
15fdd4e1e0SJan Lentfer  *                                                                          *
16fdd4e1e0SJan Lentfer  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17fdd4e1e0SJan Lentfer  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18fdd4e1e0SJan Lentfer  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19fdd4e1e0SJan Lentfer  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20fdd4e1e0SJan Lentfer  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21fdd4e1e0SJan Lentfer  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22fdd4e1e0SJan Lentfer  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23fdd4e1e0SJan Lentfer  *                                                                          *
24fdd4e1e0SJan Lentfer  * Except as contained in this notice, the name(s) of the above copyright   *
25fdd4e1e0SJan Lentfer  * holders shall not be used in advertising or otherwise to promote the     *
26fdd4e1e0SJan Lentfer  * sale, use or other dealings in this Software without prior written       *
27fdd4e1e0SJan Lentfer  * authorization.                                                           *
28fdd4e1e0SJan Lentfer  ****************************************************************************/
29fdd4e1e0SJan Lentfer 
30fdd4e1e0SJan Lentfer /****************************************************************************
31fdd4e1e0SJan Lentfer  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
32fdd4e1e0SJan Lentfer  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
331d102085SJan Lentfer  *     and: Thomas E. Dickey                        1996-on                 *
34fdd4e1e0SJan Lentfer  ****************************************************************************/
35fdd4e1e0SJan Lentfer 
36fdd4e1e0SJan Lentfer /*
37*32bb5217SDaniel Fojt  *	captoinfo.c
38*32bb5217SDaniel Fojt  *
39*32bb5217SDaniel Fojt  *	Provide conversion in both directions between termcap and terminfo.
40*32bb5217SDaniel Fojt  *
41*32bb5217SDaniel Fojt  * cap-to-info --- conversion between termcap and terminfo formats
42fdd4e1e0SJan Lentfer  *
43fdd4e1e0SJan Lentfer  *	The captoinfo() code was swiped from Ross Ridge's mytinfo package,
44fdd4e1e0SJan Lentfer  *	adapted to fit ncurses by Eric S. Raymond <esr@snark.thyrsus.com>.
45fdd4e1e0SJan Lentfer  *
46*32bb5217SDaniel Fojt  *	It has just one entry point:
47fdd4e1e0SJan Lentfer  *
48fdd4e1e0SJan Lentfer  *	char *_nc_captoinfo(n, s, parameterized)
49fdd4e1e0SJan Lentfer  *
50fdd4e1e0SJan Lentfer  *	Convert value s for termcap string capability named n into terminfo
51fdd4e1e0SJan Lentfer  *	format.
52fdd4e1e0SJan Lentfer  *
53fdd4e1e0SJan Lentfer  *	This code recognizes all the standard 4.4BSD %-escapes:
54fdd4e1e0SJan Lentfer  *
55fdd4e1e0SJan Lentfer  *	%%       output `%'
56fdd4e1e0SJan Lentfer  *	%d       output value as in printf %d
57fdd4e1e0SJan Lentfer  *	%2       output value as in printf %2d
58fdd4e1e0SJan Lentfer  *	%3       output value as in printf %3d
59fdd4e1e0SJan Lentfer  *	%.       output value as in printf %c
60fdd4e1e0SJan Lentfer  *	%+x      add x to value, then do %.
61fdd4e1e0SJan Lentfer  *	%>xy     if value > x then add y, no output
62fdd4e1e0SJan Lentfer  *	%r       reverse order of two parameters, no output
63fdd4e1e0SJan Lentfer  *	%i       increment by one, no output
64fdd4e1e0SJan Lentfer  *	%n       exclusive-or all parameters with 0140 (Datamedia 2500)
65fdd4e1e0SJan Lentfer  *	%B       BCD (16*(value/10)) + (value%10), no output
66fdd4e1e0SJan Lentfer  *	%D       Reverse coding (value - 2*(value%16)), no output (Delta Data).
67fdd4e1e0SJan Lentfer  *
68fdd4e1e0SJan Lentfer  *	Also, %02 and %03 are accepted as synonyms for %2 and %3.
69fdd4e1e0SJan Lentfer  *
70fdd4e1e0SJan Lentfer  *	Besides all the standard termcap escapes, this translator understands
71fdd4e1e0SJan Lentfer  *	the following extended escapes:
72fdd4e1e0SJan Lentfer  *
73fdd4e1e0SJan Lentfer  *	used by GNU Emacs termcap libraries
74fdd4e1e0SJan Lentfer  *		%a[+*-/=][cp]x	GNU arithmetic.
75fdd4e1e0SJan Lentfer  *		%m		xor the first two parameters by 0177
76fdd4e1e0SJan Lentfer  *		%b		backup to previous parameter
77fdd4e1e0SJan Lentfer  *		%f		skip this parameter
78fdd4e1e0SJan Lentfer  *
79fdd4e1e0SJan Lentfer  *	used by the University of Waterloo (MFCF) termcap libraries
80fdd4e1e0SJan Lentfer  *		%-x	 subtract parameter FROM char x and output it as a char
81fdd4e1e0SJan Lentfer  *		%ax	 add the character x to parameter
82fdd4e1e0SJan Lentfer  *
83fdd4e1e0SJan Lentfer  *	If #define WATERLOO is on, also enable these translations:
84fdd4e1e0SJan Lentfer  *
85fdd4e1e0SJan Lentfer  *		%sx	 subtract parameter FROM the character x
86fdd4e1e0SJan Lentfer  *
87fdd4e1e0SJan Lentfer  *	By default, this Waterloo translations are not compiled in, because
88fdd4e1e0SJan Lentfer  *	the Waterloo %s conflicts with the way terminfo uses %s in strings for
89fdd4e1e0SJan Lentfer  *	function programming.
90fdd4e1e0SJan Lentfer  *
91fdd4e1e0SJan Lentfer  *	Note the two definitions of %a: the GNU definition is translated if the
92fdd4e1e0SJan Lentfer  *	characters after the 'a' are valid for it, otherwise the UW definition
93fdd4e1e0SJan Lentfer  *	is translated.
94fdd4e1e0SJan Lentfer  */
95fdd4e1e0SJan Lentfer 
96fdd4e1e0SJan Lentfer #include <curses.priv.h>
97fdd4e1e0SJan Lentfer 
98fdd4e1e0SJan Lentfer #include <ctype.h>
99fdd4e1e0SJan Lentfer #include <tic.h>
100fdd4e1e0SJan Lentfer 
101*32bb5217SDaniel Fojt MODULE_ID("$Id: captoinfo.c,v 1.98 2020/02/02 23:34:34 tom Exp $")
102*32bb5217SDaniel Fojt 
103*32bb5217SDaniel Fojt #if 0
104*32bb5217SDaniel Fojt #define DEBUG_THIS(p) DEBUG(9, p)
105*32bb5217SDaniel Fojt #else
106*32bb5217SDaniel Fojt #define DEBUG_THIS(p)		/* nothing */
107*32bb5217SDaniel Fojt #endif
108fdd4e1e0SJan Lentfer 
109fdd4e1e0SJan Lentfer #define MAX_PUSHED	16	/* max # args we can push onto the stack */
110fdd4e1e0SJan Lentfer 
111fdd4e1e0SJan Lentfer static int stack[MAX_PUSHED];	/* the stack */
112fdd4e1e0SJan Lentfer static int stackptr;		/* the next empty place on the stack */
113fdd4e1e0SJan Lentfer static int onstack;		/* the top of stack */
114fdd4e1e0SJan Lentfer static int seenm;		/* seen a %m */
115fdd4e1e0SJan Lentfer static int seenn;		/* seen a %n */
116fdd4e1e0SJan Lentfer static int seenr;		/* seen a %r */
117fdd4e1e0SJan Lentfer static int param;		/* current parameter */
118fdd4e1e0SJan Lentfer static char *dp;		/* pointer to end of the converted string */
119fdd4e1e0SJan Lentfer 
120fdd4e1e0SJan Lentfer static char *my_string;
121fdd4e1e0SJan Lentfer static size_t my_length;
122fdd4e1e0SJan Lentfer 
123fdd4e1e0SJan Lentfer static char *
init_string(void)124fdd4e1e0SJan Lentfer init_string(void)
125fdd4e1e0SJan Lentfer /* initialize 'my_string', 'my_length' */
126fdd4e1e0SJan Lentfer {
127fdd4e1e0SJan Lentfer     if (my_string == 0)
1283468e90cSJohn Marino 	TYPE_MALLOC(char, my_length = 256, my_string);
129fdd4e1e0SJan Lentfer 
130fdd4e1e0SJan Lentfer     *my_string = '\0';
131fdd4e1e0SJan Lentfer     return my_string;
132fdd4e1e0SJan Lentfer }
133fdd4e1e0SJan Lentfer 
134fdd4e1e0SJan Lentfer static char *
save_string(char * d,const char * const s)135fdd4e1e0SJan Lentfer save_string(char *d, const char *const s)
136fdd4e1e0SJan Lentfer {
13700d8f3c4SJohn Marino     size_t have = (size_t) (d - my_string);
138fdd4e1e0SJan Lentfer     size_t need = have + strlen(s) + 2;
139fdd4e1e0SJan Lentfer     if (need > my_length) {
14000d8f3c4SJohn Marino 	my_string = (char *) _nc_doalloc(my_string, my_length = (need + need));
141fdd4e1e0SJan Lentfer 	if (my_string == 0)
142fdd4e1e0SJan Lentfer 	    _nc_err_abort(MSG_NO_MEMORY);
143fdd4e1e0SJan Lentfer 	d = my_string + have;
144fdd4e1e0SJan Lentfer     }
1453468e90cSJohn Marino     _nc_STRCPY(d, s, my_length - have);
146fdd4e1e0SJan Lentfer     return d + strlen(d);
147fdd4e1e0SJan Lentfer }
148fdd4e1e0SJan Lentfer 
1491d102085SJan Lentfer static NCURSES_INLINE char *
save_char(char * s,int c)150fdd4e1e0SJan Lentfer save_char(char *s, int c)
151fdd4e1e0SJan Lentfer {
152fdd4e1e0SJan Lentfer     static char temp[2];
153fdd4e1e0SJan Lentfer     temp[0] = (char) c;
154fdd4e1e0SJan Lentfer     return save_string(s, temp);
155fdd4e1e0SJan Lentfer }
156fdd4e1e0SJan Lentfer 
157fdd4e1e0SJan Lentfer static void
push(void)158fdd4e1e0SJan Lentfer push(void)
159fdd4e1e0SJan Lentfer /* push onstack on to the stack */
160fdd4e1e0SJan Lentfer {
1611d102085SJan Lentfer     if (stackptr >= MAX_PUSHED)
162fdd4e1e0SJan Lentfer 	_nc_warning("string too complex to convert");
163fdd4e1e0SJan Lentfer     else
164fdd4e1e0SJan Lentfer 	stack[stackptr++] = onstack;
165fdd4e1e0SJan Lentfer }
166fdd4e1e0SJan Lentfer 
167fdd4e1e0SJan Lentfer static void
pop(void)168fdd4e1e0SJan Lentfer pop(void)
169fdd4e1e0SJan Lentfer /* pop the top of the stack into onstack */
170fdd4e1e0SJan Lentfer {
171fdd4e1e0SJan Lentfer     if (stackptr == 0) {
172fdd4e1e0SJan Lentfer 	if (onstack == 0)
173fdd4e1e0SJan Lentfer 	    _nc_warning("I'm confused");
174fdd4e1e0SJan Lentfer 	else
175fdd4e1e0SJan Lentfer 	    onstack = 0;
176fdd4e1e0SJan Lentfer     } else
177fdd4e1e0SJan Lentfer 	onstack = stack[--stackptr];
178fdd4e1e0SJan Lentfer     param++;
179fdd4e1e0SJan Lentfer }
180fdd4e1e0SJan Lentfer 
181fdd4e1e0SJan Lentfer static int
cvtchar(register const char * sp)182fdd4e1e0SJan Lentfer cvtchar(register const char *sp)
183fdd4e1e0SJan Lentfer /* convert a character to a terminfo push */
184fdd4e1e0SJan Lentfer {
185fdd4e1e0SJan Lentfer     unsigned char c = 0;
186fdd4e1e0SJan Lentfer     int len;
187fdd4e1e0SJan Lentfer 
188fdd4e1e0SJan Lentfer     switch (*sp) {
189fdd4e1e0SJan Lentfer     case '\\':
190fdd4e1e0SJan Lentfer 	switch (*++sp) {
191fdd4e1e0SJan Lentfer 	case '\'':
192fdd4e1e0SJan Lentfer 	case '$':
193fdd4e1e0SJan Lentfer 	case '\\':
194fdd4e1e0SJan Lentfer 	case '%':
195*32bb5217SDaniel Fojt 	    c = UChar(*sp);
196fdd4e1e0SJan Lentfer 	    len = 2;
197fdd4e1e0SJan Lentfer 	    break;
198fdd4e1e0SJan Lentfer 	case '\0':
199fdd4e1e0SJan Lentfer 	    c = '\\';
200fdd4e1e0SJan Lentfer 	    len = 1;
201fdd4e1e0SJan Lentfer 	    break;
202fdd4e1e0SJan Lentfer 	case '0':
203fdd4e1e0SJan Lentfer 	case '1':
204fdd4e1e0SJan Lentfer 	case '2':
205fdd4e1e0SJan Lentfer 	case '3':
206fdd4e1e0SJan Lentfer 	    len = 1;
207fdd4e1e0SJan Lentfer 	    while (isdigit(UChar(*sp))) {
208*32bb5217SDaniel Fojt 		c = UChar(8 * c + (*sp++ - '0'));
209fdd4e1e0SJan Lentfer 		len++;
210fdd4e1e0SJan Lentfer 	    }
211fdd4e1e0SJan Lentfer 	    break;
212fdd4e1e0SJan Lentfer 	default:
213*32bb5217SDaniel Fojt 	    c = UChar(*sp);
214*32bb5217SDaniel Fojt 	    len = (c != '\0') ? 2 : 1;
215fdd4e1e0SJan Lentfer 	    break;
216fdd4e1e0SJan Lentfer 	}
217fdd4e1e0SJan Lentfer 	break;
218fdd4e1e0SJan Lentfer     case '^':
219*32bb5217SDaniel Fojt 	c = UChar(*++sp);
220*32bb5217SDaniel Fojt 	if (c == '?')
221*32bb5217SDaniel Fojt 	    c = 127;
222*32bb5217SDaniel Fojt 	else
223*32bb5217SDaniel Fojt 	    c &= 0x1f;
224fdd4e1e0SJan Lentfer 	len = 2;
225fdd4e1e0SJan Lentfer 	break;
226fdd4e1e0SJan Lentfer     default:
227*32bb5217SDaniel Fojt 	c = UChar(*sp);
228*32bb5217SDaniel Fojt 	len = (c != '\0') ? 1 : 0;
229fdd4e1e0SJan Lentfer     }
230fdd4e1e0SJan Lentfer     if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
231fdd4e1e0SJan Lentfer 	dp = save_string(dp, "%\'");
232fdd4e1e0SJan Lentfer 	dp = save_char(dp, c);
233fdd4e1e0SJan Lentfer 	dp = save_char(dp, '\'');
234*32bb5217SDaniel Fojt     } else if (c != '\0') {
235fdd4e1e0SJan Lentfer 	dp = save_string(dp, "%{");
236fdd4e1e0SJan Lentfer 	if (c > 99)
237fdd4e1e0SJan Lentfer 	    dp = save_char(dp, c / 100 + '0');
238fdd4e1e0SJan Lentfer 	if (c > 9)
239fdd4e1e0SJan Lentfer 	    dp = save_char(dp, ((int) (c / 10)) % 10 + '0');
240fdd4e1e0SJan Lentfer 	dp = save_char(dp, c % 10 + '0');
241fdd4e1e0SJan Lentfer 	dp = save_char(dp, '}');
242fdd4e1e0SJan Lentfer     }
243fdd4e1e0SJan Lentfer     return len;
244fdd4e1e0SJan Lentfer }
245fdd4e1e0SJan Lentfer 
246fdd4e1e0SJan Lentfer static void
getparm(int parm,int n)247fdd4e1e0SJan Lentfer getparm(int parm, int n)
248fdd4e1e0SJan Lentfer /* push n copies of param on the terminfo stack if not already there */
249fdd4e1e0SJan Lentfer {
250*32bb5217SDaniel Fojt     int nn;
251*32bb5217SDaniel Fojt 
252fdd4e1e0SJan Lentfer     if (seenr) {
253fdd4e1e0SJan Lentfer 	if (parm == 1)
254fdd4e1e0SJan Lentfer 	    parm = 2;
255fdd4e1e0SJan Lentfer 	else if (parm == 2)
256fdd4e1e0SJan Lentfer 	    parm = 1;
257fdd4e1e0SJan Lentfer     }
2583468e90cSJohn Marino 
259*32bb5217SDaniel Fojt     for (nn = 0; nn < n; ++nn) {
2603468e90cSJohn Marino 	dp = save_string(dp, "%p");
2613468e90cSJohn Marino 	dp = save_char(dp, '0' + parm);
2623468e90cSJohn Marino     }
2633468e90cSJohn Marino 
264fdd4e1e0SJan Lentfer     if (onstack == parm) {
265fdd4e1e0SJan Lentfer 	if (n > 1) {
266fdd4e1e0SJan Lentfer 	    _nc_warning("string may not be optimal");
267fdd4e1e0SJan Lentfer 	    dp = save_string(dp, "%Pa");
268*32bb5217SDaniel Fojt 	    while (n-- > 0) {
269fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%ga");
270fdd4e1e0SJan Lentfer 	    }
271fdd4e1e0SJan Lentfer 	}
272fdd4e1e0SJan Lentfer 	return;
273fdd4e1e0SJan Lentfer     }
274fdd4e1e0SJan Lentfer     if (onstack != 0)
275fdd4e1e0SJan Lentfer 	push();
276fdd4e1e0SJan Lentfer 
277fdd4e1e0SJan Lentfer     onstack = parm;
278fdd4e1e0SJan Lentfer 
279fdd4e1e0SJan Lentfer     if (seenn && parm < 3) {
280fdd4e1e0SJan Lentfer 	dp = save_string(dp, "%{96}%^");
281fdd4e1e0SJan Lentfer     }
282fdd4e1e0SJan Lentfer 
283fdd4e1e0SJan Lentfer     if (seenm && parm < 3) {
284fdd4e1e0SJan Lentfer 	dp = save_string(dp, "%{127}%^");
285fdd4e1e0SJan Lentfer     }
286fdd4e1e0SJan Lentfer }
287fdd4e1e0SJan Lentfer 
288fdd4e1e0SJan Lentfer /*
289fdd4e1e0SJan Lentfer  * Convert a termcap string to terminfo format.
290fdd4e1e0SJan Lentfer  * 'cap' is the relevant terminfo capability index.
291fdd4e1e0SJan Lentfer  * 's' is the string value of the capability.
292fdd4e1e0SJan Lentfer  * 'parameterized' tells what type of translations to do:
293fdd4e1e0SJan Lentfer  *	% translations if 1
294fdd4e1e0SJan Lentfer  *	pad translations if >=0
295fdd4e1e0SJan Lentfer  */
2961d102085SJan Lentfer NCURSES_EXPORT(char *)
_nc_captoinfo(const char * cap,const char * s,int const parameterized)297fdd4e1e0SJan Lentfer _nc_captoinfo(const char *cap, const char *s, int const parameterized)
298fdd4e1e0SJan Lentfer {
299fdd4e1e0SJan Lentfer     const char *capstart;
300fdd4e1e0SJan Lentfer 
301fdd4e1e0SJan Lentfer     stackptr = 0;
302fdd4e1e0SJan Lentfer     onstack = 0;
303fdd4e1e0SJan Lentfer     seenm = 0;
304fdd4e1e0SJan Lentfer     seenn = 0;
305fdd4e1e0SJan Lentfer     seenr = 0;
306fdd4e1e0SJan Lentfer     param = 1;
307fdd4e1e0SJan Lentfer 
308*32bb5217SDaniel Fojt     DEBUG_THIS(("_nc_captoinfo params %d, %s", parameterized, s));
309*32bb5217SDaniel Fojt 
310fdd4e1e0SJan Lentfer     dp = init_string();
311fdd4e1e0SJan Lentfer 
312fdd4e1e0SJan Lentfer     /* skip the initial padding (if we haven't been told not to) */
313fdd4e1e0SJan Lentfer     capstart = 0;
314fdd4e1e0SJan Lentfer     if (s == 0)
315fdd4e1e0SJan Lentfer 	s = "";
316fdd4e1e0SJan Lentfer     if (parameterized >= 0 && isdigit(UChar(*s)))
317*32bb5217SDaniel Fojt 	for (capstart = s; *s != '\0'; s++)
318fdd4e1e0SJan Lentfer 	    if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.'))
319fdd4e1e0SJan Lentfer 		break;
320fdd4e1e0SJan Lentfer 
321fdd4e1e0SJan Lentfer     while (*s != '\0') {
322fdd4e1e0SJan Lentfer 	switch (*s) {
323fdd4e1e0SJan Lentfer 	case '%':
324fdd4e1e0SJan Lentfer 	    s++;
325fdd4e1e0SJan Lentfer 	    if (parameterized < 1) {
326fdd4e1e0SJan Lentfer 		dp = save_char(dp, '%');
327fdd4e1e0SJan Lentfer 		break;
328fdd4e1e0SJan Lentfer 	    }
329fdd4e1e0SJan Lentfer 	    switch (*s++) {
330fdd4e1e0SJan Lentfer 	    case '%':
331*32bb5217SDaniel Fojt 		dp = save_string(dp, "%%");
332fdd4e1e0SJan Lentfer 		break;
333fdd4e1e0SJan Lentfer 	    case 'r':
334fdd4e1e0SJan Lentfer 		if (seenr++ == 1) {
335fdd4e1e0SJan Lentfer 		    _nc_warning("saw %%r twice in %s", cap);
336fdd4e1e0SJan Lentfer 		}
337fdd4e1e0SJan Lentfer 		break;
338fdd4e1e0SJan Lentfer 	    case 'm':
339fdd4e1e0SJan Lentfer 		if (seenm++ == 1) {
340fdd4e1e0SJan Lentfer 		    _nc_warning("saw %%m twice in %s", cap);
341fdd4e1e0SJan Lentfer 		}
342fdd4e1e0SJan Lentfer 		break;
343fdd4e1e0SJan Lentfer 	    case 'n':
344fdd4e1e0SJan Lentfer 		if (seenn++ == 1) {
345fdd4e1e0SJan Lentfer 		    _nc_warning("saw %%n twice in %s", cap);
346fdd4e1e0SJan Lentfer 		}
347fdd4e1e0SJan Lentfer 		break;
348fdd4e1e0SJan Lentfer 	    case 'i':
349fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%i");
350fdd4e1e0SJan Lentfer 		break;
351fdd4e1e0SJan Lentfer 	    case '6':
352fdd4e1e0SJan Lentfer 	    case 'B':
353fdd4e1e0SJan Lentfer 		getparm(param, 1);
354fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%{10}%/%{16}%*");
355fdd4e1e0SJan Lentfer 		getparm(param, 1);
356fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%{10}%m%+");
357fdd4e1e0SJan Lentfer 		break;
358fdd4e1e0SJan Lentfer 	    case '8':
359fdd4e1e0SJan Lentfer 	    case 'D':
360fdd4e1e0SJan Lentfer 		getparm(param, 2);
361fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%{2}%*%-");
362fdd4e1e0SJan Lentfer 		break;
363fdd4e1e0SJan Lentfer 	    case '>':
364fdd4e1e0SJan Lentfer 		/* %?%{x}%>%t%{y}%+%; */
365*32bb5217SDaniel Fojt 		if (s[0] && s[1]) {
366*32bb5217SDaniel Fojt 		    getparm(param, 2);
367fdd4e1e0SJan Lentfer 		    dp = save_string(dp, "%?");
368fdd4e1e0SJan Lentfer 		    s += cvtchar(s);
369fdd4e1e0SJan Lentfer 		    dp = save_string(dp, "%>%t");
370fdd4e1e0SJan Lentfer 		    s += cvtchar(s);
371fdd4e1e0SJan Lentfer 		    dp = save_string(dp, "%+%;");
372*32bb5217SDaniel Fojt 		} else {
373*32bb5217SDaniel Fojt 		    _nc_warning("expected two characters after %%>");
374*32bb5217SDaniel Fojt 		    dp = save_string(dp, "%>");
375*32bb5217SDaniel Fojt 		}
376fdd4e1e0SJan Lentfer 		break;
377fdd4e1e0SJan Lentfer 	    case 'a':
378fdd4e1e0SJan Lentfer 		if ((*s == '=' || *s == '+' || *s == '-'
379fdd4e1e0SJan Lentfer 		     || *s == '*' || *s == '/')
380fdd4e1e0SJan Lentfer 		    && (s[1] == 'p' || s[1] == 'c')
381fdd4e1e0SJan Lentfer 		    && s[2] != '\0') {
382fdd4e1e0SJan Lentfer 		    int l;
383fdd4e1e0SJan Lentfer 		    l = 2;
384fdd4e1e0SJan Lentfer 		    if (*s != '=')
385fdd4e1e0SJan Lentfer 			getparm(param, 1);
386fdd4e1e0SJan Lentfer 		    if (s[1] == 'p') {
387fdd4e1e0SJan Lentfer 			getparm(param + s[2] - '@', 1);
388fdd4e1e0SJan Lentfer 			if (param != onstack) {
389fdd4e1e0SJan Lentfer 			    pop();
390fdd4e1e0SJan Lentfer 			    param--;
391fdd4e1e0SJan Lentfer 			}
392fdd4e1e0SJan Lentfer 			l++;
393fdd4e1e0SJan Lentfer 		    } else
394fdd4e1e0SJan Lentfer 			l += cvtchar(s + 2);
395fdd4e1e0SJan Lentfer 		    switch (*s) {
396fdd4e1e0SJan Lentfer 		    case '+':
397fdd4e1e0SJan Lentfer 			dp = save_string(dp, "%+");
398fdd4e1e0SJan Lentfer 			break;
399fdd4e1e0SJan Lentfer 		    case '-':
400fdd4e1e0SJan Lentfer 			dp = save_string(dp, "%-");
401fdd4e1e0SJan Lentfer 			break;
402fdd4e1e0SJan Lentfer 		    case '*':
403fdd4e1e0SJan Lentfer 			dp = save_string(dp, "%*");
404fdd4e1e0SJan Lentfer 			break;
405fdd4e1e0SJan Lentfer 		    case '/':
406fdd4e1e0SJan Lentfer 			dp = save_string(dp, "%/");
407fdd4e1e0SJan Lentfer 			break;
408fdd4e1e0SJan Lentfer 		    case '=':
409fdd4e1e0SJan Lentfer 			if (seenr) {
410fdd4e1e0SJan Lentfer 			    if (param == 1)
411fdd4e1e0SJan Lentfer 				onstack = 2;
412fdd4e1e0SJan Lentfer 			    else if (param == 2)
413fdd4e1e0SJan Lentfer 				onstack = 1;
414fdd4e1e0SJan Lentfer 			    else
415fdd4e1e0SJan Lentfer 				onstack = param;
416fdd4e1e0SJan Lentfer 			} else
417fdd4e1e0SJan Lentfer 			    onstack = param;
418fdd4e1e0SJan Lentfer 			break;
419fdd4e1e0SJan Lentfer 		    }
420fdd4e1e0SJan Lentfer 		    s += l;
421fdd4e1e0SJan Lentfer 		    break;
422fdd4e1e0SJan Lentfer 		}
423fdd4e1e0SJan Lentfer 		getparm(param, 1);
424fdd4e1e0SJan Lentfer 		s += cvtchar(s);
425fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%+");
426fdd4e1e0SJan Lentfer 		break;
427fdd4e1e0SJan Lentfer 	    case '+':
428fdd4e1e0SJan Lentfer 		getparm(param, 1);
429fdd4e1e0SJan Lentfer 		s += cvtchar(s);
430fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%+%c");
431fdd4e1e0SJan Lentfer 		pop();
432fdd4e1e0SJan Lentfer 		break;
433fdd4e1e0SJan Lentfer 	    case 's':
434fdd4e1e0SJan Lentfer #ifdef WATERLOO
435fdd4e1e0SJan Lentfer 		s += cvtchar(s);
436fdd4e1e0SJan Lentfer 		getparm(param, 1);
437fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%-");
438fdd4e1e0SJan Lentfer #else
439fdd4e1e0SJan Lentfer 		getparm(param, 1);
440fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%s");
441fdd4e1e0SJan Lentfer 		pop();
442fdd4e1e0SJan Lentfer #endif /* WATERLOO */
443fdd4e1e0SJan Lentfer 		break;
444fdd4e1e0SJan Lentfer 	    case '-':
445fdd4e1e0SJan Lentfer 		s += cvtchar(s);
446fdd4e1e0SJan Lentfer 		getparm(param, 1);
447fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%-%c");
448fdd4e1e0SJan Lentfer 		pop();
449fdd4e1e0SJan Lentfer 		break;
450fdd4e1e0SJan Lentfer 	    case '.':
451fdd4e1e0SJan Lentfer 		getparm(param, 1);
452fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%c");
453fdd4e1e0SJan Lentfer 		pop();
454fdd4e1e0SJan Lentfer 		break;
455fdd4e1e0SJan Lentfer 	    case '0':		/* not clear any of the historical termcaps did this */
456*32bb5217SDaniel Fojt 		if (*s == '3') {
457*32bb5217SDaniel Fojt 		    ++s;
458fdd4e1e0SJan Lentfer 		    goto see03;
459*32bb5217SDaniel Fojt 		}
460*32bb5217SDaniel Fojt 		if (*s == '2') {
461*32bb5217SDaniel Fojt 		    ++s;
462*32bb5217SDaniel Fojt 		    goto see02;
463*32bb5217SDaniel Fojt 		}
464fdd4e1e0SJan Lentfer 		goto invalid;
465fdd4e1e0SJan Lentfer 	    case '2':
466*32bb5217SDaniel Fojt 	      see02:
467fdd4e1e0SJan Lentfer 		getparm(param, 1);
468fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%2d");
469fdd4e1e0SJan Lentfer 		pop();
470fdd4e1e0SJan Lentfer 		break;
471fdd4e1e0SJan Lentfer 	    case '3':
472fdd4e1e0SJan Lentfer 	      see03:
473fdd4e1e0SJan Lentfer 		getparm(param, 1);
474fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%3d");
475fdd4e1e0SJan Lentfer 		pop();
476fdd4e1e0SJan Lentfer 		break;
477fdd4e1e0SJan Lentfer 	    case 'd':
478fdd4e1e0SJan Lentfer 		getparm(param, 1);
479fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%d");
480fdd4e1e0SJan Lentfer 		pop();
481fdd4e1e0SJan Lentfer 		break;
482fdd4e1e0SJan Lentfer 	    case 'f':
483fdd4e1e0SJan Lentfer 		param++;
484fdd4e1e0SJan Lentfer 		break;
485fdd4e1e0SJan Lentfer 	    case 'b':
486fdd4e1e0SJan Lentfer 		param--;
487fdd4e1e0SJan Lentfer 		break;
488fdd4e1e0SJan Lentfer 	    case '\\':
489fdd4e1e0SJan Lentfer 		dp = save_string(dp, "%\\");
490fdd4e1e0SJan Lentfer 		break;
491fdd4e1e0SJan Lentfer 	    default:
492fdd4e1e0SJan Lentfer 	      invalid:
493fdd4e1e0SJan Lentfer 		dp = save_char(dp, '%');
494fdd4e1e0SJan Lentfer 		s--;
495fdd4e1e0SJan Lentfer 		_nc_warning("unknown %% code %s (%#x) in %s",
496fdd4e1e0SJan Lentfer 			    unctrl((chtype) *s), UChar(*s), cap);
497fdd4e1e0SJan Lentfer 		break;
498fdd4e1e0SJan Lentfer 	    }
499fdd4e1e0SJan Lentfer 	    break;
500fdd4e1e0SJan Lentfer 	default:
501*32bb5217SDaniel Fojt 	    if (*s != '\0')
502fdd4e1e0SJan Lentfer 		dp = save_char(dp, *s++);
503fdd4e1e0SJan Lentfer 	    break;
504fdd4e1e0SJan Lentfer 	}
505fdd4e1e0SJan Lentfer     }
506fdd4e1e0SJan Lentfer 
507fdd4e1e0SJan Lentfer     /*
508fdd4e1e0SJan Lentfer      * Now, if we stripped off some leading padding, add it at the end
509fdd4e1e0SJan Lentfer      * of the string as mandatory padding.
510fdd4e1e0SJan Lentfer      */
511fdd4e1e0SJan Lentfer     if (capstart) {
512fdd4e1e0SJan Lentfer 	dp = save_string(dp, "$<");
513*32bb5217SDaniel Fojt 	for (s = capstart; *s != '\0'; s++)
514fdd4e1e0SJan Lentfer 	    if (isdigit(UChar(*s)) || *s == '*' || *s == '.')
515fdd4e1e0SJan Lentfer 		dp = save_char(dp, *s);
516fdd4e1e0SJan Lentfer 	    else
517fdd4e1e0SJan Lentfer 		break;
518fdd4e1e0SJan Lentfer 	dp = save_string(dp, "/>");
519fdd4e1e0SJan Lentfer     }
520fdd4e1e0SJan Lentfer 
521fdd4e1e0SJan Lentfer     (void) save_char(dp, '\0');
522*32bb5217SDaniel Fojt 
523*32bb5217SDaniel Fojt     DEBUG_THIS(("... _nc_captoinfo %s", NonNull(my_string)));
524*32bb5217SDaniel Fojt 
525fdd4e1e0SJan Lentfer     return (my_string);
526fdd4e1e0SJan Lentfer }
527fdd4e1e0SJan Lentfer 
528fdd4e1e0SJan Lentfer /*
529fdd4e1e0SJan Lentfer  * Check for an expression that corresponds to "%B" (BCD):
530fdd4e1e0SJan Lentfer  *	(parameter / 10) * 16 + (parameter % 10)
531fdd4e1e0SJan Lentfer  */
532fdd4e1e0SJan Lentfer static int
bcd_expression(const char * str)533fdd4e1e0SJan Lentfer bcd_expression(const char *str)
534fdd4e1e0SJan Lentfer {
535fdd4e1e0SJan Lentfer     /* leave this non-const for HPUX */
536fdd4e1e0SJan Lentfer     static char fmt[] = "%%p%c%%{10}%%/%%{16}%%*%%p%c%%{10}%%m%%+";
537fdd4e1e0SJan Lentfer     int len = 0;
538fdd4e1e0SJan Lentfer     char ch1, ch2;
539fdd4e1e0SJan Lentfer 
540fdd4e1e0SJan Lentfer     if (sscanf(str, fmt, &ch1, &ch2) == 2
541fdd4e1e0SJan Lentfer 	&& isdigit(UChar(ch1))
542fdd4e1e0SJan Lentfer 	&& isdigit(UChar(ch2))
543fdd4e1e0SJan Lentfer 	&& (ch1 == ch2)) {
544fdd4e1e0SJan Lentfer 	len = 28;
545fdd4e1e0SJan Lentfer #ifndef NDEBUG
546fdd4e1e0SJan Lentfer 	{
547fdd4e1e0SJan Lentfer 	    char buffer[80];
548fdd4e1e0SJan Lentfer 	    int tst;
5493468e90cSJohn Marino 	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) fmt, ch1, ch2);
550fdd4e1e0SJan Lentfer 	    tst = strlen(buffer) - 1;
551fdd4e1e0SJan Lentfer 	    assert(len == tst);
552fdd4e1e0SJan Lentfer 	}
553fdd4e1e0SJan Lentfer #endif
554fdd4e1e0SJan Lentfer     }
555fdd4e1e0SJan Lentfer     return len;
556fdd4e1e0SJan Lentfer }
557fdd4e1e0SJan Lentfer 
558fdd4e1e0SJan Lentfer static char *
save_tc_char(char * bufptr,int c1)559fdd4e1e0SJan Lentfer save_tc_char(char *bufptr, int c1)
560fdd4e1e0SJan Lentfer {
561fdd4e1e0SJan Lentfer     if (is7bits(c1) && isprint(c1)) {
562fdd4e1e0SJan Lentfer 	if (c1 == ':' || c1 == '\\')
563fdd4e1e0SJan Lentfer 	    bufptr = save_char(bufptr, '\\');
564fdd4e1e0SJan Lentfer 	bufptr = save_char(bufptr, c1);
565fdd4e1e0SJan Lentfer     } else {
566*32bb5217SDaniel Fojt 	char temp[80];
567*32bb5217SDaniel Fojt 
5683468e90cSJohn Marino 	if (c1 == (c1 & 0x1f)) {	/* iscntrl() returns T on 255 */
5693468e90cSJohn Marino 	    _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
5703468e90cSJohn Marino 			"%.20s", unctrl((chtype) c1));
5713468e90cSJohn Marino 	} else {
5723468e90cSJohn Marino 	    _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
5733468e90cSJohn Marino 			"\\%03o", c1);
5743468e90cSJohn Marino 	}
575fdd4e1e0SJan Lentfer 	bufptr = save_string(bufptr, temp);
576fdd4e1e0SJan Lentfer     }
577fdd4e1e0SJan Lentfer     return bufptr;
578fdd4e1e0SJan Lentfer }
579fdd4e1e0SJan Lentfer 
580fdd4e1e0SJan Lentfer static char *
save_tc_inequality(char * bufptr,int c1,int c2)581fdd4e1e0SJan Lentfer save_tc_inequality(char *bufptr, int c1, int c2)
582fdd4e1e0SJan Lentfer {
583fdd4e1e0SJan Lentfer     bufptr = save_string(bufptr, "%>");
584fdd4e1e0SJan Lentfer     bufptr = save_tc_char(bufptr, c1);
585fdd4e1e0SJan Lentfer     bufptr = save_tc_char(bufptr, c2);
586fdd4e1e0SJan Lentfer     return bufptr;
587fdd4e1e0SJan Lentfer }
588fdd4e1e0SJan Lentfer 
589fdd4e1e0SJan Lentfer /*
590*32bb5217SDaniel Fojt  * info-to-cap --- conversion between terminfo and termcap formats
591*32bb5217SDaniel Fojt  *
592fdd4e1e0SJan Lentfer  * Here are the capabilities infotocap assumes it can translate to:
593fdd4e1e0SJan Lentfer  *
594fdd4e1e0SJan Lentfer  *     %%       output `%'
595fdd4e1e0SJan Lentfer  *     %d       output value as in printf %d
596fdd4e1e0SJan Lentfer  *     %2       output value as in printf %2d
597fdd4e1e0SJan Lentfer  *     %3       output value as in printf %3d
598fdd4e1e0SJan Lentfer  *     %.       output value as in printf %c
599fdd4e1e0SJan Lentfer  *     %+c      add character c to value, then do %.
600fdd4e1e0SJan Lentfer  *     %>xy     if value > x then add y, no output
601fdd4e1e0SJan Lentfer  *     %r       reverse order of two parameters, no output
602fdd4e1e0SJan Lentfer  *     %i       increment by one, no output
603fdd4e1e0SJan Lentfer  *     %n       exclusive-or all parameters with 0140 (Datamedia 2500)
604fdd4e1e0SJan Lentfer  *     %B       BCD (16*(value/10)) + (value%10), no output
605fdd4e1e0SJan Lentfer  *     %D       Reverse coding (value - 2*(value%16)), no output (Delta Data).
606fdd4e1e0SJan Lentfer  *     %m       exclusive-or all parameters with 0177 (not in 4.4BSD)
607fdd4e1e0SJan Lentfer  */
608fdd4e1e0SJan Lentfer 
609*32bb5217SDaniel Fojt #define octal_fixup(n, c) fixups[n].ch = ((fixups[n].ch << 3) | ((c) - '0'))
610*32bb5217SDaniel Fojt 
611fdd4e1e0SJan Lentfer /*
612fdd4e1e0SJan Lentfer  * Convert a terminfo string to termcap format.  Parameters are as in
613fdd4e1e0SJan Lentfer  * _nc_captoinfo().
614fdd4e1e0SJan Lentfer  */
6151d102085SJan Lentfer NCURSES_EXPORT(char *)
_nc_infotocap(const char * cap GCC_UNUSED,const char * str,int const parameterized)616fdd4e1e0SJan Lentfer _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized)
617fdd4e1e0SJan Lentfer {
618fdd4e1e0SJan Lentfer     int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0;
619fdd4e1e0SJan Lentfer     const char *padding;
620fdd4e1e0SJan Lentfer     const char *trimmed = 0;
62100d8f3c4SJohn Marino     int in0, in1, in2;
622fdd4e1e0SJan Lentfer     char ch1 = 0, ch2 = 0;
623fdd4e1e0SJan Lentfer     char *bufptr = init_string();
6243468e90cSJohn Marino     char octal[4];
625fdd4e1e0SJan Lentfer     int len;
626*32bb5217SDaniel Fojt     int digits;
627fdd4e1e0SJan Lentfer     bool syntax_error = FALSE;
628*32bb5217SDaniel Fojt     int myfix = 0;
629*32bb5217SDaniel Fojt     struct {
630*32bb5217SDaniel Fojt 	int ch;
631*32bb5217SDaniel Fojt 	int offset;
632*32bb5217SDaniel Fojt     } fixups[MAX_TC_FIXUPS];
633*32bb5217SDaniel Fojt 
634*32bb5217SDaniel Fojt     DEBUG_THIS(("_nc_infotocap params %d, %s", parameterized, str));
635fdd4e1e0SJan Lentfer 
636fdd4e1e0SJan Lentfer     /* we may have to move some trailing mandatory padding up front */
637fdd4e1e0SJan Lentfer     padding = str + strlen(str) - 1;
6383468e90cSJohn Marino     if (padding > str && *padding == '>') {
6393468e90cSJohn Marino 	if (*--padding == '/')
640fdd4e1e0SJan Lentfer 	    --padding;
641fdd4e1e0SJan Lentfer 	while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
642fdd4e1e0SJan Lentfer 	    padding--;
643fdd4e1e0SJan Lentfer 	if (padding > str && *padding == '<' && *--padding == '$')
644fdd4e1e0SJan Lentfer 	    trimmed = padding;
645fdd4e1e0SJan Lentfer 	padding += 2;
646fdd4e1e0SJan Lentfer 
647fdd4e1e0SJan Lentfer 	while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
648fdd4e1e0SJan Lentfer 	    bufptr = save_char(bufptr, *padding++);
649fdd4e1e0SJan Lentfer     }
650fdd4e1e0SJan Lentfer 
651*32bb5217SDaniel Fojt     for (; !syntax_error &&
652*32bb5217SDaniel Fojt 	 *str &&
653*32bb5217SDaniel Fojt 	 ((trimmed == 0) || (str < trimmed)); str++) {
654fdd4e1e0SJan Lentfer 	int c1, c2;
655fdd4e1e0SJan Lentfer 	char *cp = 0;
656fdd4e1e0SJan Lentfer 
65700d8f3c4SJohn Marino 	if (str[0] == '^') {
65800d8f3c4SJohn Marino 	    if (str[1] == '\0' || (str + 1) == trimmed) {
65900d8f3c4SJohn Marino 		bufptr = save_string(bufptr, "\\136");
66000d8f3c4SJohn Marino 		++str;
661*32bb5217SDaniel Fojt 	    } else if (str[1] == '?') {
662*32bb5217SDaniel Fojt 		/*
663*32bb5217SDaniel Fojt 		 * Although the 4.3BSD termcap file has an instance of "kb=^?",
664*32bb5217SDaniel Fojt 		 * that appears to be just cut/paste since neither 4.3BSD nor
665*32bb5217SDaniel Fojt 		 * 4.4BSD termcap interprets "^?" as DEL.
666*32bb5217SDaniel Fojt 		 */
667*32bb5217SDaniel Fojt 		bufptr = save_string(bufptr, "\\177");
668*32bb5217SDaniel Fojt 		++str;
66900d8f3c4SJohn Marino 	    } else {
67000d8f3c4SJohn Marino 		bufptr = save_char(bufptr, *str++);
67100d8f3c4SJohn Marino 		bufptr = save_char(bufptr, *str);
67200d8f3c4SJohn Marino 	    }
67300d8f3c4SJohn Marino 	} else if (str[0] == '\\') {
67400d8f3c4SJohn Marino 	    if (str[1] == '\0' || (str + 1) == trimmed) {
67500d8f3c4SJohn Marino 		bufptr = save_string(bufptr, "\\134");
67600d8f3c4SJohn Marino 		++str;
67700d8f3c4SJohn Marino 	    } else if (str[1] == '^') {
67800d8f3c4SJohn Marino 		bufptr = save_string(bufptr, "\\136");
67900d8f3c4SJohn Marino 		++str;
68000d8f3c4SJohn Marino 	    } else if (str[1] == ',') {
681fdd4e1e0SJan Lentfer 		bufptr = save_char(bufptr, *++str);
68200d8f3c4SJohn Marino 	    } else {
683*32bb5217SDaniel Fojt 		int xx1;
6843468e90cSJohn Marino 
68500d8f3c4SJohn Marino 		bufptr = save_char(bufptr, *str++);
6863468e90cSJohn Marino 		xx1 = *str;
6873468e90cSJohn Marino 		if (_nc_strict_bsd) {
6883468e90cSJohn Marino 
689*32bb5217SDaniel Fojt 		    if (isoctal(UChar(xx1))) {
690*32bb5217SDaniel Fojt 			int pad = 0;
691*32bb5217SDaniel Fojt 			int xx2;
692*32bb5217SDaniel Fojt 			int fix = 0;
693*32bb5217SDaniel Fojt 
694*32bb5217SDaniel Fojt 			if (!isoctal(UChar(str[1])))
6953468e90cSJohn Marino 			    pad = 2;
696*32bb5217SDaniel Fojt 			else if (str[1] && !isoctal(UChar(str[2])))
6973468e90cSJohn Marino 			    pad = 1;
6983468e90cSJohn Marino 
6993468e90cSJohn Marino 			/*
7003468e90cSJohn Marino 			 * Test for "\0", "\00" or "\000" and transform those
7013468e90cSJohn Marino 			 * into "\200".
7023468e90cSJohn Marino 			 */
7033468e90cSJohn Marino 			if (xx1 == '0'
7043468e90cSJohn Marino 			    && ((pad == 2) || (str[1] == '0'))
7053468e90cSJohn Marino 			    && ((pad >= 1) || (str[2] == '0'))) {
7063468e90cSJohn Marino 			    xx2 = '2';
7073468e90cSJohn Marino 			} else {
7083468e90cSJohn Marino 			    xx2 = '0';
7093468e90cSJohn Marino 			    pad = 0;	/* FIXME - optionally pad to 3 digits */
7103468e90cSJohn Marino 			}
711*32bb5217SDaniel Fojt 			if (myfix < MAX_TC_FIXUPS) {
712*32bb5217SDaniel Fojt 			    fix = 3 - pad;
713*32bb5217SDaniel Fojt 			    fixups[myfix].ch = 0;
714*32bb5217SDaniel Fojt 			    fixups[myfix].offset = (int) (bufptr
715*32bb5217SDaniel Fojt 							  - my_string
716*32bb5217SDaniel Fojt 							  - 1);
717*32bb5217SDaniel Fojt 			}
7183468e90cSJohn Marino 			while (pad-- > 0) {
7193468e90cSJohn Marino 			    bufptr = save_char(bufptr, xx2);
720*32bb5217SDaniel Fojt 			    if (myfix < MAX_TC_FIXUPS) {
721*32bb5217SDaniel Fojt 				fixups[myfix].ch <<= 3;
722*32bb5217SDaniel Fojt 				fixups[myfix].ch |= (xx2 - '0');
723*32bb5217SDaniel Fojt 			    }
7243468e90cSJohn Marino 			    xx2 = '0';
7253468e90cSJohn Marino 			}
726*32bb5217SDaniel Fojt 			if (myfix < MAX_TC_FIXUPS) {
727*32bb5217SDaniel Fojt 			    int n;
728*32bb5217SDaniel Fojt 			    for (n = 0; n < fix; ++n) {
729*32bb5217SDaniel Fojt 				fixups[myfix].ch <<= 3;
730*32bb5217SDaniel Fojt 				fixups[myfix].ch |= (str[n] - '0');
731*32bb5217SDaniel Fojt 			    }
732*32bb5217SDaniel Fojt 			    if (fixups[myfix].ch < 32) {
733*32bb5217SDaniel Fojt 				++myfix;
734*32bb5217SDaniel Fojt 			    }
735*32bb5217SDaniel Fojt 			}
7363468e90cSJohn Marino 		    } else if (strchr("E\\nrtbf", xx1) == 0) {
7373468e90cSJohn Marino 			switch (xx1) {
7383468e90cSJohn Marino 			case 'e':
7393468e90cSJohn Marino 			    xx1 = 'E';
7403468e90cSJohn Marino 			    break;
7413468e90cSJohn Marino 			case 'l':
7423468e90cSJohn Marino 			    xx1 = 'n';
7433468e90cSJohn Marino 			    break;
7443468e90cSJohn Marino 			case 's':
7453468e90cSJohn Marino 			    bufptr = save_char(bufptr, '0');
7463468e90cSJohn Marino 			    bufptr = save_char(bufptr, '4');
7473468e90cSJohn Marino 			    xx1 = '0';
7483468e90cSJohn Marino 			    break;
7493468e90cSJohn Marino 			case ':':
7503468e90cSJohn Marino 			    /*
7513468e90cSJohn Marino 			     * Note: termcap documentation claims that ":"
7523468e90cSJohn Marino 			     * must be escaped as "\072", however the
7533468e90cSJohn Marino 			     * documentation is incorrect - read the code.
7543468e90cSJohn Marino 			     * The replacement does not work reliably,
7553468e90cSJohn Marino 			     * so the advice is not helpful.
7563468e90cSJohn Marino 			     */
7573468e90cSJohn Marino 			    bufptr = save_char(bufptr, '0');
7583468e90cSJohn Marino 			    bufptr = save_char(bufptr, '7');
7593468e90cSJohn Marino 			    xx1 = '2';
7603468e90cSJohn Marino 			    break;
7613468e90cSJohn Marino 			default:
7623468e90cSJohn Marino 			    /* should not happen, but handle this anyway */
7633468e90cSJohn Marino 			    _nc_SPRINTF(octal, _nc_SLIMIT(sizeof(octal))
7643468e90cSJohn Marino 					"%03o", UChar(xx1));
7653468e90cSJohn Marino 			    bufptr = save_char(bufptr, octal[0]);
7663468e90cSJohn Marino 			    bufptr = save_char(bufptr, octal[1]);
7673468e90cSJohn Marino 			    xx1 = octal[2];
7683468e90cSJohn Marino 			    break;
7693468e90cSJohn Marino 			}
7703468e90cSJohn Marino 		    }
771*32bb5217SDaniel Fojt 		} else {
772*32bb5217SDaniel Fojt 		    if (myfix < MAX_TC_FIXUPS && isoctal(UChar(xx1))) {
773*32bb5217SDaniel Fojt 			bool will_fix = TRUE;
774*32bb5217SDaniel Fojt 			int n;
775*32bb5217SDaniel Fojt 
776*32bb5217SDaniel Fojt 			fixups[myfix].ch = 0;
777*32bb5217SDaniel Fojt 			fixups[myfix].offset = (int) (bufptr - my_string - 1);
778*32bb5217SDaniel Fojt 			for (n = 0; n < 3; ++n) {
779*32bb5217SDaniel Fojt 			    if (isoctal(str[n])) {
780*32bb5217SDaniel Fojt 				octal_fixup(myfix, str[n]);
781*32bb5217SDaniel Fojt 			    } else {
782*32bb5217SDaniel Fojt 				will_fix = FALSE;
783*32bb5217SDaniel Fojt 				break;
784*32bb5217SDaniel Fojt 			    }
785*32bb5217SDaniel Fojt 			}
786*32bb5217SDaniel Fojt 			if (will_fix && (fixups[myfix].ch < 32))
787*32bb5217SDaniel Fojt 			    ++myfix;
788*32bb5217SDaniel Fojt 		    }
7893468e90cSJohn Marino 		}
7903468e90cSJohn Marino 		bufptr = save_char(bufptr, xx1);
79100d8f3c4SJohn Marino 	    }
792fdd4e1e0SJan Lentfer 	} else if (str[0] == '$' && str[1] == '<') {	/* discard padding */
793fdd4e1e0SJan Lentfer 	    str += 2;
794fdd4e1e0SJan Lentfer 	    while (isdigit(UChar(*str))
795fdd4e1e0SJan Lentfer 		   || *str == '.'
796fdd4e1e0SJan Lentfer 		   || *str == '*'
797fdd4e1e0SJan Lentfer 		   || *str == '/'
798fdd4e1e0SJan Lentfer 		   || *str == '>')
799fdd4e1e0SJan Lentfer 		str++;
800fdd4e1e0SJan Lentfer 	    --str;
80100d8f3c4SJohn Marino 	} else if (sscanf(str,
80200d8f3c4SJohn Marino 			  "[%%?%%p1%%{8}%%<%%t%d%%p1%%d%%e%%p1%%{16}%%<%%t%d%%p1%%{8}%%-%%d%%e%d;5;%%p1%%d%%;m",
80300d8f3c4SJohn Marino 			  &in0, &in1, &in2) == 3
80400d8f3c4SJohn Marino 		   && ((in0 == 4 && in1 == 10 && in2 == 48)
80500d8f3c4SJohn Marino 		       || (in0 == 3 && in1 == 9 && in2 == 38))) {
80600d8f3c4SJohn Marino 	    /* dumb-down an optimized case from xterm-256color for termcap */
8073468e90cSJohn Marino 	    if ((str = strstr(str, ";m")) == 0)
8083468e90cSJohn Marino 		break;		/* cannot happen */
80900d8f3c4SJohn Marino 	    ++str;
81000d8f3c4SJohn Marino 	    if (in2 == 48) {
81100d8f3c4SJohn Marino 		bufptr = save_string(bufptr, "[48;5;%dm");
81200d8f3c4SJohn Marino 	    } else {
81300d8f3c4SJohn Marino 		bufptr = save_string(bufptr, "[38;5;%dm");
81400d8f3c4SJohn Marino 	    }
815fdd4e1e0SJan Lentfer 	} else if (str[0] == '%' && str[1] == '%') {	/* escaped '%' */
816fdd4e1e0SJan Lentfer 	    bufptr = save_string(bufptr, "%%");
8171d102085SJan Lentfer 	    ++str;
818fdd4e1e0SJan Lentfer 	} else if (*str != '%' || (parameterized < 1)) {
819fdd4e1e0SJan Lentfer 	    bufptr = save_char(bufptr, *str);
820fdd4e1e0SJan Lentfer 	} else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1, &c2) == 2) {
821fdd4e1e0SJan Lentfer 	    str = strchr(str, ';');
822fdd4e1e0SJan Lentfer 	    bufptr = save_tc_inequality(bufptr, c1, c2);
823fdd4e1e0SJan Lentfer 	} else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1, &ch2) == 2) {
824fdd4e1e0SJan Lentfer 	    str = strchr(str, ';');
8253468e90cSJohn Marino 	    bufptr = save_tc_inequality(bufptr, c1, ch2);
826fdd4e1e0SJan Lentfer 	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1, &c2) == 2) {
827fdd4e1e0SJan Lentfer 	    str = strchr(str, ';');
8283468e90cSJohn Marino 	    bufptr = save_tc_inequality(bufptr, ch1, c2);
829fdd4e1e0SJan Lentfer 	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2) {
830fdd4e1e0SJan Lentfer 	    str = strchr(str, ';');
8313468e90cSJohn Marino 	    bufptr = save_tc_inequality(bufptr, ch1, ch2);
832fdd4e1e0SJan Lentfer 	} else if ((len = bcd_expression(str)) != 0) {
833fdd4e1e0SJan Lentfer 	    str += len;
834fdd4e1e0SJan Lentfer 	    bufptr = save_string(bufptr, "%B");
835*32bb5217SDaniel Fojt 	} else if ((sscanf(str, "%%{%d}%%+%%%c", &c1, &ch2) == 2
836*32bb5217SDaniel Fojt 		    || sscanf(str, "%%'%c'%%+%%%c", &ch1, &ch2) == 2)
837*32bb5217SDaniel Fojt 		   && ch2 == 'c'
838fdd4e1e0SJan Lentfer 		   && (cp = strchr(str, '+'))) {
839fdd4e1e0SJan Lentfer 	    str = cp + 2;
840fdd4e1e0SJan Lentfer 	    bufptr = save_string(bufptr, "%+");
841fdd4e1e0SJan Lentfer 
842fdd4e1e0SJan Lentfer 	    if (ch1)
843fdd4e1e0SJan Lentfer 		c1 = ch1;
844fdd4e1e0SJan Lentfer 	    bufptr = save_tc_char(bufptr, c1);
845fdd4e1e0SJan Lentfer 	}
846fdd4e1e0SJan Lentfer 	/* FIXME: this "works" for 'delta' */
8473468e90cSJohn Marino 	else if (strncmp(str, "%{2}%*%-", (size_t) 8) == 0) {
848fdd4e1e0SJan Lentfer 	    str += 7;
849fdd4e1e0SJan Lentfer 	    bufptr = save_string(bufptr, "%D");
8503468e90cSJohn Marino 	} else if (strncmp(str, "%{96}%^", (size_t) 7) == 0) {
851fdd4e1e0SJan Lentfer 	    str += 6;
852fdd4e1e0SJan Lentfer 	    if (saw_m++ == 0) {
853fdd4e1e0SJan Lentfer 		bufptr = save_string(bufptr, "%n");
854fdd4e1e0SJan Lentfer 	    }
8553468e90cSJohn Marino 	} else if (strncmp(str, "%{127}%^", (size_t) 8) == 0) {
856fdd4e1e0SJan Lentfer 	    str += 7;
857fdd4e1e0SJan Lentfer 	    if (saw_n++ == 0) {
858fdd4e1e0SJan Lentfer 		bufptr = save_string(bufptr, "%m");
859fdd4e1e0SJan Lentfer 	    }
860fdd4e1e0SJan Lentfer 	} else {		/* cm-style format element */
861fdd4e1e0SJan Lentfer 	    str++;
862fdd4e1e0SJan Lentfer 	    switch (*str) {
863fdd4e1e0SJan Lentfer 	    case '%':
864fdd4e1e0SJan Lentfer 		bufptr = save_char(bufptr, '%');
865fdd4e1e0SJan Lentfer 		break;
866fdd4e1e0SJan Lentfer 
867fdd4e1e0SJan Lentfer 	    case '0':
868fdd4e1e0SJan Lentfer 	    case '1':
869fdd4e1e0SJan Lentfer 	    case '2':
870fdd4e1e0SJan Lentfer 	    case '3':
871fdd4e1e0SJan Lentfer 	    case '4':
872fdd4e1e0SJan Lentfer 	    case '5':
873fdd4e1e0SJan Lentfer 	    case '6':
874fdd4e1e0SJan Lentfer 	    case '7':
875fdd4e1e0SJan Lentfer 	    case '8':
876fdd4e1e0SJan Lentfer 	    case '9':
877fdd4e1e0SJan Lentfer 		bufptr = save_char(bufptr, '%');
8783468e90cSJohn Marino 		ch1 = 0;
8793468e90cSJohn Marino 		ch2 = 0;
880*32bb5217SDaniel Fojt 		digits = 0;
8813468e90cSJohn Marino 		while (isdigit(UChar(*str))) {
882*32bb5217SDaniel Fojt 		    if (++digits > 2) {
883*32bb5217SDaniel Fojt 			syntax_error = TRUE;
884*32bb5217SDaniel Fojt 			break;
885*32bb5217SDaniel Fojt 		    }
8863468e90cSJohn Marino 		    ch2 = ch1;
8873468e90cSJohn Marino 		    ch1 = *str++;
888*32bb5217SDaniel Fojt 		    if (digits == 2 && ch2 != '0') {
889*32bb5217SDaniel Fojt 			syntax_error = TRUE;
890*32bb5217SDaniel Fojt 			break;
891*32bb5217SDaniel Fojt 		    } else if (_nc_strict_bsd) {
892*32bb5217SDaniel Fojt 			if (ch1 > '3') {
893*32bb5217SDaniel Fojt 			    syntax_error = TRUE;
894*32bb5217SDaniel Fojt 			    break;
895*32bb5217SDaniel Fojt 			}
8963468e90cSJohn Marino 		    } else {
8973468e90cSJohn Marino 			bufptr = save_char(bufptr, ch1);
8983468e90cSJohn Marino 		    }
8993468e90cSJohn Marino 		}
900*32bb5217SDaniel Fojt 		if (syntax_error)
901*32bb5217SDaniel Fojt 		    break;
902*32bb5217SDaniel Fojt 		/*
903*32bb5217SDaniel Fojt 		 * Convert %02 to %2 and %03 to %3
904*32bb5217SDaniel Fojt 		 */
905*32bb5217SDaniel Fojt 		if (ch2 == '0' && !_nc_strict_bsd) {
906*32bb5217SDaniel Fojt 		    ch2 = 0;
907*32bb5217SDaniel Fojt 		    bufptr[-2] = bufptr[-1];
908*32bb5217SDaniel Fojt 		    *--bufptr = 0;
909*32bb5217SDaniel Fojt 		}
9103468e90cSJohn Marino 		if (_nc_strict_bsd) {
911*32bb5217SDaniel Fojt 		    if (ch2 != 0 && ch2 != '0') {
912*32bb5217SDaniel Fojt 			syntax_error = TRUE;
913*32bb5217SDaniel Fojt 		    } else if (ch1 < '2') {
9143468e90cSJohn Marino 			ch1 = 'd';
915*32bb5217SDaniel Fojt 		    }
9163468e90cSJohn Marino 		    bufptr = save_char(bufptr, ch1);
9173468e90cSJohn Marino 		}
918*32bb5217SDaniel Fojt 		if (strchr("oxX.", *str)) {
919*32bb5217SDaniel Fojt 		    syntax_error = TRUE;	/* termcap doesn't have octal, hex */
920fdd4e1e0SJan Lentfer 		}
921fdd4e1e0SJan Lentfer 		break;
922fdd4e1e0SJan Lentfer 
923fdd4e1e0SJan Lentfer 	    case 'd':
924fdd4e1e0SJan Lentfer 		bufptr = save_string(bufptr, "%d");
925fdd4e1e0SJan Lentfer 		break;
926fdd4e1e0SJan Lentfer 
927fdd4e1e0SJan Lentfer 	    case 'c':
928fdd4e1e0SJan Lentfer 		bufptr = save_string(bufptr, "%.");
929fdd4e1e0SJan Lentfer 		break;
930fdd4e1e0SJan Lentfer 
931fdd4e1e0SJan Lentfer 		/*
932fdd4e1e0SJan Lentfer 		 * %s isn't in termcap, but it's convenient to pass it through
933fdd4e1e0SJan Lentfer 		 * so we can represent things like terminfo pfkey strings in
934fdd4e1e0SJan Lentfer 		 * termcap notation.
935fdd4e1e0SJan Lentfer 		 */
936fdd4e1e0SJan Lentfer 	    case 's':
937*32bb5217SDaniel Fojt 		if (_nc_strict_bsd) {
938*32bb5217SDaniel Fojt 		    syntax_error = TRUE;
939*32bb5217SDaniel Fojt 		} else {
940fdd4e1e0SJan Lentfer 		    bufptr = save_string(bufptr, "%s");
941*32bb5217SDaniel Fojt 		}
942fdd4e1e0SJan Lentfer 		break;
943fdd4e1e0SJan Lentfer 
944fdd4e1e0SJan Lentfer 	    case 'p':
945fdd4e1e0SJan Lentfer 		str++;
946fdd4e1e0SJan Lentfer 		if (*str == '1')
947fdd4e1e0SJan Lentfer 		    seenone = 1;
948fdd4e1e0SJan Lentfer 		else if (*str == '2') {
949fdd4e1e0SJan Lentfer 		    if (!seenone && !seentwo) {
950fdd4e1e0SJan Lentfer 			bufptr = save_string(bufptr, "%r");
951fdd4e1e0SJan Lentfer 			seentwo++;
952fdd4e1e0SJan Lentfer 		    }
953*32bb5217SDaniel Fojt 		} else if (*str >= '3') {
954*32bb5217SDaniel Fojt 		    syntax_error = TRUE;
955*32bb5217SDaniel Fojt 		}
956fdd4e1e0SJan Lentfer 		break;
957fdd4e1e0SJan Lentfer 
958fdd4e1e0SJan Lentfer 	    case 'i':
959fdd4e1e0SJan Lentfer 		bufptr = save_string(bufptr, "%i");
960fdd4e1e0SJan Lentfer 		break;
961fdd4e1e0SJan Lentfer 
962fdd4e1e0SJan Lentfer 	    default:
963fdd4e1e0SJan Lentfer 		bufptr = save_char(bufptr, *str);
964fdd4e1e0SJan Lentfer 		syntax_error = TRUE;
965fdd4e1e0SJan Lentfer 		break;
966fdd4e1e0SJan Lentfer 	    }			/* endswitch (*str) */
967fdd4e1e0SJan Lentfer 	}			/* endelse (*str == '%') */
968fdd4e1e0SJan Lentfer 
9691d102085SJan Lentfer 	/*
9701d102085SJan Lentfer 	 * 'str' always points to the end of what was scanned in this step,
9711d102085SJan Lentfer 	 * but that may not be the end of the string.
9721d102085SJan Lentfer 	 */
9731d102085SJan Lentfer 	assert(str != 0);
9743468e90cSJohn Marino 	if (str == 0 || *str == '\0')
975fdd4e1e0SJan Lentfer 	    break;
976fdd4e1e0SJan Lentfer 
977fdd4e1e0SJan Lentfer     }				/* endwhile (*str) */
978fdd4e1e0SJan Lentfer 
979*32bb5217SDaniel Fojt     if (!syntax_error &&
980*32bb5217SDaniel Fojt 	myfix > 0 &&
981*32bb5217SDaniel Fojt 	((int) strlen(my_string) - (4 * myfix)) < MIN_TC_FIXUPS) {
982*32bb5217SDaniel Fojt 	while (--myfix >= 0) {
983*32bb5217SDaniel Fojt 	    char *p = fixups[myfix].offset + my_string;
984*32bb5217SDaniel Fojt 	    *p++ = '^';
985*32bb5217SDaniel Fojt 	    *p++ = (char) (fixups[myfix].ch | '@');
986*32bb5217SDaniel Fojt 	    while ((p[0] = p[2]) != '\0') {
987*32bb5217SDaniel Fojt 		++p;
988*32bb5217SDaniel Fojt 	    }
989*32bb5217SDaniel Fojt 	}
990*32bb5217SDaniel Fojt     }
991*32bb5217SDaniel Fojt 
992*32bb5217SDaniel Fojt     DEBUG_THIS(("... _nc_infotocap %s",
993*32bb5217SDaniel Fojt 		syntax_error
994*32bb5217SDaniel Fojt 		? "<ERR>"
995*32bb5217SDaniel Fojt 		: _nc_visbuf(my_string)));
996*32bb5217SDaniel Fojt 
997fdd4e1e0SJan Lentfer     return (syntax_error ? NULL : my_string);
998fdd4e1e0SJan Lentfer }
999fdd4e1e0SJan Lentfer 
1000fdd4e1e0SJan Lentfer #ifdef MAIN
1001fdd4e1e0SJan Lentfer 
1002fdd4e1e0SJan Lentfer int curr_line;
1003fdd4e1e0SJan Lentfer 
1004fdd4e1e0SJan Lentfer int
main(int argc,char * argv[])1005fdd4e1e0SJan Lentfer main(int argc, char *argv[])
1006fdd4e1e0SJan Lentfer {
1007fdd4e1e0SJan Lentfer     int c, tc = FALSE;
1008fdd4e1e0SJan Lentfer 
1009fdd4e1e0SJan Lentfer     while ((c = getopt(argc, argv, "c")) != EOF)
1010fdd4e1e0SJan Lentfer 	switch (c) {
1011fdd4e1e0SJan Lentfer 	case 'c':
1012fdd4e1e0SJan Lentfer 	    tc = TRUE;
1013fdd4e1e0SJan Lentfer 	    break;
1014fdd4e1e0SJan Lentfer 	}
1015fdd4e1e0SJan Lentfer 
1016fdd4e1e0SJan Lentfer     curr_line = 0;
1017fdd4e1e0SJan Lentfer     for (;;) {
1018fdd4e1e0SJan Lentfer 	char buf[BUFSIZ];
1019fdd4e1e0SJan Lentfer 
1020fdd4e1e0SJan Lentfer 	++curr_line;
1021fdd4e1e0SJan Lentfer 	if (fgets(buf, sizeof(buf), stdin) == 0)
1022fdd4e1e0SJan Lentfer 	    break;
1023fdd4e1e0SJan Lentfer 	buf[strlen(buf) - 1] = '\0';
1024fdd4e1e0SJan Lentfer 	_nc_set_source(buf);
1025fdd4e1e0SJan Lentfer 
1026fdd4e1e0SJan Lentfer 	if (tc) {
1027fdd4e1e0SJan Lentfer 	    char *cp = _nc_infotocap("to termcap", buf, 1);
1028fdd4e1e0SJan Lentfer 
1029fdd4e1e0SJan Lentfer 	    if (cp)
1030fdd4e1e0SJan Lentfer 		(void) fputs(cp, stdout);
1031fdd4e1e0SJan Lentfer 	} else
1032fdd4e1e0SJan Lentfer 	    (void) fputs(_nc_captoinfo("to terminfo", buf, 1), stdout);
1033fdd4e1e0SJan Lentfer 	(void) putchar('\n');
1034fdd4e1e0SJan Lentfer     }
1035fdd4e1e0SJan Lentfer     return (0);
1036fdd4e1e0SJan Lentfer }
1037fdd4e1e0SJan Lentfer #endif /* MAIN */
1038fdd4e1e0SJan Lentfer 
10391d102085SJan Lentfer #if NO_LEAKS
10401d102085SJan Lentfer NCURSES_EXPORT(void)
_nc_captoinfo_leaks(void)10411d102085SJan Lentfer _nc_captoinfo_leaks(void)
10421d102085SJan Lentfer {
10431d102085SJan Lentfer     if (my_string != 0) {
10441d102085SJan Lentfer 	FreeAndNull(my_string);
10451d102085SJan Lentfer     }
10461d102085SJan Lentfer     my_length = 0;
10471d102085SJan Lentfer }
10481d102085SJan Lentfer #endif
1049