$HOME does not get abbreviated in prompt \w output when there is a trailing slash

2014-05-16 Thread Libor Pechacek
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc -I/home/abuild/rpmbuild/BUILD/bash-4.2 
-L/home/abuild/rpmbuild/BUILD/bash-4.2/../readline-6.2
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-suse-linux-gnu' 
-DCONF_VENDOR='suse' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -fmessage-length=0 
-grecord-gcc-switches -fstack-protector -O2 -Wall -D_FORTIFY_SOURCE=2 
-funwind-tables -fasynchronous-unwind-tables -g  -D_GNU_SOURCE -DRECYCLES_PIDS 
-Wall -g -std=gnu89 -Wuninitialized -Wextra -Wno-unprototyped-calls 
-Wno-switch-enum -Wno-unused-variable -Wno-unused-parameter -ftree-loop-linear 
-pipe -DBNC382214=0 -fprofile-use
uname output: Linux fmn.suse.cz 3.12.18-4-default #1 SMP Thu May 8 16:21:49 UTC 
2014 (607beab) x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-suse-linux-gnu

Bash Version: 4.2
Patch Level: 46
Release Status: release

Description:
Bash prompt always shows full path in prompt instead of tilde
abbreviation when $HOME ends with slash.

Repeat-By:
lpechacek@fmn:~> PS1='\w\$ '
~$ HOME=/home/lpechacek/
/home/lpechacek$ HOME=/home/lpechacek
~$  # the above line should start with '~$ '



Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash

2014-05-16 Thread Libor Pechacek
Hi Chet,

On Fri 16-05-14 09:13:34, Chet Ramey wrote:
> On 5/16/14, 5:22 AM, Libor Pechacek wrote:
> 
> > Bash Version: 4.2
> > Patch Level: 46
> > Release Status: release
> > 
> > Description:
> > Bash prompt always shows full path in prompt instead of tilde
> > abbreviation when $HOME ends with slash.
> 
> This came up in March, 2012:
> 
> http://lists.gnu.org/archive/html/bug-bash/2012-03/msg00055.html
> 
> My opinion that this is not a bug in bash hasn't changed.  There are a
> number of easy ways to remove this trailing slash.

Agree.  On the other hand, passwd(5) does not fobid the trailing slash.  That
said I think that either bash should tolerate the trailing slash - will likely
be easy as you mentioned above - or the limitation should be documented in bash
manual so that no more people burn their time on this unexpected behavior.

Libor
-- 
Libor Pechacek
Project Manager SUSE Labs, Prague



Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash

2014-05-23 Thread Libor Pechacek
On Fri 16-05-14 09:13:34, Chet Ramey wrote:
> On 5/16/14, 5:22 AM, Libor Pechacek wrote:
> 
> > Bash Version: 4.2
> > Patch Level: 46
> > Release Status: release
> > 
> > Description:
> > Bash prompt always shows full path in prompt instead of tilde
> > abbreviation when $HOME ends with slash.
> 
> This came up in March, 2012:
> 
> http://lists.gnu.org/archive/html/bug-bash/2012-03/msg00055.html
> 
> My opinion that this is not a bug in bash hasn't changed.  There are a
> number of easy ways to remove this trailing slash.

Proposed patch:

>From da53c262cb7c356a09e5786f01e6c8c8d7301940 Mon Sep 17 00:00:00 2001
From: Libor Pechacek 
Date: Fri, 23 May 2014 09:30:49 +0200
Subject: [PATCH] Make \w and \W tolerate trailing slash in $HOME

Currently \w and \W abbreviate $HOME into tilde only when it ends with a
character different from slash.  This patch makes them tolerate trailing
slashes.
---
 general.c | 5 -
 parse.y   | 8 ++--
 y.tab.c   | 6 +-
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/general.c b/general.c
index 087689eb74cc..de6093b57995 100644
--- a/general.c
+++ b/general.c
@@ -699,7 +699,10 @@ polite_directory_format (name)
   int l;
 
   home = get_string_value ("HOME");
