From 6dd0013a5d7cc8adc035c0e9b0e8ba741108fd90 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Jun 2012 10:30:05 -0700 Subject: [PATCH 01/14] Fix for extra space in some completions Addresses https://github.com/fish-shell/fish-shell/issues/60 --- reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reader.cpp b/reader.cpp index d23d8182e..62dacd15c 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1089,7 +1089,7 @@ static void run_pager( const wcstring &prefix, int is_quoted, const std::vector< { prefix_esc = escape_string(prefix, 1); } - + wcstring cmd = format_string(L"fish_pager -c 3 -r 4 %ls -p %ls", // L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./fish_pager %d %ls", is_quoted?L"-q":L"", @@ -1607,7 +1607,7 @@ static int handle_completions( const std::vector &comp ) 0, 0 ); - len = &buff[data->buff_pos]-prefix_start+1; + len = &buff[data->buff_pos]-prefix_start; if( len <= PREFIX_MAX_LEN ) { From 1d54bff385240d9f7fd1d3ad6df56e74ddd5ef49 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Jun 2012 12:30:20 -0700 Subject: [PATCH 02/14] Disble futimes() calls in hopes of fixing https://github.com/fish-shell/fish-shell/issues/122 This should keep sudo from thinking that the tty has changed as part of its tty_tickets feature. --- screen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/screen.cpp b/screen.cpp index 2596c42ad..79b7b7d14 100644 --- a/screen.cpp +++ b/screen.cpp @@ -327,6 +327,10 @@ static int room_for_usec(struct stat *st) 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 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( 2, t ); +#endif fstat( 1, &s->prev_buff_1 ); fstat( 2, &s->prev_buff_2 ); From afd8d2f9bae14cb3c263987a01aedb748b975176 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Jun 2012 13:05:58 -0700 Subject: [PATCH 03/14] Fix for https://github.com/fish-shell/fish-shell/issues/135 Don't use std::map::insert when we need to overwrite values --- env.cpp | 13 ++++++------- env_universal_common.cpp | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/env.cpp b/env.cpp index dd44b33c5..6e6a8d741 100644 --- a/env.cpp +++ b/env.cpp @@ -901,8 +901,7 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode) } entry->val = val; - - node->env.insert(std::pair(key, entry)); + node->env[key] = entry; if( entry->exportv ) { @@ -1397,7 +1396,8 @@ static void get_exported( const env_node_t *n, std::map &h ) var_entry_t *val_entry = iter->second; if( val_entry->exportv && (val_entry->val != ENV_NULL ) ) { - h.insert(std::pair(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 wchar_t *val = env_universal_get( key.c_str() ); - std::map::iterator result = vals.find( key ); - if( wcscmp( val, ENV_NULL) && ( result == vals.end() ) ) - { + if (wcscmp( val, ENV_NULL)) { + // Note that std::map::insert does NOT overwrite a value already in the map, + // which we depend on here vals.insert(std::pair(key, val)); } - } std::vector local_export_buffer; diff --git a/env_universal_common.cpp b/env_universal_common.cpp index 8704cc70d..d80a4d0d1 100644 --- a/env_universal_common.cpp +++ b/env_universal_common.cpp @@ -555,7 +555,7 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor entry->val = val; env_universal_common_remove( key ); - env_universal_var.insert( std::pair(key, entry)); + env_universal_var[key] = entry; if( callback ) { callback( exportv?SET_EXPORT:SET, key, val ); From 6cf42075fcbf4cb75fa00197f227b8a5eceae2bd Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Jun 2012 14:08:58 -0700 Subject: [PATCH 04/14] Fix to check for case insensitive filesystems in is_potential_path Addresses https://github.com/fish-shell/fish-shell/issues/119 --- highlight.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/highlight.cpp b/highlight.cpp index b74f52404..a43840a62 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -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 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! */ 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 */ std::set 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++) { 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 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 */ bool is_dir = false; 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; if (out_path) { @@ -213,10 +249,13 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct out_path->clear(); 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); if (! string_suffixes_string(L"/", *out_path)) out_path->push_back(L'/'); + printf("path: %ls\n", out_path->c_str()); } out_path->append(ent); /* We actually do want a trailing / for directories, since it makes autosuggestion a bit nicer */ From 34fd8e0e00a701f399b61e069c601c59e31b10e9 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Jun 2012 21:25:33 -0700 Subject: [PATCH 05/14] Tweak fork guards to be more forgiving Fixes https://github.com/fish-shell/fish-shell/issues/101 --- common.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common.cpp b/common.cpp index 0fec7fcf3..a7289e752 100644 --- a/common.cpp +++ b/common.cpp @@ -1943,9 +1943,12 @@ void configure_thread_assertions_for_testing(void) { } /* Notice when we've forked */ -static pid_t initial_pid; +static pid_t initial_pid = 0; 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); if (is_child_of_fork) { printf("Uh-oh: %d\n", getpid()); From 17567028dace634465b3a9af34c6338a832d05e1 Mon Sep 17 00:00:00 2001 From: Siteshwar Vashisht Date: Sun, 17 Jun 2012 11:25:21 +0530 Subject: [PATCH 06/14] Fixed a bug in wsetlocale() --- common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.cpp b/common.cpp index a7289e752..b6639e100 100644 --- a/common.cpp +++ b/common.cpp @@ -555,7 +555,7 @@ wcstring wsetlocale(int category, const wchar_t *locale) { char *lang = NULL; - if (locale && wcscmp(locale,L"")){ + if (locale){ lang = wcs2str( locale ); } char * res = setlocale(category,lang); From 27212719dc43c1069982ec1dd7389c76956aee2a Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 17 Jun 2012 13:20:22 -0700 Subject: [PATCH 07/14] Removed an errant printf --- highlight.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/highlight.cpp b/highlight.cpp index a43840a62..09a7666a3 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -255,7 +255,6 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct out_path->append(path_base); if (! string_suffixes_string(L"/", *out_path)) out_path->push_back(L'/'); - printf("path: %ls\n", out_path->c_str()); } out_path->append(ent); /* We actually do want a trailing / for directories, since it makes autosuggestion a bit nicer */ From ebfa285122b8660ef842f4d1d6ed194a002253b0 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 17 Jun 2012 14:46:24 -0700 Subject: [PATCH 08/14] Teach __fish_print_help.fish about the new man path --- share/functions/__fish_print_help.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_print_help.fish b/share/functions/__fish_print_help.fish index b213c8811..08a70f72e 100644 --- a/share/functions/__fish_print_help.fish +++ b/share/functions/__fish_print_help.fish @@ -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 # 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) # Print an empty line first From eebe12684275b11f8b284ba9dd1a69b865855106 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 17 Jun 2012 14:49:45 -0700 Subject: [PATCH 09/14] Fix for a busted format string --- builtin_set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin_set.cpp b/builtin_set.cpp index d55421d8e..fae6e5014 100644 --- a/builtin_set.cpp +++ b/builtin_set.cpp @@ -627,7 +627,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( erase ) { append_format(stderr_buffer, - _(L"%ls: Erase needs a variable name\n%ls\n"), + _(L"%ls: Erase needs a variable name\n"), argv[0] ); builtin_print_help( parser, argv[0], stderr_buffer ); From 1fa0c4d4d3ea5de180c3f64aa00c478c90f04904 Mon Sep 17 00:00:00 2001 From: Evan Jones Date: Sun, 17 Jun 2012 07:06:06 -0400 Subject: [PATCH 10/14] alias: Support seds that don't support \n in replacements. This makes the alias command work on Mac OS X. --- share/functions/alias.fish | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/functions/alias.fish b/share/functions/alias.fish index cc5dab98a..25eec3ea0 100644 --- a/share/functions/alias.fish +++ b/share/functions/alias.fish @@ -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." return 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 body $tmp[2] From 01780f19b1ffda0026e44a116d27d887dbfb096e Mon Sep 17 00:00:00 2001 From: Evan Jones Date: Sun, 17 Jun 2012 07:17:05 -0400 Subject: [PATCH 11/14] Fix other usages of \n in sed replacements. --- share/functions/__fish_complete_command.fish | 6 +++++- share/functions/__fish_complete_lpr_option.fish | 6 +++++- share/functions/__fish_print_make_targets.fish | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/share/functions/__fish_complete_command.fish b/share/functions/__fish_complete_command.fish index 8dc1d3114..983366db6 100644 --- a/share/functions/__fish_complete_command.fish +++ b/share/functions/__fish_complete_command.fish @@ -2,7 +2,11 @@ function __fish_complete_command --description 'Complete using all available com set -l ctoken (commandline -ct) switch $ctoken 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]) case '*' complete -C$ctoken diff --git a/share/functions/__fish_complete_lpr_option.fish b/share/functions/__fish_complete_lpr_option.fish index 287b13ebf..aa9d981f0 100644 --- a/share/functions/__fish_complete_lpr_option.fish +++ b/share/functions/__fish_complete_lpr_option.fish @@ -5,7 +5,11 @@ function __fish_complete_lpr_option --description 'Complete lpr option' set -l IFS = echo $optstr | read -l opt val 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] set descr $l continue diff --git a/share/functions/__fish_print_make_targets.fish b/share/functions/__fish_print_make_targets.fish index c57e88713..bda806f46 100644 --- a/share/functions/__fish_print_make_targets.fish +++ b/share/functions/__fish_print_make_targets.fish @@ -1,4 +1,8 @@ function __fish_print_make_targets 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 From 71f8960ef1d69e18ebe1485889cf7a880a2db831 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 18 Jun 2012 00:27:44 +0800 Subject: [PATCH 12/14] make clean should remove all generated documentation --- Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 9320c8cee..d1f880f40 100644 --- a/Makefile.in +++ b/Makefile.in @@ -932,11 +932,12 @@ clean: rm -f $(GENERATED_INTERN_SCRIPT_FILES) 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 command_list.txt toc.txt 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.gz rm -f fish-@PACKAGE_VERSION@.tar.bz2 - rm -rf doc; + rm -rf doc user_doc share/man; rm -rf fish-@PACKAGE_VERSION@ rm -f $(TRANSLATIONS) test ! -d "$(XSEL)" || make -C $(XSEL) clean From 6681f3bfec4d944a9e978aa7d5fd84363ca38cba Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 18 Jun 2012 00:29:11 +0800 Subject: [PATCH 13/14] only touch user_doc if doxygen installed If doxygen isn't installed, an empty file called user_doc will be created. If doxygen is later installed, the documentation will not generate correctly. --- Makefile.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.in b/Makefile.in index d1f880f40..b70dd6217 100644 --- a/Makefile.in +++ b/Makefile.in @@ -337,8 +337,7 @@ prof: user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) $(MAKE) doc.h $(HDR_FILES) - - doxygen Doxyfile.user - touch user_doc + - doxygen Doxyfile.user && touch user_doc # From 1bead8adf7e3139e0b4644a6215751fac60daddf Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 17 Jun 2012 15:19:55 -0700 Subject: [PATCH 14/14] Fix to create_manpage_completions.py to flush after every line (so you see more progress) and to put the cursor at the beginning (so it doesn't jump around) --- share/tools/create_manpage_completions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/tools/create_manpage_completions.py b/share/tools/create_manpage_completions.py index f0c814699..051a3a50c 100755 --- a/share/tools/create_manpage_completions.py +++ b/share/tools/create_manpage_completions.py @@ -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 padded_progress_str = progress_str.ljust(last_progress_string_length) 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: if parse_manpage_at_path(manpage_path, output_directory): successful_count += 1