github.com/stchris/docker@v1.4.2-0.20150106053530-1510a324dbd5/builder/parser/utils.go (about) 1 package parser 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // QuoteString walks characters (after trimming), escapes any quotes and 9 // escapes, then wraps the whole thing in quotes. Very useful for generating 10 // argument output in nodes. 11 func QuoteString(str string) string { 12 result := "" 13 chars := strings.Split(strings.TrimSpace(str), "") 14 15 for _, char := range chars { 16 switch char { 17 case `"`: 18 result += `\"` 19 case `\`: 20 result += `\\` 21 default: 22 result += char 23 } 24 } 25 26 return `"` + result + `"` 27 } 28 29 // dumps the AST defined by `node` as a list of sexps. Returns a string 30 // suitable for printing. 31 func (node *Node) Dump() string { 32 str := "" 33 str += node.Value 34 35 for _, n := range node.Children { 36 str += "(" + n.Dump() + ")\n" 37 } 38 39 if node.Next != nil { 40 for n := node.Next; n != nil; n = n.Next { 41 if len(n.Children) > 0 { 42 str += " " + n.Dump() 43 } else { 44 str += " " + QuoteString(n.Value) 45 } 46 } 47 } 48 49 return strings.TrimSpace(str) 50 } 51 52 // performs the dispatch based on the two primal strings, cmd and args. Please 53 // look at the dispatch table in parser.go to see how these dispatchers work. 54 func fullDispatch(cmd, args string) (*Node, map[string]bool, error) { 55 fn := dispatch[cmd] 56 57 // Ignore invalid Dockerfile instructions 58 if fn == nil { 59 fn = parseIgnore 60 } 61 62 sexp, attrs, err := fn(args) 63 if err != nil { 64 return nil, nil, err 65 } 66 67 return sexp, attrs, nil 68 } 69 70 // splitCommand takes a single line of text and parses out the cmd and args, 71 // which are used for dispatching to more exact parsing functions. 72 func splitCommand(line string) (string, string, error) { 73 cmdline := TOKEN_WHITESPACE.Split(line, 2) 74 75 if len(cmdline) != 2 { 76 return "", "", fmt.Errorf("We do not understand this file. Please ensure it is a valid Dockerfile. Parser error at %q", line) 77 } 78 79 cmd := strings.ToLower(cmdline[0]) 80 // the cmd should never have whitespace, but it's possible for the args to 81 // have trailing whitespace. 82 return cmd, strings.TrimSpace(cmdline[1]), nil 83 } 84 85 // covers comments and empty lines. Lines should be trimmed before passing to 86 // this function. 87 func stripComments(line string) string { 88 // string is already trimmed at this point 89 if TOKEN_COMMENT.MatchString(line) { 90 return TOKEN_COMMENT.ReplaceAllString(line, "") 91 } 92 93 return line 94 }