1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #33436 from Microsoft/jjh/parserdirective

Builder: Fix parser directive refactoring
This commit is contained in:
John Howard 2017-06-01 21:21:46 -07:00 committed by GitHub
commit 57ca00240b

View file

@ -107,29 +107,28 @@ func (d *Directive) setEscapeToken(s string) error {
return nil return nil
} }
// processLine looks for a parser directive '# escapeToken=<char>. Parser // possibleParserDirective looks for one or more parser directives '# escapeToken=<char>' and
// directives must precede any builder instruction or other comments, and cannot // '# platform=<string>'. Parser directives must precede any builder instruction
// be repeated. // or other comments, and cannot be repeated.
func (d *Directive) processLine(line string) error { func (d *Directive) possibleParserDirective(line string) error {
if d.processingComplete { if d.processingComplete {
return nil return nil
} }
// Processing is finished after the first call
defer func() { d.processingComplete = true }()
tecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line)) tecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line))
if len(tecMatch) == 0 { if len(tecMatch) != 0 {
return nil for i, n := range tokenEscapeCommand.SubexpNames() {
} if n == "escapechar" {
if d.escapeSeen == true { if d.escapeSeen == true {
return errors.New("only one escape parser directive can be used") return errors.New("only one escape parser directive can be used")
} }
for i, n := range tokenEscapeCommand.SubexpNames() { d.escapeSeen = true
if n == "escapechar" { return d.setEscapeToken(tecMatch[i])
d.escapeSeen = true }
return d.setEscapeToken(tecMatch[i])
} }
} }
d.processingComplete = true
return nil return nil
} }
@ -213,34 +212,36 @@ func Parse(rwc io.Reader) (*Result, error) {
var err error var err error
for scanner.Scan() { for scanner.Scan() {
bytes := scanner.Bytes() bytesRead := scanner.Bytes()
switch currentLine { if currentLine == 0 {
case 0: // First line, strip the byte-order-marker if present
bytes, err = processFirstLine(d, bytes) bytesRead = bytes.TrimPrefix(bytesRead, utf8bom)
if err != nil { }
return nil, err bytesRead, err = processLine(d, bytesRead, true)
} if err != nil {
default: return nil, err
bytes = processLine(bytes, true)
} }
currentLine++ currentLine++
startLine := currentLine startLine := currentLine
line, isEndOfLine := trimContinuationCharacter(string(bytes), d) line, isEndOfLine := trimContinuationCharacter(string(bytesRead), d)
if isEndOfLine && line == "" { if isEndOfLine && line == "" {
continue continue
} }
for !isEndOfLine && scanner.Scan() { for !isEndOfLine && scanner.Scan() {
bytes := processLine(scanner.Bytes(), false) bytesRead, err := processLine(d, scanner.Bytes(), false)
if err != nil {
return nil, err
}
currentLine++ currentLine++
// TODO: warn this is being deprecated/removed // TODO: warn this is being deprecated/removed
if isEmptyContinuationLine(bytes) { if isEmptyContinuationLine(bytesRead) {
continue continue
} }
continuationLine := string(bytes) continuationLine := string(bytesRead)
continuationLine, isEndOfLine = trimContinuationCharacter(continuationLine, d) continuationLine, isEndOfLine = trimContinuationCharacter(continuationLine, d)
line += continuationLine line += continuationLine
} }
@ -251,7 +252,6 @@ func Parse(rwc io.Reader) (*Result, error) {
} }
root.AddChild(child, startLine, currentLine) root.AddChild(child, startLine, currentLine)
} }
return &Result{AST: root, EscapeToken: d.escapeToken}, nil return &Result{AST: root, EscapeToken: d.escapeToken}, nil
} }
@ -279,16 +279,10 @@ func trimContinuationCharacter(line string, d *Directive) (string, bool) {
// TODO: remove stripLeftWhitespace after deprecation period. It seems silly // TODO: remove stripLeftWhitespace after deprecation period. It seems silly
// to preserve whitespace on continuation lines. Why is that done? // to preserve whitespace on continuation lines. Why is that done?
func processLine(token []byte, stripLeftWhitespace bool) []byte { func processLine(d *Directive, token []byte, stripLeftWhitespace bool) ([]byte, error) {
if stripLeftWhitespace { if stripLeftWhitespace {
token = trimWhitespace(token) token = trimWhitespace(token)
} }
return trimComments(token) err := d.possibleParserDirective(string(token))
}
func processFirstLine(d *Directive, token []byte) ([]byte, error) {
token = bytes.TrimPrefix(token, utf8bom)
token = trimWhitespace(token)
err := d.processLine(string(token))
return trimComments(token), err return trimComments(token), err
} }