<commit_before>package pipeline

import (
	"fmt"
	"os"
	"strings"

	"github.com/colinrgodsey/step-daemon/lib/gcode"
	"github.com/colinrgodsey/step-daemon/lib/io"
)

func SourceHandler(head, tail io.Conn) {
	started := false

	readFunc := func() {
		//TODO: actual N increment testing
		for msg := range head.Rc() {
			str, ok := msg.(string) // only strings
			if !ok {
				tail.Write(msg)
				continue
			}

			if strings.IndexRune(str, ';') == 0 || str == "" {
				continue // comment-only or blank line
			}

			g, err := gcode.Parse(str)
			if err != nil {
				msg := fmt.Sprintf("error: failed parsing gcode (%v)", err)
				head.Write(msg)
				continue
			}

			if !g.IsM(110) {
				// send to tail before responding ok, incase tail blocks
				tail.Write(g)
			}

			switch g.Num {
			case -1:
				head.Write("ok")
			default:
				head.Write(fmt.Sprintf("ok N%v", g.Num))
			}
		}
	}

	for msg := range tail.Rc() {
		if str := msg.(string); str == "pages_ready" && !started {
			head.Write("info:stepd initialized")
			started = true
			go readFunc()
		} else if str := msg.(string); (str == "echo:start" || str == "pages_ready") && started {
			//TODO: redo this with an appropriate close pattern on the channels
			fmt.Println("fatal:device restart detected")
			os.Exit(1)
		}
		head.Write(msg)
	}
}
<commit_msg>Graceful gcode parse failures<commit_after>package pipeline

import (
	"fmt"
	"os"
	"strings"

	"github.com/colinrgodsey/step-daemon/lib/gcode"
	"github.com/colinrgodsey/step-daemon/lib/io"
)

func SourceHandler(head, tail io.Conn) {
	started := false

	readFunc := func() {
		//TODO: actual N increment testing
		for msg := range head.Rc() {
			str, ok := msg.(string) // only strings
			if !ok {
				tail.Write(msg)
				continue
			}

			if strings.IndexRune(str, ';') == 0 || str == "" {
				continue // comment-only or blank line
			}

			g, err := gcode.Parse(str)
			if err != nil {
				msg := fmt.Sprintf("error: failed parsing gcode (%v)", err)
				head.Write(msg)
			}

			if !g.IsM(110) && err == nil {
				// send to tail before responding ok, incase tail blocks
				tail.Write(g)
			}

			switch g.Num {
			case -1:
				head.Write("ok")
			default:
				head.Write(fmt.Sprintf("ok N%v", g.Num))
			}
		}
	}

	for msg := range tail.Rc() {
		if str := msg.(string); str == "pages_ready" && !started {
			head.Write("info:stepd initialized")
			started = true
			go readFunc()
		} else if str := msg.(string); (str == "echo:start" || str == "pages_ready") && started {
			//TODO: redo this with an appropriate close pattern on the channels
			fmt.Println("fatal:device restart detected")
			os.Exit(1)
		}
		head.Write(msg)
	}
}

{'fraction_non_alphanumeric': 0.1618366578848325, 'fraction_numerical': 0.004516371847948814, 'mean_word_length': 2.8025751072961373, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5300063', 'n_tokens_mistral': 1139, 'n_tokens_neox': 957, 'n_words': 244}