[BACK]Return to pkg-config CVS log [TXT][DIR] Up to [local] / src / usr.bin / pkg-config

Annotation of src/usr.bin/pkg-config/pkg-config, Revision 1.35

1.1       ckuethe     1: #!/usr/bin/perl
1.35    ! espie       2: # $OpenBSD: pkg-config,v 1.34 2011/03/14 08:43:59 jasper Exp $
1.1       ckuethe     3:
                      4: #$CSK: pkgconfig.pl,v 1.39 2006/11/27 16:26:20 ckuethe Exp $
                      5: # Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org>
                      6: #
                      7: # Permission to use, copy, modify, and distribute this software for any
                      8: # purpose with or without fee is hereby granted, provided that the above
                      9: # copyright notice and this permission notice appear in all copies.
                     10: #
                     11: # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12: # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13: # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14: # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15: # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16: # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17: # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:
                     19: use strict;
                     20: use warnings;
                     21: use Getopt::Long;
1.4       espie      22: use File::Basename;
1.11      espie      23: use OpenBSD::PkgConfig;
1.1       ckuethe    24:
1.27      jasper     25: my @PKGPATH = qw(/usr/lib/pkgconfig /usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig);
1.1       ckuethe    26:
1.16      espie      27: if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
                     28:        @PKGPATH = split /:/, $ENV{PKG_CONFIG_LIBDIR};
                     29: } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
1.24      ckuethe    30:        unshift(@PKGPATH, split /:/, $ENV{PKG_CONFIG_PATH});
1.1       ckuethe    31: }
                     32:
                     33: my $logfile = '';
1.16      espie      34: if (defined($ENV{PKG_CONFIG_LOGFILE}) && $ENV{PKG_CONFIG_LOGFILE}) {
                     35:        $logfile = $ENV{PKG_CONFIG_LOGFILE};
1.1       ckuethe    36: }
                     37:
1.33      jasper     38: my $allow_uninstalled =
1.16      espie      39:        defined $ENV{PKG_CONFIG_DISABLE_UNINSTALLED} ? 0 : 1;
1.14      espie      40: my $found_uninstalled = 0;
                     41:
1.32      jasper     42: my $version = 0.23; # pretend to be this version of pkgconfig
1.10      espie      43:
                     44: my %configs = ();
1.35    ! espie      45: setup_self();
        !            46:
1.10      espie      47: my %mode = ();
1.11      espie      48: my $variables = {};
1.10      espie      49: my $D = 0; # debug flag
1.1       ckuethe    50:
1.35    ! espie      51: $variables->{pc_top_builddir} = $ENV{PKG_CONFIG_TOP_BUILD_DIR} //
        !            52:        '$(top_builddir)';
        !            53:
        !            54: $variables->{pc_sysrootdir} //= $ENV{PKG_CONFIG_SYSROOT_DIR};
        !            55: # The default '/' is implied.
1.29      jasper     56:
1.35    ! espie      57: $D = 1 if defined $ENV{PKG_CONFIG_DEBUG_SPEW};
1.7       ckuethe    58:
1.4       espie      59: if ($logfile) {
1.35    ! espie      60:        open my $L, ">>" , $logfile or die;
        !            61:        print $L beautify_list($_, @ARGV), "\n";
1.4       espie      62:        close $L;
1.1       ckuethe    63: }
                     64:
                     65: # combo arg-parsing and dependency resolution loop. Hopefully when the loop
                     66: # terminates, we have a full list of packages upon which we depend, and the
                     67: # right set of compiler and linker flags to use them.
                     68: #
                     69: # as each .pc file is loaded, it is stored in %configs, indexed by package
                     70: # name. this makes it possible to then pull out flags or do substitutions
