File Coverage

blib/lib/App/Chart/SymbolMatch.pm
Criterion Covered Total %
statement 9 11 81.8
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 13 15 86.6


line stmt bran cond sub pod time code
1             # Copyright 2008, 2009, 2010, 2011, 2015, 2016 Kevin Ryde
2              
3             # This file is part of Chart.
4             #
5             # Chart is free software; you can redistribute it and/or modify it under the
6             # terms of the GNU General Public License as published by the Free Software
7             # Foundation; either version 3, or (at your option) any later version.
8             #
9             # Chart is distributed in the hope that it will be useful, but WITHOUT ANY
10             # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11             # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12             # details.
13             #
14             # You should have received a copy of the GNU General Public License along
15             # with Chart. If not, see <http://www.gnu.org/licenses/>.
16              
17             package App::Chart::SymbolMatch;
18 1     1   355 use 5.006;
  1         3  
19 1     1   4 use strict;
  1         2  
  1         17  
20 1     1   4 use warnings;
  1         2  
  1         21  
21 1     1   245 use App::Chart;
  0            
  0            
22             use App::Chart::Gtk2::Symlist;
23              
24              
25             sub find {
26             my ($target, $preferred_symlist) = @_;
27             if ($target eq '') { return; }
28             my @symlists = App::Chart::Gtk2::Symlist->all_lists;
29              
30             # elevate $preferred_symlist to first in @symlists
31             if ($preferred_symlist) {
32             @symlists = grep {$_ != $preferred_symlist} @symlists;
33             splice @symlists, 0,0, $preferred_symlist;
34             }
35              
36             # exclude subset lists like "Alerts"
37             # @symlists = grep {! $_->is_subset} @symlists;
38              
39             foreach my $proc (\&eq, \&eq_ci,
40             \&eq_sans_suffix, \&eq_ci_sans_suffix,
41             \&eq_ci_sans_hat,
42             \&prefix_ci_sans_hat) {
43             foreach my $symlist (@symlists) {
44             my $listref = $symlist->symbol_listref;
45             foreach my $symbol (@$listref) {
46             if ($proc->($target, $symbol)) {
47             return ($symbol, $symlist);
48             }
49             }
50             }
51             }
52             return undef;
53             }
54              
55             sub eq {
56             my ($x, $y) = @_;
57             return $x eq $y;
58             }
59             sub eq_ci {
60             my ($x, $y) = @_;
61             return uc($x) eq uc($y);
62             }
63             sub eq_sans_suffix {
64             my ($x, $y) = @_;
65             $x = App::Chart::symbol_sans_suffix ($x);
66             $y = App::Chart::symbol_sans_suffix ($y);
67             return $x eq $y;
68             }
69             sub eq_ci_sans_suffix {
70             my ($x, $y) = @_;
71             $x = App::Chart::symbol_sans_suffix ($x);
72             $y = App::Chart::symbol_sans_suffix ($y);
73             return uc($x) eq uc($y);
74             }
75             sub eq_ci_sans_hat {
76             my ($x, $y) = @_;
77             $x =~ s/^\^//;
78             $y =~ s/^\^//;
79             return uc($x) eq uc($y);
80             }
81             sub prefix_ci_sans_hat {
82             my ($part, $str) = @_;
83             $part =~ s/^\^//;
84             $str =~ s/^\^//;
85             return ($str =~ /^\U\Q$part/);
86             }
87              
88             1;
89             __END__
90              
91             =for stopwords symlist bh BHP BHP.AX gsp
92              
93             =head1 NAME
94              
95             App::Chart::SymbolMatch -- loose matching of symbols
96              
97             =head1 SYNOPSIS
98              
99             use App::Chart::SymbolMatch;
100              
101             =head1 DESCRIPTION
102              
103             This module is used for loose symbol entry on the command line and in the
104             Open dialog (see L<App::Chart::Gtk2::OpenDialog>). It's only a separate
105             module to keep a tricky bit of code away from other things.
106              
107             =head1 FUNCTIONS
108              
109             =over 4
110              
111             =item C<< ($symbol, $symlist) = App::Chart::SymbolMatch::find ($target) >>
112              
113             =item C<< ($symbol, $symlist) = App::Chart::SymbolMatch::find ($target, $preferred_symlist) >>
114              
115             Find a symbol for the partial string C<$target> in the symlists and return
116             the symbol and symlist, or return no values if nothing matches (which
117             include when C<$target> is the empty string C<"">).
118              
119             Progressively looser matches are attempted. So first an exact match in the
120             given C<$preferred_symlist>, otherwise other lists. Otherwise a
121             case-insensitive match, or a match without suffix (but always following an
122             explicit suffix on C<$target>), or a partial match at the start of the
123             symbol, and possibly without the index "^" marker.
124              
125             The effect is that for instance a C<$target> "bh" might match "BHP.AX", or
126             "gsp" might match "^GSPC". Note that an exact match anywhere is preferred
127             over a partial match in the current list, because otherwise you could type
128             an exact full symbol like "FOO" and still be left on a "FOO.AX" in the
129             current list.
130              
131             =back
132              
133             =head1 SEE ALSO
134              
135             L<App::Chart>
136              
137             =head1 HOME PAGE
138              
139             L<http://user42.tuxfamily.org/chart/index.html>
140              
141             =head1 LICENCE
142              
143             Copyright 2008, 2009, 2010, 2011, 2015, 2016 Kevin Ryde
144              
145             Chart is free software; you can redistribute it and/or modify it under the
146             terms of the GNU General Public License as published by the Free Software
147             Foundation; either version 3, or (at your option) any later version.
148              
149             Chart is distributed in the hope that it will be useful, but WITHOUT ANY
150             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
151             FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
152             details.
153              
154             You should have received a copy of the GNU General Public License along with
155             Chart; see the file F<COPYING>. Failing that, see
156             L<http://www.gnu.org/licenses/>.
157              
158             =cut