Codebase list libsort-naturally-perl / 14a1e03
Imported Upstream version 1.03 Florian Schlichting 12 years ago
9 changed file(s) with 165 addition(s) and 64 deletion(s). Raw diff Collapse all Expand all
00 Revision history for Perl module Sort::Naturally
1 Time-stamp: "2004-12-29 18:30:21 AST"
1
2 2012-04-11 bingos bingos@cpan.org
3
4 * release 1.03 -- modernise the distribution
25
36 2004-12-29 Sean M. Burke sburke@cpan.org
47
58 * Release 1.02 -- just rebundling, no code changes
6
9
710 2001-05-25 Sean M. Burke sburke@cpan.org
811
912 * Release 1.01 -- first public release.
66 t/00_about_verbose.t
77 t/01_old_junk.t
88 META.yml Module meta-data (added by MakeMaker)
9 META.json Module JSON meta-data (added by MakeMaker)
33 CVS
44 blib
55 ~
6
6 .git
7 .bak$
0 {
1 "abstract" : "sort lexically, but sort numeral parts numerically",
2 "author" : [
3 "Sean M. Burke <sburke@cpan.org>"
4 ],
5 "dynamic_config" : 1,
6 "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120921",
7 "license" : [
8 "perl_5"
9 ],
10 "meta-spec" : {
11 "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
12 "version" : "2"
13 },
14 "name" : "Sort-Naturally",
15 "no_index" : {
16 "directory" : [
17 "t",
18 "inc"
19 ]
20 },
21 "prereqs" : {
22 "build" : {
23 "requires" : {
24 "ExtUtils::MakeMaker" : "0"
25 }
26 },
27 "configure" : {
28 "requires" : {
29 "ExtUtils::MakeMaker" : "0"
30 }
31 },
32 "runtime" : {
33 "requires" : {
34 "perl" : "5"
35 }
36 }
37 },
38 "release_status" : "stable",
39 "resources" : {
40 "repository" : {
41 "url" : "https://github.com/bingos/sort-naturally"
42 }
43 },
44 "version" : "1.03"
45 }
0 # http://module-build.sourceforge.net/META-spec.html
1 #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
2 name: Sort-Naturally
3 version: 1.02
4 version_from: lib/Sort/Naturally.pm
5 installdirs: site
0 ---
1 abstract: 'sort lexically, but sort numeral parts numerically'
2 author:
3 - 'Sean M. Burke <sburke@cpan.org>'
4 build_requires:
5 ExtUtils::MakeMaker: 0
6 configure_requires:
7 ExtUtils::MakeMaker: 0
8 dynamic_config: 1
9 generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120921'
10 license: perl
11 meta-spec:
12 url: http://module-build.sourceforge.net/META-spec-v1.4.html
13 version: 1.4
14 name: Sort-Naturally
15 no_index:
16 directory:
17 - t
18 - inc
619 requires:
7
8 distribution_type: module
9 generated_by: ExtUtils::MakeMaker version 6.17
20 perl: 5
21 resources:
22 repository: https://github.com/bingos/sort-naturally
23 version: 1.03
88 use strict;
99 use ExtUtils::MakeMaker;
1010
11 WriteMakefile(
12 'NAME' => 'Sort::Naturally',
11 WriteMakefile1(
12 LICENSE => 'perl',
13 MIN_PERL_VERSION => '5',
14 META_MERGE => {
15 resources => {
16 repository => 'https://github.com/bingos/sort-naturally',
17 },
18 },
19 #BUILD_REQUIRES => {
20 #},
21
22 'AUTHOR' => 'Sean M. Burke <sburke@cpan.org>',
23 'ABSTRACT' => 'sort lexically, but sort numeral parts numerically',
24 'NAME' => 'Sort::Naturally',
1325 'VERSION_FROM' => 'lib/Sort/Naturally.pm', # finds $VERSION
1426 'dist' => { COMPRESS => 'gzip -6f', SUFFIX => 'gz', },
1527 );
1628
29
30 sub WriteMakefile1 { #Written by Alexandr Ciornii, version 0.21. Added by eumm-upgrade.
31 my %params=@_;
32 my $eumm_version=$ExtUtils::MakeMaker::VERSION;
33 $eumm_version=eval $eumm_version;
34 die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
35 die "License not specified" if not exists $params{LICENSE};
36 if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {
37 #EUMM 6.5502 has problems with BUILD_REQUIRES
38 $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };
39 delete $params{BUILD_REQUIRES};
40 }
41 delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;
42 delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;
43 delete $params{META_MERGE} if $eumm_version < 6.46;
44 delete $params{META_ADD} if $eumm_version < 6.46;
45 delete $params{LICENSE} if $eumm_version < 6.31;
46 delete $params{AUTHOR} if $] < 5.005;
47 delete $params{ABSTRACT_FROM} if $] < 5.005;
48 delete $params{BINARY_LOCATION} if $] < 5.005;
49
50 WriteMakefile(%params);
51 }
52
00
11 require 5;
22 package Sort::Naturally; # Time-stamp: "2004-12-29 18:30:03 AST"
3 $VERSION = '1.02';
3 $VERSION = '1.03';
44 @EXPORT = ('nsort', 'ncmp');
55 require Exporter;
66 @ISA = ('Exporter');
5454 } else {
5555 $rv = 0;
5656 }
57
57
5858 unless($rv) {
5959 # Normal case:
6060 $rv = 0;
6161 DEBUG and print "<$x> and <$y> compared...\n";
62
62
6363 Consideration:
6464 while(length $x and length $y) {
65
65
6666 DEBUG > 2 and print " <$x> and <$y>...\n";
67
67
6868 # First, non-numeric comparison:
6969 $x2 = ($x =~ m/^(\D+)/s) ? length($1) : 0;
7070 $y2 = ($y =~ m/^(\D+)/s) ? length($1) : 0;
7171 # Now make x2 the min length of the two:
7272 $x2 = $y2 if $x2 > $y2;
7373 if($x2) {
74 DEBUG > 1 and printf " <%s> and <%s> lexically for length $x2...\n",
74 DEBUG > 1 and printf " <%s> and <%s> lexically for length $x2...\n",
7575 substr($x,0,$x2), substr($y,0,$x2);
7676 do {
7777 my $i = substr($x,0,$x2);
8080 print "SCREAM! on <$i><$j> -- $sv != $rv \n" unless $rv == $sv;
8181 last;
8282 }
83
84
83
84
8585 if $rv =
86 # The ''. things here force a copy that seems to work around a
86 # The ''. things here force a copy that seems to work around a
8787 # mysterious intermittent bug that 'use locale' provokes in
8888 # many versions of Perl.
8989 $cmp
9999 substr($x,0,$x2) = '';
100100 substr($y,0,$x2) = '';
101101 }
102
102
103103 # Now numeric:
104104 # (actually just using $x2 and $y2 as scratch)
105105
113113 last if $rv = $x2 <=> $1;
114114 } else {
115115 # ARBITRARILY large integers!
116
116
117117 # This saves on loss of precision that could happen
118118 # with actual stringification.
119119 # Also, I sense that very large numbers aren't too
120120 # terribly common in sort data.
121
121
122122 # trim leading 0's:
123123 ($y2 = $1) =~ s/^0+//s;
124124 $x2 =~ s/^0+//s;
137137 # X is numeric but Y isn't
138138 $rv = Y_FIRST;
139139 last;
140 }
140 }
141141 } elsif( $y =~ s/^\d+//s ) { # we don't need to capture the substring
142142 $rv = X_FIRST;
143143 last;
165165 ($cmp,$lc) = @{shift @_} if @_ and ref($_[0]) eq 'ARRAY';
166166
167167 return @_ unless @_ > 1 or wantarray; # be clever
168
168
169169 my($x, $x2, $y, $y2, $rv); # scratch vars
170170
171171 # We use a Schwartzian xform to memoize the lc'ing and \W-removal
174174 sort {
175175 if($a->[0] eq $b->[0]) { 0 } # trap this expensive case
176176 else {
177
177
178178 $x = $a->[1];
179179 $y = $b->[1];
180180
187187 || ($x cmp $y )
188188 || ($a->[0] cmp $b->[0])
189189 ;
190
190
191191 DEBUG > 1 and print " <${$a}[0]> cmp <${$b}[0]> is $rv ($ORD[$rv])\n";
192192 $rv;
193193 }}
219219 }
220220 my($a,$b) = @_;
221221 my($x, $x2, $y, $y2, $rv); # scratch vars
222
222
223223 DEBUG > 1 and print "ncmp args <$a><$b>\n";
224224 if($a eq $b) { # trap this expensive case
225225 0;
228228 $x =~ s/\W+//s;
229229 $y = ($lc ? $lc->($b) : lc($b));
230230 $y =~ s/\W+//s;
231
231
232232 ~COMPARATOR~
233233
234234
239239 || ($x cmp $y)
240240 || ($a cmp $b)
241241 ;
242
242
243243 DEBUG > 1 and print " <$a> cmp <$b> is $rv\n";
244244 $rv;
245245 }
390390 map { [$_, make_a_sort_key_from($_) ]
391391 @_
392392 ;
393
393
394394 ...you wight want something that replaces not C<sort>, but C<cmp>.
395395 That's what Sort::Naturally's C<ncmp> function is for. Call it with
396396 the syntax C<ncmp($left,$right)> instead of C<$left cmp $right>,
502502 sub nsort {
503503 my($cmp, $lc);
504504 return @_ if @_ < 2; # Just to be CLEVER.
505
505
506506 my($x, $i); # scratch vars
507
507
508508 # And now, the GREAT BIG Schwartzian transform:
509
509
510510 map
511511 $_->[0],
512512
541541
542542 map {
543543 my @bit = ($x = defined($_) ? $_ : '');
544
544
545545 if($x =~ m/^[+-]?(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee](?:[+-]?\d+))?\z/s) {
546546 # It's entirely purely numeric, so treat it specially:
547547 push @bit, '', $x;
564564 # ['foo32.pl' => 'foo', 32, , '.pl', 0 ]
565565 # ['foo325.pl' => 'foo', 325, , '.pl', 0 ]
566566 # Yes, always an ODD number of elements.
567
567
568568 \@bit;
569569 }
570570 @_;
575575
576576 sub nsorts {
577577 return @_ if @_ < 2; # Just to be CLEVER.
578
578
579579 my($x, $i); # scratch vars
580
580
581581 # And now, the GREAT BIG Schwartzian transform:
582
582
583583 map
584584 $_->[0],
585585
614614
615615 map {
616616 my @bit = ($x = defined($_) ? $_ : '');
617
617
618618 while(length $x) {
619619 push @bit, ($x =~ s/^(\D+)//s) ? lc($1) : '';
620620 push @bit, ($x =~ s/^(\d+)//s) ? $1 : 0;
631631 # ['foo32.pl' => 'foo', 32, , '.pl', 0 ]
632632 # ['foo325.pl' => 'foo', 325, , '.pl', 0 ]
633633 # Yes, always an ODD number of elements.
634
634
635635 \@bit;
636636 }
637637 @_;
642642
643643 sub nsort0 {
644644 return @_ if @_ < 2; # Just to be CLEVER.
645
645
646646 my($x, $i); # scratch vars
647
647
648648 # And now, the GREAT BIG Schwartzian transform:
649
649
650650 map
651651 $_->[0],
652652
681681
682682 map {
683683 my @bit = ($x = defined($_) ? $_ : '');
684
684
685685 if($x =~ m/^[+-]?(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee](?:[+-]?\d+))?\z/s) {
686686 # It's entirely purely numeric, so treat it specially:
687687 push @bit, '', $x;
702702 }
703703 }
704704 DEBUG and print "$bit[0] => ", map("{$_} ", @bit), "\n";
705
705
706706 \@bit;
707707 }
708708 @_;
714714
715715 sub nsortf {
716716 return @_ if @_ < 2; # Just to be CLEVER.
717
717
718718 my($x, $i); # scratch vars
719
719
720720 # And now, the GREAT BIG Schwartzian transform:
721
721
722722 map
723723 $_->[0],
724724
748748 $x || (@$a <=> @$b ) || ($a->[1] cmp $b->[1])
749749 || ($a->[2] <=> $b->[2]) || ($a->[0] cmp $b->[0]);
750750 # unless we found a result for $x in the while loop,
751 # use length as a tiebreaker, otherwise use the
751 # use length as a tiebreaker, otherwise use the
752752 # lc'd extension, otherwise the verison, otherwise use
753753 # the original string as a fallback tiebreaker.
754754 }
755755
756756 map {
757757 my @bit = ( ($x = defined($_) ? $_ : ''), '',0 );
758
758
759759 {
760760 # Consume the string.
761
761
762762 # First, pull off any VAX-style version
763763 $bit[2] = $1 if $x =~ s/;(\d+)$//;
764
764
765765 # Then pull off any apparent extension
766766 if( $x !~ m/^\.+$/s and # don't mangle ".", "..", or "..."
767767 $x =~ s/(\.[^\.\;]*)$//sg
799799 }
800800 }
801801 }
802
802
803803 DEBUG and print "$bit[0] => ", map("{$_} ", @bit), "\n";
804
804
805805 \@bit;
806806 }
807807 @_;
3636 next if $this eq 'main'; # %main:: is %::
3737
3838 #print "Peeking at $this => ${$this . '::VERSION'}\n";
39
39
4040 if(defined ${$this . '::VERSION'} ) {
4141 $v{$this} = ${$this . '::VERSION'}
4242 } elsif(
5050 # It's probably an unpopulated package.
5151 ## $v{$this} = '...';
5252 }
53
53
5454 $pref = length($this) ? "$this\::" : '';
5555 push @stack, map m/^(.+)::$/ ? "$pref$1" : (), keys %{$this . '::'};
5656 #print "Stack: @stack\n";
2929 foo12a foo12z foo13a foo 14 9x foo12 fooa foolio Foolio Foo12a
3030 )
3131 ;
32
32
3333 print "#\n# In: <@x>\n";
3434 print "# nsort ...\n";
3535 my @y = nsort(map $_, @x);
3636 print "# ncmp ...\n";
3737 my @z = sort {&ncmp($a,$b)}
38 # map $_,
38 # map $_,
3939 @x
4040 ;
4141 #print "OK, <@x> => <@y>\n";
42 print(
42 print(
4343 "@y" eq "@z"
44 ? scalar(ok(1), "# Good, eq") : scalar(ok(0), "# Feh, NE!\n< <@x>"),
44 ? scalar(ok(1), "# Good, eq") : scalar(ok(0), "# Feh, NE!\n< <@x>"),
4545 "\n# <@y>\n# :<@z>\n"
4646 );
4747 if("@y" eq $ok1) {