pajenerator/pajen.go

73 lines
1.2 KiB
Go
Raw Normal View History

2024-01-23 00:55:15 +01:00
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
}
}
}
}