1.34      jasper     71: # without having to go back and reload the files from disk.
1.1       ckuethe    72:
                     73: Getopt::Long::Configure('no_ignore_case');
                     74: GetOptions(    'debug' => \$D,
                     75:                'help' => \&help, #does not return
                     76:                'usage' => \&help, #does not return
1.14      espie      77:                'list-all' => \$mode{list},
1.1       ckuethe    78:                'version' => sub { print "$version\n" ; exit(0);} ,
1.11      espie      79:                'errors-to-stdout' => sub { $mode{estdout} = 1},
                     80:                'print-errors' => sub { $mode{printerr} = 1},
                     81:                'silence-errors' => sub { $mode{printerr} = 0},
1.23      jasper     82:                'short-errors' => sub { $mode{printerr} = 0},
1.14      espie      83:                'atleast-pkgconfig-version=s' => \$mode{myminvers},
1.30      jasper     84:                'print-provides' => \$mode{printprovides},
                     85:                'print-requires' => \$mode{printrequires},
                     86:                'print-requires-private' => \$mode{printrequiresprivate},
1.11      espie      87:
                     88:                'cflags' => sub { $mode{cflags} = 3},
                     89:                'cflags-only-I' => sub { $mode{cflags} |= 1},
                     90:                'cflags-only-other' => sub { $mode{cflags} |= 2},
                     91:                'libs' => sub { $mode{libs} = 7},
                     92:                'libs-only-l' => sub { $mode{libs} |= 1},
                     93:                'libs-only-L' => sub { $mode{libs} |= 2},
                     94:                'libs-only-other' => sub { $mode{libs} |= 4},
                     95:                'exists' => sub { $mode{exists} = 1} ,
                     96:                'static' => sub { $mode{static} = 1},
                     97:                'uninstalled' => sub { $mode{uninstalled} = 1},
1.14      espie      98:                'atleast-version=s' => \$mode{minversion},
                     99:                'exact-version=s' => \$mode{exactversion},
                    100:                'max-version=s' => \$mode{maxversion},
1.13      espie     101:                'modversion' => \$mode{modversion},
1.11      espie     102:                'variable=s' => \$mode{variable},
                    103:                'define-variable=s' => $variables,
1.1       ckuethe   104:        );
                    105:
1.14      espie     106: # Initial value of printerr depends on the options...
                    107: if (!defined $mode{printerr}) {
1.33      jasper    108:        if (defined $mode{libs} || defined $mode{cflags}
1.14      espie     109:            || defined $mode{version} || defined $mode{list}) {
                    110:                $mode{printerr} = 1;
                    111:        } else {
                    112:                $mode{printerr} = 0;
                    113:        }
                    114: }
                    115:
1.35    ! espie     116: print STDERR "\n", beautify_list($0, @ARGV), "\n" if $D;
1.13      espie     117:
                    118: my $rc = 0;
1.1       ckuethe   119:
1.14      espie     120: # XXX pkg-config is a bit weird
1.10      espie     121: {
                    122: my $p = join(' ', @ARGV);
1.14      espie     123: $p =~ s/^\s+//;
1.35    ! espie     124: @ARGV = split /\,?\s+/, $p;
1.10      espie     125: }
1.1       ckuethe   126:
1.14      espie     127: if ($mode{myminvers}) {
                    128:        exit self_version($mode{myminvers});
                    129: }
                    130:
                    131: if ($mode{list}) {
                    132:        exit do_list();
1.1       ckuethe   133: }
                    134:
1.13      espie     135: my $cfg_full_list = [];
1.14      espie     136: my $top_config = [];
1.1       ckuethe   137:
                    138: while (@ARGV){
1.13      espie     139:        my $p = shift @ARGV;
                    140:        my $op = undef;
                    141:        my $v = undef;
1.35    ! espie     142:        if (@ARGV >= 2  && $ARGV[0] =~ /^[<=>]+$/ &&
        !           143:            $ARGV[1] =~ /^[\d\.]+$/) {
1.13      espie     144:                $op = shift @ARGV;
                    145:                $v = shift @ARGV;
1.1       ckuethe   146:        }
1.13      espie     147:        handle_config($p, $op, $v, $cfg_full_list);
1.14      espie     148:        push(@$top_config, $p);
                    149: }
                    150:
                    151: if ($mode{exists}) {
                    152:        exit $rc;
                    153: }
                    154:
                    155: if ($mode{uninstalled}) {
                    156:        $rc = 1 unless $found_uninstalled;
                    157:        exit $rc;
1.11      espie     158: }
1.1       ckuethe   159:
1.30      jasper    160: if ($mode{modversion} || $mode{printprovides}) {
1.14      espie     161:        for my $pkg (@$top_config) {
                    162:                do_modversion($pkg);
                    163:        }
                    164: }
