/usr/share/barnowl/lib/BarnOwl/Parse.pm is in barnowl 1.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | use warnings;
use strict;
package BarnOwl::Parse;
use base qw(Exporter);
our @EXPORT_OK = qw(tokenize tokenize_with_point);
# TODO: have the main function return whether or not it was a valid parse, with
# possible error messages or something. (Still give a parse of some sort on
# invalid parses, just let us know it's invalid if we care.) This is to
# implement command-line-ish things in Perl.
=for doc
Ideally, this should use the same codepath we use to /actually/
tokenize commands, but for now, make sure this is kept in sync with
owl_parseline in util.c
Unlike owl_parseline, we always return a result, even in the presence
of parse errors, since we may be called on incomplete command-lines.
The owl_parseline rules are:
* Tokenize on ' ' and '\t'
* ' and " are quote characters
* \ has no effect
=cut
my $boring = qr{[^'" \t]};
my $quote = qr{['"]};
my $space = qr{[ \t]};
sub tokenize_with_point {
my $line = shift;
my $point = shift;
my @words = ();
my $cword = 0;
my $cword_start;
my $cword_end;
my $word_point;
my $word = '';
my $wstart = 0;
my $skipped = 0;
my $have_word = 0;
pos($line) = 0;
while(pos($line) < length($line)) {
if($line =~ m{\G ($boring+) }gcx) {
$word .= $1;
$have_word = 1;
} elsif ($line =~ m{\G ($quote)}gcx) {
my $chr = $1;
$skipped++ if pos($line) > $point;
if($line =~ m{\G ([^$chr]*) $chr}gcx) {
$word .= $1;
$skipped++ if pos($line) > $point;
} else {
$word .= substr($line, pos($line));
pos($line) = length($line);
}
$have_word = 1;
}
if ($line =~ m{\G ($space+|$)}gcx) {
my $wend = pos($line) - length($1);
if ($have_word) {
push @words, $word;
$cword++ unless $wend >= $point;
if(($wend >= $point) && !defined($word_point)) {
$word_point = length($word) - ($wend - $point) + $skipped;
$cword_start = $wstart;
$cword_end = $wend;
}
}
# Always reset, so we get $wstart right
$word = '';
$wstart = pos($line);
$skipped = 0;
$have_word = 0;
}
}
if(length($word)) { die("Internal error, leftover=$word"); }
unless(defined($word_point)) {
$word_point = 0;
$cword_start = $cword_end = $point;
}
return (\@words, $cword, $word_point, $cword_start, $cword_end);
}
sub tokenize {
my $line = shift;
my ($words, $word, $word_point,
$word_start, $word_end) = tokenize_with_point($line, 0);
return $words;
}
|