diff options
author | Daniel Stenberg <daniel@haxx.se> | 2005-09-22 11:22:43 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2005-09-22 11:22:43 +0000 |
commit | c0f455993a8a82b2e85b07d6b9fa8c885c029b0f (patch) | |
tree | 3a9f5a34ce780a28d08b8fb69e6eca70c3ec0e07 /tools | |
parent | 747bba530c7f6271bf56f6e8d3f815e668f4c4cf (diff) | |
download | rockbox-c0f455993a8a82b2e85b07d6b9fa8c885c029b0f.tar.gz rockbox-c0f455993a8a82b2e85b07d6b9fa8c885c029b0f.zip |
Initial parser for the langv2 language file format
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7537 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/genlang2 | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tools/genlang2 b/tools/genlang2 new file mode 100755 index 0000000000..6db7d39a45 --- /dev/null +++ b/tools/genlang2 | |||
@@ -0,0 +1,252 @@ | |||
1 | #!/usr/bin/perl -s | ||
2 | |||
3 | if(!$ARGV[0]) { | ||
4 | print <<MOO | ||
5 | Usage: genlang2 [-p=<prefix>][-t=<target>][-v] <language file> | ||
6 | |||
7 | <prefix>.h and <prefix>.c will be created in the current directory. <prefix> | ||
8 | is "lang" by default. | ||
9 | |||
10 | Use -v for verbose (debug) output. | ||
11 | |||
12 | MOO | ||
13 | ; | ||
14 | exit; | ||
15 | } | ||
16 | |||
17 | my $prefix = $p; | ||
18 | if(!$prefix) { | ||
19 | $prefix="lang"; | ||
20 | } | ||
21 | my $target = $t; | ||
22 | if(!$target) { | ||
23 | print "Please specify a target!\n"; | ||
24 | exit; | ||
25 | } | ||
26 | my $verbose=$v; | ||
27 | |||
28 | my %id; # string to num hash | ||
29 | my @idnum; # num to string array | ||
30 | |||
31 | my %source; # id string to source phrase hash | ||
32 | my %dest; # id string to dest phrase hash | ||
33 | my %voice; # id string to voice phrase hash | ||
34 | |||
35 | |||
36 | my $input = $ARGV[0]; | ||
37 | |||
38 | open(HFILE, ">$prefix.h"); | ||
39 | open(CFILE, ">$prefix.c"); | ||
40 | |||
41 | print HFILE <<MOO | ||
42 | /* This file was automatically generated using genlang2 */ | ||
43 | /* | ||
44 | * The str() macro/functions is how to access strings that might be | ||
45 | * translated. Use it like str(MACRO) and expect a string to be | ||
46 | * returned! | ||
47 | */ | ||
48 | #define str(x) language_strings[x] | ||
49 | |||
50 | /* this is the array for holding the string pointers. | ||
51 | It will be initialized at runtime. */ | ||
52 | extern unsigned char *language_strings[]; | ||
53 | /* this contains the concatenation of all strings, separated by \\0 chars */ | ||
54 | extern const unsigned char language_builtin[]; | ||
55 | |||
56 | /* The enum below contains all available strings */ | ||
57 | enum { | ||
58 | MOO | ||
59 | ; | ||
60 | |||
61 | print CFILE <<MOO | ||
62 | /* This file was automaticly generated using genlang2, the strings come | ||
63 | from "$input" */ | ||
64 | |||
65 | #include "$prefix.h" | ||
66 | |||
67 | unsigned char *language_strings[LANG_LAST_INDEX_IN_ARRAY]; | ||
68 | const unsigned char language_builtin[] = | ||
69 | MOO | ||
70 | ; | ||
71 | |||
72 | my @m; | ||
73 | my $m="blank"; | ||
74 | |||
75 | sub match { | ||
76 | my ($string, $pattern)=@_; | ||
77 | |||
78 | $pattern =~ s/\*/.?*/g; | ||
79 | $pattern =~ s/\?/./g; | ||
80 | |||
81 | return ($string =~ $pattern); | ||
82 | } | ||
83 | |||
84 | sub blank { | ||
85 | # nothing to do | ||
86 | } | ||
87 | |||
88 | my %head; | ||
89 | sub header { | ||
90 | my ($full, $n, $v)=@_; | ||
91 | $head{$n}=$v; | ||
92 | } | ||
93 | |||
94 | my %phrase; | ||
95 | sub phrase { | ||
96 | my ($full, $n, $v)=@_; | ||
97 | $phrase{$n}=$v; | ||
98 | } | ||
99 | |||
100 | sub parsetarget { | ||
101 | my ($debug, $strref, $full, $n, $v)=@_; | ||
102 | my $string; | ||
103 | my @all= split(" *, *", $n); | ||
104 | my $test; | ||
105 | for $test (@all) { | ||
106 | # print "TEST ($debug) $target for $test\n"; | ||
107 | if(match($target, $test)) { | ||
108 | $string = $v; | ||
109 | # print "MATCH: $test => $v\n"; | ||
110 | } | ||
111 | } | ||
112 | if($string) { | ||
113 | $$strref = $string; | ||
114 | } | ||
115 | return $string; | ||
116 | } | ||
117 | |||
118 | my $src; | ||
119 | sub source { | ||
120 | parsetarget("src", \$src, @_); | ||
121 | } | ||
122 | |||
123 | my $dest; | ||
124 | sub dest { | ||
125 | parsetarget("dest", \$dest, @_); | ||
126 | } | ||
127 | |||
128 | my $voice; | ||
129 | sub voice { | ||
130 | parsetarget("voice", \$voice, @_); | ||
131 | } | ||
132 | |||
133 | my $idcount; # counter for ID numbers | ||
134 | |||
135 | open(LANG, "<$input"); | ||
136 | while(<LANG>) { | ||
137 | $line++; | ||
138 | if($_ =~ / *\#/) { | ||
139 | # comment | ||
140 | next; | ||
141 | } | ||
142 | # get rid of DOS newlines | ||
143 | $_ =~ s/\r//g; | ||
144 | |||
145 | # print "M: $m\n"; | ||
146 | |||
147 | if(/ *<([^>]*)>/) { | ||
148 | my $part = $1; | ||
149 | #print "P: $part\n"; | ||
150 | if($part =~ /^\//) { | ||
151 | if($part eq "/phrase") { | ||
152 | my $idstr = $phrase{'id'}; | ||
153 | |||
154 | $id{$idstr} = $idcount; | ||
155 | $idnum[$idcount]=$idstr; | ||
156 | |||
157 | $source{$idstr}=$src; | ||
158 | $dest{$idstr}=$dest; | ||
159 | $voice{$idstr}=$voice; | ||
160 | |||
161 | if($verbose) { | ||
162 | print "id: $phrase{id}\n"; | ||
163 | print "source: $src\n"; | ||
164 | print "dest: $dest\n"; | ||
165 | print "voice: $voice\n"; | ||
166 | } | ||
167 | |||
168 | $idcount++; | ||
169 | |||
170 | undef $src; | ||
171 | undef $dest; | ||
172 | undef $voice; | ||
173 | undef %phrase; | ||
174 | } | ||
175 | # starts with a slash, this _ends_ this section | ||
176 | $m = pop @m; # get back old value | ||
177 | next; | ||
178 | } | ||
179 | push @m, $m; # store old value | ||
180 | $m = $1; | ||
181 | next; | ||
182 | } | ||
183 | |||
184 | if(/^ *([^:]+): *(.*)/) { | ||
185 | my ($name, $val)=($1, $2); | ||
186 | &$m($_, $name, $val); | ||
187 | } | ||
188 | |||
189 | } | ||
190 | close(LANG); | ||
191 | |||
192 | # Output the ID names for the enum in the header file | ||
193 | my $i; | ||
194 | for $i (1 .. $idcount) { | ||
195 | my $name=$idnum[$i - 1]; # get the ID name | ||
196 | |||
197 | $name =~ s/\"//g; # cut off the quotes | ||
198 | |||
199 | printf HFILE (" %s,\n", $name); | ||
200 | } | ||
201 | |||
202 | # Output separation marker for last string ID and the upcoming voice IDs | ||
203 | |||
204 | print HFILE <<MOO | ||
205 | LANG_LAST_INDEX_IN_ARRAY, /* this is not a string, this is a marker */ | ||
206 | /* --- below this follows voice-only strings --- */ | ||
207 | VOICEONLY_DELIMITER = 0x8000, | ||
208 | MOO | ||
209 | ; | ||
210 | |||
211 | # TODO: add voice-only phrase IDs here | ||
212 | |||
213 | # Output end of enum | ||
214 | print HFILE <<MOO | ||
215 | }; | ||
216 | /* end of generated enum list */ | ||
217 | MOO | ||
218 | ; | ||
219 | |||
220 | # Output the target phrases for the source file | ||
221 | for $i (1 .. $idcount) { | ||
222 | my $name=$idnum[$i - 1]; # get the ID | ||
223 | my $dest = $dest{$name}; # get the destination phrase | ||
224 | |||
225 | $dest =~ s:\"$:\\0\":; # insert a \0 before the second quote | ||
226 | |||
227 | printf CFILE (" %s\n", $dest); | ||
228 | } | ||
229 | |||
230 | # Output end of string chunk | ||
231 | print CFILE <<MOO | ||
232 | ; | ||
233 | /* end of generated string list */ | ||
234 | MOO | ||
235 | ; | ||
236 | |||
237 | close(HFILE); | ||
238 | close(CFILE); | ||
239 | |||
240 | if($verbose) { | ||
241 | printf("%d ID strings scanned\n", $idcount); | ||
242 | |||
243 | print "* head *\n"; | ||
244 | for(keys %head) { | ||
245 | printf "$_: %s\n", $head{$_}; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | #print "* phrase *\n"; | ||
250 | #for(keys %phrase) { | ||
251 | # print "$_\n"; | ||
252 | #} | ||