@@ -285,14 +285,14 @@ fn compile_sequence(
285285 let mut cmd = Rc :: new ( RefCell :: new ( Command :: at_position ( lines, line) ) ) ;
286286 let n_addr = compile_address_range ( lines, line, & mut cmd, context) ?;
287287 line. eat_spaces ( ) ;
288- let mut cmd_spec = get_verified_cmd_spec ( lines, line, n_addr) ?;
288+ let mut cmd_spec = get_verified_cmd_spec ( lines, line, n_addr, context . posix ) ?;
289289
290290 // Compile the command according to its specification.
291291 let mut cmd_mut = cmd. borrow_mut ( ) ;
292292 cmd_mut. code = line. current ( ) ;
293293 match ( cmd_spec. handler ) ( lines, line, & mut cmd_mut, context) ? {
294294 CommandHandling :: GetNext => {
295- cmd_spec = get_verified_cmd_spec ( lines, line, n_addr) ?;
295+ cmd_spec = get_verified_cmd_spec ( lines, line, n_addr, context . posix ) ?;
296296 cmd_mut. code = line. current ( ) ;
297297 ( cmd_spec. handler ) ( lines, line, & mut cmd_mut, context) ?;
298298 }
@@ -1119,7 +1119,6 @@ fn compile_text_command(
11191119 context : & mut ProcessingContext ,
11201120) -> UResult < CommandHandling > {
11211121 line. advance ( ) ; // Skip the command character.
1122-
11231122 line. eat_spaces ( ) ; // Skip any leading whitespace.
11241123 if context. posix {
11251124 compile_text_command_posix ( lines, line, cmd, context)
@@ -1251,13 +1250,14 @@ fn get_verified_cmd_spec(
12511250 lines : & ScriptLineProvider ,
12521251 line : & ScriptCharProvider ,
12531252 n_addr : usize ,
1253+ posix : bool ,
12541254) -> UResult < CommandSpec > {
12551255 if line. eol ( ) {
12561256 return compilation_error ( lines, line, "command expected" ) ;
12571257 }
12581258
12591259 let ch = line. current ( ) ;
1260- let cmd_spec = get_cmd_spec ( lines, line, ch) ?;
1260+ let cmd_spec = get_cmd_spec ( lines, line, ch, posix ) ?;
12611261
12621262 if n_addr > cmd_spec. n_addr {
12631263 return compilation_error (
@@ -1278,14 +1278,15 @@ fn get_cmd_spec(
12781278 lines : & ScriptLineProvider ,
12791279 line : & ScriptCharProvider ,
12801280 cmd_code : char ,
1281+ posix : bool ,
12811282) -> UResult < CommandSpec > {
12821283 match cmd_code {
12831284 '!' => Ok ( CommandSpec {
12841285 n_addr : 2 ,
12851286 handler : compile_negation_command,
12861287 } ) ,
12871288 '=' => Ok ( CommandSpec {
1288- n_addr : 1 ,
1289+ n_addr : if posix { 1 } else { 2 } ,
12891290 handler : compile_empty_command,
12901291 } ) ,
12911292 ':' => Ok ( CommandSpec {
@@ -1301,7 +1302,7 @@ fn get_cmd_spec(
13011302 handler : compile_end_group_command,
13021303 } ) ,
13031304 'a' | 'i' => Ok ( CommandSpec {
1304- n_addr : 1 ,
1305+ n_addr : if posix { 1 } else { 2 } ,
13051306 handler : compile_text_command,
13061307 } ) ,
13071308 'b' | 't' => Ok ( CommandSpec {
@@ -1320,13 +1321,17 @@ fn get_cmd_spec(
13201321 n_addr : 2 ,
13211322 handler : compile_number_command,
13221323 } ) ,
1324+ 'q' => Ok ( CommandSpec {
1325+ n_addr : if posix { 1 } else { 2 } ,
1326+ handler : compile_number_command,
1327+ } ) ,
13231328 // Q is a GNU extension
1324- 'q' | ' Q' => Ok ( CommandSpec {
1329+ 'Q' => Ok ( CommandSpec {
13251330 n_addr : 1 ,
13261331 handler : compile_number_command,
13271332 } ) ,
13281333 'r' => Ok ( CommandSpec {
1329- n_addr : 1 ,
1334+ n_addr : if posix { 1 } else { 2 } ,
13301335 handler : compile_read_file_command,
13311336 } ) ,
13321337 's' => Ok ( CommandSpec {
@@ -1378,35 +1383,35 @@ mod tests {
13781383 #[ test]
13791384 fn test_lookup_empty_command ( ) {
13801385 let ( lines, line) = make_providers ( "123abc" ) ;
1381- let cmd = get_cmd_spec ( & lines, & line, 'd' ) . unwrap ( ) ;
1386+ let cmd = get_cmd_spec ( & lines, & line, 'd' , false ) . unwrap ( ) ;
13821387 assert_eq ! ( cmd. n_addr, 2 ) ;
13831388 }
13841389
13851390 #[ test]
13861391 fn test_lookup_text_command ( ) {
13871392 let ( lines, line) = make_providers ( "123abc" ) ;
1388- let cmd = get_cmd_spec ( & lines, & line, 'a' ) . unwrap ( ) ;
1389- assert_eq ! ( cmd. n_addr, 1 ) ;
1393+ let cmd = get_cmd_spec ( & lines, & line, 'a' , false ) . unwrap ( ) ;
1394+ assert_eq ! ( cmd. n_addr, 2 ) ;
13901395 }
13911396
13921397 #[ test]
13931398 fn test_lookup_nonselect_command ( ) {
13941399 let ( lines, line) = make_providers ( "123abc" ) ;
1395- let cmd = get_cmd_spec ( & lines, & line, '!' ) . unwrap ( ) ;
1400+ let cmd = get_cmd_spec ( & lines, & line, '!' , false ) . unwrap ( ) ;
13961401 assert_eq ! ( cmd. n_addr, 2 ) ;
13971402 }
13981403
13991404 #[ test]
14001405 fn test_lookup_endgroup_command ( ) {
14011406 let ( lines, line) = make_providers ( "123abc" ) ;
1402- let cmd = get_cmd_spec ( & lines, & line, '}' ) . unwrap ( ) ;
1407+ let cmd = get_cmd_spec ( & lines, & line, '}' , false ) . unwrap ( ) ;
14031408 assert_eq ! ( cmd. n_addr, 0 ) ;
14041409 }
14051410
14061411 #[ test]
14071412 fn test_lookup_invalid_command ( ) {
14081413 let ( lines, line) = make_providers ( "123abc" ) ;
1409- let result = get_cmd_spec ( & lines, & line, 'Z' ) ;
1414+ let result = get_cmd_spec ( & lines, & line, 'Z' , false ) ;
14101415 assert ! ( result. is_err( ) ) ;
14111416 }
14121417
@@ -1458,7 +1463,7 @@ mod tests {
14581463 fn test_missing_command_character ( ) {
14591464 let lines = ScriptLineProvider :: with_active_state ( "test.sed" , 1 ) ;
14601465 let line = char_provider_from ( "" ) ;
1461- let result = get_verified_cmd_spec ( & lines, & line, 0 ) ;
1466+ let result = get_verified_cmd_spec ( & lines, & line, 0 , ctx ( ) . posix ) ;
14621467
14631468 assert ! ( result. is_err( ) ) ;
14641469 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1469,7 +1474,7 @@ mod tests {
14691474 fn test_invalid_command_character ( ) {
14701475 let lines = ScriptLineProvider :: with_active_state ( "script.sed" , 2 ) ;
14711476 let line = char_provider_from ( "@" ) ;
1472- let result = get_verified_cmd_spec ( & lines, & line, 0 ) ;
1477+ let result = get_verified_cmd_spec ( & lines, & line, 0 , ctx ( ) . posix ) ;
14731478
14741479 assert ! ( result. is_err( ) ) ;
14751480 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1480,7 +1485,7 @@ mod tests {
14801485 fn test_too_many_addresses ( ) {
14811486 let lines = ScriptLineProvider :: with_active_state ( "input.sed" , 3 ) ;
14821487 let line = char_provider_from ( "q" ) ; // q takes one address
1483- let result = get_verified_cmd_spec ( & lines, & line, 2 ) ;
1488+ let result = get_verified_cmd_spec ( & lines, & line, 2 , true ) ;
14841489
14851490 assert ! ( result. is_err( ) ) ;
14861491 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1493,11 +1498,22 @@ mod tests {
14931498 fn test_valid_command_spec ( ) {
14941499 let lines = ScriptLineProvider :: with_active_state ( "input.sed" , 4 ) ;
14951500 let line = char_provider_from ( "a" ) ; // valid command
1496- let result = get_verified_cmd_spec ( & lines, & line, 1 ) ;
1497-
1501+ let result = get_verified_cmd_spec ( & lines, & line, 2 , ctx ( ) . posix ) ;
14981502 assert ! ( result. is_ok( ) ) ;
14991503 let spec = result. unwrap ( ) ;
1500- assert_eq ! ( spec. n_addr, 1 ) ;
1504+ assert_eq ! ( spec. n_addr, 2 ) ;
1505+ }
1506+
1507+ #[ test]
1508+ fn test_invalid_address_range_posix ( ) {
1509+ let lines = ScriptLineProvider :: with_active_state ( "input.sed" , 1 ) ;
1510+ let line = char_provider_from ( "i" ) ; // valid command
1511+ let result = get_verified_cmd_spec ( & lines, & line, 2 , true ) ;
1512+ assert ! ( result. is_err( ) ) ;
1513+ let msg = result. unwrap_err ( ) . to_string ( ) ;
1514+ assert ! (
1515+ msg. contains( "input.sed:1:1: error: command i expects up to 1 address(es), found 2" )
1516+ ) ;
15011517 }
15021518
15031519 // parse_number
0 commit comments