72 lines
1.2 KiB
Go
72 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// 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() {
|
|
buf := make([]byte, 255)
|
|
|
|
for {
|
|
_, err := r.out.Read(buf)
|
|
if err != nil {
|
|
log.Println("pajen read error:", err)
|
|
return
|
|
}
|
|
|
|
wk := string(buf)
|
|
lines := strings.Split(wk, "\n")
|
|
|
|
for _, l := range lines {
|
|
if l != "" && l != "\n" {
|
|
r.Chan <- l
|
|
}
|
|
}
|
|
}
|
|
}
|