67 lines
1.1 KiB
Go
67 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os/exec"
|
|
)
|
|
|
|
// Pajen represents an instance of the pajen.pl script running in infinite
|
|
// generation mode.
|
|
type Pajen struct {
|
|
Chan chan string
|
|
|
|
proc *exec.Cmd
|
|
out io.ReadCloser
|
|
}
|
|
|
|
// NewPajen starts the pajen script at the path given.
|
|
func NewPajen(path string) (*Pajen, error) {
|
|
p := new(Pajen)
|
|
|
|
p.proc = exec.Command("/usr/bin/perl", path, "-i")
|
|
p.proc.Stdin = p
|
|
|
|
pi, err := p.proc.StdoutPipe()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("pajen: pipe pajen.pl: %w", err)
|
|
}
|
|
p.out = pi
|
|
p.proc.Stderr = p.proc.Stdout
|
|
|
|
p.Chan = make(chan string)
|
|
|
|
if err := p.proc.Start(); err != nil {
|
|
return nil, fmt.Errorf("pajen: start pajen.pl: %w", err)
|
|
}
|
|
|
|
go p.run()
|
|
return p, nil
|
|
}
|
|
|
|
// Read feeds constant newlines to the program.
|
|
func (r *Pajen) Read(b []byte) (int, error) {
|
|
if len(b) < 1 {
|
|
return 0, nil
|
|
}
|
|
|
|
return copy(b, []byte("\n")), nil
|
|
}
|
|
|
|
func (r *Pajen) run() {
|
|
sc := bufio.NewScanner(r.out)
|
|
sc.Split(bufio.ScanLines)
|
|
|
|
for sc.Scan() {
|
|
l := sc.Text()
|
|
if l != "" && l != "\n" {
|
|
r.Chan <- l
|
|
}
|
|
}
|
|
|
|
if sc.Err() != nil {
|
|
log.Println("pajen: output read error: %s", sc.Err())
|
|
}
|
|
}
|