nls updates -> nlsinfo to search for nls strings in source code
This commit is contained in:
parent
fff4456dee
commit
8b2f2dd040
1 changed files with 291 additions and 0 deletions
291
nls/nlsinfo
Normal file
291
nls/nlsinfo
Normal file
|
@ -0,0 +1,291 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
# This perl script is intended to go through the fluxbox source
|
||||
# code searching for the special NLS strings. It then dumps
|
||||
# the requested details.
|
||||
#
|
||||
# I started trying to write it fairly generic, but it was difficult :-)
|
||||
# Should be fairly adaptable though
|
||||
#
|
||||
# It doesn't currently handle more than one NLS define per line
|
||||
# => If you get an "undefined" error, its probably 2 on one line
|
||||
|
||||
$VERSION = "0.1";
|
||||
|
||||
use strict;
|
||||
use Getopt::Std;
|
||||
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
|
||||
# the boolitem and focusitem is pretty dodgy, but it'll do for now
|
||||
my $match_re = "(?:_FB(?:TK)?TEXT|_BOOLITEM|_FOCUSITEM)";
|
||||
# regular expression for not a unquoted quote
|
||||
my $noquote = q'(?:[^\"]|\\")';
|
||||
|
||||
my $fielddelim = "\0";
|
||||
my $recorddelim = "\0";
|
||||
|
||||
#############################
|
||||
# Parse and validate arguments
|
||||
my %opts;
|
||||
|
||||
my $command = $0;
|
||||
$command =~ s,^.*/,,;
|
||||
|
||||
my $fullcommand = "$command " . join(" ", @ARGV);
|
||||
|
||||
if (!getopts("d:fhn:pr:vFHN:R", \%opts)) {
|
||||
HELP_MESSAGE("error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
my $arg = shift;
|
||||
my $FD = *STDOUT;
|
||||
if (defined($arg) && $arg eq "error") {
|
||||
$FD = *STDERR;
|
||||
}
|
||||
|
||||
print $FD "Usage: $command [options] directory\n";
|
||||
print $FD " Where options can be:\n";
|
||||
print $FD " -R\tDon't recurse into subdirectories.\n";
|
||||
print $FD " -f\tThe argument is a file, not a directory\n";
|
||||
print $FD " -F\tPrint full NLS names, not shorthand ones\n";
|
||||
print $FD " -d delim\tUse delim as the default delimiter\n";
|
||||
print $FD " -r delim\tUse delim as the record delimiter\n";
|
||||
print $FD " -n\tHeader name, default FLUXBOX_NLS_HH\n";
|
||||
print $FD " -N\tNamespace for header\n";
|
||||
print $FD " -v\tverbose output\n";
|
||||
print $FD " -h\tPrint this help message\n";
|
||||
print $FD "\nPlus one of the following options that direct how to operate:\n";
|
||||
print $FD " -H\tGenerate a header file for the strings encountered (-n implied).\n";
|
||||
print $FD " -p\tPrint out a null-separated tuple of Set,String,Default,Description\n";
|
||||
print $FD " \t\n";
|
||||
print $FD "\n";
|
||||
|
||||
}
|
||||
|
||||
if (defined($opts{"h"})) {
|
||||
HELP_MESSAGE();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
my $num_modes = 0;
|
||||
my $mode;
|
||||
|
||||
sub mode_opt {
|
||||
my $opt = shift;
|
||||
my $modename = shift;
|
||||
return if (!defined($opts{$opt}));
|
||||
$num_modes++;
|
||||
$mode = $modename;
|
||||
}
|
||||
|
||||
mode_opt("H", "header");
|
||||
mode_opt("p", "print");
|
||||
|
||||
if ($num_modes == 0) {
|
||||
print STDERR "Must give one mode of operation!\n";
|
||||
HELP_MESSAGE("error");
|
||||
exit(1);
|
||||
} elsif ($num_modes > 1) {
|
||||
print STDERR "Too many modes of operation - must give exactly one!\n";
|
||||
HELP_MESSAGE("error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $recurse = 1;
|
||||
$recurse = 0 if (defined($opts{"R"}));
|
||||
|
||||
my $fullnames = 0;
|
||||
$fullnames = 1 if (defined($opts{"f"}) || $mode eq "header");
|
||||
|
||||
my $headername = "FLUXBOX_NLS_HH";
|
||||
$headername = $opts{"n"} if (defined($opts{"n"}));
|
||||
|
||||
my $namespace;
|
||||
$namespace = $opts{"N"} if (defined($opts{"N"}));
|
||||
|
||||
my $verbose = 0;
|
||||
$verbose = 1 if (defined($opts{"v"}));
|
||||
|
||||
if (defined($opts{"d"})) {
|
||||
$fielddelim = $opts{"d"};
|
||||
$recorddelim = $opts{"d"};
|
||||
}
|
||||
|
||||
if (defined($opts{"r"})) {
|
||||
$recorddelim = $opts{"r"};
|
||||
}
|
||||
|
||||
|
||||
if (scalar(@ARGV) == 0) {
|
||||
print STDERR "Must give one more argument - the directory to scan\n";
|
||||
exit(1);
|
||||
} elsif (scalar(@ARGV) > 1) {
|
||||
print STDERR "Too many arguments, none expected after directory to scan\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
my $dir = $ARGV[0];
|
||||
my $file;
|
||||
if (!defined($opts{"f"}) && ! -d $dir ) {
|
||||
print STDERR "$dir is not a directory, aborting\n";
|
||||
exit(2);
|
||||
} elsif (defined($opts{"f"})) {
|
||||
$file = $dir;
|
||||
undef $dir;
|
||||
$recurse = 0;
|
||||
|
||||
if (! -r $file) {
|
||||
print STDERR "$file is not a readable file, aborting\n";
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
# Actually do stuff! (finally...)
|
||||
|
||||
my %sets;
|
||||
|
||||
if (defined($dir)) {
|
||||
process_dir($dir);
|
||||
} else {
|
||||
process_file($file);
|
||||
}
|
||||
|
||||
# Now we have the data, we need to print it out
|
||||
eval "mode_$mode()";
|
||||
exit(0);
|
||||
|
||||
# this function is given the fbtext arguments
|
||||
# But the first argument is the macro name...
|
||||
sub store {
|
||||
my ($type, $set, $str, $default, $desc) = @_;
|
||||
|
||||
if ($type eq "_FBTKTEXT") {
|
||||
$set = "FbTk$set";
|
||||
}
|
||||
|
||||
if ($fullnames == 1) {
|
||||
$str = $set . $str;
|
||||
$set = $set . "Set";
|
||||
}
|
||||
|
||||
$sets{$set}->{$str}{"default"} = $default;
|
||||
$sets{$set}->{$str}{"desc"} = $desc;
|
||||
|
||||
}
|
||||
|
||||
# C strings can just be a bunch of quoted strings adjacent to
|
||||
# each other. This just puts them all together, removes the quotes
|
||||
# and unquotes anything we want to.
|
||||
# there may be newlines embedded... compare everything /s
|
||||
sub squish {
|
||||
my $str = shift;
|
||||
|
||||
# remove first and last quote
|
||||
$str =~ s/^\s*\"//s;
|
||||
$str =~ s/\"\s*$//s;
|
||||
|
||||
# now remove any inner quotes and intervening spaces
|
||||
$str =~ s/([^\\])\"\s*\"/$1/sg;
|
||||
|
||||
# finally, unescape any remaining quotes
|
||||
$str =~ s/\\\"/\"/g;
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub process_dir {
|
||||
my $dir = shift;
|
||||
print STDERR "Processing directory '$dir'\n" if ($verbose == 1);
|
||||
opendir(DIR, $dir) || die "can't opendir $dir: $!";
|
||||
my @files = grep { ( /\.(cc|hh)$/ && -f "$dir/$_" ) ||
|
||||
( -d "$dir/$_" && $_ !~ /^\.\.?$/ )
|
||||
} readdir(DIR);
|
||||
closedir DIR;
|
||||
|
||||
foreach my $file (@files) {
|
||||
if (-d "$dir/$file") {
|
||||
process_dir("$dir/$file") if ($recurse == 1);
|
||||
} else {
|
||||
process_file("$dir/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# assumptions for now:
|
||||
# - no more than one NLS thing on any single line
|
||||
# - internal parenthesis are balanced
|
||||
# - one nls thing can span several lines
|
||||
sub process_file {
|
||||
my $file = shift;
|
||||
|
||||
print STDERR "Processing file '$file'\n" if ($verbose == 1);
|
||||
open(FILE, "<$file") || die "Can't open file $file: $!";
|
||||
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
if (/$match_re/ && $_ !~ /^\#(define|undef)/) {
|
||||
my $tail = $_;
|
||||
# strip away leading stuff
|
||||
# note that this doesn't work with more than one match on a line
|
||||
$tail =~ s/^.*($match_re)/$1/;
|
||||
# now we just need to find the end, looking out for any
|
||||
# quotes
|
||||
my $end = 0;
|
||||
my $full = $tail;
|
||||
while ($end == 0) {
|
||||
# match the defined macro, plus the first 4 arguments
|
||||
# (ignore any more), then handle them
|
||||
if ($full =~ /^($match_re)\(([^,]+),\s*([^,]+),((?:\s*\"$noquote*\")+),((?:\s*"$noquote*")+)\s*(?:,.*)?\)/s ) {
|
||||
store($1, $2, $3, squish($4), squish($5));
|
||||
$end++;
|
||||
} else {
|
||||
my $extra = <FILE>;
|
||||
last if (!defined($extra));
|
||||
$full .= $extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(FILE);
|
||||
}
|
||||
|
||||
|
||||
sub mode_print {
|
||||
foreach my $set (sort keys %sets) {
|
||||
foreach my $str (sort keys %{$sets{$set}}) {
|
||||
print $set . $fielddelim . $str . $fielddelim . $sets{$set}->{$str}{"default"} . $fielddelim . $sets{$set}->{$str}{"desc"} . $recorddelim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub mode_header {
|
||||
print "// This file generated by $fullcommand, on " . localtime() . "\n\n";
|
||||
print "#ifndef $headername\n";
|
||||
print "#define $headername\n\n";
|
||||
print "namespace $namespace {\n\n" if (defined($namespace));
|
||||
print "enum {\n";
|
||||
|
||||
my $setnum = 0;
|
||||
foreach my $set (sort keys %sets) {
|
||||
$setnum++;
|
||||
printf "\t%s = 0x%x,\n", $set, $setnum;
|
||||
|
||||
my $strnum = 0;
|
||||
foreach my $str (sort keys %{$sets{$set}}) {
|
||||
$strnum++;
|
||||
printf "\t%s = 0x%x,\n", $str, $strnum;
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
print "\tdummy_not_used = 0 // just for the end\n\n";
|
||||
print "}; // end enum\n\n";
|
||||
print "}; // end namespace $namespace\n\n" if (defined($namespace));
|
||||
print "#endif // $headername\n";
|
||||
}
|
||||
|
Loading…
Reference in a new issue