1.13      espie     165:
1.30      jasper    166: if ($mode{printrequires} || $mode{printrequiresprivate}) {
                    167:        for my $pkg (@$top_config) {
                    168:                print_requires($pkg);
                    169:        }
                    170: }
                    171:
1.14      espie     172: if ($mode{minversion}) {
                    173:        my $v = $mode{minversion};
                    174:        for my $pkg (@$top_config) {
                    175:                $rc = 1 unless versionmatch($configs{$pkg}, '>=', $v);
                    176:        }
                    177:        exit $rc;
                    178: }
                    179:
                    180: if ($mode{exactversion}) {
                    181:        my $v = $mode{exactversion};
                    182:        for my $pkg (@$top_config) {
                    183:                $rc = 1 unless versionmatch($configs{$pkg}, '=', $v);
                    184:        }
                    185:        exit $rc;
                    186: }
                    187:
                    188: if ($mode{minversion}) {
                    189:        my $v = $mode{maxversion};
                    190:        for my $pkg (@$top_config) {
                    191:                $rc = 1 unless versionmatch($configs{$pkg}, '<=', $v);
                    192:        }
                    193:        exit $rc;
                    194: }
                    195:
                    196: my @vlist = ();
                    197:
                    198: if ($mode{variable}) {
                    199:        for my $pkg (@$top_config) {
                    200:                do_variable($pkg, $mode{variable});
                    201:        }
                    202: }
                    203:
                    204: my $dep_cfg_list = simplify_and_reverse($cfg_full_list);
                    205:
                    206: if ($mode{cflags} || $mode{libs} || $mode{variable}) {
                    207:     push @vlist, do_cflags($dep_cfg_list) if $mode{cflags};
                    208:     push @vlist, do_libs($dep_cfg_list) if $mode{libs};
1.17      espie     209:     print join(' ', @vlist), "\n" if $rc == 0;
1.1       ckuethe   210: }
                    211:
1.13      espie     212: exit $rc;
1.1       ckuethe   213:
                    214: ###########################################################################
                    215:
1.11      espie     216: sub handle_config
                    217: {
1.13      espie     218:        my ($p, $op, $v, $list) = @_;
1.35    ! espie     219:        my $cfg = cache_find_config($p);
1.13      espie     220:
1.35    ! espie     221:        unshift @$list, $p if defined $cfg;
1.11      espie     222:
1.35    ! espie     223:        if (!defined $cfg) {
        !           224:                $rc = 1;
        !           225:                return undef;
        !           226:        }
1.15      espie     227:
1.35    ! espie     228:        if (defined $op) {
        !           229:                if (!versionmatch($cfg, $op, $v)) {
        !           230:                        mismatch($p, $cfg, $op, $v) if $mode{printerr};
1.13      espie     231:                        $rc = 1;
                    232:                        return undef;
                    233:                }
1.35    ! espie     234:        }
1.11      espie     235:
1.35    ! espie     236:        my $deps = $cfg->get_property('Requires', $variables);
        !           237:        if (defined $deps) {
        !           238:                for my $dep (@$deps) {
        !           239:                        if ($dep =~ m/^(.*?)\s*([<=>]+)\s*([\d\.]+)$/) {
        !           240:                                handle_config($1, $2, $3, $list);
        !           241:                        } else {
        !           242:                                handle_config($dep, undef, undef, $list);
1.26      jasper    243:                        }
                    244:                }
1.35    ! espie     245:                print STDERR "package $p requires ",
        !           246:                    join(',', @$deps), "\n" if $D;
        !           247:        }
1.26      jasper    248:
1.35    ! espie     249:        $deps = $cfg->get_property('Requires.private', $variables);
        !           250:        if (defined $deps) {
        !           251:                for my $dep (@$deps) {
        !           252:                        if ($dep =~ m/^(.*?)\s*([<=>]+)\s*([\d\.]+)$/) {
        !           253:                                handle_config($1, $2, $3, $list);
        !           254:                        } else {
        !           255:                                handle_config($dep, undef, undef, $list);
1.13      espie     256:                        }
                    257:                }
1.35    ! espie     258:                print STDERR "package $p requires (private)",
        !           259:                    join(',', @$deps), "\n" if $D;
1.11      espie     260:        }
                    261: }
                    262:
