File Coverage

blib/lib/Env/PS1.pm
Criterion Covered Total %
statement 75 92 81.5
branch 38 60 63.3
condition 16 25 64.0
subroutine 14 17 82.3
pod 1 5 20.0
total 144 199 72.3


line stmt bran cond sub pod time code
1             package Env::PS1;
2              
3 1     1   978 use strict;
  1         2  
  1         48  
4 1     1   5 use Carp;
  1         2  
  1         84  
5 1     1   6874 use AutoLoader 'AUTOLOAD';
  1         2382  
  1         9  
6              
7             our $VERSION = 0.06;
8              
9             our $_getpwuid = eval { getpwuid($>) }; # Not supported on some platforms
10              
11             sub import {
12 1     1   12 my $class = shift;
13 1 50       7 return unless @_;
14 1         4 my ($caller) = caller;
15 1         3 for (@_) {
16 1 50       9 /^\$(.+)/ or croak qq/$class can't export "$_", try "\$$_"/;
17 1     1   148 no strict 'refs';
  1         2  
  1         1507  
18 1         2 tie ${"$caller\::$1"}, $class, $1;
  1         11  
19             }
20             }
21              
22             sub TIESCALAR {
23 2     2   6 my ($class, $var) = @_;
24 2   50     13 my $self = bless {
25             var => $var || 'PS1',
26             format => '',
27             }, $class;
28 2         11 $self->cache();
29 2         20 return $self;
30             }
31              
32             sub STORE {
33 4     4   8 my $self = shift;
34 4 50       17 if (ref $$self{var}) { ${$$self{var}} = shift }
  0         0  
  0         0  
35 4         30 else { $ENV{$$self{var}} = shift }
36             }
37              
38             sub FETCH {
39 12     12   856 my $self = shift;
40 12 100       49 my $format = ref($$self{var}) ? ${$$self{var}} : $ENV{$$self{var}} ;
  2         4  
41 12         74 $format =~ s#(\\\\)|(?
42 6 100       40 $1 ? '\\\\' : $2 ? $ENV{$2} : $ENV{$3}
    100          
43             #ge;
44 12 100 100     96 unless ($format eq $$self{format} and exists $ENV{CLICOLOR}
      66        
45             and $ENV{CLICOLOR} eq $$self{clicolor}) {
46 11         38 @$self{qw/format clicolor/} = ($format, $ENV{CLICOLOR});
47 11         28 $$self{cache} = [ $self->cache($format) ];
48             }
49 12 100       25 my $string = join '', map { ref($_) ? $_->() : $_ } @{$$self{cache}};
  16         64  
  12         29  
50 12         27 $string =~ s#\$\((.+)\)#
51 0         0 `$1`;
52             #ge;
53 12         242 return $string;
54             }
55              
56             sub sprintf {
57 1     1 1 3 my $format = pop;
58 1         7 $format =~ s#(\\\\)|(?
59 0 0       0 $1 ? '\\\\' : $2 ? $ENV{$2} : $ENV{$3}
    0          
60             #ge;
61 1 50       5 return join '', map { ref($_) ? $_->() : $_ } Env::PS1->cache($format);
  1         12  
62             }
63              
64             our @user_info; # ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire)
65             our %map; # for custom stuff
66             our %alias = (
67             '$' => 'dollar',
68             '@' => 'D', t => 'D', T => 'D', A => 'D',
69             );
70              
71             sub cache {
72 14     14 0 27 my ($self, $format) = @_;
73 14 100       33 return '' unless defined $format; # get rid of uninitialised warnings
74 12 50       15654 @user_info = getpwuid($>) if $_getpwuid;
75 12         25 my @parts;
76             #print "# string: $format\n";
77 12         101 while ($format =~ s/^(.*?)(\\\\|\\([aenr]|0\d\d)|\\(.)|!)//s) {
78 20   100     112 push @parts, $1 || '';
79 20 100 33     126 if ($2 eq '\\\\') { push @parts, '\\' } # stripped when \! is substitued
  2 100       10  
    100          
    100          
    100          
    50          
80 2         6 elsif ($2 eq '!') { push @parts, '!!' } # posix prompt escape :$
81 4         340 elsif ($3) { push @parts, eval qq/"\\$3"/ }
82 30         121 elsif (exists $map{$4}) {
83 2         4 my $item = $map{$4};
84 2 50 66     15 if (ref $item and $format =~ s/^\{(.*?)\}//) {
85 0         0 push @parts, $item->($1); # obscure foo
86             }
87 2         8 else { push @parts, $item }
88             }
89             elsif (grep {$4 eq $_} qw/C D P/) { # special cases
90 2         6 my $sub = $4 ;
91 2         18 $format =~ s/^\{(.*?)\}//;
92 2         43 push @parts, $self->$sub($sub, $1);
93             }
94 0         0 elsif ($4 eq '[' or $4 eq ']') { next }
95             else {
96 8 100       31 my $sub = exists($alias{$4}) ? $alias{$4} : uc($4) ;
97 8 100       67 push @parts, $self->can($sub) ? ($self->$sub($4)) : $4;
98             }
99             }
100 12         37 push @parts, $format;
101 12         22 my @cache = ('');
102 12         23 for (@parts) { # optimise: join strings, push code refs
103 50 100 100     181 if (ref $_ or ref $cache[-1]) { push @cache, $_ }
  2         6  
104 48         84 else { $cache[-1] .= $_ }
105             }
106 12         810 return @cache;
107             }
108              
109             ## format subs
110              
111 5 50 33 5 0 49 sub U { $user_info[0] || $ENV{USER} || $ENV{LOGNAME} }
112              
113             sub W {
114 0 0   0 0 0 return sub { $ENV{PWD} eq $ENV{HOME} ? "~" : $ENV{PWD} } if $_[1] eq 'w';
  0 0   0   0  
115             return sub {
116 0 0   0   0 return '/' if $ENV{PWD} eq '/';
117 0 0       0 if($ENV{PWD} eq $ENV{HOME}) {
118 0         0 return "~";
119             }
120 0         0 $ENV{PWD} =~ m#([^/]*)/?$#;
121 0         0 return $1;
122 0         0 };
123             }
124              
125             ## others defined below for Autoload
126              
127             1;
128              
129             __END__