10
10
//! Subs which have numeric field chars make use of the num_format
11
11
//! submodule
12
12
use crate :: error:: { UError , UResult } ;
13
+ use crate :: quoting_style:: { escape_name, QuotingStyle } ;
13
14
use itertools:: { put_back_n, PutBackN } ;
14
15
use std:: error:: Error ;
15
16
use std:: fmt:: Display ;
@@ -91,7 +92,7 @@ impl Sub {
91
92
// for more dry printing, field characters are grouped
92
93
// in initialization of token.
93
94
let field_type = match field_char {
94
- 's' | 'b' => FieldType :: Strf ,
95
+ 's' | 'b' | 'q' => FieldType :: Strf ,
95
96
'd' | 'i' | 'u' | 'o' | 'x' | 'X' => FieldType :: Intf ,
96
97
'f' | 'F' => FieldType :: Floatf ,
97
98
'a' | 'A' => FieldType :: CninetyNineHexFloatf ,
@@ -189,7 +190,7 @@ impl SubParser {
189
190
190
191
let mut legal_fields = [
191
192
// 'a', 'A', //c99 hex float implementation not yet complete
192
- 'b' , 'c' , 'd' , 'e' , 'E' , 'f' , 'F' , 'g' , 'G' , 'i' , 'o' , 's' , 'u' , 'x' , 'X' ,
193
+ 'b' , 'c' , 'd' , 'e' , 'E' , 'f' , 'F' , 'g' , 'G' , 'i' , 'o' , 'q' , ' s', 'u' , 'x' , 'X' ,
193
194
] ;
194
195
let mut specifiers = [ 'h' , 'j' , 'l' , 'L' , 't' , 'z' ] ;
195
196
legal_fields. sort_unstable ( ) ;
@@ -260,7 +261,6 @@ impl SubParser {
260
261
}
261
262
x if legal_fields. binary_search ( & x) . is_ok ( ) => {
262
263
self . field_char = Some ( ch) ;
263
- self . text_so_far . push ( ch) ;
264
264
break ;
265
265
}
266
266
x if specifiers. binary_search ( & x) . is_ok ( ) => {
@@ -331,7 +331,7 @@ impl SubParser {
331
331
if ( field_char == 's' && self . min_width_tmp == Some ( String :: from ( "0" ) ) )
332
332
|| ( field_char == 'c'
333
333
&& ( self . min_width_tmp == Some ( String :: from ( "0" ) ) || self . past_decimal ) )
334
- || ( field_char == 'b'
334
+ || ( ( field_char == 'b' || field_char == 'q' )
335
335
&& ( self . min_width_tmp . is_some ( )
336
336
|| self . past_decimal
337
337
|| self . second_field_tmp . is_some ( ) ) )
@@ -391,6 +391,7 @@ impl Sub {
391
391
// if %s just return arg
392
392
// if %b use UnescapedText module's unescape-fn
393
393
// if %c return first char of arg
394
+ // if %q return arg which non-printable characters are escaped
394
395
FieldType :: Strf | FieldType :: Charf => {
395
396
match pf_arg {
396
397
Some ( arg_string) => {
@@ -404,11 +405,18 @@ impl Sub {
404
405
UnescapedText :: from_it_core ( writer, & mut a_it, true ) ;
405
406
None
406
407
}
407
- // for 'c': get iter of string vals,
408
+ 'q' => Some ( escape_name (
409
+ arg_string. as_ref ( ) ,
410
+ & QuotingStyle :: Shell {
411
+ escape : true ,
412
+ always_quote : false ,
413
+ show_control : false ,
414
+ } ,
415
+ ) ) ,
408
416
// get opt<char> of first val
409
417
// and map it to opt<String>
410
- /* 'c' | */
411
- _ => arg_string . chars ( ) . next ( ) . map ( |x| x . to_string ( ) ) ,
418
+ 'c' => arg_string . chars ( ) . next ( ) . map ( |x| x . to_string ( ) ) ,
419
+ _ => unreachable ! ( ) ,
412
420
}
413
421
}
414
422
None => None ,
0 commit comments