[pacman-dev] [PATCH 2/3] pacsearch with repo-agnostic coloring
The 6 basic shell colors are stored in an array. An arbitrary hash of the repo name sets which color is used for the output. Added CLI option -n, --nocolor. Currently, "ver", "group" and "installed" are not bold. A single variable can print them bold. Now to_color() takes an array instead of a string. This removes the need for another row of regex substitutions, while making the code shorter and faster. Signed-off-by: Pierre Neidhardt <ambrevar@gmail.com> --- contrib/pacsearch.in | 113 ++++++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/contrib/pacsearch.in b/contrib/pacsearch.in index 2418e19..d860471 100644 --- a/contrib/pacsearch.in +++ b/contrib/pacsearch.in @@ -1,7 +1,7 @@ #!/usr/bin/perl -# pacsearch - Adds color and install information to a 'pacman -Ss' search +# pacsearch - Perform a pacman search using both the local and the sync databases # -# Copyright (C) 2008-2011 Dan McGee <dan@archlinux.org> +# Copyright (C) 2008-2014 Dan McGee <dan@archlinux.org> # # Based off original shell script version: # Copyright (C) 2006-2007 Dan McGee <dan@archlinux.org> @@ -19,9 +19,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -#TODO: colors flag on commandline -#TODO: for now the whole line is bold and some parts have the same formatting (e.g. extra and version), maybe it would be better to use regular formatting - use strict; use warnings; @@ -31,13 +28,15 @@ my $myver = '@PACKAGE_VERSION@'; sub usage { print "$myname (pacman) v$myver\n\n"; print "Perform a pacman search using both the local and the sync databases.\n\n"; - print "Usage: $myname <pattern>\n\n"; + print "Usage: $myname [-n] <pattern>\n\n"; + print "Options:\n"; + print " -n, --nocolor: turn off coloring\n\n"; print "Example: $myname ^gnome\n"; } sub version { printf "%s %s\n", $myname, $myver; - print "Copyright (C) 2008-2011 Dan McGee <dan\@archlinux.org>\n\n"; + print "Copyright (C) 2008-2014 Dan McGee <dan\@archlinux.org>\n\n"; print "Based off original shell script version:\n"; print "Copyright (C) 2006-2007 Dan McGee <dan\@archlinux.org>\n"; } @@ -56,37 +55,47 @@ if ($ARGV[0] eq "--version" || $ARGV[0] eq "-V") { } # define formatting variables -my $FMT_BLUE = "\e[1;94m"; -my $FMT_CYAN = "\e[1;96m"; -my $FMT_GREEN = "\e[1;92m"; -my $FMT_MAGENTA = "\e[1;95m"; -my $FMT_RED = "\e[1;91m"; -my $FMT_YELLOW = "\e[1;93m"; -my $FMT_BOLD = "\e[1m"; -my $FMT_RESET = "\e[0m"; +my $BLUE = "\e[94m"; +my $CYAN = "\e[96m"; +my $GREEN = "\e[92m"; +my $MAGENTA = "\e[95m"; +my $RED = "\e[91m"; +my $YELLOW = "\e[93m"; +my $BOLD = "\e[1m"; +my $REGULAR = ""; +my $RESET = "\e[0m"; +if ($ARGV[0] eq "--nocolor" || $ARGV[0] eq "-n") { + shift; + $BLUE = ""; + $CYAN = ""; + $GREEN = ""; + $MAGENTA = ""; + $RED = ""; + $YELLOW = ""; + $BOLD = ""; + $REGULAR = ""; + $RESET = ""; +} + +my @COLORS=($RED, $GREEN, $YELLOW, $BLUE, $MAGENTA, $CYAN); + +# We can choose if we output repo/pkgname bold or not. Same thing for 'ver group +# installed'. Not sure if it's worth a CLI option. +my $FMT_REPO = $BOLD; +my $FMT_OTHER = $REGULAR; # Color a "repo/pkgname pkgver (goups) [installed]" line. # We try to stick to pacman colors. sub to_color { - my $line = shift; - # get the installed text colored first (between square brackets) - $line =~ s/(\[.*\]$)/$FMT_CYAN$1$FMT_RESET/; - # group (between parentheses) - $line =~ s/(\(.*\))/$FMT_BLUE$1$FMT_RESET/; - # version (second field) - $line =~ s/^([^ ]+) ([^ ]+) /$1 $FMT_GREEN$2$FMT_RESET /; - # name (word after slash) - $line =~ s/\/([\w-]*)/\/$FMT_BOLD$1$FMT_RESET/; - # repo (word before slash inclusive) - $line =~ s/(^core\/)/$FMT_BLUE$1$FMT_RESET/; - $line =~ s/(^extra\/)/$FMT_GREEN$1$FMT_RESET/; - $line =~ s/(^community\/)/$FMT_MAGENTA$1$FMT_RESET/; - $line =~ s/(^testing\/)/$FMT_CYAN$1$FMT_RESET/; - $line =~ s/(^community-testing\/)/$FMT_RED$1$FMT_RESET/; - $line =~ s/(^multilib\/)/$FMT_YELLOW$1$FMT_RESET/; - $line =~ s/(^local\/)/$FMT_CYAN$1$FMT_RESET/; - # any other unknown repository - $line =~ s/(^[\w-]*\/)/$FMT_YELLOW$1$FMT_RESET/; + my @v = @_; + # Each repo name is hashed to give a unique, persistant color index. The + # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge; + my $repo_color=$COLORS[$repohash % 6]; + my $line = "$RESET$FMT_REPO$repo_color$v[0]/$RESET$FMT_REPO$v[1]$RESET $GREEN$FMT_OTHER$v[2]$RESET"; + $line .= " $BLUE$FMT_OTHER$v[3]$RESET" if $v[3] ne ""; + $line .= " $CYAN$FMT_OTHER$v[4]$RESET" if $v[4] ne ""; return $line; } @@ -103,16 +112,17 @@ if ($#syncpkgs >= 0) { # counter var for packages, used here and in the query loop too my $cnt = 0; foreach $_ (@syncpkgs) { - # we grab 4 fields here: repo, name/ver, installed, and desc - my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; + # we grab the following fields: repo, name, ver, group, installed, and desc + my @pkgfields = /^(.*?)\/(.*?) (.*?) ?(\(.*?\))? ?(\[.*\])?\n(.*)$/s; if(not @pkgfields) { # skip any non-matching line and just print it for the user print $_, "\n"; next; } - # since installed is optional, we should fill it in if necessary - $pkgfields[2] = "" if not defined $pkgfields[2]; - # add a fifth field that indicates original order + # since 'group' and 'installed' are optional, we should fill it in if necessary + $pkgfields[3] = "" if not defined $pkgfields[3]; + $pkgfields[4] = "" if not defined $pkgfields[4]; + # add a last field that indicates original order push (@pkgfields, $cnt++); # add each sync pkg by name/ver to a hash table for quick lookup $allpkgs{$pkgfields[1]} = [ @pkgfields ]; @@ -127,30 +137,31 @@ if ($#querypkgs >= 0) { } foreach $_ (@querypkgs) { - # we grab 4 fields here: repo, name/ver, installed, and desc - my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; + # we grab the following fields: repo, name, ver, group, installed, and desc + my @pkgfields = /^(.*?)\/(.*?) (.*?) ?(\(.*?\))? ?(\[.*\])?\n(.*)$/s; + # my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; # skip any non-matching line next if not defined $pkgfields[1]; - # since installed is optional, we should fill it in if necessary - $pkgfields[2] = "" if not defined $pkgfields[2]; # check if the package was listed in the sync out if (not exists $allpkgs{$pkgfields[1]}) { - $pkgfields[2] = "[installed]"; - # add a fifth field that indicates original order (after sync) + # since 'group' is optional, we should fill it in if necessary + $pkgfields[3] = "" if not defined $pkgfields[3]; + # TODO: localize the "installed" word + $pkgfields[4] = "[installed]"; + # add a last field that indicates original order (after sync) push (@pkgfields, $cnt++); # add our local-only package to the hash $allpkgs{$pkgfields[1]} = [ @pkgfields ]; } } -# sort by original order (the fifth field) and print -foreach $_ ( sort{ @{$allpkgs{$a}}[4] <=> @{$allpkgs{$b}}[4] } keys %allpkgs) { +# sort by original order (the last field) and print +foreach $_ ( sort{ @{$allpkgs{$a}}[6] <=> @{$allpkgs{$b}}[6] } keys %allpkgs) { my @v = @{$allpkgs{$_}}; - my $line = "$v[0]/$v[1] $v[2]"; - $line = to_color($line); - # print colorized "repo/pkgname pkgver" string with possible installed text + my $line = to_color(@v); + # print colorized "repo/pkgname pkgver ..." string with possible installed text print "$line\n"; - print "$v[3]\n"; + print "$v[5]\n"; } #vim: set noet: -- 1.8.5.2
On 10/01/14 06:21, Pierre Neidhardt wrote:
The 6 basic shell colors are stored in an array. An arbitrary hash of the repo name sets which color is used for the output.
Added CLI option -n, --nocolor.
Currently, "ver", "group" and "installed" are not bold. A single variable can print them bold.
Now to_color() takes an array instead of a string. This removes the need for another row of regex substitutions, while making the code shorter and faster.
Signed-off-by: Pierre Neidhardt <ambrevar@gmail.com> --- contrib/pacsearch.in | 113 ++++++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 51 deletions(-)
diff --git a/contrib/pacsearch.in b/contrib/pacsearch.in index 2418e19..d860471 100644 --- a/contrib/pacsearch.in +++ b/contrib/pacsearch.in @@ -1,7 +1,7 @@ #!/usr/bin/perl -# pacsearch - Adds color and install information to a 'pacman -Ss' search +# pacsearch - Perform a pacman search using both the local and the sync databases
Do this in that separate patch I mentioned in the other review.
# -# Copyright (C) 2008-2011 Dan McGee <dan@archlinux.org> +# Copyright (C) 2008-2014 Dan McGee <dan@archlinux.org>
Bump this in the separate patch - make it first in the series.
# # Based off original shell script version: # Copyright (C) 2006-2007 Dan McGee <dan@archlinux.org> @@ -19,9 +19,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>.
-#TODO: colors flag on commandline -#TODO: for now the whole line is bold and some parts have the same formatting (e.g. extra and version), maybe it would be better to use regular formatting - use strict; use warnings;
@@ -31,13 +28,15 @@ my $myver = '@PACKAGE_VERSION@'; sub usage { print "$myname (pacman) v$myver\n\n"; print "Perform a pacman search using both the local and the sync databases.\n\n"; - print "Usage: $myname <pattern>\n\n"; + print "Usage: $myname [-n] <pattern>\n\n"; + print "Options:\n"; + print " -n, --nocolor: turn off coloring\n\n"; print "Example: $myname ^gnome\n"; }
sub version { printf "%s %s\n", $myname, $myver; - print "Copyright (C) 2008-2011 Dan McGee <dan\@archlinux.org>\n\n"; + print "Copyright (C) 2008-2014 Dan McGee <dan\@archlinux.org>\n\n";
Combine tn separate patch too.
print "Based off original shell script version:\n"; print "Copyright (C) 2006-2007 Dan McGee <dan\@archlinux.org>\n"; } @@ -56,37 +55,47 @@ if ($ARGV[0] eq "--version" || $ARGV[0] eq "-V") { }
# define formatting variables -my $FMT_BLUE = "\e[1;94m"; -my $FMT_CYAN = "\e[1;96m"; -my $FMT_GREEN = "\e[1;92m"; -my $FMT_MAGENTA = "\e[1;95m"; -my $FMT_RED = "\e[1;91m"; -my $FMT_YELLOW = "\e[1;93m"; -my $FMT_BOLD = "\e[1m"; -my $FMT_RESET = "\e[0m"; +my $BLUE = "\e[94m"; +my $CYAN = "\e[96m"; +my $GREEN = "\e[92m"; +my $MAGENTA = "\e[95m"; +my $RED = "\e[91m"; +my $YELLOW = "\e[93m"; +my $BOLD = "\e[1m"; +my $REGULAR = ""; +my $RESET = "\e[0m"; +if ($ARGV[0] eq "--nocolor" || $ARGV[0] eq "-n") { + shift; + $BLUE = ""; + $CYAN = ""; + $GREEN = ""; + $MAGENTA = ""; + $RED = ""; + $YELLOW = ""; + $BOLD = ""; + $REGULAR = ""; + $RESET = ""; +} + +my @COLORS=($RED, $GREEN, $YELLOW, $BLUE, $MAGENTA, $CYAN);
This changes format in the patch 3/3. Merge it here.
+ +# We can choose if we output repo/pkgname bold or not. Same thing for 'ver group +# installed'. Not sure if it's worth a CLI option. +my $FMT_REPO = $BOLD; +my $FMT_OTHER = $REGULAR;
Just do the whole row bold like in pacman.
# Color a "repo/pkgname pkgver (goups) [installed]" line. # We try to stick to pacman colors. sub to_color { - my $line = shift; - # get the installed text colored first (between square brackets) - $line =~ s/(\[.*\]$)/$FMT_CYAN$1$FMT_RESET/; - # group (between parentheses) - $line =~ s/(\(.*\))/$FMT_BLUE$1$FMT_RESET/; - # version (second field) - $line =~ s/^([^ ]+) ([^ ]+) /$1 $FMT_GREEN$2$FMT_RESET /; - # name (word after slash) - $line =~ s/\/([\w-]*)/\/$FMT_BOLD$1$FMT_RESET/; - # repo (word before slash inclusive) - $line =~ s/(^core\/)/$FMT_BLUE$1$FMT_RESET/; - $line =~ s/(^extra\/)/$FMT_GREEN$1$FMT_RESET/; - $line =~ s/(^community\/)/$FMT_MAGENTA$1$FMT_RESET/; - $line =~ s/(^testing\/)/$FMT_CYAN$1$FMT_RESET/; - $line =~ s/(^community-testing\/)/$FMT_RED$1$FMT_RESET/; - $line =~ s/(^multilib\/)/$FMT_YELLOW$1$FMT_RESET/; - $line =~ s/(^local\/)/$FMT_CYAN$1$FMT_RESET/; - # any other unknown repository - $line =~ s/(^[\w-]*\/)/$FMT_YELLOW$1$FMT_RESET/; + my @v = @_; + # Each repo name is hashed to give a unique, persistant color index. The
typo: persistent
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
+ my $repo_color=$COLORS[$repohash % 6]; + my $line = "$RESET$FMT_REPO$repo_color$v[0]/$RESET$FMT_REPO$v[1]$RESET $GREEN$FMT_OTHER$v[2]$RESET"; + $line .= " $BLUE$FMT_OTHER$v[3]$RESET" if $v[3] ne ""; + $line .= " $CYAN$FMT_OTHER$v[4]$RESET" if $v[4] ne ""; return $line; }
@@ -103,16 +112,17 @@ if ($#syncpkgs >= 0) { # counter var for packages, used here and in the query loop too my $cnt = 0; foreach $_ (@syncpkgs) { - # we grab 4 fields here: repo, name/ver, installed, and desc - my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; + # we grab the following fields: repo, name, ver, group, installed, and desc + my @pkgfields = /^(.*?)\/(.*?) (.*?) ?(\(.*?\))? ?(\[.*\])?\n(.*)$/s; if(not @pkgfields) { # skip any non-matching line and just print it for the user print $_, "\n"; next; } - # since installed is optional, we should fill it in if necessary - $pkgfields[2] = "" if not defined $pkgfields[2]; - # add a fifth field that indicates original order + # since 'group' and 'installed' are optional, we should fill it in if necessary + $pkgfields[3] = "" if not defined $pkgfields[3]; + $pkgfields[4] = "" if not defined $pkgfields[4]; + # add a last field that indicates original order push (@pkgfields, $cnt++); # add each sync pkg by name/ver to a hash table for quick lookup $allpkgs{$pkgfields[1]} = [ @pkgfields ]; @@ -127,30 +137,31 @@ if ($#querypkgs >= 0) { }
foreach $_ (@querypkgs) { - # we grab 4 fields here: repo, name/ver, installed, and desc - my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; + # we grab the following fields: repo, name, ver, group, installed, and desc + my @pkgfields = /^(.*?)\/(.*?) (.*?) ?(\(.*?\))? ?(\[.*\])?\n(.*)$/s; + # my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s; # skip any non-matching line next if not defined $pkgfields[1]; - # since installed is optional, we should fill it in if necessary - $pkgfields[2] = "" if not defined $pkgfields[2]; # check if the package was listed in the sync out if (not exists $allpkgs{$pkgfields[1]}) { - $pkgfields[2] = "[installed]"; - # add a fifth field that indicates original order (after sync) + # since 'group' is optional, we should fill it in if necessary + $pkgfields[3] = "" if not defined $pkgfields[3]; + # TODO: localize the "installed" word + $pkgfields[4] = "[installed]"; + # add a last field that indicates original order (after sync) push (@pkgfields, $cnt++); # add our local-only package to the hash $allpkgs{$pkgfields[1]} = [ @pkgfields ]; } }
-# sort by original order (the fifth field) and print -foreach $_ ( sort{ @{$allpkgs{$a}}[4] <=> @{$allpkgs{$b}}[4] } keys %allpkgs) { +# sort by original order (the last field) and print +foreach $_ ( sort{ @{$allpkgs{$a}}[6] <=> @{$allpkgs{$b}}[6] } keys %allpkgs) { my @v = @{$allpkgs{$_}}; - my $line = "$v[0]/$v[1] $v[2]"; - $line = to_color($line); - # print colorized "repo/pkgname pkgver" string with possible installed text + my $line = to_color(@v); + # print colorized "repo/pkgname pkgver ..." string with possible installed text print "$line\n"; - print "$v[3]\n"; + print "$v[5]\n"; }
#vim: set noet:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation. cheers! mar77i [0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
that is, no, g is 'global' [0]. sorry for the mess. cheers! mar77i [0] http://www.comp.leeds.ac.uk/Perl/sandtr.html
On 14-01-15 17:03:39, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
That's right except for 'g' as you stated in you following mail. This hash function is a bit hackish though, but I do not think this problem has any better solution. * We need to color repo according to their name. * We want repo to have different colors. * We have only 6 colors... So my hash functions makes core, multilib, local, extra and community have different colors. With different repo names, the hash may return the same color for all of them. Any better idea? -- Pierre Neidhardt Sometimes love ain't nothing but a misunderstanding between two fools.
On 16/01/14 02:03, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
Does that mean the answer can only be odd? Allan
On 14-01-16 10:13:18, Allan McRae wrote:
On 16/01/14 02:03, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
Does that mean the answer can only be odd?
Ooopsy! Looks like I forgot to sum the result! Actually I didn't notice the flaw since it still works. The reason is that the resulting numbers are so big they are casted and rounded to float or sth equivalent. This is _terrible_ code indeed! In the first place this was an attempt to use Perl features for a quick, one-line hash of strings, but since I'm not a Perl guru this may be doomed to fail. Any better suggestion from a Perl champion? A more traditional way to do it: sub hash_string { my $sum = 0; foreach my $l (split //, $_[0]) { $sum = $sum + 31*ord($l) + 5; } return $sum; } [...] my $repo_hash = hash_string($v[0]); This is not a very good hash since a permutation will yield the same result. The following is much better $sum = $sum + 31*ord($l)^$pos + 7; but do we really need this? This is just for repo names after all, the extra exponentiation is superfluous in my opinion. The offset (e.g. '+5') can be patched by other distributions make sure their repo have different colors. -- Pierre Neidhardt "Now this is a totally brain damaged algorithm. Gag me with a smurfette." -- P. Buhr, Computer Science 354
On 01/16/14 at 11:48am, Pierre Neidhardt wrote:
On 14-01-16 10:13:18, Allan McRae wrote:
On 16/01/14 02:03, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
Does that mean the answer can only be odd?
Ooopsy! Looks like I forgot to sum the result! Actually I didn't notice the flaw since it still works. The reason is that the resulting numbers are so big they are casted and rounded to float or sth equivalent. This is _terrible_ code indeed!
In the first place this was an attempt to use Perl features for a quick, one-line hash of strings, but since I'm not a Perl guru this may be doomed to fail. Any better suggestion from a Perl champion?
A more traditional way to do it:
sub hash_string { my $sum = 0; foreach my $l (split //, $_[0]) { $sum = $sum + 31*ord($l) + 5; } return $sum; }
[...] my $repo_hash = hash_string($v[0]);
This is not a very good hash since a permutation will yield the same result. The following is much better
$sum = $sum + 31*ord($l)^$pos + 7;
but do we really need this? This is just for repo names after all, the extra exponentiation is superfluous in my opinion.
The offset (e.g. '+5') can be patched by other distributions make sure their repo have different colors.
Two suggestions: 1. Use Term::ANSIColor instead of raw ANSI color codes. This will make the code more readable and make life easier for distro's that need to patch in their own repo colors. 2. Provide a hash variable for hard-coding repo colors. It can be empty by default, making it very easy for distro's to patch in their official repos if the default gives poor results. Something like: use Term::ANSIColor; my %repo_colors; my @colors = ( color('blue'), color('red'), ... ); ... my $repo_name = ...; my $color = ( $repo_colors{$repo_name} || $colors[ hash($repo_name) ] ); apg
On 17/01/14 14:07, Andrew Gregory wrote:
On 01/16/14 at 11:48am, Pierre Neidhardt wrote:
On 14-01-16 10:13:18, Allan McRae wrote:
On 16/01/14 02:03, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
+ # hash function (x*2+1) is completely arbitrary. + my $repohash = $v[0]; + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
Does that mean the answer can only be odd?
Ooopsy! Looks like I forgot to sum the result! Actually I didn't notice the flaw since it still works. The reason is that the resulting numbers are so big they are casted and rounded to float or sth equivalent. This is _terrible_ code indeed!
In the first place this was an attempt to use Perl features for a quick, one-line hash of strings, but since I'm not a Perl guru this may be doomed to fail. Any better suggestion from a Perl champion?
A more traditional way to do it:
sub hash_string { my $sum = 0; foreach my $l (split //, $_[0]) { $sum = $sum + 31*ord($l) + 5; } return $sum; }
[...] my $repo_hash = hash_string($v[0]);
This is not a very good hash since a permutation will yield the same result. The following is much better
$sum = $sum + 31*ord($l)^$pos + 7;
but do we really need this? This is just for repo names after all, the extra exponentiation is superfluous in my opinion.
The offset (e.g. '+5') can be patched by other distributions make sure their repo have different colors.
Two suggestions:
1. Use Term::ANSIColor instead of raw ANSI color codes. This will make the code more readable and make life easier for distro's that need to patch in their own repo colors.
2. Provide a hash variable for hard-coding repo colors. It can be empty by default, making it very easy for distro's to patch in their official repos if the default gives poor results.
Something like:
use Term::ANSIColor;
my %repo_colors;
my @colors = ( color('blue'), color('red'), ... ); ... my $repo_name = ...; my $color = ( $repo_colors{$repo_name} || $colors[ hash($repo_name) ] );
Just throwing this out there... How important is it to have the repos different colours? Dan? Allan
On 14-01-17 20:29:36, Allan McRae wrote:
On 17/01/14 14:07, Andrew Gregory wrote:
On 01/16/14 at 11:48am, Pierre Neidhardt wrote:
On 14-01-16 10:13:18, Allan McRae wrote:
On 16/01/14 02:03, Martti Kühne wrote:
On Wed, Jan 15, 2014 at 9:50 AM, Allan McRae <allan@archlinux.org> wrote: [...]
> + # hash function (x*2+1) is completely arbitrary. > + my $repohash = $v[0]; > + $repohash =~ s/(.)/ord($1)*2+1/ge;
I have very little perl knowledge, so I have no idea what that hash is doing. Can someone explain to me so I can see if that "hash" is reasonable.
Replace each character with its [0] ascii index times two plus one? 'g' is group regexes, 'e' is eval expressions [1], as to utilize the result of the calculation.
cheers! mar77i
[0] http://perldoc.perl.org/functions/ord.html [1] http://stackoverflow.com/questions/6082219/perl-regex-e-eval-modifier-with-s
Does that mean the answer can only be odd?
Ooopsy! Looks like I forgot to sum the result! Actually I didn't notice the flaw since it still works. The reason is that the resulting numbers are so big they are casted and rounded to float or sth equivalent. This is _terrible_ code indeed!
In the first place this was an attempt to use Perl features for a quick, one-line hash of strings, but since I'm not a Perl guru this may be doomed to fail. Any better suggestion from a Perl champion?
A more traditional way to do it:
sub hash_string { my $sum = 0; foreach my $l (split //, $_[0]) { $sum = $sum + 31*ord($l) + 5; } return $sum; }
[...] my $repo_hash = hash_string($v[0]);
This is not a very good hash since a permutation will yield the same result. The following is much better
$sum = $sum + 31*ord($l)^$pos + 7;
but do we really need this? This is just for repo names after all, the extra exponentiation is superfluous in my opinion.
The offset (e.g. '+5') can be patched by other distributions make sure their repo have different colors.
Two suggestions:
1. Use Term::ANSIColor instead of raw ANSI color codes. This will make the code more readable and make life easier for distro's that need to patch in their own repo colors.
2. Provide a hash variable for hard-coding repo colors. It can be empty by default, making it very easy for distro's to patch in their official repos if the default gives poor results.
Something like:
use Term::ANSIColor;
my %repo_colors;
my @colors = ( color('blue'), color('red'), ... ); ... my $repo_name = ...; my $color = ( $repo_colors{$repo_name} || $colors[ hash($repo_name) ] );
Just throwing this out there... How important is it to have the repos different colours? Dan?
Allan
I agree, all this is sounding rather futile... This is causing debatable design issues, which are certainly worthless. But this is also one of the only 2 pacsearch features: per-repo colouring and local+sync searching. -- Pierre Neidhardt We are all dying -- and we're gonna be dead for a long time.
On Fri, Jan 17, 2014 at 5:44 AM, Pierre Neidhardt <ambrevar@gmail.com> wrote:
On 14-01-17 20:29:36, Allan McRae wrote:
On 17/01/14 14:07, Andrew Gregory wrote:
On 01/16/14 at 11:48am, Pierre Neidhardt wrote:
Ooopsy! Looks like I forgot to sum the result! Actually I didn't notice the flaw since it still works. The reason is that the resulting numbers are so big they are casted and rounded to float or sth equivalent. This is _terrible_ code indeed!
In the first place this was an attempt to use Perl features for a quick, one-line hash of strings, but since I'm not a Perl guru this may be doomed to fail. Any better suggestion from a Perl champion?
A more traditional way to do it:
sub hash_string { my $sum = 0; foreach my $l (split //, $_[0]) { $sum = $sum + 31*ord($l) + 5; } return $sum; }
[...] my $repo_hash = hash_string($v[0]);
This is not a very good hash since a permutation will yield the same result. The following is much better
$sum = $sum + 31*ord($l)^$pos + 7;
but do we really need this? This is just for repo names after all, the extra exponentiation is superfluous in my opinion.
The offset (e.g. '+5') can be patched by other distributions make sure their repo have different colors.
Two suggestions:
1. Use Term::ANSIColor instead of raw ANSI color codes. This will make the code more readable and make life easier for distro's that need to patch in their own repo colors.
2. Provide a hash variable for hard-coding repo colors. It can be empty by default, making it very easy for distro's to patch in their official repos if the default gives poor results.
Something like:
use Term::ANSIColor;
my %repo_colors;
my @colors = ( color('blue'), color('red'), ... ); ... my $repo_name = ...; my $color = ( $repo_colors{$repo_name} || $colors[ hash($repo_name) ] );
Just throwing this out there... How important is it to have the repos different colours? Dan?
Allan
I agree, all this is sounding rather futile... This is causing debatable design issues, which are certainly worthless. But this is also one of the only 2 pacsearch features: per-repo colouring and local+sync searching.
-- Pierre Neidhardt
If the goal is to make pacsearch's output match that of 'pacman -{S,Q}s', then this per-repo coloring should be scrapped completely because those pacman commands use only one color for every repo. However, because the remaining benefit of pacsearch is a combined 'pacman -{S,Q}s' search, it would be useful to have one color for local packages and a different color for packages in the sync repos. Jason
participants (5)
-
Allan McRae
-
Andrew Gregory
-
Jason St. John
-
Martti Kühne
-
Pierre Neidhardt