// Copyright (c) 2018, Daniel Martà <mvdan@mvdan.cc>// See LICENSE for licensing informationpackage syntaximportvar ( litLeftBrace = &Lit{Value: "{"} litComma = &Lit{Value: ","} litDots = &Lit{Value: ".."} litRightBrace = &Lit{Value: "}"})// SplitBraces parses brace expansions within a word's literal parts. If any// valid brace expansions are found, they are replaced with BraceExp nodes, and// the function returns true. Otherwise, the word is left untouched and the// function returns false.//// For example, a literal word "foo{bar,baz}" will result in a word containing// the literal "foo", and a brace expansion with the elements "bar" and "baz".//// It does not return an error; malformed brace expansions are simply skipped.// For example, the literal word "a{b" is left unchanged.func ( *Word) bool { := false := &Word{} := var *BraceExp := []*BraceExp{} := func() *BraceExp { := = [:len()-1]iflen() == 0 { = nil = } else { = [len()-1] = .Elems[len(.Elems)-1] }return } := func( *Lit) { .Parts = append(.Parts, ) }for , := range .Parts { , := .(*Lit)if ! { .Parts = append(.Parts, )continue } := 0for := 0; < len(.Value); ++ { := func() {if == {return// empty lit } := * .Value = .Value[:] (&) }switch .Value[] {case'{': () = &Word{} = &BraceExp{Elems: []*Word{}} = append(, )case',':if == nil {continue } () = &Word{} .Elems = append(.Elems, )case'.':if == nil {continue }if +1 >= len(.Value) || .Value[+1] != '.' {continue } () .Sequence = true = &Word{} .Elems = append(.Elems, ) ++case'}':if == nil {continue } = true () := ()iflen(.Elems) == 1 {// return {x} to a non-brace (litLeftBrace) .Parts = append(.Parts, .Elems[0].Parts...) (litRightBrace)break }if !.Sequence { .Parts = append(.Parts, )break }var [2]bool := falsefor , := range .Elems[:2] { := .Lit()if , := strconv.Atoi(); == nil { } elseiflen() == 1 &&'a' <= [0] && [0] <= 'z' { [] = true } else { = true } }iflen(.Elems) == 3 {// increment must be a number := .Elems[2].Lit()if , := strconv.Atoi(); != nil { = true } }// are start and end both chars or // non-chars?if [0] != [1] { = true }if ! { .Parts = append(.Parts, )break }// return broken {x..y[..incr]} to a non-brace (litLeftBrace)for , := range .Elems {if > 0 { (litDots) } .Parts = append(.Parts, .Parts...) } (litRightBrace)default:continue } = + 1 }if == 0 { () } else { := * .Value = .Value[:] (&) } }if ! {returnfalse }// open braces that were never closed fall back to non-bracesfor != { := () (litLeftBrace)for , := range .Elems {if > 0 {if .Sequence { (litDots) } else { (litComma) } } .Parts = append(.Parts, .Parts...) } } * = *returntrue}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.