source: trunk/essentials/dev-lang/perl/vms/ext/XSSymSet.pm@ 3310

Last change on this file since 3310 was 3181, checked in by bird, 19 years ago

perl 5.8.8

File size: 7.0 KB
Line 
1package ExtUtils::XSSymSet;
2
3use Carp qw( &carp );
4use strict;
5use vars qw( $VERSION );
6$VERSION = '1.0';
7
8
9sub new {
10 my($pkg,$maxlen,$silent) = @_;
11 $maxlen ||= 31;
12 $silent ||= 0;
13 my($obj) = { '__M@xLen' => $maxlen, '__S!lent' => $silent };
14 bless $obj, $pkg;
15}
16
17
18sub trimsym {
19 my($self,$name,$maxlen,$silent) = @_;
20
21 unless (defined $maxlen) {
22 if (ref $self) { $maxlen ||= $self->{'__M@xLen'}; }
23 $maxlen ||= 31;
24 }
25 unless (defined $silent) {
26 if (ref $self) { $silent ||= $self->{'__S!lent'}; }
27 $silent ||= 0;
28 }
29 return $name if (length $name <= $maxlen);
30
31 my $trimmed = $name;
32 # First, just try to remove duplicated delimiters
33 $trimmed =~ s/__/_/g;
34 if (length $trimmed > $maxlen) {
35 # Next, all duplicated chars
36 $trimmed =~ s/(.)\1+/$1/g;
37 if (length $trimmed > $maxlen) {
38 my $squeezed = $trimmed;
39 my($xs,$prefix,$func) = $trimmed =~ /^(XS_)?(.*)_([^_]*)$/;
40 if (length $func <= 12) { # Try to preserve short function names
41 my $frac = int(length $prefix / (length $trimmed - $maxlen) + 0.5);
42 my $pat = '([^_])';
43 if ($frac > 1) { $pat .= '[^A-Z_]{' . ($frac - 1) . '}'; }
44 $prefix =~ s/$pat/$1/g;
45 $squeezed = "$xs$prefix" . "_$func";
46 if (length $squeezed > $maxlen) {
47 $pat =~ s/A-Z//;
48 $prefix =~ s/$pat/$1/g;
49 $squeezed = "$xs$prefix" . "_$func";
50 }
51 }
52 else {
53 my $frac = int(length $trimmed / (length $trimmed - $maxlen) + 0.5);
54 my $pat = '([^_])';
55 if ($frac > 1) { $pat .= '[^A-Z_]{' . ($frac - 1) . '}'; }
56 $squeezed = "$prefix$func";
57 $squeezed =~ s/$pat/$1/g;
58 if (length "$xs$squeezed" > $maxlen) {
59 $pat =~ s/A-Z//;
60 $squeezed =~ s/$pat/$1/g;
61 }
62 $squeezed = "$xs$squeezed";
63 }
64 if (length $squeezed <= $maxlen) { $trimmed = $squeezed; }
65 else {
66 my $frac = int((length $trimmed - $maxlen) / length $trimmed + 0.5);
67 my $pat = '(.).{$frac}';
68 $trimmed =~ s/$pat/$1/g;
69 }
70 }
71 }
72 carp "Warning: long symbol $name\n\ttrimmed to $trimmed\n\t" unless $silent;
73 return $trimmed;
74}
75
76
77sub addsym {
78 my($self,$sym,$maxlen,$silent) = @_;
79 my $trimmed = $self->get_trimmed($sym);
80
81 return $trimmed if defined $trimmed;
82
83 $maxlen ||= $self->{'__M@xLen'} || 31;
84 $silent ||= $self->{'__S!lent'} || 0;
85 $trimmed = $self->trimsym($sym,$maxlen,1);
86 if (exists $self->{$trimmed}) {
87 my($i) = "00";
88 $trimmed = $self->trimsym($sym,$maxlen-3,$silent);
89 while (exists $self->{"${trimmed}_$i"}) { $i++; }
90 carp "Warning: duplicate symbol $trimmed\n\tchanged to ${trimmed}_$i\n\t(original was $sym)\n\t"
91 unless $silent;
92 $trimmed .= "_$i";
93 }
94 elsif (not $silent and $trimmed ne $sym) {
95 carp "Warning: long symbol $sym\n\ttrimmed to $trimmed\n\t";
96 }
97 $self->{$trimmed} = $sym;
98 $self->{'__N+Map'}->{$sym} = $trimmed;
99 $trimmed;
100}
101
102
103sub delsym {
104 my($self,$sym) = @_;
105 my $trimmed = $self->{'__N+Map'}->{$sym};
106 if (defined $trimmed) {
107 delete $self->{'__N+Map'}->{$sym};
108 delete $self->{$trimmed};
109 }
110 $trimmed;
111}
112
113
114sub get_trimmed {
115 my($self,$sym) = @_;
116 $self->{'__N+Map'}->{$sym};
117}
118
119
120sub get_orig {
121 my($self,$trimmed) = @_;
122 $self->{$trimmed};
123}
124
125
126sub all_orig { (keys %{$_[0]->{'__N+Map'}}); }
127sub all_trimmed { (grep { /^\w+$/ } keys %{$_[0]}); }
128
129__END__
130
131=head1 NAME
132