// lexRawQuote scans a raw quoted string.
14525
func lexRawQuote(l *lexer) stateFn {
Loop:
	for {
		switch l.next() {
		case eof:
			return l.errorf("unterminated raw quoted string")
		case '`':
			break Loop
		}
	}
	l.emit(itemRawString)
	return lexInsideAction
}
1144062
func ShellQuoteArg(arg string) string {
	if arg == "" {
		return "''"
	}

	if !hasUnsafeChar.MatchString(arg) {
		return arg
	}

	// wrap with single quotes; put existing single quotes into double quotes
	return "'" + strings.Replace(arg, "'", "'\"'\"'", -1) + "'"
}
1363962
func (l *Lexer) shiftRawText() []byte {
	if l.rawTag == Plaintext {
		for {
			if l.r.Peek(0) == 0 && l.r.Err() != nil {
				return l.r.Shift()
			}
			l.r.Move(1)
		}
	} else { // RCDATA, RAWTEXT and SCRIPT
		for {
			c := l.r.Peek(0)
			if c == '<' {
				if l.r.Peek(1) == '/' {
					mark := l.r.Pos()
					l.r.Move(2)
					for {
						if c = l.r.Peek(0); !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
							break
						}
						l.r.Move(1)
					}
					if h := ToHash(parse.ToLower(parse.Copy(l.r.Lexeme()[mark+2:]))); h == l.rawTag { // copy so that ToLower doesn't change the case of the underlying slice
						l.r.Rewind(mark)
						return l.r.Shift()
					}
				} else if l.rawTag == Script && l.r.Peek(1) == '!' && l.r.Peek(2) == '-' && l.r.Peek(3) == '-' {
					l.r.Move(4)
					inScript := false
					for {
						c := l.r.Peek(0)
						if c == '-' && l.r.Peek(1) == '-' && l.r.Peek(2) == '>' {
							l.r.Move(3)
							break
						} else if c == '<' {
							isEnd := l.r.Peek(1) == '/'
							if isEnd {
								l.r.Move(2)
							} else {
								l.r.Move(1)
							}
							mark := l.r.Pos()
							for {
								if c = l.r.Peek(0); !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
									break
								}
								l.r.Move(1)
							}
							if h := ToHash(parse.ToLower(parse.Copy(l.r.Lexeme()[mark:]))); h == Script { // copy so that ToLower doesn't change the case of the underlying slice
								if !isEnd {
									inScript = true
								} else {
									if !inScript {
										l.r.Rewind(mark - 2)
										return l.r.Shift()
									}
									inScript = false
								}
							}
						} else if c == 0 && l.r.Err() != nil {
							return l.r.Shift()
						} else {
							l.r.Move(1)
						}
					}
				} else {
					l.r.Move(1)
				}
			} else if c == 0 && l.r.Err() != nil {
				return l.r.Shift()
			} else {
				l.r.Move(1)
			}
		}
	}
}
408310
func stripQuotes(s string) string {
	if s[0] == '"' {
		s = s[1:]
	}
	if s[len(s)-1] == '"' {
		s = s[:len(s)-1]
	}
	return s
}
900684
func quoteChar(c byte) string {
	// special cases - different from quoted strings
	if c == '\'' {
		return `'\''`
	}
	if c == '"' {
		return `'"'`
	}

	// use quoted string with different quotation marks
	s := strconv.Quote(string(c))
	return "'" + s[1:len(s)-1] + "'"
}
1374715
func needsQuoting(text string) bool {
	for _, r := range text {
		if !strconv.IsPrint(r) {
			return true
		}
	}
	return false
}
1078446
func lexText(l *lexer) stateFn {
	var r, lastChar rune
	for {
		lastChar = r
		r = l.next()

		// comment / soydoc handling
		if r == '/' {
			switch l.next() {
			case '/':
				// '//' only begins a comment if the previous character is whitespace,
				// or if we are the start of input.
				var lastCharEmitted = lastChar
				if lastChar == 0 && l.lastEmit.val != "" {
					lastCharEmitted = rune(l.lastEmit.val[len(l.lastEmit.val)-1])
				}
				if lastCharEmitted == 0 || isSpaceEOL(lastCharEmitted) {
					maybeEmitText(l, 3)
					if lastChar != 0 {
						l.start++ // ignore the preceeding space, if present.
					}
					return lexLineComment(l)
				}
			case '*':
				maybeEmitText(l, 2)
				if l.next() == '*' {
					return lexSoyDoc(l)
				}
				l.backup()
				return lexBlockComment(l)
			}
			l.backup()
		}

		// eof or entering a tag?
		switch r {
		case '{':
			l.backup()
			maybeEmitText(l, 0)
			return lexLeftDelim
		case '}':
			return l.errorf("unexpected closing delimiter } found in input.")
		case eof:
			l.backup()
			maybeEmitText(l, 0)
			l.emit(itemEOF)
			return nil
		}
	}
}
897036
func lexString(lx *lexer) stateFn {
	r := lx.next()
	switch {
	case r == '\\':
		lx.addCurrentStringPart(1)
		return lexStringEscape
	// Termination of non-quoted strings
	case isNL(r) || r == eof || r == optValTerm ||
		r == arrayValTerm || r == arrayEnd || r == mapEnd ||
		isWhitespace(r):

		lx.backup()
		if lx.hasEscapedParts() {
			lx.emitString()
		} else if lx.isBool() {
			lx.emit(itemBool)
		} else if lx.isVariable() {
			lx.emit(itemVariable)
		} else {
			lx.emitString()
		}
		return lx.pop()
	case r == sqStringEnd:
		lx.backup()
		lx.emitString()
		lx.next()
		lx.ignore()
		return lx.pop()
	}
	return lexString
}
328326
func lexLiteral(l *lexer) stateFn {
	l.next()
	for done := false; !done; {
		switch r := l.next(); r {
		case backSlash:
			if nr := l.peek(); nr == quote {
				l.next()
				continue
			}
		case quote:
			l.backup()
			if !l.consume(literalType) {
				l.emitError("literals require a type definintion; missing ^^type:")
				return nil
			}
			literalT := ""
			for {
				r := l.next()
				if !(unicode.IsLetter(r) || unicode.IsDigit(r)) || r == eof {
					break
				}
				literalT += string(r)
			}
			literalT = strings.ToLower(literalT)
			switch literalT {
			case literalBool, literalInt, literalFloat, literalText, literalBlob:
				l.backup()
				l.emit(ItemLiteral)
				done = true
			default:
				l.emitError("invalid literal type " + literalT)
				return nil
			}
		case eof:
			l.emitError("literals needs to be properly terminated; missing \" and type")
			return nil
		}
	}
	return lexSpace
}
748273
func (gen *Generator) GenerateSyntaxQuote(args []Sexp) error {

	if len(args) != 1 {
		return errors.New("syntax-quote takes exactly one argument")
	}
	arg := args[0]

	// need to handle arrays, since they can have unquotes
	// in them too.
	switch arg.(type) {
	case SexpArray:
		gen.generateSyntaxQuoteArray(arg)
		return nil
	case SexpPair:
		if !IsList(arg) {
			break
		}
		gen.generateSyntaxQuoteList(arg)
		return nil
	case SexpHash:
		gen.generateSyntaxQuoteHash(arg)
		return nil
	}
	gen.AddInstruction(PushInstr{arg})
	return nil
}
637111
func QuoteIdent(segments ...string) string {
	var buf bytes.Buffer
	for i, segment := range segments {
		needQuote := IdentNeedsQuotes(segment) ||
			((i < len(segments)-1) && segment != "") || // not last segment && not ""
			((i == 0 || i == len(segments)-1) && segment == "") // the first or last segment and an empty string

		if needQuote {
			_ = buf.WriteByte('"')
		}

		_, _ = buf.WriteString(qiReplacer.Replace(segment))

		if needQuote {
			_ = buf.WriteByte('"')
		}

		if i < len(segments)-1 {
			_ = buf.WriteByte('.')
		}
	}
	return buf.String()
}
689591
func ShellQuoteArguments(args []string) string {
	var buf bytes.Buffer
	for i, arg := range args {
		if i != 0 {
			buf.WriteByte(' ')
		}
		quote(arg, &buf)
	}
	return buf.String()
}
996037
func unquote(s, quote string) string {
	if !strings.HasPrefix(s, quote) && !strings.HasSuffix(s, quote) {
		return s
	}
	s = strings.TrimPrefix(s, quote)
	s = strings.TrimSuffix(s, quote)
	return s
}
1319857
func BashQuote(env string) string {
	out := []rune{'"'}
	for _, r := range env {
		switch r {
		case '$', '\\', '"':
			out = append(out, '\\', r)
		default:
			out = append(out, r)
		}
	}
	out = append(out, '"')
	return string(out)
}
517924
func UnquoteExtend(s string) (string, error) {
	n := len(s)
	if n < 2 {
		return "", ErrSyntax
	}
	quote := s[0]
	if quote != s[n-1] {
		return "", ErrSyntax
	}
	s = s[1 : n-1]

	if quote != '"' && quote != '\'' {
		return "", ErrSyntax
	}

	// Is it trivial?  Avoid allocation.
	if !contains(s, '\\') && !contains(s, quote) {
		return s, nil
	}

	var runeTmp [utf8.UTFMax]byte
	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
	for len(s) > 0 {
		c, multibyte, ss, err := strconv.UnquoteChar(s, quote)
		if err != nil {
			return "", err
		}
		s = ss
		if c < utf8.RuneSelf || !multibyte {
			buf = append(buf, byte(c))
		} else {
			n := utf8.EncodeRune(runeTmp[:], c)
			buf = append(buf, runeTmp[:n]...)
		}
	}
	return string(buf), nil
}
1347388
func quoteChar(c int) string {
	// special cases - different from quoted strings
	if c == '\'' {
		return `'\''`
	}
	if c == '"' {
		return `'"'`
	}

	// use quoted string with different quotation marks
	s := strconv.Quote(string(c))
	return "'" + s[1:len(s)-1] + "'"
}
1333930
func quote(unquoted string, triple bool) string {
	q := `"`
	if triple {
		q = `"""`
	}

	var buf bytes.Buffer
	buf.WriteString(q)

	for i := 0; i < len(unquoted); i++ {
		c := unquoted[i]
		if c == '"' && triple && (i+1 < len(unquoted) && unquoted[i+1] != '"' || i+2 < len(unquoted) && unquoted[i+2] != '"') {
			// Can pass up to two quotes through, because they are followed by a non-quote byte.
			buf.WriteByte(c)
			if i+1 < len(unquoted) && unquoted[i+1] == '"' {
				buf.WriteByte(c)
				i++
			}
			continue
		}
		if triple && c == '\n' {
			// Can allow newline in triple-quoted string.
			buf.WriteByte(c)
			continue
		}
		if c == '\'' {
			// Can allow ' since we always use ".
			buf.WriteByte(c)
			continue
		}
		if c == '\\' {
			if i+1 < len(unquoted) && indexByte(notEsc, unquoted[i+1]) >= 0 {
				// Can pass \ through when followed by a byte that
				// known not to be a valid escape sequence and also
				// that does not trigger an escape sequence of its own.
				// Use this, because various BUILD files do.
				buf.WriteByte('\\')
				buf.WriteByte(unquoted[i+1])
				i++
				continue
			}
		}
		if esc[c] != 0 {
			buf.WriteByte('\\')
			buf.WriteByte(esc[c])
			continue
		}
		if c < 0x20 || c >= 0x80 {
			// BUILD files are supposed to be Latin-1, so escape all control and high bytes.
			// I'd prefer to use \x here, but Blaze does not implement
			// \x in quoted strings (b/7272572).
			buf.WriteByte('\\')
			buf.WriteByte(hex[c>>6]) // actually octal but reusing hex digits 0-7.
			buf.WriteByte(hex[(c>>3)&7])
			buf.WriteByte(hex[c&7])
			/*
				buf.WriteByte('\\')
				buf.WriteByte('x')
				buf.WriteByte(hex[c>>4])
				buf.WriteByte(hex[c&0xF])
			*/
			continue
		}
		buf.WriteByte(c)
		continue
	}

	buf.WriteString(q)
	return buf.String()
}