|
Programming C, bash, Python, Perl, PHP, Java, you name it. |
|
Thread Tools | Display Modes |
|
|||
double checks in pkg-config, openbsd
I'm looking at /usr/bin/pkg-config on OpenBSD. Is there a reason to write this ...
Code:
if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) { @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) { unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); } Code:
if ($ENV{PKG_CONFIG_LIBDIR}) { @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); } elsif ($ENV{PKG_CONFIG_PATH}) { unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); } As far as I can tell, in boolean context a hash entry that doesn't exist will yield false, as will an entry that's there but undef, as will one that's there but one of the other false values (0, "", "0"). Neither does it seem like referring to a non-existent element will either cause a warning or autovivify anything. |
|
||||
Disclaimer. I don't speak perl, and cannot answer the why question. I can, however, provide you with who, so that you can ask them directly, or send them both a patch for their consideration.
The original development was by Marc Espie (espie@), at revision 1.16: Code:
Revision 1.16: download - view: text, markup, annotated - select for diffs Thu Dec 14 10:23:34 2006 UTC (7 years, 1 month ago) by espie Branches: MAIN Diff to: previous 1.15: preferred, coloured Changes since revision 1.15: +9 -7 lines add PKG_CONFIG_LIBDIR, okay bernd@ Code:
--- src/usr.bin/pkg-config/pkg-config 2006/12/10 10:58:41 1.15 +++ src/usr.bin/pkg-config/pkg-config 2006/12/14 10:23:34 1.16 @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $OpenBSD: pkg-config,v 1.15 2006/12/10 10:58:41 espie Exp $ +# $OpenBSD: pkg-config,v 1.16 2006/12/14 10:23:34 espie Exp $ #$CSK: pkgconfig.pl,v 1.39 2006/11/27 16:26:20 ckuethe Exp $ # Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org> @@ -24,17 +24,19 @@ use OpenBSD::PkgConfig; my @PKGPATH = qw(/usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig ); -if (defined($ENV{'PKG_CONFIG_PATH'}) && $ENV{'PKG_CONFIG_PATH'}) { - push(@PKGPATH, split /:/, $ENV{'PKG_CONFIG_PATH'}); +if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) { + @PKGPATH = split /:/, $ENV{PKG_CONFIG_LIBDIR}; +} elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) { + push(@PKGPATH, split /:/, $ENV{PKG_CONFIG_PATH}); } my $logfile = ''; -if (defined($ENV{'PKG_CONFIG_LOGFILE'}) && $ENV{'PKG_CONFIG_LOGFILE'}) { - $logfile = $ENV{'PKG_CONFIG_LOGFILE'}; +if (defined($ENV{PKG_CONFIG_LOGFILE}) && $ENV{PKG_CONFIG_LOGFILE}) { + $logfile = $ENV{PKG_CONFIG_LOGFILE}; } my $allow_uninstalled = - defined $ENV{'PKG_CONFIG_DISABLE_UNINSTALLED'} ? 0 : 1; + defined $ENV{PKG_CONFIG_DISABLE_UNINSTALLED} ? 0 : 1; my $found_uninstalled = 0; my $version = 0.19; # pretend to be this version of pkgconfig @@ -45,7 +47,7 @@ my $variables = {}; my $D = 0; # debug flag { - my $d = $ENV{'PKG_CONFIG_TOP_BUILD_DIR'}; + my $d = $ENV{PKG_CONFIG_TOP_BUILD_DIR}; if (defined $d) { $variables->{pc_top_builddir} = $d; } else { Code:
Revision 1.66: download - view: text, markup, annotated - select for diffs Thu Jun 16 08:38:30 2011 UTC (2 years, 7 months ago) by jasper Branches: MAIN Diff to: previous 1.65: preferred, coloured Changes since revision 1.65: +18 -15 lines - finally unconfuse emacs by using parentheses for split() Code:
--- src/usr.bin/pkg-config/pkg-config 2011/06/16 09:33:54 1.65 +++ src/usr.bin/pkg-config/pkg-config 2011/06/16 09:38:30 1.66 @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $OpenBSD: pkg-config,v 1.65 2011/06/16 08:33:54 jasper Exp $ +# $OpenBSD: pkg-config,v 1.66 2011/06/16 08:38:30 jasper Exp $ # $CSK: pkgconfig.pl,v 1.39 2006/11/27 16:26:20 ckuethe Exp $ # Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org> @@ -27,9 +27,9 @@ use OpenBSD::PkgConfig; my @PKGPATH = qw(/usr/lib/pkgconfig /usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig); if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) { - @PKGPATH = split /:/, $ENV{PKG_CONFIG_LIBDIR}; + @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) { - unshift(@PKGPATH, split /:/, $ENV{PKG_CONFIG_PATH}); + unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); } my $logfile = ''; @@ -124,7 +124,7 @@ my $rc = 0; { my $p = join(' ', @ARGV); $p =~ s/^\s+//; -@ARGV = split /\,?\s+/, $p; +@ARGV = split(/\,?\s+/, $p); } if ($mode{myminvers}) { @@ -211,9 +211,9 @@ if ($mode{variable}) { my $dep_cfg_list = simplify_and_reverse($cfg_full_list); if ($mode{cflags} || $mode{libs} || $mode{variable}) { - push @vlist, do_cflags($dep_cfg_list) if $mode{cflags}; - push @vlist, do_libs($dep_cfg_list) if $mode{libs}; - print join(' ', @vlist), "\n" if $rc == 0; + push @vlist, do_cflags($dep_cfg_list) if $mode{cflags}; + push @vlist, do_libs($dep_cfg_list) if $mode{libs}; + print join(' ', @vlist), "\n" if $rc == 0; } exit $rc; @@ -256,7 +256,9 @@ sub handle_config } }; - if (defined $mode{cflags} or $mode{static} or $mode{printrequiresprivate}) { + if (defined $mode{cflags} + or ($mode{static} && $mode{libs}) + or $mode{printrequiresprivate}) { &$get_props("Requires.private"); } &$get_props("Requires"); @@ -458,7 +460,8 @@ sub do_libs my $l = $configs{$pkg}->get_property('Libs', $variables); push(@$libs, @$l) if defined $l; } - + + # Get the linker path directives (-L). my $a = OpenBSD::PkgConfig->compress($libs, sub { local $_ = shift; @@ -476,7 +479,7 @@ sub do_libs if ($mode{libs} & 1) { my $b = OpenBSD::PkgConfig->rcompress($libs, - sub { shift =~ m/^-l/; }); + sub { shift =~ m/^-l/; }); return ($a, $b); } else { return $a; @@ -533,7 +536,7 @@ Usage: $0 [options] --print-provides - print all the modules the given package provides --print-requires - print all the modules the given package requires --print-requires-private - print all the private modules the given package requires ---silence-errors - don't print error messages in case of error +--silence-errors - don\'t print error messages in case of error --atleast-pkgconfig-version [version] - require a certain version of pkgconfig --cflags package [versionspec] [package [versionspec]] --cflags-only-I - only output -Iincludepath flags @@ -560,8 +563,8 @@ sub self_version my ($v) = @_; my (@a, @b); - @a = split /\./, $v; - @b = split /\./, $version; + @a = split(/\./, $v); + @b = split(/\./, $version); if (($b[0] >= $a[0]) && ($b[1] >= $a[1])) { return 0; @@ -593,8 +596,8 @@ sub compare $suffix_b[1] = $2; } - my @a = split /\./, $a; - my @b = split /\./, $b; + my @a = split(/\./, $a); + my @b = split(/\./, $b); while (@a && @b) { #so long as both lists have something if (!(@suffix_a || @suffix_b)) { |
|
|||
The part that nagged me wasn't that there was an elsif, it was that it said...
if (defined(A) && A) ... instead of just if (A) I think, for a check like this in boolean context, if it is the case that $ENV{SHELLVAR} is not in the hash or in the hash with an undefined value or in the hash with a blank or zero value, it's all the same as far as the condition and "if ($ENV{SHELLVAR})" covers it. My experiments seem to confirm this, but I could be missing something. Perl is pretty complicated when you try to analyze the dwim stuff. It seems to have been this way since the first version by Chris Kuethe. Good of you to look to the history. I should have done that. I'm a little wary sending this to misc. I've got this intuition this might be something that's really annoying for me to point out (though apparently not so annoying not to bother you guys with it ... sorry). The last person I want to annoy with novice Perl questions is Marc Espie. Pretty sure there's no practical harm or performance problem to the double check, it just bugs me reading it. Maybe I could try the local Perl mongers see if they know why someone would write it this way. Last edited by thirdm; 6th February 2014 at 07:18 PM. Reason: clarification |
|
|||
Right now, I don't have time to work on this anymore, but maybe somebody else has
A shell test program aptly called testit that sets the environment and calls that Perl snippet with some diagnostics: Code:
#!/bin/sh pkg_path='PKG_PATH=/home/p1:scp://j65nko@pkg_bulk.my.local:ftp://ftp.nluug.nl/pub/OpenBSD' pkg_config_libdir='PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib' env -i ${pkg_path} ${pkg_config_libdir} ./wonder_why.pl Code:
#!/usr/bin/perl use warnings; use strict; my @PKGPATH; sub show_env { print "The environment:\n===============\n"; foreach my $key (sort keys %ENV) { print $key, '=', $ENV{$key}, "\n"; } print "===============\n\n"; } sub pr_array { my $listref = shift; print "\n---- $listref -----\n"; for (@$listref) { print; print " \n"; } print "---- end of $listref -----\n"; } sub orig { defined($ENV{PKG_CONFIG_LIBDIR}) ? print "YES defined\n" : print "NOT defined\n"; $ENV{PKG_CONFIG_LIBDIR} ? print "YES bare\n" : print "NO bare\n"; if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) { print "\nPKG_CONFIG_LIBDIR test succeeded\n"; @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); pr_array(\@PKGPATH); } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) { print "\nPKG_CONFIG_PATH test succeeded\n"; unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); pr_array(\@PKGPATH); } } sub new { if ($ENV{PKG_CONFIG_LIBDIR}) { @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); } elsif ($ENV{PKG_CONFIG_PATH}) { unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); } } show_env() ; orig(); Code:
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
|
|||
Quote:
Code:
$ cat ./test.pl #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my %h = ( zero_value => 0, zero_string => '0', empty_string => '', undef_element => undef ); print Data::Dumper->Dump([\%h], [qw/h/]); for my $k (keys %h) { print "'$k'\t'$h{$k}'\n"; } print '=' x 4, $/; for my $k (keys %h) { print "'$k'\t'$h{$k}'\n" if defined $h{$k}; } $ chmod +x ./test.pl $ ./test.pl $h = { 'zero_value' => 0, 'undef_element' => undef, 'zero_string' => '0', 'empty_string' => '' }; 'zero_value' '0' Use of uninitialized value $h{"undef_element"} in concatenation (.) or string at ./autovivify.pl line 12. 'undef_element' '' 'zero_string' '0' 'empty_string' '' ==== 'zero_value' '0' 'zero_string' '0' 'empty_string' '' $ So to further this hand-waving explanation, I would say that the practice is simply stylistic. Plus, I haven't taken the time to fully grok the CVS history. Last edited by ocicat; 6th February 2014 at 07:40 PM. Reason: remove dangling articles... :) |
|
|||
Quote:
|
|
|||
Quote:
A difference between the code you've posted and the pkg-config case is that in your case you only need care if it's undefined before using the hash element. Had you wanted only to print "true" values and written ... print "'$k'\t'$h{$k}'\n" if defined $h{$k} and $h{$k}; (or how about print "'$k'\t'$h{$k}'\n" if exists $h{$k} and defined $h{$k} and $h{$k}; ) ... then I would be wondering why you hadn't simply written print "'$k'\t'$h{$k}'\n" if $h{$k} I can understand sprinkling extra defined checks around reflexively from getting yelled at by the Perl warnings. Maybe that's all it's about, plus C programmer instinct to guard against access to an undefined element, analogous to if (p && *p != '\0') ... . In which case, criticizing that practice might be annoying. I'll look more closely at your script tonight, J65nko. My manager just got after me to make progress on what I'm supposed to be working on. |
|
|||
Quote:
Code:
$ cat test.pl #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my %h = ( zero_value => 0, zero_string => '0', empty_string => '', undef_element => undef ); print Data::Dumper->Dump([\%h], [qw/h/]); print '=' x 4, $/; for my $k (keys %h) { print "'$k'\t'$h{$k}'\n"; } print '=' x 4, $/; for my $k (keys %h) { print "'$k'\t'$h{$k}'\n" if $h{$k}; } print '=' x 4, $/; for my $k (keys %h) { print "'$k'\t'$h{$k}'\n" if defined $h{$k}; } $ test.pl $h = { 'zero_value' => 0, 'undef_element' => undef, 'zero_string' => '0', 'empty_string' => '' }; ==== 'zero_value' '0' Use of uninitialized value $h{"undef_element"} in concatenation (.) or string at ./autovivify.pl line 13. 'undef_element' '' 'zero_string' '0' 'empty_string' '' ==== ==== 'zero_value' '0' 'zero_string' '0' 'empty_string' '' $ Last edited by ocicat; 6th February 2014 at 08:32 PM. |
|
|||
From the "Perl Cookbook" chapter about hashes by Christiansen and Torkington:
Quote:
Code:
#!/usr/bin/perl use warnings; use strict; my %age = (); my $thing; $age{'Toddler'} = 3; $age{'Unborn'} = 0; $age{'Phantasm'} = undef; foreach $thing('Toddler', 'Unborn', 'Phantasm', 'Relic') { print "$thing: "; print "Exists " if exists $age{$thing}; print "Defined " if defined $age{$thing}; print "True " if $age{$thing}; print "\n"; } Code:
Toddler: Exists Defined True Unborn: Exists Defined Phantasm: Exists Relic: $age{'Unborn'} fails the truth test because the number 0 is one of Perl's false values. $age{'Phantasm'} only exists because it has been given a value in the hash. Because that value is 'undef' it does not pass the test for definedness. 'undef' is also a Perl false value.
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
|
|||
Quote:
Code:
#!/usr/bin/perl use warnings; use strict; use feature 'say'; my @PKGPATH = '/usr/lib/pkgconfig'; sub show_env { say "The environment:\n==============="; foreach my $key (sort keys %ENV) { say $key, '=', $ENV{$key}; } say "===============\n"; } sub orig { defined($ENV{PKG_CONFIG_LIBDIR}) ? say "YES defined" : say "NOT defined"; $ENV{PKG_CONFIG_LIBDIR} ? say "YES bare" : say "NO bare"; if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) { say "\nPKG_CONFIG_LIBDIR test succeeded"; @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); { local $, = "\n"; say 'PKGPATH...', @PKGPATH } } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) { say "\nPKG_CONFIG_PATH test succeeded"; unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); { local $, = "\n"; say 'PKGPATH...', @PKGPATH } } } sub new { defined($ENV{PKG_CONFIG_LIBDIR}) ? say "YES defined" : say "NOT defined"; $ENV{PKG_CONFIG_LIBDIR} ? say "YES bare" : say "NO bare"; if ($ENV{PKG_CONFIG_LIBDIR}) { say "\nPKG_CONFIG_LIBDIR test succeeded"; @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR}); { local $, = "\n"; say 'PKGPATH...', @PKGPATH } } elsif ($ENV{PKG_CONFIG_PATH}) { say "\nPKG_CONFIG_PATH test succeeded"; unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH})); { local $, = "\n"; say 'PKGPATH...', @PKGPATH } } } show_env(); die unless @ARGV == 1; #say 'running ', @ARGV; no strict 'refs'; $ARGV[0]->(); say "\n"; Code:
#!/bin/sh pkg_config_libdir='PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib' pkg_config_path='PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig'; for fn in orig new; do { env -i ${pkg_config_libdir} ${pkg_config_path} ./wonder_why.pl $fn env -i ${pkg_config_path} ./wonder_why.pl $fn } | tee $fn.out done if cmp orig.out new.out; then echo Result: output identical else diff -u orig.out new.out fi Code:
The environment: =============== PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig =============== YES defined YES bare PKG_CONFIG_LIBDIR test succeeded PKGPATH... /usr/bin/local/lib /sbin/lib /usr/sbin/lib The environment: =============== PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig =============== NOT defined NO bare PKG_CONFIG_PATH test succeeded PKGPATH... /usr/X11R6/lib/pkgconfig /usr/X11R6/share/pkgconfig /usr/lib/pkgconfig The environment: =============== PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig =============== YES defined YES bare PKG_CONFIG_LIBDIR test succeeded PKGPATH... /usr/bin/local/lib /sbin/lib /usr/sbin/lib The environment: =============== PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig =============== NOT defined NO bare PKG_CONFIG_PATH test succeeded PKGPATH... /usr/X11R6/lib/pkgconfig /usr/X11R6/share/pkgconfig /usr/lib/pkgconfig Result: output identical $ |
|
|||
Quote:
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
OpenBSD-5.4::PF config issue | Atlantis | OpenBSD Security | 7 | 15th February 2014 01:30 PM |
OpenBSD 5.3 X server config | danielcrvg | OpenBSD General | 18 | 20th June 2013 01:03 AM |
double nat routing | giagni | General software and network | 5 | 22nd May 2009 07:10 PM |
double posting? | ocicat | Feedback and Suggestions | 6 | 26th May 2008 12:34 AM |
openVPN 2.1_rc7 (server) on openBSD 4.3 config examples | s2scott | Guides | 2 | 23rd May 2008 06:16 PM |