@@ -7,31 +7,41 @@ mod tests;
77/// The result is intended to be informational, for embedding in debug metadata,
88/// and might not be properly quoted/escaped for actual command-line use.
99pub ( crate ) fn quote_command_line_args ( args : & [ String ] ) -> String {
10- // Start with a decent-sized buffer, since rustc invocations tend to be long.
11- let mut buf = String :: with_capacity ( 128 ) ;
10+ // The characters we care about quoting are all ASCII, so we can get some free
11+ // performance by performing the quoting step on bytes instead of characters.
12+ //
13+ // Non-ASCII bytes will be copied as-is, so the result is still UTF-8.
14+
15+ // Calculate an adequate buffer size, assuming no escaping will be needed.
16+ // The `+ 3` represents an extra space and pair of quotes per arg.
17+ let capacity_estimate = args. iter ( ) . map ( |arg| arg. len ( ) + 3 ) . sum :: < usize > ( ) ;
18+ let mut buf = Vec :: with_capacity ( capacity_estimate) ;
1219
1320 for arg in args {
1421 if !buf. is_empty ( ) {
15- buf. push ( ' ' ) ;
22+ buf. push ( b ' ') ;
1623 }
1724
1825 print_arg_quoted ( & mut buf, arg) ;
1926 }
2027
21- buf
28+ // Converting back to String isn't strictly necessary, since the bytes are
29+ // only passed to LLVM which doesn't care, but validating should be cheap
30+ // and it's nice to have some assurance that we didn't mess up.
31+ String :: from_utf8 ( buf) . expect ( "quoted args should still be UTF-8" )
2232}
2333
2434/// Equivalent to LLVM's `sys::printArg` with quoting always enabled
2535/// (see llvm/lib/Support/Program.cpp).
26- fn print_arg_quoted ( buf : & mut String , arg : & str ) {
36+ fn print_arg_quoted ( buf : & mut Vec < u8 > , arg : & str ) {
2737 buf. reserve ( arg. len ( ) + 2 ) ;
2838
29- buf. push ( '"' ) ;
30- for ch in arg. chars ( ) {
31- if matches ! ( ch , '"' | '\\' | '$' ) {
32- buf. push ( '\\' ) ;
39+ buf. push ( b '"') ;
40+ for & byte in arg. as_bytes ( ) {
41+ if matches ! ( byte , b '"' | b '\\' | b '$') {
42+ buf. push ( b '\\') ;
3343 }
34- buf. push ( ch ) ;
44+ buf. push ( byte ) ;
3545 }
36- buf. push ( '"' ) ;
46+ buf. push ( b '"') ;
3747}
0 commit comments