bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: inconsistent output for field reference for a number stored as a str


From: Andrew J. Schorr
Subject: Re: inconsistent output for field reference for a number stored as a string
Date: Sun, 7 Jun 2020 20:38:21 -0400
User-agent: Mutt/1.5.21 (2010-09-15)

Hi,

On Sun, Jun 07, 2020 at 04:59:59PM -0400, Ed Morton wrote:
> Using:
> 
>    $ gawk --version
>    GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
> 
> I'd have expected all of these to produce the same output:
> 
>    $ echo 'a b c' | awk '{print $("2")}'
>    b
>    $ echo 'a b c' | awk '{print ($"2")}'
>    b
>    $ echo 'a b c' | awk '{print $("2")}'
>    b
>    $ echo 'a b c' | awk '{printf "%s\n", $"2"}'
>    b
>    $ echo 'a b c' | awk '{a=$"2"; print a}'
>    b
>    $ echo 'a b c' | awk '{print $"2"}'
>    a b c
> 
> but as you can see that last one doesn't and I don't know why. Is it
> a bug or, if not, what's the explanation?

That's very weird. Who would ever think to write $"2" instead of $2?
It seems like it must be a bug though to treat {printf "%s\n", $"2"}
and {print $"2"} differently. In my view, it should either be a syntax error
in both cases, or it should work the same way. It seems to me like a bug
in the parser, since the debugger prints this dump for the last one:

bash-4.2$ cat /tmp/test.awk
{print $"2"}
bash-4.2$ ./gawk -D -f /tmp/test.awk 
gawk> dump

[      :0x23f11e8] Op_newfile          : [target_jmp = 0x23efe28] 
[target_endfile = 0x23efe50]
                                         [target_get_record = 0x23efea0]
[      :0x23efe78] Op_no_op            : 
[      :0x23f0030] Op_after_beginfile  : 
[      :0x23efea0] Op_get_record       : [target_newfile = 0x23f11e8]

        # Rule

[     1:0x23f2688] Op_rule             : [in_rule = Rule] [source_file = 
/tmp/test.awk]
[     1:0x23efef0] Op_K_print_rec      : [redir_type = ""]
[      :0x23eff68] Op_no_op            : 
[      :0x23f0008] Op_jmp              : [target_jmp = 0x23efea0]
[      :0x23efe50] Op_no_op            : 
[      :0x23effe0] Op_after_endfile    : 
[      :0x23efe28] Op_no_op            : 
[      :0x23efec8] Op_atexit           : 
[      :0x23eff40] Op_stop             : 

There's simply no mention of 2 in the parsed code. Whereas {printf "%s\n", $"2"}
looks like this:

gawk> dump

[      :0x1af61e8] Op_newfile          : [target_jmp = 0x1af4e28] 
[target_endfile = 0x1af4e50]
                                         [target_get_record = 0x1af4ea0]
[      :0x1af4e78] Op_no_op            : 
[      :0x1af50a8] Op_after_beginfile  : 
[      :0x1af4ea0] Op_get_record       : [target_newfile = 0x1af61e8]

        # Rule

[     1:0x1af76c8] Op_rule             : [in_rule = Rule] [source_file = 
/tmp/test2.awk]
[     1:0x1af4f18] Op_push_i           : "%s\n" [MALLOC|STRING|STRCUR]
[     1:0x1af4fb8] Op_push_i           : "2" [MALLOC|STRING|STRCUR]
[     1:0x1af4f90] Op_field_spec       : 
[     1:0x1af4ef0] Op_K_printf         : [expr_count = 2] [redir_type = ""]
[      :0x1af4f68] Op_no_op            : 
[      :0x1af5080] Op_jmp              : [target_jmp = 0x1af4ea0]
[      :0x1af4e50] Op_no_op            : 
[      :0x1af5058] Op_after_endfile    : 
[      :0x1af4e28] Op_no_op            : 
[      :0x1af4ec8] Op_atexit           : 
[      :0x1af4fe0] Op_stop             : 

And the simple version without the quotes {print $2} gives:

gawk> dump

[      :0x1e931e8] Op_newfile          : [target_jmp = 0x1e91e28] 
[target_endfile = 0x1e91e50]
                                         [target_get_record = 0x1e91ea0]
[      :0x1e91e78] Op_no_op            : 
[      :0x1e92080] Op_after_beginfile  : 
[      :0x1e91ea0] Op_get_record       : [target_newfile = 0x1e931e8]

        # Rule

[     1:0x1e94688] Op_rule             : [in_rule = Rule] [source_file = 
/tmp/test3.awk]
[     1:0x1e91f40] Op_push_i           : 2 [MALLOC|NUMCUR|NUMBER|NUMINT]
[     1:0x1e91f18] Op_field_spec       : 
[     1:0x1e91ef0] Op_K_print          : [expr_count = 1] [redir_type = ""]
[      :0x1e91f90] Op_no_op            : 
[      :0x1e92058] Op_jmp              : [target_jmp = 0x1e91ea0]
[      :0x1e91e50] Op_no_op            : 
[      :0x1e92030] Op_after_endfile    : 
[      :0x1e91e28] Op_no_op            : 
[      :0x1e91ec8] Op_atexit           : 
[      :0x1e91fb8] Op_stop             : 

I don't have time to dive into awkgram.y at the moment. Arnold's the only
one courageous enough to touch that code. :-)

Regards,
Andy



reply via email to

[Prev in Thread] Current Thread [Next in Thread]