1.1       ckuethe   263: # look for the .pc file in each of the PKGPATH elements. Return the path or
                    264: # undef if it's not there
1.4       espie     265: sub pathresolve
                    266: {
                    267:        my ($p) = @_;
                    268:
1.14      espie     269:        if ($allow_uninstalled && $p !~ m/\-uninstalled$/) {
                    270:                foreach my $d (@PKGPATH) {
                    271:                        my $f = "$d/$p-uninstalled.pc";
                    272:                        print STDERR "pathresolve($p) looking in $f\n" if $D;
                    273:                        if (-f $f) {
                    274:                                $found_uninstalled = 1;
                    275:                                return $f;
                    276:                        }
                    277:                }
                    278:        }
                    279:
1.4       espie     280:        foreach my $d (@PKGPATH) {
1.10      espie     281:                my $f = "$d/$p.pc";
1.4       espie     282:                print STDERR "pathresolve($p) looking in $f\n" if $D;
1.10      espie     283:                return $f if -f $f;
1.1       ckuethe   284:        }
1.10      espie     285:        return undef;
1.1       ckuethe   286: }
                    287:
1.11      espie     288: sub get_config
                    289: {
                    290:        my ($f) = @_;
                    291:
                    292:        my $cfg;
1.33      jasper    293:        eval {
1.11      espie     294:            $cfg = OpenBSD::PkgConfig->read_file($f);
                    295:        };
                    296:        if (!$@) {
                    297:                return $cfg;
                    298:        } else {
1.12      espie     299:                print STDERR $@, "\n" if $D;
1.11      espie     300:        }
                    301:        return undef;
                    302: }
                    303:
1.13      espie     304: sub cache_find_config
                    305: {
                    306:        my $name = shift;
                    307:
                    308:        print STDERR "processing $name\n" if $D;
                    309:
                    310:        if (exists $configs{$name}) {
                    311:                return $configs{$name};
                    312:        } else {
                    313:                return $configs{$name} = find_config($name);
                    314:        }
                    315: }
                    316:
1.35    ! espie     317: # pkg-config won't install a pkg-config.pc file itself, but it may be
        !           318:
        !           319: # listed as a dependency in other files.
        !           320: # so, prime the cache with self
        !           321: sub setup_self
        !           322: {
        !           323:        my $pkg_pc = OpenBSD::PkgConfig->new;
        !           324:        $pkg_pc->add_property('Version', $version);
        !           325:        $configs{'pkg-config'} = $pkg_pc;
        !           326: }
        !           327:
1.11      espie     328: sub find_config
                    329: {
                    330:        my ($p) = @_;
                    331:        my $f = pathresolve($p);
                    332:        if (defined $f) {
                    333:                return get_config($f);
                    334:        }
1.13      espie     335:        if ($mode{printerr}) {
1.33      jasper    336:            print STDERR
1.13      espie     337:                "Package $p was not found in the pkg-config search path\n";
                    338:        }
1.11      espie     339:        return undef;
                    340: }
1.1       ckuethe   341:
1.11      espie     342: sub stringize
1.4       espie     343: {
1.11      espie     344:        my $list = shift;
1.21      simon     345:        my $sep = shift || ',';
1.4       espie     346:
1.11      espie     347:        if (defined $list) {
1.21      simon     348:                return join($sep, @$list)
1.11      espie     349:        } else {
                    350:                return '';
1.1       ckuethe   351:        }
                    352: }
                    353:
                    354: #if the variable option is set, pull out the named variable
