Split some UCI stuff into a separate module.
[remoteglot] / Engine.pm
1 #! /usr/bin/perl
2 use strict;
3 use warnings;
4
5 package Engine;
6
7 sub open {
8         my ($class, $cmdline, $tag) = @_;
9
10         my ($uciread, $uciwrite);
11         my $pid = IPC::Open2::open2($uciread, $uciwrite, $cmdline);
12
13         my $engine = {
14                 pid => $pid,
15                 read => $uciread,
16                 readbuf => '',
17                 write => $uciwrite,
18                 info => {},
19                 ids => {},
20                 tag => $tag,
21         };
22
23         return bless $engine;
24 }
25
26 sub print {
27         my ($engine, $msg) = @_;
28         print { $engine->{'write'} } "$msg\n";
29 }
30
31 sub read_lines {
32         my $engine = shift;
33
34         # 
35         # Read until we've got a full line -- if the engine sends part of
36         # a line and then stops we're pretty much hosed, but that should
37         # never happen.
38         #
39         while ($engine->{'readbuf'} !~ /\n/) {
40                 my $tmp;
41                 my $ret = sysread $engine->{'read'}, $tmp, 4096;
42
43                 if (!defined($ret)) {
44                         next if ($!{EINTR});
45                         die "error in reading from the UCI engine: $!";
46                 } elsif ($ret == 0) {
47                         die "EOF from UCI engine";
48                 }
49
50                 $engine->{'readbuf'} .= $tmp;
51         }
52
53         # Blah.
54         my @lines = ();
55         while ($engine->{'readbuf'} =~ s/^([^\n]*)\n//) {
56                 my $line = $1;
57                 $line =~ tr/\r\n//d;
58                 push @lines, $line;
59         }
60         return @lines;
61 }
62
63
64
65 1;