BATsh

 view release on metacpan or  search on metacpan

lib/BATsh/SH.pm  view on Meta::CPAN

# friends).  $convert_sub converts one pattern-list alternative (which
# may itself contain nested extglob groups) to a regex fragment.
#
# Returns ($pos_after_close_paren, $regex_fragment), or () when the
# text at $i is not a well-formed extglob group (extglob is then left
# to fall through to its ordinary, literal meaning for that character).
#
# !(list) is approximated as "any run of characters that never forms a
# complete match of one of the alternatives" via a negative lookahead
# repeated per character; this matches the common "exclude these whole
# patterns" usage (e.g. !(*.jpg|*.png)) but, unlike real extglob, is not
# exact when !(...) is combined with more pattern after it in the same
# glob -- documented as a known limitation.
# ----------------------------------------------------------------
sub _extglob_scan {
    my ($chars_ref, $i, $convert_sub) = @_;
    my @c = @{$chars_ref};
    my $n = scalar @c;
    return () unless $i+1 < $n && $c[$i+1] eq '(';
    my $op    = $c[$i];
    my $depth = 1;

lib/BATsh/SH.pm  view on Meta::CPAN

supported (each alternative is itself recursively brace-expanded).

=head2 Extended Pattern Matching (extglob)

  shopt -s extglob        # enable; "shopt -u extglob" disables (the default)
  shopt extglob            # query; "shopt" alone lists all known options
  shopt -p extglob          # print in "shopt -s/-u extglob" form

  case $f in
    @(*.tar.gz|*.tgz)) echo archive ;;
    !(*.jpg|*.png))     echo not-an-image ;;
  esac

  echo ${name%%+([0-9])}   # strip a trailing run of digits

While C<shopt -s extglob> is active, C<?(list)>, C<*(list)>, C<+(list)>,
C<@(list)>, and C<!(list)> pattern-list operators (C<|>-separated
alternatives, each itself an ordinary glob or a nested extglob group) are
recognised in case patterns and in the C<${VAR%pat}> / C<${VAR%%pat}> /
C<${VAR#pat}> / C<${VAR##pat}> / C<${VAR/pat/rep}> / C<${VAR//pat/rep}>
pattern operand.  C<extglob> is off by default, matching bash, and is

lib/BATsh/SH.pm  view on Meta::CPAN

C<set -e> / C<-u> / C<-x>.

=head3 Extended Pattern Matching Limitations

=over 4

=item *

Extglob operators are recognised in case patterns and in the
C<${VAR#pat}>-family parameter-expansion patterns only.  Pathname
(filename) globbing (C<echo *.@(jpg|png)>) does not expand them: an
unquoted C<(> C<)> is read by the line parser as a subshell command
group long before the word reaches the pathname matcher.

=item *

C<!(list)> is approximated with a repeated negative-lookahead regex
fragment ("any run of characters that never forms a complete match of
one of the alternatives").  This matches the common "exclude these whole
patterns" usage exactly, but is not a byte-for-byte reimplementation of
bash's extglob matcher when C<!(...)> is combined with further pattern

t/0021-sh-extended-features.t  view on Meta::CPAN

# EF08: shopt -s extglob enables @(...) alternation in case patterns
sub {
    my (undef, $out) = _run_capture(
        "shopt -s extglob\ncase abc in\n\@(abc|def)) echo yes ;;\n*) echo no ;;\nesac\n");
    ok_is($out, "yes\n", 'EF08 shopt -s extglob: @(a|b) alternation matches');
},

# EF09: extglob !(...) exclusion in case patterns
sub {
    my (undef, $out) = _run_capture(
        "shopt -s extglob\ncase foo.txt in\n!(*.jpg|*.png)) echo keep ;;\n*) echo skip ;;\nesac\n");
    ok_is($out, "keep\n", 'EF09 extglob !(list) exclusion matches');
},

# EF10: here-string feeds a builtin's stdin
sub {
    my (undef, $out) = _run_capture("read LINE <<< hello\necho \$LINE\n");
    ok_is($out, "hello\n", 'EF10 here-string <<< feeds read');
},

# EF11: here-string content is variable-expanded

t/lib/INA_CPAN_Check.pm  view on Meta::CPAN

    for my $p (@fb) {
        $p =~ s{^\Q$root\E/}{};
    }
    return @fb;
}

# MANIFEST entries that are text and therefore subject to the encoding
# checks.  Anything with a known binary extension is excluded.
sub _text_files {
    my ($root) = @_;
    return grep { !/\.(?:gz|tgz|zip|tar|bz2|png|jpe?g|gif|ico|pdf)$/i }
           _manifest_files($root);
}

# Find $pattern in $path, ignoring POD, __END__, comments, string literals
# and regex literals, so that a match is real code and not prose or data.
# Returns a list of { line => N, text => "..." }.
sub _scan_code {
    my ($path, $pattern) = @_;
    my $text = _slurp($path);
    return () unless $text ne '';



( run in 1.909 second using v1.01-cache-2.11-cpan-788537b7465 )