@@ -264,14 +264,14 @@ fn compile_sequence(
264264 let mut cmd = Rc :: new ( RefCell :: new ( Command :: at_position ( lines, line) ) ) ;
265265 let n_addr = compile_address_range ( lines, line, & mut cmd, context) ?;
266266 line. eat_spaces ( ) ;
267- let mut cmd_spec = get_verified_cmd_spec ( lines, line, n_addr) ?;
267+ let mut cmd_spec = get_verified_cmd_spec ( lines, line, n_addr, context ) ?;
268268
269269 // Compile the command according to its specification.
270270 let mut cmd_mut = cmd. borrow_mut ( ) ;
271271 cmd_mut. code = line. current ( ) ;
272272 match ( cmd_spec. handler ) ( lines, line, & mut cmd_mut, context) ? {
273273 CommandHandling :: GetNext => {
274- cmd_spec = get_verified_cmd_spec ( lines, line, n_addr) ?;
274+ cmd_spec = get_verified_cmd_spec ( lines, line, n_addr, context ) ?;
275275 cmd_mut. code = line. current ( ) ;
276276 ( cmd_spec. handler ) ( lines, line, & mut cmd_mut, context) ?;
277277 }
@@ -1175,6 +1175,7 @@ fn get_verified_cmd_spec(
11751175 lines : & ScriptLineProvider ,
11761176 line : & ScriptCharProvider ,
11771177 n_addr : usize ,
1178+ context : & ProcessingContext ,
11781179) -> UResult < CommandSpec > {
11791180 if line. eol ( ) {
11801181 return compilation_error ( lines, line, "command expected" ) ;
@@ -1194,9 +1195,18 @@ fn get_verified_cmd_spec(
11941195 ) ;
11951196 }
11961197
1198+ if context. is_posix_enabled ( ) && is_gnu_extension ( ch, n_addr) {
1199+ return compilation_error ( lines, line, "command only uses one address" ) ;
1200+ }
1201+
11971202 Ok ( cmd_spec)
11981203}
11991204
1205+ /// Check if the command usage is a GNU extension (not allowed in POSIX mode)
1206+ fn is_gnu_extension ( cmd_code : char , n_addr : usize ) -> bool {
1207+ matches ! ( cmd_code, 'a' | 'i' | '=' | 'l' | 'q' | 'r' ) && n_addr == 2
1208+ }
1209+
12001210// Look up a command addresses and handler by its command code.
12011211fn get_cmd_spec (
12021212 lines : & ScriptLineProvider ,
@@ -1209,7 +1219,7 @@ fn get_cmd_spec(
12091219 handler : compile_negation_command,
12101220 } ) ,
12111221 '=' => Ok ( CommandSpec {
1212- n_addr : 1 ,
1222+ n_addr : 2 ,
12131223 handler : compile_empty_command,
12141224 } ) ,
12151225 ':' => Ok ( CommandSpec {
@@ -1225,7 +1235,7 @@ fn get_cmd_spec(
12251235 handler : compile_end_group_command,
12261236 } ) ,
12271237 'a' | 'i' => Ok ( CommandSpec {
1228- n_addr : 1 ,
1238+ n_addr : 2 ,
12291239 handler : compile_text_command,
12301240 } ) ,
12311241 'b' | 't' => Ok ( CommandSpec {
@@ -1382,7 +1392,7 @@ mod tests {
13821392 fn test_missing_command_character ( ) {
13831393 let lines = ScriptLineProvider :: with_active_state ( "test.sed" , 1 ) ;
13841394 let line = char_provider_from ( "" ) ;
1385- let result = get_verified_cmd_spec ( & lines, & line, 0 ) ;
1395+ let result = get_verified_cmd_spec ( & lines, & line, 0 , & ctx ( ) ) ;
13861396
13871397 assert ! ( result. is_err( ) ) ;
13881398 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1393,7 +1403,7 @@ mod tests {
13931403 fn test_invalid_command_character ( ) {
13941404 let lines = ScriptLineProvider :: with_active_state ( "script.sed" , 2 ) ;
13951405 let line = char_provider_from ( "@" ) ;
1396- let result = get_verified_cmd_spec ( & lines, & line, 0 ) ;
1406+ let result = get_verified_cmd_spec ( & lines, & line, 0 , & ctx ( ) ) ;
13971407
13981408 assert ! ( result. is_err( ) ) ;
13991409 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1404,7 +1414,7 @@ mod tests {
14041414 fn test_too_many_addresses ( ) {
14051415 let lines = ScriptLineProvider :: with_active_state ( "input.sed" , 3 ) ;
14061416 let line = char_provider_from ( "q" ) ; // q takes one address
1407- let result = get_verified_cmd_spec ( & lines, & line, 2 ) ;
1417+ let result = get_verified_cmd_spec ( & lines, & line, 2 , & ctx ( ) ) ;
14081418
14091419 assert ! ( result. is_err( ) ) ;
14101420 let msg = result. unwrap_err ( ) . to_string ( ) ;
@@ -1417,7 +1427,7 @@ mod tests {
14171427 fn test_valid_command_spec ( ) {
14181428 let lines = ScriptLineProvider :: with_active_state ( "input.sed" , 4 ) ;
14191429 let line = char_provider_from ( "a" ) ; // valid command
1420- let result = get_verified_cmd_spec ( & lines, & line, 1 ) ;
1430+ let result = get_verified_cmd_spec ( & lines, & line, 1 , & ctx ( ) ) ;
14211431
14221432 assert ! ( result. is_ok( ) ) ;
14231433 let spec = result. unwrap ( ) ;
0 commit comments