[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.23

1.1       ckuethe     1: #!/usr/bin/perl
1.23    ! jasper      2: # $OpenBSD: pkg-config,v 1.22 2008/09/06 10:49:28 simon 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:
                     25: my @PKGPATH = qw(/usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig );
                     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}) {
                     30:        push(@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.14      espie      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.23    ! jasper     42: my $version = 0.21; # pretend to be this version of pkgconfig
1.10      espie      43:
                     44: my %configs = ();
                     45: my %mode = ();
1.11      espie      46: my $variables = {};
1.10      espie      47: my $D = 0; # debug flag
1.1       ckuethe    48:
1.14      espie      49: {
1.16      espie      50:     my $d = $ENV{PKG_CONFIG_TOP_BUILD_DIR};
1.14      espie      51:     if (defined $d) {
                     52:            $variables->{pc_top_builddir} = $d;
                     53:     } else {
                     54:            $variables->{pc_top_builddir} = '$(top_builddir)';
                     55:     }
                     56: }
1.7       ckuethe    57:
1.4       espie      58: if ($logfile) {
                     59:        open my $L, ">>" . $logfile;
                     60:        print $L '[' . join('] [', $0, @ARGV) . "]\n";
                     61:        close $L;
1.1       ckuethe    62: }
                     63:
                     64: # combo arg-parsing and dependency resolution loop. Hopefully when the loop
                     65: # terminates, we have a full list of packages upon which we depend, and the
                     66: # right set of compiler and linker flags to use them.
                     67: #
                     68: # as each .pc file is loaded, it is stored in %configs, indexed by package
                     69: # name. this makes it possible to then pull out flags or do substitutions
                     70: # without having to go back and reload the files from disk
                     71:
                     72: Getopt::Long::Configure('no_ignore_case');
                     73: GetOptions(    'debug' => \$D,
                     74:                'help' => \&help, #does not return
                     75:                'usage' => \&help, #does not return
1.14      espie      76:                'list-all' => \$mode{list},
1.1       ckuethe    77:                'version' => sub { print "$version\n" ; exit(0);} ,
1.11      espie      78:                'errors-to-stdout' => sub { $mode{estdout} = 1},
                     79:                'print-errors' => sub { $mode{printerr} = 1},
                     80:                'silence-errors' => sub { $mode{printerr} = 0},
1.23    ! jasper     81:                'short-errors' => sub { $mode{printerr} = 0},
1.14      espie      82:                'atleast-pkgconfig-version=s' => \$mode{myminvers},
1.11      espie      83:
                     84:                'cflags' => sub { $mode{cflags} = 3},
                     85:                'cflags-only-I' => sub { $mode{cflags} |= 1},
                     86:                'cflags-only-other' => sub { $mode{cflags} |= 2},
                     87:                'libs' => sub { $mode{libs} = 7},
                     88:                'libs-only-l' => sub { $mode{libs} |= 1},
                     89:                'libs-only-L' => sub { $mode{libs} |= 2},
                     90:                'libs-only-other' => sub { $mode{libs} |= 4},
                     91:                'exists' => sub { $mode{exists} = 1} ,
                     92:                'static' => sub { $mode{static} = 1},
                     93:                'uninstalled' => sub { $mode{uninstalled} = 1},
1.14      espie      94:                'atleast-version=s' => \$mode{minversion},
                     95:                'exact-version=s' => \$mode{exactversion},
                     96:                'max-version=s' => \$mode{maxversion},
1.13      espie      97:                'modversion' => \$mode{modversion},
1.11      espie      98:                'variable=s' => \$mode{variable},
                     99:                'define-variable=s' => $variables,
1.1       ckuethe   100:        );
                    101:
1.14      espie     102: # Initial value of printerr depends on the options...
                    103: if (!defined $mode{printerr}) {
                    104:        if (defined $mode{libs} || defined $mode{cflags}
                    105:            || defined $mode{version} || defined $mode{list}) {
                    106:                $mode{printerr} = 1;
                    107:        } else {
                    108:                $mode{printerr} = 0;
                    109:        }
                    110: }
                    111:
1.4       espie     112: print STDERR "\n[" . join('] [', $0, @ARGV) . "]\n" if $D;
1.13      espie     113:
                    114: my $rc = 0;
1.1       ckuethe   115:
1.14      espie     116: # XXX pkg-config is a bit weird
1.10      espie     117: {
                    118: my $p = join(' ', @ARGV);
1.14      espie     119: $p =~ s/^\s+//;
1.4       espie     120: @ARGV = split /\s+/, $p;
1.10      espie     121: }
1.1       ckuethe   122:
1.14      espie     123: if ($mode{myminvers}) {
                    124:        exit self_version($mode{myminvers});
                    125: }
                    126:
                    127: if ($mode{list}) {
                    128:        exit do_list();
1.1       ckuethe   129: }
                    130:
1.13      espie     131: my $cfg_full_list = [];
1.14      espie     132: my $top_config = [];
1.1       ckuethe   133:
                    134: while (@ARGV){
1.13      espie     135:        my $p = shift @ARGV;
                    136:        my $op = undef;
                    137:        my $v = undef;
                    138:        if (@ARGV >= 2  && $ARGV[0] =~ /[<=>]+/ &&
                    139:            $ARGV[1] =~ /[0-9\.]+/) {
                    140:                $op = shift @ARGV;
                    141:                $v = shift @ARGV;
1.1       ckuethe   142:        }
                    143:        $p =~ s/,//g;
1.13      espie     144:        handle_config($p, $op, $v, $cfg_full_list);
1.14      espie     145:        push(@$top_config, $p);
                    146: }
                    147:
                    148: if ($mode{exists}) {
                    149:        exit $rc;
                    150: }
                    151:
                    152: if ($mode{uninstalled}) {
                    153:        $rc = 1 unless $found_uninstalled;
                    154:        exit $rc;
1.11      espie     155: }
1.1       ckuethe   156:
1.14      espie     157: if ($mode{modversion}) {
                    158:        for my $pkg (@$top_config) {
                    159:                do_modversion($pkg);
                    160:        }
                    161: }
1.13      espie     162:
1.14      espie     163: if ($mode{minversion}) {
                    164:        my $v = $mode{minversion};
                    165:        for my $pkg (@$top_config) {
                    166:                $rc = 1 unless versionmatch($configs{$pkg}, '>=', $v);
                    167:        }
                    168:        exit $rc;
                    169: }
                    170:
                    171: if ($mode{exactversion}) {
                    172:        my $v = $mode{exactversion};
                    173:        for my $pkg (@$top_config) {
                    174:                $rc = 1 unless versionmatch($configs{$pkg}, '=', $v);
                    175:        }
                    176:        exit $rc;
                    177: }
                    178:
                    179: if ($mode{minversion}) {
                    180:        my $v = $mode{maxversion};
                    181:        for my $pkg (@$top_config) {
                    182:                $rc = 1 unless versionmatch($configs{$pkg}, '<=', $v);
                    183:        }
                    184:        exit $rc;
                    185: }
                    186:
                    187: my @vlist = ();
                    188:
                    189: if ($mode{variable}) {
                    190:        for my $pkg (@$top_config) {
                    191:                do_variable($pkg, $mode{variable});
                    192:        }
                    193: }
                    194:
                    195: my $dep_cfg_list = simplify_and_reverse($cfg_full_list);
                    196:
                    197: if ($mode{cflags} || $mode{libs} || $mode{variable}) {
                    198:     push @vlist, do_cflags($dep_cfg_list) if $mode{cflags};
                    199:     push @vlist, do_libs($dep_cfg_list) if $mode{libs};
1.17      espie     200:     print join(' ', @vlist), "\n" if $rc == 0;
1.1       ckuethe   201: }
                    202:
1.13      espie     203: exit $rc;
1.1       ckuethe   204:
                    205: ###########################################################################
                    206:
1.11      espie     207: sub handle_config
                    208: {
1.13      espie     209:        my ($p, $op, $v, $list) = @_;
                    210:
1.11      espie     211:
1.13      espie     212:        my $cfg = cache_find_config($p);
1.11      espie     213:
1.13      espie     214:        unshift @$list, $p if defined $cfg;
1.11      espie     215:
1.15      espie     216:        if (!defined $cfg) {
                    217:                $rc = 1;
                    218:                return undef;
                    219:        }
                    220:
1.13      espie     221:        if (defined $op) {
                    222:                if (!versionmatch($cfg, $op, $v)) {
                    223:                        mismatch($p, $cfg, $op, $v) if $mode{printerr};
                    224:                        $rc = 1;
                    225:                        return undef;
                    226:                }
1.14      espie     227:        }
1.11      espie     228:
                    229:        my $deps = $cfg->get_property('Requires', $variables);
                    230:        if (defined $deps) {
1.13      espie     231:                for my $dep (@$deps) {
                    232:                        if ($dep =~ m/^(.*?)\s*([<=>]+)\s*([\d\.]+)$/) {
                    233:                                handle_config($1, $2, $3, $list);
                    234:                        } else {
                    235:                                handle_config($dep, undef, undef, $list);
                    236:                        }
                    237:                }
1.11      espie     238:                print STDERR "package $p requires ",
                    239:                    join(',', @$deps), "\n" if $D;
                    240:        }
                    241:
                    242:        $deps = $cfg->get_property('Requires.private', $variables);
                    243:        if (defined $deps) {
1.13      espie     244:                for my $dep (@$deps) {
                    245:                        if ($dep =~ m/^(.*?)\s*([<=>]+)\s*([\d\.]+)$/) {
                    246:                                handle_config($1, $2, $3, $list);
                    247:                        } else {
                    248:                                handle_config($dep, undef, undef, $list);
                    249:                        }
                    250:                }
1.11      espie     251:                print STDERR "package $p requires (private)",
                    252:                        join(',', @$deps), "\n" if $D;
                    253:        }
                    254: }
                    255:
1.1       ckuethe   256: # look for the .pc file in each of the PKGPATH elements. Return the path or
                    257: # undef if it's not there
1.4       espie     258: sub pathresolve
                    259: {
                    260:        my ($p) = @_;
                    261:
1.14      espie     262:        if ($allow_uninstalled && $p !~ m/\-uninstalled$/) {
                    263:                foreach my $d (@PKGPATH) {
                    264:                        my $f = "$d/$p-uninstalled.pc";
                    265:                        print STDERR "pathresolve($p) looking in $f\n" if $D;
                    266:                        if (-f $f) {
                    267:                                $found_uninstalled = 1;
                    268:                                return $f;
                    269:                        }
                    270:                }
                    271:        }
                    272:
1.4       espie     273:        foreach my $d (@PKGPATH) {
1.10      espie     274:                my $f = "$d/$p.pc";
1.4       espie     275:                print STDERR "pathresolve($p) looking in $f\n" if $D;
1.10      espie     276:                return $f if -f $f;
1.1       ckuethe   277:        }
1.10      espie     278:        return undef;
1.1       ckuethe   279: }
                    280:
1.11      espie     281: sub get_config
                    282: {
                    283:        my ($f) = @_;
                    284:
                    285:        my $cfg;
                    286:        eval {
                    287:            $cfg = OpenBSD::PkgConfig->read_file($f);
                    288:        };
                    289:        if (!$@) {
                    290:                return $cfg;
                    291:        } else {
1.12      espie     292:                print STDERR $@, "\n" if $D;
1.11      espie     293:        }
                    294:        return undef;
                    295: }
                    296:
1.13      espie     297: sub cache_find_config
                    298: {
                    299:        my $name = shift;
                    300:
                    301:        print STDERR "processing $name\n" if $D;
                    302:
                    303:        if (exists $configs{$name}) {
                    304:                return $configs{$name};
                    305:        } else {
                    306:                return $configs{$name} = find_config($name);
                    307:        }
                    308: }
                    309:
1.11      espie     310: sub find_config
                    311: {
                    312:        my ($p) = @_;
                    313:        my $f = pathresolve($p);
                    314:        if (defined $f) {
                    315:                return get_config($f);
                    316:        }
1.13      espie     317:        if ($mode{printerr}) {
                    318:            print STDERR
                    319:                "Package $p was not found in the pkg-config search path\n";
                    320:        }
1.11      espie     321:        return undef;
                    322: }
1.1       ckuethe   323:
1.11      espie     324: sub stringize
1.4       espie     325: {
1.11      espie     326:        my $list = shift;
1.21      simon     327:        my $sep = shift || ',';
1.4       espie     328:
1.11      espie     329:        if (defined $list) {
1.21      simon     330:                return join($sep, @$list)
1.11      espie     331:        } else {
                    332:                return '';
1.1       ckuethe   333:        }
                    334: }
                    335:
                    336: #if the variable option is set, pull out the named variable
1.4       espie     337: sub do_variable
                    338: {
1.11      espie     339:        my ($p, $v) = @_;
1.1       ckuethe   340:
1.13      espie     341:        my $cfg = cache_find_config($p);
                    342:
                    343:        if (defined $cfg) {
1.11      espie     344:                my $value = $cfg->get_variable($v, $variables);
                    345:                if (defined $value) {
1.13      espie     346:                        push(@vlist, $value);
1.11      espie     347:                }
1.19      espie     348:                return undef;
1.11      espie     349:        }
1.19      espie     350:        $rc = 1;
1.1       ckuethe   351: }
                    352:
                    353: #if the modversion option is set, pull out the compiler flags
1.4       espie     354: sub do_modversion
                    355: {
1.11      espie     356:        my ($p) = @_;
1.1       ckuethe   357:
1.13      espie     358:        my $cfg = cache_find_config($p);
                    359:
                    360:        if (defined $cfg) {
1.11      espie     361:                my $value = $cfg->get_property('Version', $variables);
                    362:                if (defined $value) {
                    363:                        print stringize($value), "\n";
1.13      espie     364:                        return undef;
1.11      espie     365:                }
                    366:        }
1.13      espie     367:        $rc = 1;
1.1       ckuethe   368: }
                    369:
                    370: #if the cflags option is set, pull out the compiler flags
1.4       espie     371: sub do_cflags
                    372: {
1.14      espie     373:        my $list = shift;
                    374:
1.11      espie     375:        my $cflags = [];
1.1       ckuethe   376:
1.14      espie     377:        foreach my $pkg (@$list) {
1.11      espie     378:                my $l = $configs{$pkg}->get_property('Cflags', $variables);
                    379:                push(@$cflags, @$l) if defined $l;
                    380:        }
                    381:        return OpenBSD::PkgConfig->compress($cflags,
                    382:                sub {
                    383:                        local $_ = shift;
                    384:                        if (($mode{cflags} & 1) && /^-I/ ||
                    385:                            ($mode{cflags} & 2) && !/^-I/) {
                    386:                            return 1;
                    387:                        } else {
                    388:                            return 0;
1.4       espie     389:                        }
1.11      espie     390:                });
1.14      espie     391:        return undef;
1.1       ckuethe   392: }
                    393:
                    394: #if the lib option is set, pull out the linker flags
1.4       espie     395: sub do_libs
                    396: {
1.14      espie     397:        my $list = shift;
                    398:
1.11      espie     399:        my $libs = [];
1.1       ckuethe   400:
1.14      espie     401:        foreach my $pkg (@$list) {
1.11      espie     402:                my $l = $configs{$pkg}->get_property('Libs', $variables);
                    403:                push(@$libs, @$l) if defined $l;
                    404:        }
1.13      espie     405:        my $a = OpenBSD::PkgConfig->compress($libs,
1.11      espie     406:                sub {
                    407:                        local $_ = shift;
1.13      espie     408:                        if (($mode{libs} & 2) && /^-L/ ||
1.11      espie     409:                            ($mode{libs} & 4) && !/^-[lL]/) {
                    410:                            return 1;
                    411:                        } else {
                    412:                            return 0;
1.4       espie     413:                        }
1.11      espie     414:                });
1.13      espie     415:        if ($mode{libs} & 1) {
                    416:                my $b = OpenBSD::PkgConfig->rcompress($libs,
                    417:                        sub { shift =~ m/^-l/; });
                    418:                return ($a, $b);
                    419:        } else {
                    420:                return $a;
                    421:        }
1.1       ckuethe   422: }
                    423:
                    424: #list all packages
1.4       espie     425: sub do_list
                    426: {
1.1       ckuethe   427:        my ($p, $x, $y, @files, $fname, $name);
1.20      espie     428:        my $error = 0;
                    429:
1.4       espie     430:        foreach my $p (@PKGPATH) {
                    431:                push(@files, <$p/*.pc>);
                    432:        }
1.1       ckuethe   433:
                    434:        # Scan the lengths of the package names so I can make a format
                    435:        # string to line the list up just like the real pkgconfig does.
                    436:        $x = 0;
1.4       espie     437:        foreach my $f (@files) {
                    438:                $fname = basename($f, '.pc');
                    439:                $y = length $fname;
1.1       ckuethe   440:                $x = (($y > $x) ? $y : $x);
                    441:        }
                    442:        $x *= -1;
                    443:
1.4       espie     444:        foreach my $f (@files) {
1.11      espie     445:                my $cfg = get_config($f);
1.20      espie     446:                if (!defined $cfg) {
                    447:                        print STDERR "Problem reading file $f\n";
                    448:                        $error = 1;
                    449:                        next;
                    450:                }
1.4       espie     451:                $fname = basename($f, '.pc');
1.11      espie     452:                printf("%${x}s %s - %s\n", $fname,
                    453:                    stringize($cfg->get_property('Name', $variables)),
1.21      simon     454:                    stringize($cfg->get_property('Description', $variables),
                    455:                    ' '));
1.1       ckuethe   456:        }
1.20      espie     457:        return $error;
1.1       ckuethe   458: }
                    459:
1.4       espie     460: sub help
                    461: {
1.1       ckuethe   462:        print <<EOF
                    463: Usage: $0 [options]
                    464: --debug        - turn on debugging output
                    465: --help - this message
                    466: --usage - this message
                    467: --list-all - show all packages that $0 can find
1.8       ckuethe   468: --version - print version of pkgconfig
                    469: --errors-to-stdout - direct error messages to stdout rather than stderr
                    470: --print-errors - print error messages in case of error
                    471: --silence-errors - don't print error messages in case of error
1.1       ckuethe   472: --atleast-pkgconfig-version [version] - require a certain version of pkgconfig
                    473: --cflags package [versionspec] [package [versionspec]]
                    474: --cflags-only-I - only output -Iincludepath flags
                    475: --cflags-only-other - only output flags that are not -I
1.11      espie     476: --define-variable=NAME=VALUE - define variables
1.1       ckuethe   477: --libs package [versionspec] [package [versionspec]]
                    478: --libs-only-l - only output -llib flags
                    479: --libs-only-L - only output -Llibpath flags
                    480: --libs-only-other - only output flags that are not -l or -L
                    481: --exists package [versionspec] [package [versionspec]]
                    482: --uninstalled - allow for uninstalled versions to be used
1.8       ckuethe   483: --static - adjust output for static linking
                    484: --atleast-version [version] - require a certain version of a package
                    485: --modversion [package] - query the version of a package
                    486: --variable var package - return the definition of <var> in <package>
1.1       ckuethe   487: EOF
                    488: ;
1.22      simon     489:        exit 0;
1.1       ckuethe   490: }
                    491:
                    492: # do we meet/beat the version the caller requested?
1.4       espie     493: sub self_version
                    494: {
                    495:        my ($v) = @_;
                    496:        my (@a, @b);
                    497:
                    498:        @a = split /\./, $v;
                    499:        @b = split /\./, $version;
1.1       ckuethe   500:
1.4       espie     501:        if (($b[0] >= $a[0]) && ($b[1] >= $a[1])) {
1.14      espie     502:                return 0;
1.1       ckuethe   503:        } else {
1.14      espie     504:                return 1;
                    505:        }
                    506: }
                    507:
                    508: sub compare
                    509: {
                    510:        my ($a, $b) = @_;
                    511:
                    512:        if ($a eq $b) {
                    513:                return 0;
1.1       ckuethe   514:        }
1.14      espie     515:
                    516:        my @a = split /\./, $a;
                    517:        my @b = split /\./, $b;
                    518:
                    519:        while (@a && @b) { #so long as both lists have something
                    520:                return 1 if $a[0] > $b[0];
                    521:                return -1 if $a[0] < $b[0];
                    522:                shift @a; shift @b;
                    523:        }
                    524:        return 1 if @a;
                    525:        return -1 if @b;
                    526:        return 0;
1.1       ckuethe   527: }
                    528:
                    529: # got a package meeting the requested specific version?
1.4       espie     530: sub versionmatch
                    531: {
1.14      espie     532:        my ($cfg, $op, $want) = @_;
1.1       ckuethe   533:
                    534:        # can't possibly match if we can't find the file
1.11      espie     535:        return 0 if !defined $cfg;
                    536:
1.14      espie     537:        my $inst = stringize($cfg->get_property('Version', $variables));
1.11      espie     538:
1.1       ckuethe   539:        # can't possibly match if we can't find the version string
1.14      espie     540:        return 0 if $inst eq '';
1.1       ckuethe   541:
1.14      espie     542:        print "comparing $want (wanted) to $inst (installed)\n" if $D;
                    543:        my $value = compare($inst, $want);
                    544:        if ($op eq '>=') {
                    545:                return $value >= 0;
                    546:        }
                    547:        elsif ($op eq '=') {
                    548:                return $value == 0;
                    549:        } elsif ($op eq '!=') {
                    550:                return $value != 0;
                    551:        } elsif ($op eq '<') {
                    552:                return $value < 0;
                    553:        } elsif ($op eq '>') {
                    554:                return $value > 0;
                    555:        } elsif ($op eq '<=') {
                    556:                return $value <= 0;
                    557:        }
1.13      espie     558: }
                    559:
                    560: sub mismatch
                    561: {
                    562:        my ($p, $cfg, $op, $v) = @_;
                    563:        print STDERR "Requested '$p $op $v' but version of ",
                    564:            stringize($cfg->get_property('Name')), " is ",
                    565:            stringize($cfg->get_property('Version')), "\n";
                    566: }
                    567:
                    568: sub simplify_and_reverse
                    569: {
                    570:        my $reqlist = shift;
                    571:        my $dejavu = {};
                    572:        my $result = [];
                    573:
                    574:        for my $item (@$reqlist) {
                    575:                if (!$dejavu->{$item}) {
                    576:                        unshift @$result, $item;
                    577:                        $dejavu->{$item} = 1;
                    578:                }
                    579:        }
                    580:        return $result;
1.1       ckuethe   581: }