#!perl use strict; use warnings; my $head_loc = `sdl-config --cflags`; $head_loc = ( split ' ', $head_loc )[0]; $head_loc =~ s/-I//; print "# Getting header constants from $head_loc\n"; my @header = <$head_loc/*.h>; my $is_enum = 0; my $is_comment = 0; my $enum_val = -1; my $line = ''; my @names = (); my @values = (); my $maxNameLen = 0; foreach (@header) { #print "\n# from $_:\n"; open( FH, $_ ) || die "Can not open file $_: $!"; while () { $_ =~ s/\/\*.*\*\///g; $_ =~ s/\/\/.*$//g; $_ =~ s/^\s+//; $_ =~ s/\s+$//; #print $_; if ( $_ =~ /\/\*/ ) { $line .= $_; $line =~ s/\/\*.*//; $is_comment = 1; #print(__LINE__); } if ( $is_comment && $_ =~ /\*\// ) { $_ =~ s/.*\*\///; $line .= $_; #print "heureka$line"; $is_comment = 0; #print(__LINE__); next; } next if ( $is_comment && $_ !~ /\*\// ); # if we are inside an enum, and there is an linebreak in value if ( $is_enum && $line !~ /,\s*$/ && $_ !~ /,\s*$/ && $_ !~ /^\s*}\s+(\w+)\s*;\s*$/ && $line !~ /^typedef\s+enum\s*{\s*$/ ) { $line .= $_; #$line =~ s/\s+/ /g; next; } #elsif($is_enum && $line !~ /,\s*$/ && $_ =~ /,\s*$/ && $_ !~ /^\s*}\s+(\w+)\s*;\s*$/ && $line !~ /^typedef\s+enum\s*{\s*$/) elsif ($is_enum && $line !~ /,\s*$/ && $_ =~ /,\s*$/ && $line !~ /^typedef\s+enum\s*{\s*$/ ) { $line .= $_; #print(__LINE__); #make_constant($line); #$line =~ s/\s+/ /g; } elsif ( $is_enum && $line !~ /,\s*$/ && $_ =~ /^\s*}\s+(\w+)\s*;\s*$/ ) { #print(__LINE__); make_constant($line); #print(__LINE__); make_constant($_); $line = $_; #next; } # elsif($is_enum && $_ =~ /,\s*$/) # { # print(__LINE__); make_constant($_); # $line = $_; # } #else { #print(__LINE__); make_constant($line); $line = $_; } #make_constant($line); } close FH; } for ( my $i = 0; $i < $#names; $i++ ) { print("use constant {\n") unless $i; print("};\n\nuse constant {\n") if 'enum' eq $names[$i] && 'open' eq $values[$i]; print("}; # $values[$i]\n\nuse constant {\n") if 'enum' eq $names[$i] && 'open' ne $values[$i]; printf( "\t%-" . $maxNameLen . "s => %s,\n", $names[$i], $values[$i] ) if 'CRAP!' ne $values[$i] && 'enum' ne $names[$i]; print("};\n") if ( $i == $#names - 1 ); } sub make_constant { my $_line = shift; my $name = ''; my $value = ''; # found an enum if ( $_line =~ /^typedef\s+enum\s*{\s*$/ ) { $is_enum = 1; $enum_val = -1; push( @names, 'enum' ); push( @values, 'open' ); } # closed enum if ( $is_enum && $_line =~ /^\s*}\s+(\w+)\s*;\s*$/ ) { $is_enum = 0; push( @names, 'enum' ); push( @values, $1 ); } # inside an enum (without value) if ( $is_enum && $_line =~ /^\s*(\w+)\s*,{0,1}\s*$/ ) { $name = $1; $value = ++$enum_val; } # inside an enum (decimal) if ( $is_enum && $_line =~ /^\s*(\w+)\s*=\s*([+-]{0,1}\d+)\s*,{0,1}\s*$/i ) { $name = $1; $value = $2; $enum_val = $2; } # inside an enum (hex) if ( $is_enum && $_line =~ /^\s*(\w+)\s*=\s*(0x[\dA-F]+)\s*,{0,1}\s*$/i ) { $name = $1; $value = $2; } # inside an enum (function) if ( $is_enum && $_line =~ /^\s*(\w+)\s*=\s*([\w\(\)\|]+)\s*,{0,1}\s*$/i ) { $name = $1; $value = $2; } # pattern: "#define SDL_RELEASED 0" (decimal or hex or name) if ( $_line =~ /^#define\s+([^_]\w+)\s+([+-]{0,1}\d+|0x[\dA-F]+|[\w\(\)\|]+)\s*$/i ) { $name = $1; $value = $2; } if ( $name !~ /^(_.*||[a-z_]+)$/ && $value !~ /^(_.*||[a-z_]+)$/ ) { my $index = index_of( $name, @names ); if ( $index >= 0 && $name ne 'enum' ) { $values[$index] = 'CRAP!' if $value ne $values[$index]; } else { while ( $value =~ /(\w*)/g ) { my $index2 = index_of( $1, @names ); if ( $index2 >= 0 ) { $value =~ s/$1/$values[$index2]/; } } $maxNameLen = length($name) if $maxNameLen < length($name); push( @names, $name ); push( @values, $value ); } } } sub index_of { my $needle = shift; my @array = @_; for ( my $i = 0; $i <= $#array; $i++ ) { return $i if $needle eq $array[$i]; } return -1; }