Re: segfault in glib-mkenums



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]