package Perl::PrereqScanner::NotQuiteLite::Util; use strict; use warnings; use Exporter 5.57 qw/import/; our %FLAGS; BEGIN { my $i = 0; %FLAGS = map {$_ => 1 << $i++} qw/ F_KEEP_TOKENS F_EVAL F_STRING_EVAL F_EXPECTS_BRACKET F_CONDITIONAL F_SIDEFF F_SCOPE_END F_STATEMENT_END F_EXPR_END F_EXPR /; } use constant \%FLAGS; use constant { MASK_KEEP_TOKENS => ~(F_KEEP_TOKENS), MASK_EXPR_END => ~(F_EXPR_END|F_EXPR), MASK_STATEMENT_END => ~(F_KEEP_TOKENS|F_STATEMENT_END|F_EXPR|F_EXPR_END|F_SIDEFF), MASK_EVAL => ~(F_EVAL), MASK_SIDEFF => ~(F_SIDEFF), F_RESCAN => (F_KEEP_TOKENS|F_EVAL|F_STRING_EVAL|F_CONDITIONAL), }; our @EXPORT = ((keys %FLAGS), qw/ is_module_name is_version convert_string_tokens convert_string_token_list MASK_KEEP_TOKENS MASK_EXPR_END MASK_STATEMENT_END MASK_EVAL MASK_SIDEFF F_RESCAN /); sub is_module_name { my $name = shift or return; return 1 if $name =~ /^[A-Za-z_][A-Za-z0-9_]*(?:(?:::|')[A-Za-z0-9_]+)*$/; return; } sub is_version { my $version = shift; return unless defined $version; return 1 if $version =~ /\A ( [0-9]+(?:\.[0-9]+)? | v[0-9]+(?:\.[0-9]+)* | [0-9]+(?:\.[0-9]+){2,} ) (?:_[0-9]+)? \z/x; return; } sub convert_string_tokens { my $org_tokens = shift; my @tokens; my @copied_tokens = @$org_tokens; my $prev = ''; while(my $copied_token = shift @copied_tokens) { my ($token, $desc) = @$copied_token; if ($desc and $desc eq '()' and $prev ne 'WORD') { unshift @copied_tokens, @$token; next; } if (!$desc) { push @tokens, $copied_token; } elsif ($desc eq 'VERSION_STRING' or $desc eq 'NUMBER') { push @tokens, $token; } elsif ($desc eq 'STRING') { push @tokens, $token->[0]; } elsif ($desc eq 'QUOTED_WORD_LIST') { push @tokens, grep {defined $_ and $_ ne ''} split /\s/, $token->[0]; } else { push @tokens, $copied_token; } $prev = $desc; } \@tokens; } sub convert_string_token_list { my $org_tokens = shift; my @list; my @tokens; my @copied_tokens = @$org_tokens; my $prev = ''; while(my $copied_token = shift @copied_tokens) { my ($token, $desc) = @$copied_token; if ($desc and $desc eq '()' and $prev ne 'WORD') { unshift @copied_tokens, @$token; next; } if (!$desc) { push @tokens, $copied_token; } elsif ($desc eq 'VERSION_STRING' or $desc eq 'NUMBER') { push @tokens, $token; } elsif ($desc eq 'STRING') { push @tokens, $token->[0]; } elsif ($desc eq 'QUOTED_WORD_LIST') { push @list, grep {defined $_ and $_ ne ''} split /\s/, $token->[0]; } elsif ($token eq ',' or $token eq '=>') { push @list, @tokens == 1 ? $tokens[0] : \@tokens; @tokens = (); $prev = ''; } elsif ($desc eq ';') { last; } else { push @tokens, $copied_token; } $prev = $desc; } if (@tokens) { push @list, @tokens == 1 ? $tokens[0] : \@tokens; } \@list; } 1; __END__ =encoding utf-8 =head1 NAME Perl::PrereqScanner::NotQuiteLite::Util =head1 DESCRIPTION This provides a few utility functions for internal use. =head1 FUNCTIONS =head2 is_module_name takes a string and returns true if it looks like a module. =head2 is_version takes a string and returns true if it looks like a version. =head1 AUTHOR Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt> =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2015 by Kenichi Ishigaki. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut