| #!/usr/bin/perl -s |
| |
| if(!$ARGV[0]) { |
| print <<MOO |
| Usage: genlang2 [-p=<prefix>][-t=<target>][-v] <language file> |
| |
| <prefix>.h and <prefix>.c will be created in the current directory. <prefix> |
| is "lang" by default. |
| |
| Use -v for verbose (debug) output. |
| |
| MOO |
| ; |
| exit; |
| } |
| |
| my $prefix = $p; |
| if(!$prefix) { |
| $prefix="lang"; |
| } |
| my $target = $t; |
| if(!$target) { |
| print "Please specify a target!\n"; |
| exit; |
| } |
| my $verbose=$v; |
| |
| my %id; # string to num hash |
| my @idnum; # num to string array |
| |
| my %source; # id string to source phrase hash |
| my %dest; # id string to dest phrase hash |
| my %voice; # id string to voice phrase hash |
| |
| |
| my $input = $ARGV[0]; |
| |
| open(HFILE, ">$prefix.h"); |
| open(CFILE, ">$prefix.c"); |
| |
| print HFILE <<MOO |
| /* This file was automatically generated using genlang2 */ |
| /* |
| * The str() macro/functions is how to access strings that might be |
| * translated. Use it like str(MACRO) and expect a string to be |
| * returned! |
| */ |
| #define str(x) language_strings[x] |
| |
| /* this is the array for holding the string pointers. |
| It will be initialized at runtime. */ |
| extern unsigned char *language_strings[]; |
| /* this contains the concatenation of all strings, separated by \\0 chars */ |
| extern const unsigned char language_builtin[]; |
| |
| /* The enum below contains all available strings */ |
| enum { |
| MOO |
| ; |
| |
| print CFILE <<MOO |
| /* This file was automaticly generated using genlang2, the strings come |
| from "$input" */ |
| |
| #include "$prefix.h" |
| |
| unsigned char *language_strings[LANG_LAST_INDEX_IN_ARRAY]; |
| const unsigned char language_builtin[] = |
| MOO |
| ; |
| |
| my @m; |
| my $m="blank"; |
| |
| sub match { |
| my ($string, $pattern)=@_; |
| |
| $pattern =~ s/\*/.?*/g; |
| $pattern =~ s/\?/./g; |
| |
| return ($string =~ $pattern); |
| } |
| |
| sub blank { |
| # nothing to do |
| } |
| |
| my %head; |
| sub header { |
| my ($full, $n, $v)=@_; |
| $head{$n}=$v; |
| } |
| |
| my %phrase; |
| sub phrase { |
| my ($full, $n, $v)=@_; |
| $phrase{$n}=$v; |
| } |
| |
| sub parsetarget { |
| my ($debug, $strref, $full, $n, $v)=@_; |
| my $string; |
| my @all= split(" *, *", $n); |
| my $test; |
| for $test (@all) { |
| # print "TEST ($debug) $target for $test\n"; |
| if(match($target, $test)) { |
| $string = $v; |
| # print "MATCH: $test => $v\n"; |
| } |
| } |
| if($string) { |
| $$strref = $string; |
| } |
| return $string; |
| } |
| |
| my $src; |
| sub source { |
| parsetarget("src", \$src, @_); |
| } |
| |
| my $dest; |
| sub dest { |
| parsetarget("dest", \$dest, @_); |
| } |
| |
| my $voice; |
| sub voice { |
| parsetarget("voice", \$voice, @_); |
| } |
| |
| my $idcount; # counter for ID numbers |
| |
| open(LANG, "<$input"); |
| while(<LANG>) { |
| $line++; |
| if($_ =~ / *\#/) { |
| # comment |
| next; |
| } |
| # get rid of DOS newlines |
| $_ =~ s/\r//g; |
| |
| # print "M: $m\n"; |
| |
| if(/ *<([^>]*)>/) { |
| my $part = $1; |
| #print "P: $part\n"; |
| if($part =~ /^\//) { |
| if($part eq "/phrase") { |
| my $idstr = $phrase{'id'}; |
| |
| $id{$idstr} = $idcount; |
| $idnum[$idcount]=$idstr; |
| |
| $source{$idstr}=$src; |
| $dest{$idstr}=$dest; |
| $voice{$idstr}=$voice; |
| |
| if($verbose) { |
| print "id: $phrase{id}\n"; |
| print "source: $src\n"; |
| print "dest: $dest\n"; |
| print "voice: $voice\n"; |
| } |
| |
| $idcount++; |
| |
| undef $src; |
| undef $dest; |
| undef $voice; |
| undef %phrase; |
| } |
| # starts with a slash, this _ends_ this section |
| $m = pop @m; # get back old value |
| next; |
| } |
| push @m, $m; # store old value |
| $m = $1; |
| next; |
| } |
| |
| if(/^ *([^:]+): *(.*)/) { |
| my ($name, $val)=($1, $2); |
| &$m($_, $name, $val); |
| } |
| |
| } |
| close(LANG); |
| |
| # Output the ID names for the enum in the header file |
| my $i; |
| for $i (1 .. $idcount) { |
| my $name=$idnum[$i - 1]; # get the ID name |
| |
| $name =~ s/\"//g; # cut off the quotes |
| |
| printf HFILE (" %s,\n", $name); |
| } |
| |
| # Output separation marker for last string ID and the upcoming voice IDs |
| |
| print HFILE <<MOO |
| LANG_LAST_INDEX_IN_ARRAY, /* this is not a string, this is a marker */ |
| /* --- below this follows voice-only strings --- */ |
| VOICEONLY_DELIMITER = 0x8000, |
| MOO |
| ; |
| |
| # TODO: add voice-only phrase IDs here |
| |
| # Output end of enum |
| print HFILE <<MOO |
| }; |
| /* end of generated enum list */ |
| MOO |
| ; |
| |
| # Output the target phrases for the source file |
| for $i (1 .. $idcount) { |
| my $name=$idnum[$i - 1]; # get the ID |
| my $dest = $dest{$name}; # get the destination phrase |
| |
| $dest =~ s:\"$:\\0\":; # insert a \0 before the second quote |
| |
| printf CFILE (" %s\n", $dest); |
| } |
| |
| # Output end of string chunk |
| print CFILE <<MOO |
| ; |
| /* end of generated string list */ |
| MOO |
| ; |
| |
| close(HFILE); |
| close(CFILE); |
| |
| if($verbose) { |
| printf("%d ID strings scanned\n", $idcount); |
| |
| print "* head *\n"; |
| for(keys %head) { |
| printf "$_: %s\n", $head{$_}; |
| } |
| } |
| |
| #print "* phrase *\n"; |
| #for(keys %phrase) { |
| # print "$_\n"; |
| #} |