package main import ( "bufio" "flag" "fmt" "os" "regexp" "strings" "text/tabwriter" ) type queue struct { q []string maxl int } func (q *queue) insert(s string) { if len(q.q) <= q.maxl { q.q = append(q.q, s) return } q.q = append(q.q[1:len(q.q)], s) } type work struct { c chan string left int } func printWithContext(all []string, ind, ctxlen int) { var slice []string slice = append(slice, "\""+all[ind]+"\"") if len(all[:ind]) < ctxlen { slice = append(all[:ind], slice...) } else { slice = append(all[ind-ctxlen:ind], slice...) } if len(all[ind:]) < ctxlen { slice = append(slice, all[ind+1:]...) } else { slice = append(slice, all[ind+1:ind+ctxlen]...) } fmt.Fprintf(tw, "%s\n", strings.Join(slice, "\t")) } func feedworkers(wlist []*work, w string) []*work { var onefinished bool var ret []*work for _, wc := range wlist { if wc.left == 0 { close(wc.c) onefinished = true } } if onefinished && len(wlist) > 1 { ret = wlist[1:] } return ret } func print_kwic(sl []string, c chan string) { for w := range c { sl = append(sl, w) } fmt.Fprintf(tw, "%s\n", strings.Join(sl, "\t")) } func printqueue(q *queue, c chan string, left int) { var hungryhippos []*work for w := range c { index := strings.Index(w, kw) if index < 0 { q.insert(w) feedworkers(hungryhippos, w) continue } q.insert(fmt.Sprintf("%q", w)) fmt.Fprintf(os.Stdout, "%q totally matched %q\n", w, kw) fmt.Fprintf(os.Stdout, "queue was %v\n", q.q) wc := &work{c: make(chan string), left: 5} feedworkers(hungryhippos, w) sl := make([]string, MAX) n := copy(sl, q.q[6:]) fmt.Fprintf(os.Stdout, "copied %d : %v\n", n, sl) hungryhippos = append(hungryhippos, wc) go print_kwic(sl, wc.c) } for _, wc := range hungryhippos { close(wc.c) } } var ( tw *tabwriter.Writer kw string ) const MAX int = 11 func main() { flag.Parse() kw = flag.Arg(0) if len(kw) == 0 { fmt.Printf("Need string to search for. Exiting...\n") os.Exit(1) } tw = tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) splitreg := regexp.MustCompile("[ \t\n]") q := queue{maxl: MAX, q: make([]string, MAX)} sc := make(chan string, 1000) reader := bufio.NewReader(os.Stdin) line, err := reader.ReadString(byte('\n')) go func(c chan string) { var w string for err == nil { splline := splitreg.Split(line, -1) for _, w = range splline { c <- w } line, err = reader.ReadString(byte('\n')) } fmt.Printf("Got an error: %q.\n", err) c <- w close(c) }(sc) printqueue(&q, sc, 5) //printWithContext(splline, i, 5) tw.Flush() }