]> git.pld-linux.org Git - packages/bash.git/blob - bash42-029
- up to 4.2.37
[packages/bash.git] / bash42-029
1                              BASH PATCH REPORT
2                              =================
3
4 Bash-Release:   4.2
5 Patch-ID:       bash42-029
6
7 Bug-Reported-by:        "Michael Kalisz" <michael@kalisz.homelinux.net>
8 Bug-Reference-ID:       <50241.78.69.11.112.1298585641.squirrel@kalisz.homelinux.net>
9 Bug-Reference-URL:      http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00274.html
10
11 Bug-Description:
12
13 Bash-4.2 tries to leave completed directory names as the user typed them,
14 without expanding them to a full pathname.  One effect of this is that
15 shell variables used in pathnames being completed (e.g., $HOME) are left
16 unchanged, but the `$' is quoted by readline because it is a special
17 character to the shell.
18
19 This patch introduces two things:
20
21 1.  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;
24 2.  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
27 Patch (apply with `patch -p0'):
28
29 diff -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   }
362 diff -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));
381 diff -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. */
445 Binary files ../bash-4.2-patched/doc/._bashref.pdf and ./doc/._bashref.pdf differ
446 diff -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,
466 diff -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
483 diff -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.058605 seconds and 3 git commands to generate.