1.4       espie     355: sub do_variable
                    356: {
1.11      espie     357:        my ($p, $v) = @_;
1.1       ckuethe   358:
1.13      espie     359:        my $cfg = cache_find_config($p);
                    360:
                    361:        if (defined $cfg) {
1.11      espie     362:                my $value = $cfg->get_variable($v, $variables);
                    363:                if (defined $value) {
1.13      espie     364:                        push(@vlist, $value);
1.11      espie     365:                }
1.19      espie     366:                return undef;
1.11      espie     367:        }
1.19      espie     368:        $rc = 1;
1.1       ckuethe   369: }
                    370:
1.30      jasper    371: #if the modversion or print-provides options are set,
                    372: #pull out the compiler flags
1.4       espie     373: sub do_modversion
                    374: {
1.11      espie     375:        my ($p) = @_;
1.1       ckuethe   376:
1.13      espie     377:        my $cfg = cache_find_config($p);
                    378:
                    379:        if (defined $cfg) {
1.11      espie     380:                my $value = $cfg->get_property('Version', $variables);
                    381:                if (defined $value) {
1.30      jasper    382:                        if (!defined($mode{printprovides})){
                    383:                                print stringize($value), "\n";
                    384:                                return undef;
                    385:                        } else {
                    386:                                print "$p = " . stringize($value) . "\n";
                    387:                                return undef;
                    388:                        }
1.11      espie     389:                }
                    390:        }
1.13      espie     391:        $rc = 1;
1.1       ckuethe   392: }
                    393:
                    394: #if the cflags option is set, pull out the compiler flags
1.4       espie     395: sub do_cflags
                    396: {
1.14      espie     397:        my $list = shift;
                    398:
1.11      espie     399:        my $cflags = [];
1.1       ckuethe   400:
1.14      espie     401:        foreach my $pkg (@$list) {
1.11      espie     402:                my $l = $configs{$pkg}->get_property('Cflags', $variables);
                    403:                push(@$cflags, @$l) if defined $l;
                    404:        }
1.32      jasper    405:        my $a = OpenBSD::PkgConfig->compress($cflags,
1.11      espie     406:                sub {
                    407:                        local $_ = shift;
                    408:                        if (($mode{cflags} & 1) && /^-I/ ||
                    409:                            ($mode{cflags} & 2) && !/^-I/) {
                    410:                            return 1;
                    411:                        } else {
                    412:                            return 0;
1.4       espie     413:                        }
1.11      espie     414:                });
1.32      jasper    415:        if (defined($a) && defined($variables->{pc_sysrootdir})){
                    416:                $a =~ s/^-I/$&$variables->{pc_sysrootdir}/g;
                    417:        }
                    418:
                    419:        return $a;
1.1       ckuethe   420: }
                    421:
                    422: #if the lib option is set, pull out the linker flags
1.4       espie     423: sub do_libs
                    424: {
1.14      espie     425:        my $list = shift;
                    426:
1.11      espie     427:        my $libs = [];
1.1       ckuethe   428:
1.14      espie     429:        foreach my $pkg (@$list) {
1.11      espie     430:                my $l = $configs{$pkg}->get_property('Libs', $variables);
                    431:                push(@$libs, @$l) if defined $l;
                    432:        }
1.13      espie     433:        my $a = OpenBSD::PkgConfig->compress($libs,
1.11      espie     434:                sub {
                    435:                        local $_ = shift;
1.13      espie     436:                        if (($mode{libs} & 2) && /^-L/ ||
1.11      espie     437:                            ($mode{libs} & 4) && !/^-[lL]/) {
                    438:                            return 1;
                    439:                        } else {
                    440:                            return 0;
1.4       espie     441:                        }
1.11      espie     442:                });
1.32      jasper    443:
                    444:        if (defined($variables->{pc_sysrootdir})){
                    445:                $a =~ s/^-[lL]/$&$variables->{pc_sysrootdir}/g;
                    446:        }
                    447:
1.13      espie     448:        if ($mode{libs} & 1) {
                    449:                my $b = OpenBSD::PkgConfig->rcompress($libs,
                    450:                        sub { shift =~ m/^-l/; });
                    451:                return ($a, $b);
                    452:        } else {
                    453:                return $a;
                    454:        }
1.1       ckuethe   455: }
                    456:
                    457: #list all packages
