/****************************************************************************
- * Copyright (c) 2006-2011,2012 Free Software Foundation, Inc. *
+ * Copyright (c) 2006-2017,2018 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include <hashed_db.h>
#endif
-MODULE_ID("$Id: db_iterator.c,v 1.33 2012/06/23 00:16:58 tom Exp $")
+MODULE_ID("$Id: db_iterator.c,v 1.47 2018/11/24 22:42:01 tom Exp $")
#define HaveTicDirectory _nc_globals.have_tic_directory
#define KeepTicDirectory _nc_globals.keep_tic_directory
{
bool result = FALSE;
- if (stat(name, sb) == 0
- && (S_ISDIR(sb->st_mode) || S_ISREG(sb->st_mode))) {
+ if (quick_prefix(name)) {
+ result = TRUE;
+ } else if (stat(name, sb) == 0
+ && (S_ISDIR(sb->st_mode)
+ || (S_ISREG(sb->st_mode) && sb->st_size))) {
result = TRUE;
}
#if USE_HASHED_DB
else if (strlen(name) < PATH_MAX - sizeof(DBM_SUFFIX)) {
char temp[PATH_MAX];
_nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp)) "%s%s", name, DBM_SUFFIX);
- if (stat(temp, sb) == 0 && S_ISREG(sb->st_mode)) {
+ if (stat(temp, sb) == 0 && S_ISREG(sb->st_mode) && sb->st_size) {
result = TRUE;
}
}
return result;
}
+/*
+ * Trim newlines (and backslashes preceding those) and tab characters to
+ * help simplify scripting of the quick-dump feature. Leave spaces and
+ * other backslashes alone.
+ */
+static void
+trim_formatting(char *source)
+{
+ char *target = source;
+ char ch;
+
+ while ((ch = *source++) != '\0') {
+ if (ch == '\\' && *source == '\n')
+ continue;
+ if (ch == '\n' || ch == '\t')
+ continue;
+ *target++ = ch;
+ }
+ *target = '\0';
+}
+
/*
* Store the latest value of an environment variable in my_vars[] so we can
* detect if one changes, invalidating the cached search-list.
bool result = FALSE;
if (which < dbdLAST) {
- char *value = getenv(name);
+ char *value;
+ char *cached_value = my_vars[which].value;
+ bool same_value;
- if ((value = getenv(name)) == 0 || (value = strdup(value)) == 0) {
- ;
- } else if (my_vars[which].name == 0 || strcmp(my_vars[which].name, name)) {
- FreeIfNeeded(my_vars[which].value);
- my_vars[which].name = name;
- my_vars[which].value = value;
- result = TRUE;
- } else if ((my_vars[which].value != 0) ^ (value != 0)) {
- FreeIfNeeded(my_vars[which].value);
- my_vars[which].value = value;
- result = TRUE;
- } else if (value != 0 && strcmp(value, my_vars[which].value)) {
+ if ((value = getenv(name)) != 0) {
+ value = strdup(value);
+ }
+ same_value = ((value == 0 && cached_value == 0) ||
+ (value != 0 &&
+ cached_value != 0 &&
+ strcmp(value, cached_value) == 0));
+
+ /* Set variable name to enable checks in cache_expired(). */
+ my_vars[which].name = name;
+
+ if (!same_value) {
FreeIfNeeded(my_vars[which].value);
my_vars[which].value = value;
result = TRUE;
return result;
}
+#if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
static char *
cache_getenv(const char *name, DBDIRS which)
{
}
return result;
}
+#endif
/*
* The cache expires if at least a second has passed since the initial lookup,
if (path != 0) {
TicDirectory = path;
HaveTicDirectory = TRUE;
- } else if (!HaveTicDirectory && use_terminfo_vars()) {
- char *envp;
- if ((envp = getenv("TERMINFO")) != 0)
- return _nc_tic_dir(envp);
+ } else if (HaveTicDirectory == 0) {
+ if (use_terminfo_vars()) {
+ const char *envp;
+ if ((envp = getenv("TERMINFO")) != 0)
+ return _nc_tic_dir(envp);
+ }
}
}
return TicDirectory ? TicDirectory : TERMINFO;
*state = dbdTIC;
*offset = 0;
- T(("_nc_first_db"));
+ T((T_CALLED("_nc_first_db")));
/* build a blob containing all of the strings we will use for a lookup
* table.
size_t blobsize = 0;
const char *values[dbdLAST];
struct stat *my_stat;
- int j, k;
+ int j;
if (cache_has_expired)
free_cache();
*/
values[dbdTIC] = TicDirectory;
-#if USE_DATABASE
+#if NCURSES_USE_DATABASE
#ifdef TERMINFO_DIRS
values[dbdCfgList] = TERMINFO_DIRS;
#endif
#endif
#endif
-#if USE_TERMCAP
+#if NCURSES_USE_TERMCAP
values[dbdCfgList2] = TERMPATH;
#endif
if (use_terminfo_vars()) {
-#if USE_DATABASE
+#if NCURSES_USE_DATABASE
values[dbdEnvOnce] = cache_getenv("TERMINFO", dbdEnvOnce);
values[dbdHome] = _nc_home_terminfo();
(void) cache_getenv("HOME", dbdHome);
values[dbdEnvList] = cache_getenv("TERMINFO_DIRS", dbdEnvList);
#endif
-#if USE_TERMCAP
+#if NCURSES_USE_TERMCAP
values[dbdEnvOnce2] = cache_getenv("TERMCAP", dbdEnvOnce2);
/* only use $TERMCAP if it is an absolute path */
if (values[dbdEnvOnce2] != 0
values[dbdEnvOnce2] = 0;
}
values[dbdEnvList2] = cache_getenv("TERMPATH", dbdEnvList2);
-#endif /* USE_TERMCAP */
+#endif /* NCURSES_USE_TERMCAP */
}
for (j = 0; j < dbdLAST; ++j) {
my_list = typeCalloc(char *, blobsize);
my_stat = typeCalloc(struct stat, blobsize);
if (my_list != 0 && my_stat != 0) {
- k = 0;
+ int k = 0;
my_list[k++] = my_blob;
for (j = 0; my_blob[j] != '\0'; ++j) {
- if (my_blob[j] == NCURSES_PATHSEP) {
+ if (my_blob[j] == NCURSES_PATHSEP
+ && ((&my_blob[j] - my_list[k - 1]) != 3
+ || !quick_prefix(my_list[k - 1]))) {
my_blob[j] = '\0';
my_list[k++] = &my_blob[j + 1];
}
if (*my_list[j] == '\0')
my_list[j] = strdup(TERMINFO);
#endif
+ trim_formatting(my_list[j]);
for (k = 0; k < j; ++k) {
if (!strcmp(my_list[j], my_list[k])) {
+ T(("duplicate %s", my_list[j]));
k = j - 1;
while ((my_list[j] = my_list[j + 1]) != 0) {
++j;
}
#endif
if (!found) {
+ T(("not found %s", my_list[j]));
k = j;
while ((my_list[k] = my_list[k + 1]) != 0) {
++k;
free(my_stat);
}
}
+ returnVoid;
}
#if NO_LEAKS
FreeAndNull(my_blob);
if (my_list != 0)
FreeAndNull(my_list);
- for (which = 0; which < dbdLAST; ++which) {
+ for (which = 0; (int) which < dbdLAST; ++which) {
my_vars[which].name = 0;
FreeIfNeeded(my_vars[which].value);
my_vars[which].value = 0;