GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcurses/tinfo/lib_tgoto.c Lines: 11 82 13.4 %
Date: 2017-11-07 Branches: 10 57 17.5 %

Line Branch Exec Source
1
/* $OpenBSD: lib_tgoto.c,v 1.6 2010/01/14 22:53:22 nicm Exp $ */
2
3
/****************************************************************************
4
 * Copyright (c) 2000-2006,2008 Free Software Foundation, Inc.              *
5
 *                                                                          *
6
 * Permission is hereby granted, free of charge, to any person obtaining a  *
7
 * copy of this software and associated documentation files (the            *
8
 * "Software"), to deal in the Software without restriction, including      *
9
 * without limitation the rights to use, copy, modify, merge, publish,      *
10
 * distribute, distribute with modifications, sublicense, and/or sell       *
11
 * copies of the Software, and to permit persons to whom the Software is    *
12
 * furnished to do so, subject to the following conditions:                 *
13
 *                                                                          *
14
 * The above copyright notice and this permission notice shall be included  *
15
 * in all copies or substantial portions of the Software.                   *
16
 *                                                                          *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24
 *                                                                          *
25
 * Except as contained in this notice, the name(s) of the above copyright   *
26
 * holders shall not be used in advertising or otherwise to promote the     *
27
 * sale, use or other dealings in this Software without prior written       *
28
 * authorization.                                                           *
29
 ****************************************************************************/
30
31
/****************************************************************************
32
 *  Author: Thomas E. Dickey                                                *
33
 ****************************************************************************/
34
35
#include <curses.priv.h>
36
37
#include <ctype.h>
38
#include <termcap.h>
39
40
MODULE_ID("$Id: lib_tgoto.c,v 1.6 2010/01/14 22:53:22 nicm Exp $")
41
42
#if !PURE_TERMINFO
43
static bool
44
is_termcap(const char *string)
45
{
46
    bool result = TRUE;
47
48

12564
    if (string == 0 || *string == '\0') {
49
	result = FALSE;		/* tparm() handles empty strings */
50
    } else {
51
36522
	while ((*string != '\0') && result) {
52
16167
	    if (*string == '%') {
53
20311
		switch (*++string) {
54
		case 'p':
55
		    result = FALSE;
56
4188
		    break;
57
		case '\0':
58
		    string--;
59
		    break;
60
		}
61

8835
	    } else if (string[0] == '$' && string[1] == '<') {
62
		result = FALSE;
63
	    }
64
16167
	    string++;
65
	}
66
    }
67
4188
    return result;
68
}
69
70
static char *
71
tgoto_internal(const char *string, int x, int y)
72
{
73
    static char *result;
74
    static size_t length;
75
76
    int swap_arg;
77
    int param[3];
78
    size_t used = 0;
79
    size_t need = 10;
80
    size_t copied;
81
    int *value = param;
82
    bool need_BC = FALSE;
83
84
    if (BC)
85
	need += strlen(BC);
86
87
    param[0] = y;
88
    param[1] = x;
89
    param[2] = 0;
90
91
    while (*string != 0) {
92
	if ((used + need) > length) {
93
	    length += (used + need);
94
	    if ((result = typeRealloc(char, length, result)) == 0) {
95
		length = 0;
96
		break;
97
	    }
98
	}
99
	if (*string == '%') {
100
	    const char *fmt = 0;
101
102
	    switch (*++string) {
103
	    case '\0':
104
		string--;
105
		break;
106
	    case 'd':
107
		fmt = "%d";
108
		break;
109
	    case '2':
110
		fmt = "%02d";
111
		*value %= 100;
112
		break;
113
	    case '3':
114
		fmt = "%03d";
115
		*value %= 1000;
116
		break;
117
	    case '+':
118
		*value += UChar(*++string);
119
		/* FALLTHRU */
120
	    case '.':
121
		/*
122
		 * Guard against tputs() seeing a truncated string.  The
123
		 * termcap documentation refers to a similar fixup for \n
124
		 * and \r, but I don't see that it could work -TD
125
		 */
126
		if (*value == 0) {
127
		    if (BC != 0) {
128
			*value += 1;
129
			need_BC = TRUE;
130
		    } else {
131
			*value = 0200;	/* tputs will treat this as \0 */
132
		    }
133
		}
134
		result[used++] = (char) *value++;
135
		break;
136
	    case '%':
137
		result[used++] = *string;
138
		break;
139
	    case 'r':
140
		swap_arg = param[0];
141
		param[0] = param[1];
142
		param[1] = swap_arg;
143
		break;
144
	    case 'i':
145
		param[0] += 1;
146
		param[1] += 1;
147
		break;
148
	    case '>':
149
		if (*value > string[1])
150
		    *value += string[2];
151
		string += 2;
152
		break;
153
	    case 'n':		/* Datamedia 2500 */
154
		param[0] ^= 0140;
155
		param[1] ^= 0140;
156
		break;
157
	    case 'B':		/* BCD */
158
		*value = 16 * (*value / 10) + (*value % 10);
159
		break;
160
	    case 'D':		/* Reverse coding (Delta Data) */
161
		*value -= 2 * (*value % 16);
162
		break;
163
	    }
164
	    if (fmt != 0) {
165
		snprintf(result + used, length - used, fmt, *value++);
166
		used += strlen(result + used);
167
		fmt = 0;
168
	    }
169
	    if (value - param > 2) {
170
		value = param + 2;
171
		*value = 0;
172
	    }
173
	} else {
174
	    result[used++] = *string;
175
	}
176
	string++;
177
    }
178
    if (result != 0) {
179
	if (need_BC) {
180
	    copied = strlcpy(result + used, BC, length - used);
181
	    if (copied < length - used)
182
		used += copied;
183
	    else
184
		used += length - used - 1;
185
	}
186
	result[used] = '\0';
187
    }
188
    return result;
189
}
190
#endif
191
192
/*
193
 * Retained solely for upward compatibility.  Note the intentional reversing of
194
 * the last two arguments when invoking tparm().
195
 */
196
NCURSES_EXPORT(char *)
197
tgoto(const char *string, int x, int y)
198
{
199
    char *result;
200
201
    T((T_CALLED("tgoto(%s, %d, %d)"), _nc_visbuf(string), x, y));
202
#if !PURE_TERMINFO
203
8376
    if (is_termcap(string))
204
	result = tgoto_internal(string, x, y);
205
    else
206
#endif
207
4188
	result = TPARM_2((NCURSES_CONST char *) string, y, x);
208
4188
    returnPtr(result);
209
}