line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# This is the Alien::Judy module, a way to ensure that users who don't |
2
|
|
|
|
|
|
|
# natively have libJudy on their system can still get one. It provides |
3
|
|
|
|
|
|
|
# libJudy.so and Judy.h at the path $Config{sitearch}/Alien/Judy. |
4
|
|
|
|
|
|
|
package Alien::Judy; |
5
|
|
|
|
|
|
|
# ABSTRACT: A wrapper for installing the Judy library |
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
75577
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
49
|
|
8
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
43
|
|
9
|
1
|
|
|
1
|
|
6
|
use vars qw( $VERSION $DEBUG $HANDLE ); |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
69
|
|
10
|
1
|
|
|
1
|
|
6
|
use Config (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
11
|
1
|
|
|
1
|
|
6
|
use Cwd (); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
15
|
|
12
|
1
|
|
|
1
|
|
5
|
use File::Spec (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
20
|
|
13
|
1
|
|
|
1
|
|
5
|
use DynaLoader (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# This module allows users to import its three public functions |
16
|
|
|
|
|
|
|
# inc_dirs(), lib_dirs(), and dl_load_libjudy(). |
17
|
1
|
|
|
|
|
11
|
use Sub::Exporter -setup => { |
18
|
|
|
|
|
|
|
exports => [qw( inc_dirs lib_dirs dl_load_libjudy )] |
19
|
1
|
|
|
1
|
|
3156
|
}; |
|
1
|
|
|
|
|
34804
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# The provided functions inc_dirs() and lib_dirs() are currently |
22
|
|
|
|
|
|
|
# identical. Initially, they weren't. |
23
|
|
|
|
|
|
|
*lib_dirs = \&inc_dirs; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# TODO: add literate documentation |
26
|
|
|
|
|
|
|
sub inc_dirs { |
27
|
|
|
|
|
|
|
# Find files from ., $sitearch and @INC. |
28
|
15
|
50
|
|
|
|
5274
|
my @dirs = |
29
|
1
|
|
|
1
|
1
|
19
|
grep { defined() && length() } |
30
|
|
|
|
|
|
|
@Config::Config{qw(sitearchexp sitearch)}, |
31
|
|
|
|
|
|
|
@INC, |
32
|
|
|
|
|
|
|
Cwd::getcwd(); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# But first try to find them in $_/Alien/Judy/ |
35
|
15
|
|
|
|
|
91
|
unshift @dirs, |
36
|
1
|
|
|
|
|
7
|
map { File::Spec->catdir( $_, 'Alien', 'Judy' ) } |
37
|
|
|
|
|
|
|
@dirs; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# Return the unique-ified list |
40
|
1
|
|
|
|
|
4
|
my %seen; |
41
|
|
|
|
|
|
|
return |
42
|
1
|
|
|
|
|
3
|
grep { ! $seen{$_}++ } |
|
30
|
|
|
|
|
101
|
|
43
|
|
|
|
|
|
|
@dirs; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# This module depends on libJudy from |
47
|
|
|
|
|
|
|
# http://judy.sourceforge.net. Either I can find it as a |
48
|
|
|
|
|
|
|
# system-installed library: |
49
|
|
|
|
|
|
|
# |
50
|
|
|
|
|
|
|
# apt-get install libjudydebian1 # for libJudy.so |
51
|
|
|
|
|
|
|
# apt-get install libjudy-dev # for Judy.h |
52
|
|
|
|
|
|
|
# |
53
|
|
|
|
|
|
|
# Or I can get it by the perl CPAN module Alien::Judy which builds and |
54
|
|
|
|
|
|
|
# installs Judy.h and libJudy.so into $Config{sitearch}/Alien/Judy. |
55
|
|
|
|
|
|
|
# |
56
|
|
|
|
|
|
|
# CPAN testers however won't have actually installed libJudy so I'll |
57
|
|
|
|
|
|
|
# need to find it in @INC as set by $ENV{PERL5LIB} with a typical |
58
|
|
|
|
|
|
|
# value of: |
59
|
|
|
|
|
|
|
# |
60
|
|
|
|
|
|
|
# $INC[...] = '/home/josh/.cpan/build/Alien-Judy-0.01/blib/arch' |
61
|
|
|
|
|
|
|
# |
62
|
|
|
|
|
|
|
# but the files Judy.h and libJudy.so are a couple levels deeper at: |
63
|
|
|
|
|
|
|
# |
64
|
|
|
|
|
|
|
# $INC[...] = '/home/josh/.cpan/build/Alien-Judy-0.01/blib/arch/Alien/Judy' |
65
|
|
|
|
|
|
|
# |
66
|
|
|
|
|
|
|
sub _libjudy_candidates { |
67
|
|
|
|
|
|
|
# Get a list of possible libJudy.so files. |
68
|
|
|
|
|
|
|
# |
69
|
|
|
|
|
|
|
# When writing this module, I found it would occasionally not only |
70
|
|
|
|
|
|
|
# find libJudy.so but also blib/arch/Judy/Judy.so which is the |
71
|
|
|
|
|
|
|
# Perl XS module. That was when this -lJudy resolving code was |
72
|
|
|
|
|
|
|
# directly in the Judy cpan module though which has a lib/Judy.xs |
73
|
|
|
|
|
|
|
# file. It's plausible that it's entirely irrelevant now that this |
74
|
|
|
|
|
|
|
# is in Alien::Judy. |
75
|
|
|
|
|
|
|
# |
76
|
1
|
|
|
1
|
|
436488
|
my @candidate_libs = DynaLoader::dl_findfile('-lJudy'); |
77
|
1
|
50
|
|
|
|
15
|
if ( $DEBUG ) { |
78
|
1
|
|
|
|
|
123
|
printf STDERR "candidates=@candidate_libs at %s line %d.\n", __FILE__, __LINE__; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# I found that Solaris would find libJudy.so with DynaLoader but |
82
|
|
|
|
|
|
|
# ld.so.1 when loading libJudy.so for Judy.pm would fail to find |
83
|
|
|
|
|
|
|
# the right library to link against. |
84
|
|
|
|
|
|
|
# |
85
|
|
|
|
|
|
|
# I don't particularly understand it however what worked was to |
86
|
|
|
|
|
|
|
# attempt to load libJudy.so.1 first. |
87
|
1
|
|
|
|
|
128
|
my @dot_one = |
88
|
1
|
|
|
|
|
7
|
grep { -f } |
89
|
1
|
|
|
|
|
8
|
map { "$_.1" } |
90
|
|
|
|
|
|
|
@candidate_libs; |
91
|
|
|
|
|
|
|
|
92
|
1
|
|
|
|
|
5
|
unshift @candidate_libs, @dot_one; |
93
|
|
|
|
|
|
|
|
94
|
1
|
|
|
|
|
7
|
return @candidate_libs; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub _dl_load_libjudy { |
98
|
1
|
|
|
1
|
|
4
|
my @candidate_libs = @_; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# The libJudy I find must provide the base functions from the |
101
|
|
|
|
|
|
|
# libJudy library. This is to possibly skip "wrong" libJudy |
102
|
|
|
|
|
|
|
# libraries. |
103
|
|
|
|
|
|
|
# @DynaLoader::dl_require_symbols = 'Judy1Test'; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Attempt to load each candidate until something succeeds. If one |
106
|
|
|
|
|
|
|
# of the candidates happens to be the Perl XS module |
107
|
|
|
|
|
|
|
# blib/arch/Judy/Judy.so then I'd like loading to keep trying and |
108
|
|
|
|
|
|
|
# not fail. If I know how to predictably filter |
109
|
|
|
|
|
|
|
# blib/arch/Judy/Judy.so out of this list I'd do that. |
110
|
1
|
|
|
|
|
8
|
my $libjudy_loaded; |
111
|
|
|
|
|
|
|
CANDIDATE_LIBRARY: |
112
|
1
|
|
|
|
|
5
|
for my $libjudy_file ( @candidate_libs ) { |
113
|
1
|
|
|
|
|
5
|
my $ok = eval { |
114
|
1
|
|
|
|
|
205150
|
$HANDLE = DynaLoader::dl_load_file( $libjudy_file, 0x01 ); |
115
|
1
|
|
|
|
|
13
|
1; |
116
|
|
|
|
|
|
|
}; |
117
|
1
|
50
|
|
|
|
12
|
if ( $DEBUG ) { |
118
|
1
|
50
|
|
|
|
15
|
my $msgf = |
119
|
|
|
|
|
|
|
$ok |
120
|
|
|
|
|
|
|
? "Loaded $libjudy_file at %s line %d.\n" |
121
|
|
|
|
|
|
|
: "Couldn't load $libjudy_file: $@ at %s line %d.\n"; |
122
|
1
|
|
|
|
|
58
|
printf STDERR $msgf, __FILE__, __LINE__; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
1
|
50
|
|
|
|
15
|
if ( $ok ) { |
126
|
1
|
|
|
|
|
7
|
$libjudy_loaded = 1; |
127
|
1
|
|
|
|
|
7
|
last CANDIDATE_LIBRARY; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
1
|
|
|
|
|
5
|
return $libjudy_loaded; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub dl_load_libjudy { |
135
|
1
|
|
|
1
|
1
|
331
|
local @DynaLoader::dl_library_path = ( |
136
|
|
|
|
|
|
|
@DynaLoader::dl_library_path, |
137
|
|
|
|
|
|
|
lib_dirs() |
138
|
|
|
|
|
|
|
); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Enable DynaLoader debugging along with Judy debugging |
141
|
1
|
|
|
|
|
4
|
local $DynaLoader::dl_debug = $DynaLoader::dl_debug; |
142
|
1
|
50
|
|
|
|
5
|
if ( $DEBUG ) { |
143
|
1
|
|
50
|
|
|
7
|
$DynaLoader::dl_debug ||= 1; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
1
|
|
|
|
|
5
|
my @libjudy_files = _libjudy_candidates(); |
147
|
|
|
|
|
|
|
|
148
|
1
|
|
|
|
|
9
|
my $ok = _dl_load_libjudy( @libjudy_files ); |
149
|
|
|
|
|
|
|
|
150
|
1
|
|
|
|
|
23
|
return $ok; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
$VERSION = '0.26'; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
1; |