v.util: make util.smart_quote use its output string builder directly
							parent
							
								
									81fe702b77
								
							
						
					
					
						commit
						45c6b6493b
					
				|  | @ -45,7 +45,7 @@ pub fn (b &Builder) byte_at(n int) byte { | |||
| // write appends the string `s` to the buffer
 | ||||
| [inline] | ||||
| pub fn (mut b Builder) write_string(s string) { | ||||
| 	if s == '' { | ||||
| 	if s.len == 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	unsafe { b.push_many(s.str, s.len) } | ||||
|  |  | |||
|  | @ -2,93 +2,119 @@ module util | |||
| 
 | ||||
| import strings | ||||
| 
 | ||||
| const ( | ||||
| 	invalid_escapes = ['(', '{', '$', '`', '.'] | ||||
| ) | ||||
| const invalid_escapes = r'({$`.'.bytes() | ||||
| 
 | ||||
| [direct_array_access] | ||||
| const backslash = 92 | ||||
| 
 | ||||
| const backslash_r = 13 | ||||
| 
 | ||||
| const backslash_n = 10 | ||||
| 
 | ||||
| const double_quote = 34 | ||||
| 
 | ||||
| const double_escape = '\\\\' | ||||
| 
 | ||||
| //[direct_array_access]
 | ||||
| pub fn smart_quote(str string, raw bool) string { | ||||
| 	len := str.len | ||||
| 	if len == 0 { | ||||
| 		return str | ||||
| 		return '' | ||||
| 	} | ||||
| 	mut result := strings.new_builder(len) | ||||
| 	mut pos := -1 | ||||
| 	mut last := '' | ||||
| 	// TODO: This should be a single char?
 | ||||
| 	mut next := '' | ||||
| 	mut last := byte(0) | ||||
| 	mut current := byte(0) | ||||
| 	mut next := byte(0) | ||||
| 	mut skip_next := false | ||||
| 	for { | ||||
| 		pos = pos + 1 | ||||
| 		pos++ | ||||
| 		if skip_next { | ||||
| 			skip_next = false | ||||
| 			pos = pos + 1 | ||||
| 			pos++ | ||||
| 		} | ||||
| 		if pos >= len { | ||||
| 			break | ||||
| 		} | ||||
| 		if pos + 1 < len { | ||||
| 			next = str[pos + 1].ascii_str() | ||||
| 		} | ||||
| 		mut current := str | ||||
| 		mut toadd := str | ||||
| 		if len > 1 { | ||||
| 			current = str[pos].ascii_str() | ||||
| 			toadd = current | ||||
| 			next = str[pos + 1] | ||||
| 		} | ||||
| 		current = str[pos] | ||||
| 		// double quote
 | ||||
| 		if current == '"' { | ||||
| 			toadd = '\\"' | ||||
| 			current = '' | ||||
| 		if current == util.double_quote { | ||||
| 			current = 0 | ||||
| 			last = current | ||||
| 			result.write_b(util.backslash) | ||||
| 			result.write_b(util.double_quote) | ||||
| 			continue | ||||
| 		} | ||||
| 		if current == '\\' { | ||||
| 		if current == util.backslash { | ||||
| 			if raw { | ||||
| 				toadd = '\\\\' | ||||
| 				last = current | ||||
| 				result.write_string(util.double_escape) | ||||
| 				continue | ||||
| 			} else { | ||||
| 				// escaped backslash - keep as is
 | ||||
| 				if next == '\\' { | ||||
| 					toadd = '\\\\' | ||||
| 				if next == util.backslash { | ||||
| 					skip_next = true | ||||
| 				} else if next != '' { | ||||
| 					last = current | ||||
| 					result.write_string(util.double_escape) | ||||
| 					continue | ||||
| 				} else if next != 0 { | ||||
| 					if raw { | ||||
| 						toadd = '\\\\' + next | ||||
| 						skip_next = true | ||||
| 					} | ||||
| 					// keep all valid escape sequences
 | ||||
| 					else if next !in util.invalid_escapes { | ||||
| 						toadd = '\\' + next | ||||
| 						last = current | ||||
| 						result.write_string(util.double_escape) | ||||
| 						continue | ||||
| 					} else if next in util.invalid_escapes { | ||||
| 						skip_next = true | ||||
| 						last = current | ||||
| 						result.write_b(next) | ||||
| 						continue | ||||
| 					} else { | ||||
| 						toadd = next | ||||
| 						// keep all valid escape sequences
 | ||||
| 						skip_next = true | ||||
| 						last = current | ||||
| 						result.write_b(current) | ||||
| 						result.write_b(next) | ||||
| 						continue | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		// keep newlines in string
 | ||||
| 		if current == '\n' { | ||||
| 			toadd = '\\n' | ||||
| 			current = '' | ||||
| 		} else if current == '\r' && next == '\n' { | ||||
| 			toadd = '\r\n' | ||||
| 			current = '' | ||||
| 		if current == util.backslash_n { | ||||
| 			current = 0 | ||||
| 			last = current | ||||
| 			result.write_b(util.backslash) | ||||
| 			result.write_b(`n`) | ||||
| 			continue | ||||
| 		} else if current == util.backslash_r && next == util.backslash_n { | ||||
| 			result.write_b(current) | ||||
| 			result.write_b(next) | ||||
| 			current = 0 | ||||
| 			skip_next = true | ||||
| 			last = current | ||||
| 			continue | ||||
| 		} | ||||
| 		// Dolar sign
 | ||||
| 		if !raw && current == '$' { | ||||
| 			if last == '\\' { | ||||
| 				toadd = r'\$' | ||||
| 		if !raw && current == `$` { | ||||
| 			if last == util.backslash { | ||||
| 				result.write_b(last) | ||||
| 				result.write_b(current) | ||||
| 				last = current | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		// Windows style new line \r\n
 | ||||
| 		if !raw && current == '\r' { | ||||
| 			if next == '\n' { | ||||
| 				skip_next = true | ||||
| 				toadd = '\\n' | ||||
| 			} | ||||
| 		if !raw && current == util.backslash_r && next == util.backslash_n { | ||||
| 			skip_next = true | ||||
| 			result.write_b(util.backslash) | ||||
| 			result.write_b(`n`) | ||||
| 			last = current | ||||
| 			continue | ||||
| 		} | ||||
| 		result.write_string(toadd) | ||||
| 		last = current | ||||
| 		result.write_b(current) | ||||
| 	} | ||||
| 	return result.str() | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue