rockbox/tools/genlang2
Daniel Stenberg 92cf8ca257 seems to generate correct .c and .h files from v2 files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9163 a1c6a512-1295-4272-9138-f99709370657
2006-03-21 12:56:52 +00:00

278 lines
5.8 KiB
Perl
Executable file

#!/usr/bin/perl -s
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $Id$
#
# Copyright (C) 2006 by Daniel Stenberg
#
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 lang ID numbers
my $voiceid=0x8000; # counter for voice-only 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'};
my $idnum;
if($idstr =~ /^VOICE/) {
$idnum = $voiceid++;
}
else {
$idnum = $idcount++;
}
$id{$idstr} = $idnum;
$idnum[$idnum]=$idstr;
$source{$idstr}=$src;
$dest{$idstr}=$dest;
$voice{$idstr}=$voice;
if($verbose) {
print "id: $phrase{id} ($idnum)\n";
print "source: $src\n";
print "dest: $dest\n";
print "voice: $voice\n";
}
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
;
# Output the ID names for the enum in the header file
my $i;
for $i (0x8000 .. ($voiceid-1)) {
my $name=$idnum[$i]; # get the ID name
$name =~ s/\"//g; # cut off the quotes
printf HFILE (" %s,\n", $name);
}
# 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";
#}