package parse

import (
	
	
)

// Quote returns a valid Elvish expression that evaluates to the given string.
// If s is a valid bareword, it is returned as is; otherwise it is quoted,
// preferring the use of single quotes.
func ( string) string {
	, _ = QuoteAs(, Bareword)
	return 
}

// QuoteVariableName is like Quote, but quotes s if it contains any character
// that may not appear unquoted in variable names.
func ( string) string {
	if  == "" {
		return "''"
	}

	// Keep track of whether it is a valid bareword.
	 := true
	for ,  := range  {
		if !unicode.IsPrint() {
			// Contains unprintable character; force double quote.
			return quoteDouble()
		}
		if !allowedInVariableName() {
			 = false
			break
		}
	}

	if  {
		return 
	}
	return quoteSingle()
}

// QuoteAs returns a representation of s in elvish syntax, preferring the syntax
// specified by q, which must be one of Bareword, SingleQuoted, or DoubleQuoted.
// It returns the quoted string and the actual quoting.
func ( string,  PrimaryType) (string, PrimaryType) {
	if  == DoubleQuoted {
		// Everything can be quoted using double quotes, return directly.
		return quoteDouble(), DoubleQuoted
	}
	if  == "" {
		return "''", SingleQuoted
	}

	// Keep track of whether it is a valid bareword.
	 := [0] != '~'
	for ,  := range  {
		if !unicode.IsPrint() {
			// Contains unprintable character; force double quote.
			return quoteDouble(), DoubleQuoted
		}
		if !allowedInBareword(, strictExpr) {
			 = false
		}
	}

	if  == Bareword &&  {
		return , Bareword
	}
	return quoteSingle(), SingleQuoted
}

func ( string) string {
	var  bytes.Buffer
	.WriteByte('\'')
	for ,  := range  {
		.WriteRune()
		if  == '\'' {
			.WriteByte('\'')
		}
	}
	.WriteByte('\'')
	return .String()
}

func ( rune,  int) []byte {
	 := make([]byte, )
	for  :=  - 1;  >= 0; -- {
		 := byte( % 16)
		 /= 16
		if  <= 9 {
			[] = '0' + 
		} else {
			[] = 'a' +  - 10
		}
	}
	return 
}

func ( string) string {
	var  bytes.Buffer
	.WriteByte('"')
	for ,  := range  {
		if ,  := doubleUnescape[];  {
			// Takes care of " and \ as well.
			.WriteByte('\\')
			.WriteRune()
		} else if !unicode.IsPrint() {
			.WriteByte('\\')
			if  <= 0xff {
				.WriteByte('x')
				.Write(rtohex(, 2))
			} else if  <= 0xffff {
				.WriteByte('u')
				.Write(rtohex(, 4))
			} else {
				.WriteByte('U')
				.Write(rtohex(, 8))
			}
		} else {
			.WriteRune()
		}
	}
	.WriteByte('"')
	return .String()
}