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: Ed Morton
Subject: Re: inconsistent output for field reference for a number stored as a string
Date: Sun, 7 Jun 2020 22:15:39 -0400
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.8.1

Responses inline below

On 6/7/2020 8:38 PM, Andrew J. Schorr wrote:
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 came up in a discussion on stackexchange about what `$` meant in shell vs awk.
It seems like it must be a bug though to treat {printf "%s\n", $"2"}
and {print $"2"} differently.
Yeah, the real kicker for me was when `print $"2"` behaved differently from `print ($"2")`.

Thanks for looking into it.

  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]