Обсуждение: backslashes in pgindent
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) != "*")
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
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
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
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