-  l = home ? strlen (home) : 0;
+
+  /* remove trailing slashes from $HOME before comparisons */
+  for (l = home ? strlen (home) : 0; l > 1 && home[l-1] == '/'; l--);
+
   if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
 {
   strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
diff --git a/parse.y b/parse.y
index 91bf3bf649bd..2abfceb1b6ee 100644
--- a/parse.y
+++ b/parse.y
@@ -5384,7 +5384,7 @@ decode_prompt_string (string)
  {
/* Use the value of PWD because it is much more efficient. */
char t_string[PATH_MAX];
-   int tlen;
+   int tlen, l;
 
temp = get_string_value ("PWD");
 
@@ -5415,7 +5415,11 @@ decode_prompt_string (string)
 #define ROOT_PATH(x)   ((x)[0] == '/' && (x)[1] == 0)
 #define DOUBLE_SLASH_ROOT(x)   ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
-   if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || 
STREQ (t, t_string) == 0))
+   /* remove trailing slashes from $HOME before comparisons */
+   t = get_string_value ("HOME");
+   for (l = t ? strlen (t) : 0; l > 1 && t[l-1] == '/'; l--);
+
+   if (c == 'W' && ((t == 0) || STREQN (t, t_string, l) == 0))
  {
if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT 
(t_string) == 0)
  {
diff --git a/y.tab.c b/y.tab.c
index 80fe9308398e..d107e5b8dec5 100644
--- a/y.tab.c
+++ b/y.tab.c
@@ -7727,7 +7727,11 @@ decode_prompt_string (string)
 #define ROOT_PATH(x)   ((x)[0] == '/' && (x)[1] == 0)
 #define DOUBLE_SLASH_ROOT(x)   ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
-   if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || 
STREQ (t, t_string) == 0))
+   /* remove trailing slashes from $HOME before comparisons */
+   t = get_string_value ("HOME");
+   for (l = t ? strlen (t) : 0; l > 1 && t[l-1] == '/'; l--);
+
+   if (c == 'W' && ((t == 0) || STREQN (t, t_string, l) == 0))
  {
if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT 
(t_string) == 0)
  {
-- 
1.7.12.4




Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash

2014-05-29 Thread Libor Pechacek
On Fri 23-05-14 06:13:13, Eric Blake wrote:
> On 05/23/2014 02:32 AM, Libor Pechacek wrote:
> 
> > +++ b/general.c
> > @@ -699,7 +699,10 @@ polite_directory_format (name)
> >int l;
> >  
> >home = get_string_value ("HOME");
> > -  l = home ? strlen (home) : 0;
> > +
> > +  /* remove trailing slashes from $HOME before comparisons */
> > +  for (l = home ? strlen (home) : 0; l > 1 && home[l-1] == '/'; l--);
> > +
> 
> Does this still work correctly on systems where / and // are distinct
> (as allowed by POSIX) and someone has set $HOME to //?

Good question.  The trimming should not be applied to paths shorter than two
characters.  As part of the testing, I've found another bug.  Updated patch
attached.

This is how Bash behaves without the patch:
bash-master-4.3$ cd
bash-master-4.3$ PS1='\w | \W \$ '
~ | ~ $ HOME=/home
/home.local/lpechacek | lpechacek $ cd
~ | ~ $ HOME=/home/
/home | home $ cd
/home | home $ HOME=//home
/home | home $ cd
~ | ~ $ HOME=//home/
//home | home $ cd
//home | home $ HOME=/
//home | home $ cd
/ | / $ HOME=//
/ | / $ cd
~ | ~ $ exit

and this is behavior with the patch:
bash-4.3$ cd
bash-4.3$ PS1='\w | \W \$ '
~ | ~ $ HOME=/home
/home.local/lpechacek | lpechacek $ cd
~ | ~ $ HOME=/home/
~ | ~ $ cd
~ | ~ $ HOME=//home
/home | home $ cd
~ | ~ $ HOME=//home/
~ | ~ $ cd
~ | ~ $ HOME=/
//home | home $ cd
/ | / $ HOME=//
/ | / $ cd
~ | ~ $ exit


>From ef9c5e823131098d90b3f2aabaf539df59a01cba Mon Sep 17 00:00:00 2001
From: Libor Pechacek 
Date: Fri, 23 May 2014 09:30:49 +0200
Subject: [PATCH] Make \w and \W tolerate trailing slash in $HOME

Currently \w and \W abbreviate $HOME into tilde only when it ends with a
character different from slash.  This patch makes them tolerate trailing
slashes.
---
 general.c |  5 -
 parse.y   | 10 --
 y.tab.c   | 10 --
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/general.c b/general.c
index 087689eb74cc..02163d3079c3 100644
--- a/general.c
+++ b/general.c
@@ -699,7 +699,10 @@ polite_directory_format (name)
   int l;
 
   home = get_string_value ("HOME");
-  l = home ? strlen (home) : 0;
+
+  /* remove trailing slashes from $HOME before comparisons */
+  for (l = home ? strlen (home) : 0; l > 2 && home[l-1] == '/'; l--);
+
   if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
 {
   strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
diff --git a/parse.y b/parse.y
index 91bf3bf649bd..91fbaaa924de 100644
--- a/parse.y
+++ b/parse.y
@@ -5384,7 +5384,7 @@ decode_prompt_string (string)
  {
/* Use the value of PWD because it is much more efficient. */
char t_string[PATH_MAX];
-   int tlen;
+   int tlen, l;
 
temp = get_string_value ("PWD");
 
@@ -5415,7 +5415,13 @@ decode_prompt_string (string)
 #define ROOT_PATH(x)   ((x)[0] == '/' && (x)[1] == 0)
 #define DOUBLE_SLASH_ROOT(x)   ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
-   if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || 
STREQ (t, t_string) == 0))
+   /* remove trailing slashes from $HOME before comparisons */
+   t = get_string_value ("HOME");
+   for (l = t ? strlen (t) : 0; l > 2 && t[l-1] == '/'; l--);
+   if (l)
+ t[l] = 0;
+
+   if (c == 'W' && ((t == 0) || STREQ (t, t_string) == 0))
  {
if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT 
(t_string) == 0)
  {
diff --git a/y.tab.c b/y.tab.c
index 80fe9308398e..d9bf6b1d056a 100644
--- a/y.tab.c
+++ b/y.tab.c
@@ -7696,7 +7696,7 @@ decode_prompt_string (string)
  {
/* Use the value of PWD because it is much more efficient. */
char t_string[PATH_MAX];
-   int tlen;
+   int tlen, l;
 
temp = get_string_value ("PWD");
 
@@ -7727,7 +7727,13 @@ decode_prompt_string (string)
 #define ROOT_PATH(x)   ((x)[0] == '/' && (x)[1] == 0)
 #define DOUBLE_SLASH_ROOT(x)   ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
/* Abbreviate \W as ~ if $PWD == $HOME */
-   if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || 
STREQ (t, t_string) == 0))
+   /* remove trailing slashes from $HOME before comparisons */
+   t = get_string_value ("HOME");
+   for (l = t ? strlen (t) : 0; l > 2 && t[l-1] == '/'; l--);
+   if (l)
+ t[l] = 0;
+
+   if (c == 'W' && ((t == 0) || STREQ (t, t_string) == 0))
  {
if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT 
(t_string) == 0)
  {
-- 
1.7.12.4