1package Perl::PrereqScanner::NotQuiteLite::Util;
2
3use strict;
4use warnings;
5use Exporter 5.57 qw/import/;
6
7our %FLAGS; BEGIN {
8  my $i = 0;
9  %FLAGS = map {$_ => 1 << $i++} qw/
10  F_KEEP_TOKENS
11  F_EVAL
12  F_STRING_EVAL
13  F_EXPECTS_BRACKET
14  F_CONDITIONAL
15  F_SIDEFF
16  F_SCOPE_END
17  F_STATEMENT_END
18  F_EXPR_END
19  F_EXPR
20  /;
21}
22
23use constant \%FLAGS;
24use constant {
25  MASK_KEEP_TOKENS => ~(F_KEEP_TOKENS),
26  MASK_EXPR_END => ~(F_EXPR_END|F_EXPR),
27  MASK_STATEMENT_END => ~(F_KEEP_TOKENS|F_STATEMENT_END|F_EXPR|F_EXPR_END|F_SIDEFF),
28  MASK_EVAL => ~(F_EVAL),
29  MASK_SIDEFF => ~(F_SIDEFF),
30  F_RESCAN => (F_KEEP_TOKENS|F_EVAL|F_STRING_EVAL|F_CONDITIONAL),
31};
32
33our @EXPORT = ((keys %FLAGS), qw/
34  is_module_name
35  is_version
36  convert_string_tokens
37  convert_string_token_list
38  MASK_KEEP_TOKENS
39  MASK_EXPR_END
40  MASK_STATEMENT_END
41  MASK_EVAL
42  MASK_SIDEFF
43  F_RESCAN
44/);
45
46sub is_module_name {
47  my $name = shift or return;
48  return 1 if $name =~ /^[A-Za-z_][A-Za-z0-9_]*(?:(?:::|')[A-Za-z0-9_]+)*$/;
49  return;
50}
51
52sub is_version {
53  my $version = shift;
54  return unless defined $version;
55  return 1 if $version =~ /\A
56    (
57      [0-9]+(?:\.[0-9]+)?
58      |
59      v[0-9]+(?:\.[0-9]+)*
60      |
61      [0-9]+(?:\.[0-9]+){2,}
62    ) (?:_[0-9]+)?
63  \z/x;
64  return;
65}
66
67sub convert_string_tokens {
68  my $org_tokens = shift;
69  my @tokens;
70  my @copied_tokens = @$org_tokens;
71  my $prev = '';
72  while(my $copied_token = shift @copied_tokens) {
73    my ($token, $desc) = @$copied_token;
74    if ($desc and $desc eq '()' and $prev ne 'WORD') {
75      unshift @copied_tokens, @$token;
76      next;
77    }
78
79    if (!$desc) {
80      push @tokens, $copied_token;
81    } elsif ($desc eq 'VERSION_STRING' or $desc eq 'NUMBER') {
82      push @tokens, $token;
83    } elsif ($desc eq 'STRING') {
84      push @tokens, $token->[0];
85    } elsif ($desc eq 'QUOTED_WORD_LIST') {
86      push @tokens, grep {defined $_ and $_ ne ''} split /\s/, $token->[0];
87    } else {
88      push @tokens, $copied_token;
89    }
90    $prev = $desc;
91  }
92  \@tokens;
93}
94
95sub convert_string_token_list {
96  my $org_tokens = shift;
97  my @list;
98  my @tokens;
99  my @copied_tokens = @$org_tokens;
100  my $prev = '';
101  while(my $copied_token = shift @copied_tokens) {
102    my ($token, $desc) = @$copied_token;
103    if ($desc and $desc eq '()' and $prev ne 'WORD') {
104      unshift @copied_tokens, @$token;
105      next;
106    }
107
108    if (!$desc) {
109      push @tokens, $copied_token;
110    } elsif ($desc eq 'VERSION_STRING' or $desc eq 'NUMBER') {
111      push @tokens, $token;
112    } elsif ($desc eq 'STRING') {
113      push @tokens, $token->[0];
114    } elsif ($desc eq 'QUOTED_WORD_LIST') {
115      push @list, grep {defined $_ and $_ ne ''} split /\s/, $token->[0];
116    } elsif ($token eq ',' or $token eq '=>') {
117      push @list, @tokens == 1 ? $tokens[0] : \@tokens;
118      @tokens = ();
119      $prev = '';
120    } elsif ($desc eq ';') {
121      last;
122    } else {
123      push @tokens, $copied_token;
124    }
125    $prev = $desc;
126  }
127  if (@tokens) {
128    push @list, @tokens == 1 ? $tokens[0] : \@tokens;
129  }
130
131  \@list;
132}
133
1341;
135
136__END__
137
138=encoding utf-8
139
140=head1 NAME
141
142Perl::PrereqScanner::NotQuiteLite::Util
143
144=head1 DESCRIPTION
145
146This provides a few utility functions for internal use.
147
148=head1 FUNCTIONS
149
150=head2 is_module_name
151
152takes a string and returns true if it looks like a module.
153
154=head2 is_version
155
156takes a string and returns true if it looks like a version.
157
158=head1 AUTHOR
159
160Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
161
162=head1 COPYRIGHT AND LICENSE
163
164This software is copyright (c) 2015 by Kenichi Ishigaki.
165
166This is free software; you can redistribute it and/or modify it under
167the same terms as the Perl 5 programming language system itself.
168
169=cut
170