#! /usr/bin/perl # The lisp definitions for flags does not include order. # thus we must extract it ourselves. # Usage: ./enum.pl /gnome/head/cvs/gconf/gconf/*.h > gconf_enums.defs use warnings; my %token; $module="none"; while ($ARGV[0] =~ /^--(\S+)/) { shift @ARGV; $module=shift @ARGV if ($1 eq "module"); if ($1 eq "help") { print "enum.pl [--module modname] header_files ....\n"; exit 0; } } foreach $file (@ARGV) { &parse($file); } exit; # parse enums from C sub parse { my ($file)=@_; $from=0; open(FILE,$file); $enum=0; $deprecated=0; $comment=0; while() { if($comment) { # end of multiline comment $comment = 0 if(/\*\//); next; } $deprecated = 1 if(s/^#ifndef [A-Z_]+_DISABLE_DEPRECATED//); ++$deprecated if($deprecated > 0 && /^#\s*if/); --$deprecated if($deprecated > 0 && /^#\s*endif/); next if($deprecated > 0); # filter single-line comments s/\/\*.*\*\///g; # begin of multiline comment if(/\/\*/) { $comment = 1; next; } s/','/\%\%COMMA\%\%/; s/'}'/\%\%RBRACE\%\%/; if (/^\s*typedef enum/ ) { print ";; From $file\n\n" if (!$from); $from=1; $enum=1; next; } if ($enum && /\}/) { $enum=0; &process($line,$_); $line=""; } $line.=$_ if ($enum); } } # convert enums to lisp sub process { my ($line,$def)=@_; $def=~s/\s*\}\s*//g; $def=~s/\s*;\s*$//; my $c_name=$def; $line=~s/\s+/ /g; $line=~s/\/\*.*\*\///g; $line=~s/\s*{\s*//; my $entity = "enum"; $c_name =~ /^([A-Z][a-z]*)/; $module = $1 if ($module eq "none"); $def =~ s/$module//; @c_name=(); @name=(); @number=(); $val=0; foreach $i (split(/,/,$line)) { $i=~s/^\s+//; $i=~s/\s+$//; if ($i =~ /^\S+$/) { push(@c_name,$i); push(@number,sprintf("%d",$val)); $token{$i}=$val; } elsif ($i =~ /^(\S+)\s*=\s*(0x[0-9a-fA-F]+)$/ || $i =~ /^(\S+)\s*=\s*(-?[0-9]+)$/ || $i =~ /^(\S+)\s*=\s*\(?(1\s*<<\s*[0-9]+)\)?$/ ) { my ($tmp1, $tmp2) = ($1, $2); push(@c_name, $tmp1); eval("\$val = $tmp2;"); $entity = "flags" if($tmp2 =~ /^1\s*<