1.4       espie     458: sub do_list
                    459: {
1.1       ckuethe   460:        my ($p, $x, $y, @files, $fname, $name);
1.20      espie     461:        my $error = 0;
                    462:
1.33      jasper    463:        foreach my $p (@PKGPATH) {
                    464:                push(@files, <$p/*.pc>);
1.4       espie     465:        }
1.1       ckuethe   466:
                    467:        # Scan the lengths of the package names so I can make a format
                    468:        # string to line the list up just like the real pkgconfig does.
                    469:        $x = 0;
1.4       espie     470:        foreach my $f (@files) {
                    471:                $fname = basename($f, '.pc');
                    472:                $y = length $fname;
1.1       ckuethe   473:                $x = (($y > $x) ? $y : $x);
                    474:        }
                    475:        $x *= -1;
                    476:
1.4       espie     477:        foreach my $f (@files) {
1.11      espie     478:                my $cfg = get_config($f);
1.20      espie     479:                if (!defined $cfg) {
                    480:                        print STDERR "Problem reading file $f\n";
                    481:                        $error = 1;
                    482:                        next;
                    483:                }
1.4       espie     484:                $fname = basename($f, '.pc');
1.33      jasper    485:                printf("%${x}s %s - %s\n", $fname,
                    486:                    stringize($cfg->get_property('Name', $variables)),
1.21      simon     487:                    stringize($cfg->get_property('Description', $variables),
                    488:                    ' '));
1.1       ckuethe   489:        }
1.20      espie     490:        return $error;
1.1       ckuethe   491: }
                    492:
1.4       espie     493: sub help
                    494: {
1.1       ckuethe   495:        print <<EOF
                    496: Usage: $0 [options]
                    497: --debug        - turn on debugging output
                    498: --help - this message
                    499: --usage - this message
                    500: --list-all - show all packages that $0 can find
1.8       ckuethe   501: --version - print version of pkgconfig
                    502: --errors-to-stdout - direct error messages to stdout rather than stderr
                    503: --print-errors - print error messages in case of error
1.34      jasper    504: --print-provides - print all the modules the given package provides
                    505: --print-requires - print all the modules the given package requires
                    506: --print-requires-private - print all the private modules the given package requires
1.8       ckuethe   507: --silence-errors - don't print error messages in case of error
1.1       ckuethe   508: --atleast-pkgconfig-version [version] - require a certain version of pkgconfig
                    509: --cflags package [versionspec] [package [versionspec]]
                    510: --cflags-only-I - only output -Iincludepath flags
                    511: --cflags-only-other - only output flags that are not -I
1.11      espie     512: --define-variable=NAME=VALUE - define variables
1.1       ckuethe   513: --libs package [versionspec] [package [versionspec]]
                    514: --libs-only-l - only output -llib flags
                    515: --libs-only-L - only output -Llibpath flags
                    516: --libs-only-other - only output flags that are not -l or -L
                    517: --exists package [versionspec] [package [versionspec]]
                    518: --uninstalled - allow for uninstalled versions to be used
1.8       ckuethe   519: --static - adjust output for static linking
                    520: --atleast-version [version] - require a certain version of a package
                    521: --modversion [package] - query the version of a package
                    522: --variable var package - return the definition of <var> in <package>
1.1       ckuethe   523: EOF
                    524: ;
1.22      simon     525:        exit 0;
1.1       ckuethe   526: }
                    527:
                    528: # do we meet/beat the version the caller requested?
1.4       espie     529: sub self_version
                    530: {
                    531:        my ($v) = @_;
                    532:        my (@a, @b);
                    533:
                    534:        @a = split /\./, $v;
                    535:        @b = split /\./, $version;
1.1       ckuethe   536:
1.4       espie     537:        if (($b[0] >= $a[0]) && ($b[1] >= $a[1])) {
1.14      espie     538:                return 0;
1.1       ckuethe   539:        } else {
1.14      espie     540:                return 1;
                    541:        }
                    542: }
                    543:
                    544: sub compare
                    545: {
                    546:        my ($a, $b) = @_;
                    547:
1.28      jasper    548:        return 0 if ($a eq $b);
1.14      espie     549:
                    550:        my @a = split /\./, $a;
                    551:        my @b = split /\./, $b;
                    552:
                    553:        while (@a && @b) { #so long as both lists have something
                    554:                return 1 if $a[0] > $b[0];
                    555:                return -1 if $a[0] < $b[0];
                    556:                shift @a; shift @b;
                    557:        }
                    558:        return 1 if @a;
                    559:        return -1 if @b;
                    560:        return 0;
1.1       ckuethe   561: }
                    562:
                    563: # got a package meeting the requested specific version?
1.4       espie     564: sub versionmatch
                    565: {
1.14      espie     566:        my ($cfg, $op, $want) = @_;
1.33      jasper    567:
1.1       ckuethe   568:        # can't possibly match if we can't find the file
1.11      espie     569:        return 0 if !defined $cfg;
                    570:
1.14      espie     571:        my $inst = stringize($cfg->get_property('Version', $variables));
1.11      espie     572:
1.1       ckuethe   573:        # can't possibly match if we can't find the version string
1.14      espie     574:        return 0 if $inst eq '';
1.1       ckuethe   575:
1.14      espie     576:        print "comparing $want (wanted) to $inst (installed)\n" if $D;
                    577:        my $value = compare($inst, $want);
1.31      jasper    578:        if    ($op eq '>=') { return $value >= 0; }
                    579:        elsif ($op eq '=')  { return $value == 0; }
                    580:        elsif ($op eq '!=') { return $value != 0; }
                    581:        elsif ($op eq '<')  { return $value < 0; }
                    582:        elsif ($op eq '>')  { return $value > 0; }
                    583:        elsif ($op eq '<=') { return $value <= 0; }
1.13      espie     584: }
                    585:
                    586: sub mismatch
                    587: {
                    588:        my ($p, $cfg, $op, $v) = @_;
                    589:        print STDERR "Requested '$p $op $v' but version of ",
                    590:            stringize($cfg->get_property('Name')), " is ",
                    591:            stringize($cfg->get_property('Version')), "\n";
                    592: }
                    593:
                    594: sub simplify_and_reverse
                    595: {
                    596:        my $reqlist = shift;
                    597:        my $dejavu = {};
                    598:        my $result = [];
                    599:
                    600:        for my $item (@$reqlist) {
                    601:                if (!$dejavu->{$item}) {
                    602:                        unshift @$result, $item;
                    603:                        $dejavu->{$item} = 1;
                    604:                }
                    605:        }
                    606:        return $result;
1.30      jasper    607: }
                    608:
                    609: # retrieve and print Requires(.private)
                    610: sub print_requires
                    611: {
                    612:        my ($p) = @_;
                    613:
                    614:        my $cfg = cache_find_config($p);
                    615:
                    616:        if (defined($cfg)) {
                    617:                my $value;
                    618:
                    619:                if (defined($mode{printrequires})) {
                    620:                        $value = $cfg->get_property('Requires', $variables);
                    621:                } elsif (defined($mode{printrequiresprivate})) {
                    622:                        $value = $cfg->get_property('Requires.private', $variables);
                    623:                } else {
                    624:                        print STDERR "Unknown mode for print_requires.\n" if $D;
                    625:                        return 1;
                    626:                }
                    627:
                    628:                if (defined($value)) {
                    629:                        print "$_\n" foreach (@$value);
                    630:                        return undef;
                    631:                }
                    632:        }
                    633:
                    634:        $rc = 1;
1.35    ! espie     635: }
        !           636:
        !           637: sub beautify_list
        !           638: {
        !           639:        return join(' ', map {"[$_]"} @_);
1.1       ckuethe   640: }