Re: segfault in glib-mkenums
- From: Owen Taylor <otaylor redhat com>
- To: Max Horn <max quendi de>
- Cc: timj gtk org, Gtk Developers <gtk-devel-list gnome org>
- Subject: Re: segfault in glib-mkenums
- Date: 15 Sep 2001 18:35:50 -0400
Max Horn <max quendi de> writes:
> A work around for the crash in glib-mkenums, that I believe should
> work on other OSes, too, and will even speed up glib-mkenums a bit is
> to change the three occurences of
>
> while (m@/\*([^*]|\*[^/*])*\**$ x) {
> my $new;
> defined ($new = <>) || die "Unmatched comment in $ARGV";
> $_ .= $new;
> }
Hmmm, this got "deimproved" from the original version in
gtk+/gtk/makeenums.pl in GTK+-1.2:
while (m@/\*
([^*]|\*(?!/))*$
@x) {
my $new;
defined ($new = <$file>) || die "Unmatched comment";
$_ .= $new;
}
I believe the difference in efficiency here is that Perl can be
smarter with fixed length repeating expression of the form:
(a|b)*
Than one with a variable length repeating expression of the
form:
(a|bb)*
There are also bugs in the glib-mkenums version:
1) > while (m@/\*([^*]|\*[^/*])*\**$ x) {
^^
Should be \*+ or you won't handle *** strings inside a comment
2) The \** at the end is unecessary in the match-open-comments
part, though it is needed in the match-comments part.
3) $new = <> should be $new = <$file>
>
> while (m@/\*([^*]|\*[^/*])*\**$ x) {
> my $new;
> defined ($new = <>) || die "Unmatched comment in $ARGV";
> next unless ($new =~ m \*/$@);
> $_ .= $new;
> }
>
>
> This will skip intermediate lines in multi-line comments. Unless there
> is a flaw with this that I overlooked, it would be cool if it could be
> added to glib-mkenums in CVS! Thanks.
This doesn't quite work, because we actually need the complete
comment to handle multi-line pseudocomments.
typedef enum {
foo_blah_abcd, /<*
nick=blah_abcd
*>/
foo_blah_efgh
} Foo;
You could write something like:
while (m@/\*([^*]|\*[^/*])*\**$ x) {
my $new;
defined ($new = <>) || die "Unmatched comment in $ARGV";
next unless ($new =~ m \*/$@);
$_ .= $new;
}
if ([$_ ends in an open comment]) {
while (1) {
my $new;
defined ($new = <$file>) || die "Unmatched comment in $ARGV";
$_ .= $new;
break if ([$new closes comment] && ![$new ends in an open comment]);
}
}
But the simpler n^2 algorithm with the makeenums.pl regex's should
work fine for comments up to a few hundred lines anyways.
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]