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  }