]> git.pld-linux.org Git - packages/bash.git/blame - bash42-029
up to 4.2.45
[packages/bash.git] / bash42-029
CommitLineData
e5ec3c9c
ER
1 BASH PATCH REPORT
2 =================
3
4Bash-Release: 4.2
5Patch-ID: bash42-029
6
7Bug-Reported-by: "Michael Kalisz" <michael@kalisz.homelinux.net>
8Bug-Reference-ID: <50241.78.69.11.112.1298585641.squirrel@kalisz.homelinux.net>
9Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00274.html
10
11Bug-Description:
12
13Bash-4.2 tries to leave completed directory names as the user typed them,
14without expanding them to a full pathname. One effect of this is that
15shell variables used in pathnames being completed (e.g., $HOME) are left
16unchanged, but the `$' is quoted by readline because it is a special
17character to the shell.
18
19This patch introduces two things:
20
211. A new shell option, `direxpand', which, if set, attempts to emulate the
22 bash-4.1 behavior of expanding words to full pathnames during
23 completion;
242. A set of heuristics that reduce the number of times special characters
25 such as `$' are quoted when the directory name is not expanded.
26
27Patch (apply with `patch -p0'):
28
29diff -NrC 2 ../bash-4.2-patched/bashline.c ./bashline.c
30*** ../bash-4.2-patched/bashline.c 2011-01-16 15:32:47.000000000 -0500
31--- ./bashline.c 2012-05-07 16:27:18.000000000 -0400
32***************
33*** 122,125 ****
34--- 122,128 ----
35 static int bash_push_line __P((void));
36
37+ static rl_icppfunc_t *save_directory_hook __P((void));
38+ static void reset_directory_hook __P((rl_icppfunc_t *));
39+
40 static void cleanup_expansion_error __P((void));
41 static void maybe_make_readline_line __P((char *));
42***************
43*** 244,251 ****
44--- 247,261 ----
45 int dircomplete_spelling = 0;
46
47+ /* Expand directory names during word/filename completion. */
48+ int dircomplete_expand = 0;
49+ int dircomplete_expand_relpath = 0;
50+
51 static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
52 static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
53 /* )) */
54
55+ static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
56+ static char *custom_filename_quote_characters = 0;
57+
58 static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
59
60***************
61*** 502,506 ****
62 /* Tell the completer that we might want to follow symbolic links or
63 do other expansion on directory names. */
64! rl_directory_rewrite_hook = bash_directory_completion_hook;
65
66 rl_filename_rewrite_hook = bash_filename_rewrite_hook;
67--- 512,516 ----
68 /* Tell the completer that we might want to follow symbolic links or
69 do other expansion on directory names. */
70! set_directory_hook ();
71
72 rl_filename_rewrite_hook = bash_filename_rewrite_hook;
73***************
74*** 530,534 ****
75
76 /* characters that need to be quoted when appearing in filenames. */
77! rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
78
79 rl_filename_quoting_function = bash_quote_filename;
80--- 540,544 ----
81
82 /* characters that need to be quoted when appearing in filenames. */
83! rl_filename_quote_characters = default_filename_quote_characters;
84
85 rl_filename_quoting_function = bash_quote_filename;
86***************
87*** 565,570 ****
88 rl_attempted_completion_function = attempt_shell_completion;
89 rl_completion_entry_function = NULL;
90- rl_directory_rewrite_hook = bash_directory_completion_hook;
91 rl_ignore_some_completions_function = filename_completion_ignore;
92 }
93
94--- 575,582 ----
95 rl_attempted_completion_function = attempt_shell_completion;
96 rl_completion_entry_function = NULL;
97 rl_ignore_some_completions_function = filename_completion_ignore;
98+ rl_filename_quote_characters = default_filename_quote_characters;
99+
100+ set_directory_hook ();
101 }
102
103***************
104*** 1280,1283 ****
105--- 1292,1298 ----
106 rl_ignore_some_completions_function = filename_completion_ignore;
107
108+ rl_filename_quote_characters = default_filename_quote_characters;
109+ set_directory_hook ();
110+
111 /* Determine if this could be a command word. It is if it appears at
112 the start of the line (ignoring preceding whitespace), or if it
113***************
114*** 1592,1595 ****
115--- 1607,1616 ----
116 else
117 {
118+ if (dircomplete_expand && dot_or_dotdot (filename_hint))
119+ {
120+ dircomplete_expand = 0;
121+ set_directory_hook ();
122+ dircomplete_expand = 1;
123+ }
124 mapping_over = 4;
125 goto inner;
126***************
127*** 1792,1795 ****
128--- 1813,1819 ----
129 inner:
130 val = rl_filename_completion_function (filename_hint, istate);
131+ if (mapping_over == 4 && dircomplete_expand)
132+ set_directory_hook ();
133+
134 istate = 1;
135
136***************
137*** 2694,2697 ****
138--- 2718,2767 ----
139 }
140
141+ /* Functions to save and restore the appropriate directory hook */
142+ /* This is not static so the shopt code can call it */
143+ void
144+ set_directory_hook ()
145+ {
146+ if (dircomplete_expand)
147+ {
148+ rl_directory_completion_hook = bash_directory_completion_hook;
149+ rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
150+ }
151+ else
152+ {
153+ rl_directory_rewrite_hook = bash_directory_completion_hook;
154+ rl_directory_completion_hook = (rl_icppfunc_t *)0;
155+ }
156+ }
157+
158+ static rl_icppfunc_t *
159+ save_directory_hook ()
160+ {
161+ rl_icppfunc_t *ret;
162+
163+ if (dircomplete_expand)
164+ {
165+ ret = rl_directory_completion_hook;
166+ rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
167+ }
168+ else
169+ {
170+ ret = rl_directory_rewrite_hook;
171+ rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
172+ }
173+
174+ return ret;
175+ }
176+
177+ static void
178+ restore_directory_hook (hookf)
179+ rl_icppfunc_t *hookf;
180+ {
181+ if (dircomplete_expand)
182+ rl_directory_completion_hook = hookf;
183+ else
184+ rl_directory_rewrite_hook = hookf;
185+ }
186+
187 /* Handle symbolic link references and other directory name
188 expansions while hacking completion. This should return 1 if it modifies
189***************
190*** 2703,2720 ****
191 {
192 char *local_dirname, *new_dirname, *t;
193! int return_value, should_expand_dirname;
194 WORD_LIST *wl;
195 struct stat sb;
196
197! return_value = should_expand_dirname = 0;
198 local_dirname = *dirname;
199
200! if (mbschr (local_dirname, '$'))
201! should_expand_dirname = 1;
202 else
203 {
204 t = mbschr (local_dirname, '`');
205 if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
206! should_expand_dirname = 1;
207 }
208
209--- 2773,2801 ----
210 {
211 char *local_dirname, *new_dirname, *t;
212! int return_value, should_expand_dirname, nextch, closer;
213 WORD_LIST *wl;
214 struct stat sb;
215
216! return_value = should_expand_dirname = nextch = closer = 0;
217 local_dirname = *dirname;
218
219! if (t = mbschr (local_dirname, '$'))
220! {
221! should_expand_dirname = '$';
222! nextch = t[1];
223! /* Deliberately does not handle the deprecated $[...] arithmetic
224! expansion syntax */
225! if (nextch == '(')
226! closer = ')';
227! else if (nextch == '{')
228! closer = '}';
229! else
230! nextch = 0;
231! }
232 else
233 {
234 t = mbschr (local_dirname, '`');
235 if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
236! should_expand_dirname = '`';
237 }
238
239***************
240*** 2740,2743 ****
241--- 2821,2841 ----
242 dispose_words (wl);
243 local_dirname = *dirname;
244+ /* XXX - change rl_filename_quote_characters here based on
245+ should_expand_dirname/nextch/closer. This is the only place
246+ custom_filename_quote_characters is modified. */
247+ if (rl_filename_quote_characters && *rl_filename_quote_characters)
248+ {
249+ int i, j, c;
250+ i = strlen (default_filename_quote_characters);
251+ custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
252+ for (i = j = 0; c = default_filename_quote_characters[i]; i++)
253+ {
254+ if (c == should_expand_dirname || c == nextch || c == closer)
255+ continue;
256+ custom_filename_quote_characters[j++] = c;
257+ }
258+ custom_filename_quote_characters[j] = '\0';
259+ rl_filename_quote_characters = custom_filename_quote_characters;
260+ }
261 }
262 else
263***************
264*** 2759,2762 ****
265--- 2857,2871 ----
266 }
267
268+ /* no_symbolic_links == 0 -> use (default) logical view of the file system.
269+ local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
270+ current directory (./).
271+ local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
272+ in the current directory (e.g., lib/sh).
273+ XXX - should we do spelling correction on these? */
274+
275+ /* This is test as it was in bash-4.2: skip relative pathnames in current
276+ directory. Change test to
277+ (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
278+ if we want to skip paths beginning with ./ also. */
279 if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
280 {
281***************
282*** 2764,2767 ****
283--- 2873,2885 ----
284 int len1, len2;
285
286+ /* If we have a relative path
287+ (local_dirname[0] != '/' && local_dirname[0] != '.')
288+ that is canonical after appending it to the current directory, then
289+ temp1 = temp2+'/'
290+ That is,
291+ strcmp (temp1, temp2) == 0
292+ after adding a slash to temp2 below. It should be safe to not
293+ change those.
294+ */
295 t = get_working_directory ("symlink-hook");
296 temp1 = make_absolute (local_dirname, t);
297***************
298*** 2798,2802 ****
299 }
300 }
301! return_value |= STREQ (local_dirname, temp2) == 0;
302 free (local_dirname);
303 *dirname = temp2;
304--- 2916,2928 ----
305 }
306 }
307!
308! /* dircomplete_expand_relpath == 0 means we want to leave relative
309! pathnames that are unchanged by canonicalization alone.
310! *local_dirname != '/' && *local_dirname != '.' == relative pathname
311! (consistent with general.c:absolute_pathname())
312! temp1 == temp2 (after appending a slash to temp2) means the pathname
313! is not changed by canonicalization as described above. */
314! if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
315! return_value |= STREQ (local_dirname, temp2) == 0;
316 free (local_dirname);
317 *dirname = temp2;
318***************
319*** 3003,3012 ****
320 orig_func = rl_completion_entry_function;
321 orig_attempt_func = rl_attempted_completion_function;
322- orig_dir_func = rl_directory_rewrite_hook;
323 orig_ignore_func = rl_ignore_some_completions_function;
324 orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
325 rl_completion_entry_function = rl_filename_completion_function;
326 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
327- rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
328 rl_ignore_some_completions_function = filename_completion_ignore;
329 rl_completer_word_break_characters = " \t\n\"\'";
330--- 3129,3139 ----
331 orig_func = rl_completion_entry_function;
332 orig_attempt_func = rl_attempted_completion_function;
333 orig_ignore_func = rl_ignore_some_completions_function;
334 orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
335+
336+ orig_dir_func = save_directory_hook ();
337+
338 rl_completion_entry_function = rl_filename_completion_function;
339 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
340 rl_ignore_some_completions_function = filename_completion_ignore;
341 rl_completer_word_break_characters = " \t\n\"\'";
342***************
343*** 3016,3023 ****
344 rl_completion_entry_function = orig_func;
345 rl_attempted_completion_function = orig_attempt_func;
346- rl_directory_rewrite_hook = orig_dir_func;
347 rl_ignore_some_completions_function = orig_ignore_func;
348 rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
349
350 return r;
351 }
352--- 3143,3151 ----
353 rl_completion_entry_function = orig_func;
354 rl_attempted_completion_function = orig_attempt_func;
355 rl_ignore_some_completions_function = orig_ignore_func;
356 rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
357
358+ restore_directory_hook (orig_dir_func);
359+
360 return r;
361 }
362diff -NrC 2 ../bash-4.2-patched/bashline.h ./bashline.h
363*** ../bash-4.2-patched/bashline.h 2009-01-04 14:32:22.000000000 -0500
364--- ./bashline.h 2012-05-07 16:27:18.000000000 -0400
365***************
366*** 34,41 ****
367--- 34,46 ----
368 extern int bash_re_edit __P((char *));
369
370+ extern void bashline_set_event_hook __P((void));
371+ extern void bashline_reset_event_hook __P((void));
372+
373 extern int bind_keyseq_to_unix_command __P((char *));
374
375 extern char **bash_default_completion __P((const char *, int, int, int, int));
376
377+ void set_directory_hook __P((void));
378+
379 /* Used by programmable completion code. */
380 extern char *command_word_completion_function __P((const char *, int));
381diff -NrC 2 ../bash-4.2-patched/builtins/shopt.def ./builtins/shopt.def
382*** ../bash-4.2-patched/builtins/shopt.def 2010-07-02 22:42:44.000000000 -0400
383--- ./builtins/shopt.def 2012-05-07 16:27:18.000000000 -0400
384***************
385*** 62,65 ****
386--- 62,69 ----
387 #include "bashgetopt.h"
388
389+ #if defined (READLINE)
390+ # include "../bashline.h"
391+ #endif
392+
393 #if defined (HISTORY)
394 # include "../bashhist.h"
395***************
396*** 95,99 ****
397 extern int no_empty_command_completion;
398 extern int force_fignore;
399! extern int dircomplete_spelling;
400
401 extern int enable_hostname_completion __P((int));
402--- 99,103 ----
403 extern int no_empty_command_completion;
404 extern int force_fignore;
405! extern int dircomplete_spelling, dircomplete_expand;
406
407 extern int enable_hostname_completion __P((int));
408***************
409*** 122,125 ****
410--- 126,133 ----
411 #endif
412
413+ #if defined (READLINE)
414+ static int shopt_set_complete_direxpand __P((char *, int));
415+ #endif
416+
417 static int shopt_login_shell;
418 static int shopt_compat31;
419***************
420*** 151,154 ****
421--- 159,163 ----
422 { "compat41", &shopt_compat41, set_compatibility_level },
423 #if defined (READLINE)
424+ { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
425 { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
426 #endif
427***************
428*** 536,539 ****
429--- 545,559 ----
430 }
431
432+ #if defined (READLINE)
433+ static int
434+ shopt_set_complete_direxpand (option_name, mode)
435+ char *option_name;
436+ int mode;
437+ {
438+ set_directory_hook ();
439+ return 0;
440+ }
441+ #endif
442+
443 #if defined (RESTRICTED_SHELL)
444 /* Don't allow the value of restricted_shell to be modified. */
445Binary files ../bash-4.2-patched/doc/._bashref.pdf and ./doc/._bashref.pdf differ
446diff -NrC 2 ../bash-4.2-patched/doc/bash.1 ./doc/bash.1
447*** ../bash-4.2-patched/doc/bash.1 2011-01-16 15:31:39.000000000 -0500
448--- ./doc/bash.1 2012-05-07 16:27:18.000000000 -0400
449***************
450*** 8949,8952 ****
451--- 8949,8962 ----
452 The default bash behavior remains as in previous versions.
453 .TP 8
454+ .B direxpand
455+ If set,
456+ .B bash
457+ replaces directory names with the results of word expansion when performing
458+ filename completion. This changes the contents of the readline editing
459+ buffer.
460+ If not set,
461+ .B bash
462+ attempts to preserve what the user typed.
463+ .TP 8
464 .B dirspell
465 If set,
466diff -NrC 2 ../bash-4.2-patched/doc/bashref.texi ./doc/bashref.texi
467*** ../bash-4.2-patched/doc/bashref.texi 2011-01-16 15:31:57.000000000 -0500
468--- ./doc/bashref.texi 2012-05-07 16:27:18.000000000 -0400
469***************
470*** 4536,4539 ****
471--- 4536,4546 ----
472 The default Bash behavior remains as in previous versions.
473
474+ @item direxpand
475+ If set, Bash
476+ replaces directory names with the results of word expansion when performing
477+ filename completion. This changes the contents of the readline editing
478+ buffer.
479+ If not set, Bash attempts to preserve what the user typed.
480+
481 @item dirspell
482 If set, Bash
483diff -NrC 2 ../bash-4.2-patched/tests/shopt.right ./tests/shopt.right
484*** ../bash-4.2-patched/tests/shopt.right 2010-07-02 23:36:30.000000000 -0400
485--- ./tests/shopt.right 2012-05-07 16:27:18.000000000 -0400
486***************
487*** 13,16 ****
488--- 13,17 ----
489 shopt -u compat40
490 shopt -u compat41
491+ shopt -u direxpand
492 shopt -u dirspell
493 shopt -u dotglob
494***************
495*** 69,72 ****
496--- 70,74 ----
497 shopt -u compat40
498 shopt -u compat41
499+ shopt -u direxpand
500 shopt -u dirspell
501 shopt -u dotglob
502***************
503*** 102,105 ****
504--- 104,108 ----
505 compat40 off
506 compat41 off
507+ direxpand off
508 dirspell off
509 dotglob off
510*** ../bash-4.2-patched/patchlevel.h Sat Jun 12 20:14:48 2010
511--- patchlevel.h Thu Feb 24 21:41:34 2011
512***************
513*** 26,30 ****
514 looks for to find the patch level (for the sccs version string). */
515
516! #define PATCHLEVEL 28
517
518 #endif /* _PATCHLEVEL_H_ */
519--- 26,30 ----
520 looks for to find the patch level (for the sccs version string). */
521
522! #define PATCHLEVEL 29
523
524 #endif /* _PATCHLEVEL_H_ */
This page took 0.080164 seconds and 4 git commands to generate.