Thread: backslashes in pgindent

backslashes in pgindent

From
Bruce Momjian
Date:
Luke, I have had to back out the removal of backslashes in the pgindent
awk script.  Your patch was to remove them:

                  line1 !~ "^typedef" &&
                  line1 !~ "^extern[     ][     ]*\"C\"" &&
                  line1 !~ "=" &&
!                 line1 ~ "\)")
                  print "int    pgindent_func_no_var_fix;";
              line1 = line2;
          }
--- 56,62 ----
                  line1 !~ "^typedef" &&
                  line1 !~ "^extern[     ][     ]*\"C\"" &&
                  line1 !~ "=" &&
!                 line1 ~ ")")
                  print "int    pgindent_func_no_var_fix;";
              line1 = line2;

I found that parentheses in gawk regular expressions require backslashes
so they are not treated as regex groupings:

    $ echo '('|awk '$0 ~ /(/ {print $0}'
    awk: cmd. line:1: fatal: Unmatched ( or \(: /(/
    $ echo '('|awk '$0 ~ /\(/ {print $0}'
    (

Now, it seems closing parentheses are OK because there is no open group,
but I think I should use backslashes there too:

    $ echo ')'|awk '$0 ~ /)/ {print $0}'
    )
    $ echo ')'|awk '$0 ~ /\)/ {print $0}'

Does your awk produce different results?  What version is it?  Mine is GNU Awk
3.0.6.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/tools/pgindent/pgindent
===================================================================
RCS file: /cvsroot/pgsql/src/tools/pgindent/pgindent,v
retrieving revision 1.75
diff -c -c -r1.75 pgindent
*** src/tools/pgindent/pgindent    28 Jun 2005 23:55:30 -0000    1.75
--- src/tools/pgindent/pgindent    13 Jul 2005 03:53:46 -0000
***************
*** 56,62 ****
                  line1 !~ /^typedef/ &&
                  line1 !~ /^extern[     ][     ]*"C"/ &&
                  line1 !~ /=/ &&
!                 line1 ~ /)/)
                  print "int    pgindent_func_no_var_fix;";
              line1 = line2;
          }
--- 56,62 ----
                  line1 !~ /^typedef/ &&
                  line1 !~ /^extern[     ][     ]*"C"/ &&
                  line1 !~ /=/ &&
!                 line1 ~ /\)/)
                  print "int    pgindent_func_no_var_fix;";
              line1 = line2;
          }
