Merge remote-tracking branch 'fishfish/master'

This commit is contained in:
maxfl 2012-06-18 10:29:42 +04:00
commit c0e60963c1
14 changed files with 88 additions and 26 deletions

View file

@ -337,8 +337,7 @@ prof:
user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC)
$(MAKE) doc.h $(HDR_FILES) $(MAKE) doc.h $(HDR_FILES)
- doxygen Doxyfile.user - doxygen Doxyfile.user && touch user_doc
touch user_doc
# #
@ -932,11 +931,12 @@ clean:
rm -f $(GENERATED_INTERN_SCRIPT_FILES) rm -f $(GENERATED_INTERN_SCRIPT_FILES)
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
rm -f command_list.txt toc.txt
rm -f share/config.fish etc/config.fish doc_src/index.hdr doc_src/commands.hdr rm -f share/config.fish etc/config.fish doc_src/index.hdr doc_src/commands.hdr
rm -f fish-@PACKAGE_VERSION@.tar rm -f fish-@PACKAGE_VERSION@.tar
rm -f fish-@PACKAGE_VERSION@.tar.gz rm -f fish-@PACKAGE_VERSION@.tar.gz
rm -f fish-@PACKAGE_VERSION@.tar.bz2 rm -f fish-@PACKAGE_VERSION@.tar.bz2
rm -rf doc; rm -rf doc user_doc share/man;
rm -rf fish-@PACKAGE_VERSION@ rm -rf fish-@PACKAGE_VERSION@
rm -f $(TRANSLATIONS) rm -f $(TRANSLATIONS)
test ! -d "$(XSEL)" || make -C $(XSEL) clean test ! -d "$(XSEL)" || make -C $(XSEL) clean

View file

