X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fdb_iterator.c;h=7fd791825c931ea897a92a080eb18013eba4c58c;hp=90e73d6bc5990d75160bebe28003389a1bb39389;hb=30393be892025f03322b7907a04cc05cc08e8760;hpb=55051e74621a33ee60ea8e38fe1e0a3e38a573ab diff --git a/ncurses/tinfo/db_iterator.c b/ncurses/tinfo/db_iterator.c index 90e73d6b..7fd79182 100644 --- a/ncurses/tinfo/db_iterator.c +++ b/ncurses/tinfo/db_iterator.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2006-2011,2012 Free Software Foundation, Inc. * + * Copyright (c) 2006-2016,2017 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 * @@ -43,7 +43,7 @@ #include #endif -MODULE_ID("$Id: db_iterator.c,v 1.35 2012/08/25 21:55:00 tom Exp $") +MODULE_ID("$Id: db_iterator.c,v 1.46 2017/07/01 22:54:42 tom Exp $") #define HaveTicDirectory _nc_globals.have_tic_directory #define KeepTicDirectory _nc_globals.keep_tic_directory @@ -72,15 +72,18 @@ check_existence(const char *name, struct stat *sb) { 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; } } @@ -88,6 +91,27 @@ check_existence(const char *name, struct stat *sb) 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. @@ -99,19 +123,21 @@ update_getenv(const char *name, DBDIRS which) if (which < dbdLAST) { 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; @@ -185,10 +211,12 @@ _nc_tic_dir(const char *path) 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; @@ -249,7 +277,7 @@ _nc_first_db(DBDIRS * state, int *offset) *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. @@ -258,7 +286,7 @@ _nc_first_db(DBDIRS * state, int *offset) size_t blobsize = 0; const char *values[dbdLAST]; struct stat *my_stat; - int j, k; + int j; if (cache_has_expired) free_cache(); @@ -272,7 +300,7 @@ _nc_first_db(DBDIRS * state, int *offset) */ values[dbdTIC] = TicDirectory; -#if USE_DATABASE +#if NCURSES_USE_DATABASE #ifdef TERMINFO_DIRS values[dbdCfgList] = TERMINFO_DIRS; #endif @@ -281,19 +309,19 @@ _nc_first_db(DBDIRS * state, int *offset) #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 @@ -301,7 +329,7 @@ _nc_first_db(DBDIRS * state, int *offset) values[dbdEnvOnce2] = 0; } values[dbdEnvList2] = cache_getenv("TERMPATH", dbdEnvList2); -#endif /* USE_TERMCAP */ +#endif /* NCURSES_USE_TERMCAP */ } for (j = 0; j < dbdLAST; ++j) { @@ -328,10 +356,12 @@ _nc_first_db(DBDIRS * state, int *offset) 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]; } @@ -345,8 +375,10 @@ _nc_first_db(DBDIRS * state, int *offset) 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; @@ -375,6 +407,7 @@ _nc_first_db(DBDIRS * state, int *offset) } #endif if (!found) { + T(("not found %s", my_list[j])); k = j; while ((my_list[k] = my_list[k + 1]) != 0) { ++k; @@ -390,6 +423,7 @@ _nc_first_db(DBDIRS * state, int *offset) free(my_stat); } } + returnVoid; } #if NO_LEAKS