utils.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package parser
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. )
  7. // dumps the AST defined by `node` as a list of sexps. Returns a string
  8. // suitable for printing.
  9. func (node *Node) Dump() string {
  10. str := ""
  11. str += node.Value
  12. for _, n := range node.Children {
  13. str += "(" + n.Dump() + ")\n"
  14. }
  15. if node.Next != nil {
  16. for n := node.Next; n != nil; n = n.Next {
  17. if len(n.Children) > 0 {
  18. str += " " + n.Dump()
  19. } else {
  20. str += " " + strconv.Quote(n.Value)
  21. }
  22. }
  23. }
  24. return strings.TrimSpace(str)
  25. }
  26. // performs the dispatch based on the two primal strings, cmd and args. Please
  27. // look at the dispatch table in parser.go to see how these dispatchers work.
  28. func fullDispatch(cmd, args string) (*Node, map[string]bool, error) {
  29. fn := dispatch[cmd]
  30. // Ignore invalid Dockerfile instructions
  31. if fn == nil {
  32. fn = parseIgnore
  33. }
  34. sexp, attrs, err := fn(args)
  35. if err != nil {
  36. return nil, nil, err
  37. }
  38. return sexp, attrs, nil
  39. }
  40. // splitCommand takes a single line of text and parses out the cmd and args,
  41. // which are used for dispatching to more exact parsing functions.
  42. func splitCommand(line string) (string, string, error) {
  43. cmdline := TOKEN_WHITESPACE.Split(line, 2)
  44. if len(cmdline) != 2 {
  45. return "", "", fmt.Errorf("We do not understand this file. Please ensure it is a valid Dockerfile. Parser error at %q", line)
  46. }
  47. cmd := strings.ToLower(cmdline[0])
  48. // the cmd should never have whitespace, but it's possible for the args to
  49. // have trailing whitespace.
  50. return cmd, strings.TrimSpace(cmdline[1]), nil
  51. }
  52. // covers comments and empty lines. Lines should be trimmed before passing to
  53. // this function.
  54. func stripComments(line string) string {
  55. // string is already trimmed at this point
  56. if TOKEN_COMMENT.MatchString(line) {
  57. return TOKEN_COMMENT.ReplaceAllString(line, "")
  58. }
  59. return line
  60. }