bug-gawk
[Top][All Lists]
Advanced

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

Re: gawk: "please file a bug report"


From: J Naman
Subject: Re: gawk: "please file a bug report"
Date: Fri, 13 Aug 2021 18:29:45 -0400

Thanks so very much for the awksome amount of time, effort, and energy that
all of you maintainers give so freely to the rest of the free software
world! I see exactly what you did. If there is ever anything I can do for
you and/or the gawk community, please let me know. Until then, I will
continue exploring the dark edges of gawk possibilities. And I will
continue my donations to FSF, of course. -john naman

On Fri, Aug 13, 2021 at 5:08 PM <arnold@skeeve.com> wrote:

> Hi.
>
> W.R.T. this:
>
> J Naman <jnaman2@gmail.com> wrote:
>
> > Sorry, just exploring in dark corridors ... gsub() *target*: @strong
> regex.
> > Feel free to use/not use this in a future gawk_source\gawk-master\test
> > -john naman gawker@703n.com
> >
> > gawk: C:\Nsoft\@nsLib\dev\TESTquickRgxGsub.Tr2.awk:8: warning: typeof
> > detected invalid flags combination `MALLOC|STRING|STRCUR|NUMCUR|REGEX';
> > please file a bug report.
> >
> > BEGIN{
> > print "Initialize strong regex"
> > rgx2=rgx1=@/[abc]/
> > printf("rgx%d='%s'\ttypeof(rgx%d)='%s'\n",1,rgx1,1,typeof(rgx1));
> > printf("rgx%d='%s'\ttypeof(rgx%d)='%s'\n",2,rgx2,2,typeof(rgx2));
> > print "Test gsub() a strong regex"
> > gsub(/b/,"e",rgx2);
> > printf("rgx%d='%s'\ttypeof(rgx%d)='%s'\n",1,rgx1,1,typeof(rgx1));   #<
> line
> > 8 warning
> > printf("rgx%d='%s'\ttypeof(rgx%d)='%s'\n",2,rgx2,2,typeof(rgx2));
> > }
> > #========================================
> > Stdout:
> > Initialize strong regex
> > rgx1='[abc]' typeof(rgx1)='regexp'
> > rgx2='[abc]' typeof(rgx2)='regexp'
> > Test gsub() a strong regex
> > rgx1='[abc]' typeof(rgx1)='unknown'        #< line 8 warning
> > rgx2='[aec]' typeof(rgx2)='string'
> > #-----------------------------------------
>
> Here is the patch.
>
> Thanks,
>
> Arnold
> -------------------------------------------------------
> diff --git a/builtin.c b/builtin.c
> index 454034f4..e1ba5eb3 100644
> --- a/builtin.c
> +++ b/builtin.c
> @@ -2934,8 +2934,6 @@ do_sub(int nargs, unsigned int flags)
>                         RESTART(rp, target->stptr) > target->stlen)
>                 goto done;
>
> -       target->flags |= STRING;
> -
>         text = target->stptr;
>         textlen = target->stlen;
>
> @@ -3183,6 +3181,10 @@ done:
>                         DEREF(target);
>                         assert(buf != NULL);
>                         return make_str_node(buf, textlen,
> ALREADY_MALLOCED);
> +               } else if ((target->flags & STRING) == 0) {
> +                       /* return a copy of original string */
> +                       DEREF(target);
> +                       return make_str_node(target->stptr, target->stlen,
> 0);
>                 }
>
>                 /* return the original string */
> @@ -3193,8 +3195,34 @@ done:
>         if ((flags & LITERAL) != 0)
>                 DEREF(target);
>         else if (matches > 0) {
> -               unref(*lhs);
> -               *lhs = make_str_node(buf, textlen, ALREADY_MALLOCED);
> +               /*
> +                * 8/2021: There's a bit of a song and dance here.  If
> someone does
> +                *
> +                *      x = @/abc/
> +                *      sub(/b/, "x", x)
> +                *
> +                * What should the type of x be after the call? Does it
> get converted
> +                * to string? Or does it remain a regexp?  We've decided
> to let it
> +                * remain a regexp. In that case, we have to update the
> compiled
> +                * regular expression that it holds.
> +                */
> +               bool is_regex = false;
> +               NODE *target = *lhs;
> +
> +               if ((target->flags & REGEX) != 0) {
> +                       is_regex = true;
> +
> +                       // free old regex registers
> +                       refree(target->typed_re->re_reg[0]);
> +                       if (target->typed_re->re_reg[1] != NULL)
> +                               refree(target->typed_re->re_reg[1]);
> +                       freenode(target->typed_re);
> +               }
> +               unref(*lhs);            // nuke original value
> +               if (is_regex)
> +                       *lhs = make_typed_regex(buf, textlen);
> +               else
> +                       *lhs = make_str_node(buf, textlen,
> ALREADY_MALLOCED);
>         }
>
>         return make_number((AWKNUM) matches);
>


reply via email to

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