GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcurses/tinfo/db_iterator.c Lines: 41 61 67.2 %
Date: 2017-11-13 Branches: 31 58 53.4 %

Line Branch Exec Source
1
/* $OpenBSD: db_iterator.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
2
3
/****************************************************************************
4
 * Copyright (c) 2006,2007 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
/*
36
 * Iterators for terminal databases.
37
 */
38
39
#include <curses.priv.h>
40
41
#include <tic.h>
42
43
MODULE_ID("$Id: db_iterator.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
44
45
#define HaveTicDirectory _nc_globals.have_tic_directory
46
#define KeepTicDirectory _nc_globals.keep_tic_directory
47
#define TicDirectory     _nc_globals.tic_directory
48
49
/*
50
 * Record the "official" location of the terminfo directory, according to
51
 * the place where we're writing to, or the normal default, if not.
52
 */
53
NCURSES_EXPORT(const char *)
54
_nc_tic_dir(const char *path)
55
{
56
    if (!KeepTicDirectory) {
57
	if (path != 0) {
58
	    TicDirectory = path;
59
	    HaveTicDirectory = TRUE;
60
	} else if (!HaveTicDirectory && use_terminfo_vars()) {
61
	    char *envp;
62
	    if ((envp = getenv("TERMINFO")) != 0)
63
		return _nc_tic_dir(envp);
64
	}
65
    }
66
    return TicDirectory;
67
}
68
69
/*
70
 * Special fix to prevent the terminfo directory from being moved after tic
71
 * has chdir'd to it.  If we let it be changed, then if $TERMINFO has a
72
 * relative path, we'll lose track of the actual directory.
73
 */
74
NCURSES_EXPORT(void)
75
_nc_keep_tic_dir(const char *path)
76
{
77
    _nc_tic_dir(path);
78
    KeepTicDirectory = TRUE;
79
}
80
81
/*
82
 * Process the list of :-separated directories, looking for the terminal type.
83
 * We don't use strtok because it does not show us empty tokens.
84
 */
85
#define ThisDbList	_nc_globals.dbi_list
86
#define ThisDbSize	_nc_globals.dbi_size
87
88
/*
89
 * Cleanup.
90
 */
91
NCURSES_EXPORT(void)
92
_nc_last_db(void)
93
{
94
30
    if (ThisDbList != 0) {
95
3
	FreeAndNull(ThisDbList);
96
3
    }
97
15
    ThisDbSize = 0;
98
15
}
99
100
/* The TERMINFO_DIRS value, if defined by the configure script, begins with a
101
 * ":", which will be interpreted as TERMINFO.
102
 */
103
static const char *
104
next_list_item(const char *source, int *offset)
105
{
106
12
    if (source != 0) {
107
3
	FreeIfNeeded(ThisDbList);
108
3
	ThisDbList = strdup(source);
109
3
	ThisDbSize = strlen(source);
110
3
    }
111
112

9
    if (ThisDbList != 0 && ThisDbSize && *offset < ThisDbSize) {
113
	static char system_db[] = TERMINFO;
114
3
	char *result = ThisDbList + *offset;
115
3
	char *marker = strchr(result, NCURSES_PATHSEP);
116
117
	/*
118
	 * Put a null on the marker if a separator was found.  Set the offset
119
	 * to the next position after the marker so we can call this function
120
	 * again, using the data at the offset.
121
	 */
122
3
	if (marker == 0) {
123
	    *offset += strlen(result) + 1;
124
	    marker = result + *offset;
125
	} else {
126
3
	    *marker++ = 0;
127
3
	    *offset = marker - ThisDbList;
128
	}
129

3
	if (*result == 0 && result != (ThisDbList + ThisDbSize))
130
	    result = system_db;
131
	return result;
132
    }
133
3
    return 0;
134
6
}
135
136
#define NEXT_DBD(var, offset) next_list_item((*offset == 0) ? var : 0, offset)
137
138
/*
139
 * This is a simple iterator which allows the caller to step through the
140
 * possible locations for a terminfo directory.  ncurses uses this to find
141
 * terminfo files to read.
142
 */
143
NCURSES_EXPORT(const char *)
144
_nc_next_db(DBDIRS * state, int *offset)
145
{
146
    const char *result;
147
    char *envp;
148
149
36
    while (*state < dbdLAST) {
150
30
	DBDIRS next = (DBDIRS) ((int) (*state) + 1);
151
152
	result = 0;
153
154

30
	switch (*state) {
155
	case dbdTIC:
156
3
	    if (HaveTicDirectory)
157
		result = _nc_tic_dir(0);
158
	    break;
159
#if USE_DATABASE
160
	case dbdEnvOnce:
161
3
	    if (use_terminfo_vars()) {
162
3
		if ((envp = getenv("TERMINFO")) != 0)
163
		    result = _nc_tic_dir(envp);
164
	    }
165
	    break;
166
	case dbdHome:
167
3
	    if (use_terminfo_vars()) {
168
3
		result = _nc_home_terminfo();
169
3
	    }
170
	    break;
171
	case dbdEnvList:
172
3
	    if (use_terminfo_vars()) {
173

9
		if ((result = NEXT_DBD(getenv("TERMINFO_DIRS"), offset)) != 0)
174
		    next = *state;
175
	    }
176
	    break;
177
	case dbdCfgList:
178
#ifdef TERMINFO_DIRS
179
3
	    if ((result = NEXT_DBD(TERMINFO_DIRS, offset)) != 0)
180
3
		next = *state;
181
#endif
182
	    break;
183
	case dbdCfgOnce:
184
#ifndef TERMINFO_DIRS
185
	    result = TERMINFO;
186
#endif
187
	    break;
188
#endif /* USE_DATABASE */
189
#if USE_TERMCAP
190
	case dbdEnvOnce2:
191
	    if (use_terminfo_vars()) {
192
		if ((envp = getenv("TERMCAP")) != 0)
193
		    result = _nc_tic_dir(envp);
194
	    }
195
	    break;
196
	case dbdEnvList2:
197
	    if (use_terminfo_vars()) {
198
		if ((result = NEXT_DBD(getenv("TERMPATH"), offset)) != 0)
199
		    next = *state;
200
	    }
201
	    break;
202
	case dbdCfgList2:
203
	    if ((result = NEXT_DBD(TERMPATH, offset)) != 0)
204
		next = *state;
205
	    break;
206
#endif /* USE_TERMCAP */
207
	case dbdLAST:
208
	    break;
209
	}
210
15
	if (*state != next) {
211
12
	    *state = next;
212
12
	    *offset = 0;
213
12
	    _nc_last_db();
214
12
	}
215
15
	if (result != 0) {
216
6
	    return result;
217
	}
218
9
    }
219
    return 0;
220
6
}
221
222
NCURSES_EXPORT(void)
223
_nc_first_db(DBDIRS * state, int *offset)
224
{
225
    *state = dbdTIC;
226
    *offset = 0;
227
}