@ -627,7 +627,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv )
if( erase ) if( erase )
{ {
append_format(stderr_buffer, append_format(stderr_buffer,
_(L"%ls: Erase needs a variable name\n%ls\n"), _(L"%ls: Erase needs a variable name\n"),
argv[0] ); argv[0] );
builtin_print_help( parser, argv[0], stderr_buffer ); builtin_print_help( parser, argv[0], stderr_buffer );

View file

@ -555,7 +555,7 @@ wcstring wsetlocale(int category, const wchar_t *locale)
{ {
char *lang = NULL; char *lang = NULL;
if (locale && wcscmp(locale,L"")){ if (locale){
lang = wcs2str( locale ); lang = wcs2str( locale );
} }
char * res = setlocale(category,lang); char * res = setlocale(category,lang);
@ -1943,9 +1943,12 @@ void configure_thread_assertions_for_testing(void) {
} }
/* Notice when we've forked */ /* Notice when we've forked */
static pid_t initial_pid; static pid_t initial_pid = 0;
bool is_forked_child(void) { bool is_forked_child(void) {
/* Just bail if nobody's called setup_fork_guards - e.g. fishd */
if (! initial_pid) return false;
bool is_child_of_fork = (getpid() != initial_pid); bool is_child_of_fork = (getpid() != initial_pid);
if (is_child_of_fork) { if (is_child_of_fork) {
printf("Uh-oh: %d\n", getpid()); printf("Uh-oh: %d\n", getpid());

13
env.cpp
View file

@ -901,8 +901,7 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
} }
entry->val = val; entry->val = val;
node->env[key] = entry;
node->env.insert(std::pair<wcstring, var_entry_t*>(key, entry));
if( entry->exportv ) if( entry->exportv )
{ {
@ -1397,7 +1396,8 @@ static void get_exported( const env_node_t *n, std::map<wcstring, wcstring> &h )
var_entry_t *val_entry = iter->second; var_entry_t *val_entry = iter->second;
if( val_entry->exportv && (val_entry->val != ENV_NULL ) ) if( val_entry->exportv && (val_entry->val != ENV_NULL ) )
{ {
h.insert(std::pair<wcstring, wcstring>(key, val_entry->val)); // Don't use std::map::insert here, since we need to overwrite existing values from previous scopes
h[key] = val_entry->val;
} }
} }
} }
@ -1455,12 +1455,11 @@ static void update_export_array_if_necessary(bool recalc) {
const wcstring &key = uni.at(i); const wcstring &key = uni.at(i);
const wchar_t *val = env_universal_get( key.c_str() ); const wchar_t *val = env_universal_get( key.c_str() );
std::map<wcstring, wcstring>::iterator result = vals.find( key ); if (wcscmp( val, ENV_NULL)) {
if( wcscmp( val, ENV_NULL) && ( result == vals.end() ) ) // Note that std::map::insert does NOT overwrite a value already in the map,
{ // which we depend on here
vals.insert(std::pair<wcstring, wcstring>(key, val)); vals.insert(std::pair<wcstring, wcstring>(key, val));
} }
} }
std::vector<std::string> local_export_buffer; std::vector<std::string> local_export_buffer;

View file

@ -555,7 +555,7 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor
entry->val = val; entry->val = val;
env_universal_common_remove( key ); env_universal_common_remove( key );
env_universal_var.insert( std::pair<wcstring, var_uni_entry_t*>(key, entry)); env_universal_var[key] = entry;
if( callback ) if( callback )
{ {
callback( exportv?SET_EXPORT:SET, key, val ); callback( exportv?SET_EXPORT:SET, key, val );

View file

@ -103,6 +103,28 @@ static wcstring apply_working_directory(const wcstring &path, const wcstring &wo
} }
} }
/* Determine if the filesystem containing the given fd is case insensitive. */
typedef std::map<wcstring, bool> case_sensitivity_cache_t;
bool fs_is_case_insensitive(const wcstring &path, int fd, case_sensitivity_cache_t &case_sensitivity_cache)
{
/* If _PC_CASE_SENSITIVE is not defined, assume case sensitive */
bool result = false;
#ifdef _PC_CASE_SENSITIVE
/* Try the cache first */
case_sensitivity_cache_t::iterator cache = case_sensitivity_cache.find(path);
if (cache != case_sensitivity_cache.end()) {
/* Use the cached value */
result = cache->second;
} else {
/* Ask the system. A -1 value means error (so assume case sensitive), a 1 value means case sensitive, and a 0 value means case insensitive */
long ret = fpathconf(fd, _PC_CASE_SENSITIVE);
result = (ret == 0);
case_sensitivity_cache[path] = result;
}
#endif
return result;
}
/* Tests whether the specified string cpath is the prefix of anything we could cd to. directories is a list of possible parent directories (typically either the working directory, or the cdpath). This does I/O! /* Tests whether the specified string cpath is the prefix of anything we could cd to. directories is a list of possible parent directories (typically either the working directory, or the cdpath). This does I/O!
*/ */
bool is_potential_path(const wcstring &const_path, const wcstring_list_t &directories, bool require_dir, wcstring *out_path) bool is_potential_path(const wcstring &const_path, const wcstring_list_t &directories, bool require_dir, wcstring *out_path)
@ -161,6 +183,9 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
/* Don't test the same path multiple times, which can happen if the path is absolute and the CDPATH contains multiple entries */ /* Don't test the same path multiple times, which can happen if the path is absolute and the CDPATH contains multiple entries */
std::set<wcstring> checked_paths; std::set<wcstring> checked_paths;
/* Keep a cache of which paths / filesystems are case sensitive */
case_sensitivity_cache_t case_sensitivity_cache;
for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++) { for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++) {
const wcstring &wd = directories.at(wd_idx); const wcstring &wd = directories.at(wd_idx);
@ -200,12 +225,23 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
// We opened the dir_name; look for a string where the base name prefixes it // We opened the dir_name; look for a string where the base name prefixes it
wcstring ent; wcstring ent;
// Check if we're case insensitive
bool case_insensitive = fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache);
// Don't ask for the is_dir value unless we care, because it can cause extra filesystem acces */ // Don't ask for the is_dir value unless we care, because it can cause extra filesystem acces */
bool is_dir = false; bool is_dir = false;
while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL)) while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL))
{ {
// TODO: support doing the right thing on case-insensitive filesystems like HFS+
if (string_prefixes_string(base_name, ent) && (! require_dir || is_dir)) /* Determine which function to call to check for prefixes */
bool (*prefix_func)(const wcstring &, const wcstring &);
if (case_insensitive) {
prefix_func = string_prefixes_string_case_insensitive;
} else {
prefix_func = string_prefixes_string;
}
if (prefix_func(base_name, ent) && (! require_dir || is_dir))
{ {
result = true; result = true;
if (out_path) { if (out_path) {
@ -213,7 +249,9 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
out_path->clear(); out_path->clear();
const wcstring path_base = wdirname(const_path); const wcstring path_base = wdirname(const_path);
if (string_prefixes_string(path_base, const_path)) {
if (prefix_func(path_base, const_path)) {
out_path->append(path_base); out_path->append(path_base);
if (! string_suffixes_string(L"/", *out_path)) if (! string_suffixes_string(L"/", *out_path))
out_path->push_back(L'/'); out_path->push_back(L'/');

View file

@ -1607,7 +1607,7 @@ static int handle_completions( const std::vector<completion_t> &comp )
0, 0,
0 ); 0 );
len = &buff[data->buff_pos]-prefix_start+1; len = &buff[data->buff_pos]-prefix_start;
if( len <= PREFIX_MAX_LEN ) if( len <= PREFIX_MAX_LEN )
{ {

View file

@ -327,6 +327,10 @@ static int room_for_usec(struct stat *st)
static void s_save_status( screen_t *s) static void s_save_status( screen_t *s)
{ {
// PCA Let's not do this futimes stuff, because sudo dumbly uses the
// tty's ctime as part of its tty_tickets feature
// Disabling this should fix https://github.com/fish-shell/fish-shell/issues/122
#if 0
/* /*
This futimes call tries to trick the system into using st_mtime This futimes call tries to trick the system into using st_mtime
as a tampering flag. This of course only works on systems where as a tampering flag. This of course only works on systems where
@ -354,6 +358,7 @@ static void s_save_status( screen_t *s)
*/ */
futimes( 1, t ); futimes( 1, t );
futimes( 2, t ); futimes( 2, t );
#endif
fstat( 1, &s->prev_buff_1 ); fstat( 1, &s->prev_buff_1 );
fstat( 2, &s->prev_buff_2 ); fstat( 2, &s->prev_buff_2 );

View file

@ -2,7 +2,11 @@ function __fish_complete_command --description 'Complete using all available com
set -l ctoken (commandline -ct) set -l ctoken (commandline -ct)
switch $ctoken switch $ctoken
case '*=*' case '*=*'
set ctoken (echo $ctoken | sed 's/=/\n/') # Some seds (e.g. on Mac OS X), don't support \n in the RHS
# Use a literal newline instead
# http://sed.sourceforge.net/sedfaq4.html#s4.1
set ctoken (echo $ctoken | sed 's/=/\\
/')
printf '%s\n' $ctoken[1]=(complete -C$ctoken[2]) printf '%s\n' $ctoken[1]=(complete -C$ctoken[2])
case '*' case '*'
complete -C$ctoken complete -C$ctoken

View file

@ -5,7 +5,11 @@ function __fish_complete_lpr_option --description 'Complete lpr option'
set -l IFS = set -l IFS =
echo $optstr | read -l opt val echo $optstr | read -l opt val
set -l descr set -l descr
for l in (lpoptions -l ^ /dev/null | grep $opt | sed 's+\(.*\)/\(.*\):\s*\(.*\)$+\2 \3+; s/ /\n/g;') # Some seds (e.g. on Mac OS X), don't support \n in the RHS
# Use a literal newline instead
# http://sed.sourceforge.net/sedfaq4.html#s4.1
for l in (lpoptions -l ^ /dev/null | grep $opt | sed 's+\(.*\)/\(.*\):\s*\(.*\)$+\2 \3+; s/ /\\
/g;')
if not set -q descr[1] if not set -q descr[1]
set descr $l set descr $l
continue continue

View file

@ -23,7 +23,7 @@ function __fish_print_help --description "Print help message for the specified f
set -l sed_cmd -e $cmd1 -e $cmd2 -e $cmd3 set -l sed_cmd -e $cmd1 -e $cmd2 -e $cmd3
# Render help output, save output into the variable 'help' # Render help output, save output into the variable 'help'
set -l help (nroff -man $__fish_datadir/man/$item.1) set -l help (nroff -man $__fish_datadir/man/man1/$item.1)
set -l lines (count $help) set -l lines (count $help)
# Print an empty line first # Print an empty line first

View file

@ -1,4 +1,8 @@
function __fish_print_make_targets function __fish_print_make_targets
set files Makefile makefile GNUmakefile set files Makefile makefile GNUmakefile
sgrep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\n/g' ^/dev/null # Some seds (e.g. on Mac OS X), don't support \n in the RHS
# Use a literal newline instead
# http://sed.sourceforge.net/sedfaq4.html#s4.1
sgrep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\\
/g' ^/dev/null
end end

View file

@ -17,7 +17,11 @@ function alias --description "Legacy function for creating shellscript functions
echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information." echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information."
return 1 return 1
case 1 case 1
set -l tmp (echo $argv|sed -e "s/\([^=]\)=/\1\n/") # Some seds (e.g. on Mac OS X), don't support \n in the RHS
# Use a literal newline instead
# http://sed.sourceforge.net/sedfaq4.html#s4.1
set -l tmp (echo $argv|sed -e "s/\([^=]\)=/\1\\
/")
set name $tmp[1] set name $tmp[1]
set body $tmp[2] set body $tmp[2]

View file

@ -753,7 +753,8 @@ def parse_and_output_man_pages(paths, output_directory, show_progress):
# Pad on the right with spaces so we overwrite whatever we wrote last time # Pad on the right with spaces so we overwrite whatever we wrote last time
padded_progress_str = progress_str.ljust(last_progress_string_length) padded_progress_str = progress_str.ljust(last_progress_string_length)
last_progress_string_length = len(progress_str) last_progress_string_length = len(progress_str)
sys.stdout.write("\r\r{0} {1}".format(padded_progress_str, chr(27))) sys.stdout.write("\r{0} {1}\r".format(padded_progress_str, chr(27)))
sys.stdout.flush();
try: try:
if parse_manpage_at_path(manpage_path, output_directory): if parse_manpage_at_path(manpage_path, output_directory):
successful_count += 1 successful_count += 1