***************
*** 1688,1703 ****
  #  like real functions.
      awk '    BEGIN    {paren_level = 0}
      {
!         if ($0 ~ /^[a-zA-Z_][a-zA-Z_0-9]*[^(]*$/)
          {
              saved_len = 0;
              saved_lines[++saved_len] = $0;
              if ((getline saved_lines[++saved_len]) == 0)
                  print saved_lines[1];
              else
!             if (saved_lines[saved_len] !~ /^[a-zA-Z_][a-zA-Z_0-9]*(/ ||
!                 saved_lines[saved_len] ~  /^[a-zA-Z_][a-zA-Z_0-9]*(.*)$/ ||
!                 saved_lines[saved_len] ~  /^[a-zA-Z_][a-zA-Z_0-9]*(.*);$/)
              {
                  print saved_lines[1];
                  print saved_lines[2];
--- 1688,1703 ----
  #  like real functions.
      awk '    BEGIN    {paren_level = 0}
      {
!         if ($0 ~ /^[a-zA-Z_][a-zA-Z_0-9]*[^\(]*$/)
          {
              saved_len = 0;
              saved_lines[++saved_len] = $0;
              if ((getline saved_lines[++saved_len]) == 0)
                  print saved_lines[1];
              else
!             if (saved_lines[saved_len] !~ /^[a-zA-Z_][a-zA-Z_0-9]*\(/ ||
!                 saved_lines[saved_len] ~  /^[a-zA-Z_][a-zA-Z_0-9]*\(.*\)$/ ||
!                 saved_lines[saved_len] ~  /^[a-zA-Z_][a-zA-Z_0-9]*\(.*\);$/)
              {
                  print saved_lines[1];
                  print saved_lines[2];
***************
*** 1714,1720 ****
                  }
                  for (i=1; i <= saved_len; i++)
                  {
!                     if (i == 1 && saved_lines[saved_len] ~ /);$/)
                      {
                          printf "%s", saved_lines[i];
                          if (substr(saved_lines[i], length(saved_lines[i]),1) != "*")
--- 1714,1720 ----
                  }
                  for (i=1; i <= saved_len; i++)
                  {
!                     if (i == 1 && saved_lines[saved_len] ~ /\);$/)
                      {
                          printf "%s", saved_lines[i];
                          if (substr(saved_lines[i], length(saved_lines[i]),1) != "*")

Re: backslashes in pgindent

From
"Luke Lonergan"
Date:
Bruce,
> I found that parentheses in gawk regular expressions require backslashes
> so they are not treated as regex groupings:
>
> $ echo '('|awk '$0 ~ /(/ {print $0}'
> awk: cmd. line:1: fatal: Unmatched ( or \(: /(/
> $ echo '('|awk '$0 ~ /\(/ {print $0}'
> (


> Now, it seems closing parentheses are OK because there is no open group,
> but I think I should use backslashes there too:
>
> $ echo ')'|awk '$0 ~ /)/ {print $0}'
> )
> $ echo ')'|awk '$0 ~ /\)/ {print $0}'
>
> Does your awk produce different results?  What version is it?  Mine is GNU Awk
> 3.0.6.

Yes - on the last test, mine emits the ")" and yours apparently does not.
The version I ran with is 3.1.4.

The escaped parenthesis in the unpatched pgindent causes the following
warning:

 $ pgindent test.c
 Hope you installed /src/tools/pgindent/indent.bsd.patch.
 awk: cmd. line:12: warning: escape sequence `\)' treated as plain `)'

Which implies an unnecessary escaping, which appears to function correctly
without the escape.

Cheers,

- Luke



Re: backslashes in pgindent

From
Bruce Momjian
Date:
Luke Lonergan wrote:
> Bruce,
> > I found that parentheses in gawk regular expressions require backslashes
> > so they are not treated as regex groupings:
> >
> > $ echo '('|awk '$0 ~ /(/ {print $0}'
> > awk: cmd. line:1: fatal: Unmatched ( or \(: /(/
> > $ echo '('|awk '$0 ~ /\(/ {print $0}'
> > (
>
>
> > Now, it seems closing parentheses are OK because there is no open group,
> > but I think I should use backslashes there too:
> >
> > $ echo ')'|awk '$0 ~ /)/ {print $0}'
> > )
> > $ echo ')'|awk '$0 ~ /\)/ {print $0}'
> >
> > Does your awk produce different results?  What version is it?  Mine is GNU Awk
> > 3.0.6.
>
> Yes - on the last test, mine emits the ")" and yours apparently does not.
> The version I ran with is 3.1.4.

Actually, mine returns ')' too for the last command.   I didn't copy
that into the email.  How about the top tests?  Notice I get an error on
the first one without the backslash.  Are you OK escaping '(' but not
')'?  That might be a solution.

> The escaped parenthesis in the unpatched pgindent causes the following
> warning:
>
>  $ pgindent test.c
>  Hope you installed /src/tools/pgindent/indent.bsd.patch.
>  awk: cmd. line:12: warning: escape sequence `\)' treated as plain `)'
>
> Which implies an unnecessary escaping, which appears to function correctly
> without the escape.
>
> Cheers,
>
> - Luke
>
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: backslashes in pgindent

From
"Luke Lonergan"
Date:
Bruce,

On 7/15/05 9:59 PM, "Bruce Momjian" <pgman@candle.pha.pa.us> wrote:

> Actually, mine returns ')' too for the last command.   I didn't copy
> that into the email.  How about the top tests?  Notice I get an error on
> the first one without the backslash.  Are you OK escaping '(' but not
> ')'?  That might be a solution.

You know, I'm not sure - I don't know the intended meaning of this line:

    awk '   BEGIN   {line1 = ""; line2 = ""}
        {
            line2 = $0;
            if (NR >= 2)
                print line1;
            if (NR >= 2 &&
                line2 ~ "^{[    ]*$" &&
                line1 !~ "^struct" &&
                line1 !~ "^enum" &&
                line1 !~ "^typedef" &&
                line1 !~ "^extern[  ][  ]*\"C\"" &&
                line1 !~ "=" &&
=====>          line1 ~ "\)")
                print "int  pgindent_func_no_var_fix;";
            line1 = line2;
        }
        END

Is the escaped paren within "" meant to be a literal?

- Luke



Re: backslashes in pgindent

From
Bruce Momjian
Date:
Luke Lonergan wrote:
> Bruce,
>
> On 7/15/05 9:59 PM, "Bruce Momjian" <pgman@candle.pha.pa.us> wrote:
>
> > Actually, mine returns ')' too for the last command.   I didn't copy
> > that into the email.  How about the top tests?  Notice I get an error on
> > the first one without the backslash.  Are you OK escaping '(' but not
> > ')'?  That might be a solution.
>
> You know, I'm not sure - I don't know the intended meaning of this line:
>
>     awk '   BEGIN   {line1 = ""; line2 = ""}
>         {
>             line2 = $0;
>             if (NR >= 2)
>                 print line1;
>             if (NR >= 2 &&
>                 line2 ~ "^{[    ]*$" &&
>                 line1 !~ "^struct" &&
>                 line1 !~ "^enum" &&
>                 line1 !~ "^typedef" &&
>                 line1 !~ "^extern[  ][  ]*\"C\"" &&
>                 line1 !~ "=" &&
> =====>          line1 ~ "\)")
>                 print "int  pgindent_func_no_var_fix;";
>             line1 = line2;
>         }
>         END
>
> Is the escaped paren within "" meant to be a literal?

Yes, all parentheses tests in pgindent are meant to test literals. The
'\(' is required so it doesn't think it is defining a regex group.

Here is the output from my tests:

    $ echo '('|awk '$0 ~ /(/ {print $0}'
    awk: cmd. line:1: fatal: Unmatched ( or \(: /(/
    $ echo '('|awk '$0 ~ /\(/ {print $0}'
    (
    $ echo ')'|awk '$0 ~ /)/ {print $0}'
    )
    $ echo ')'|awk '$0 ~ /\)/ {print $0}'
    )

I just tried a machine that has awk 3.1.3 (you have 3.1.4) and I see:

    $ echo '('|awk '$0 ~ /(/ {print $0}'
    awk: cmd. line:1: fatal: Invalid regular expression: /(/
    $ echo '('|awk '$0 ~ /\(/ {print $0}'
    (
    $ echo ')'|awk '$0 ~ /)/ {print $0}'
    )
    $ echo ')'|awk '$0 ~ /\)/ {print $0}'
    )

which exactly matches the 3.0.4 version I usually use.  What are your
outputs for these tests?  Have you tried the current CVS version of
pgindent?  I think it might now work for you.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073