Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 1 | #!/usr/bin/perl |
| 2 | # __________ __ ___. |
| 3 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | # \/ \/ \/ \/ \/ |
| 8 | # $Id$ |
| 9 | # |
| 10 | # This program is free software; you can redistribute it and/or |
| 11 | # modify it under the terms of the GNU General Public License |
| 12 | # as published by the Free Software Foundation; either version 2 |
| 13 | # of the License, or (at your option) any later version. |
| 14 | # |
| 15 | # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 16 | # KIND, either express or implied. |
| 17 | |
| 18 | sub usage { |
| 19 | print <<MOO |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 20 | Usage langtool [--inplace] --options langfile1 [langfile2 ...] |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 21 | |
| 22 | For all actions, the modified langfile will be output on stdout. When doing |
| 23 | stuff to english.lang, you should almost always apply the same change to all |
| 24 | other languages to avoid bothering translators. |
| 25 | |
| 26 | --deprecate --id ID_1,ID_2 --id ID_3 langfile |
| 27 | |
| 28 | Deprecate a number of ids. |
| 29 | Example: langtool --id LANG_LEFT,LANG_RIGHT --LANG_BOTTOM english.lang |
| 30 | |
| 31 | --changesource --id ID --target target --to string langfile |
| 32 | |
| 33 | Change the source text of a specific string specified by id and target. Use |
| 34 | this on all langfiles if you're changing a source in english.lang that |
| 35 | doesn't need attention from translators (case changes etc.). |
| 36 | Example: |
| 37 | langtool --changesource --id LANG_OK --target e200 --to "OK" english.lang |
| 38 | |
| 39 | --changeid --from LANG_LFET --to LANG_LEFT langfile |
| 40 | |
| 41 | Change the name of an ID. THIS WILL BREAK BACKWARDS COMPATIBILITY. Use with |
| 42 | extreme caution. |
| 43 | Example: langtool --changeid --from LANG_OK --to LANG_YES english.lang |
| 44 | |
| 45 | --changedesc --to string --id LANG_LEFT langfile |
| 46 | |
| 47 | Change the desc for an ID. |
| 48 | Example: langtool --changedesc --to "New desc" --id LANG_OK english.lang |
| 49 | |
| 50 | --changetarget --from target --to target --id ID1 langfile |
| 51 | |
| 52 | Change the target for the specified id from one value to another |
| 53 | Example: |
| 54 | langtool --changetarget --from e200 --to e200,c200 --id LANG_ON dansk.lang |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 55 | |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 56 | --delete --id ID_1,ID_2 --id ID_3 langfile |
| 57 | |
| 58 | Delete a number of ids. THIS WILL BREAK BACKWARDS COMPATIBILITY. Use with |
| 59 | extreme caution. |
| 60 | Example: langtool --delete --id LANG_LEFT,LANG_RIGHT english.lang |
| 61 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 62 | --inplace |
| 63 | |
| 64 | Perform file operations in-place, instead of outputting the result to |
| 65 | stdout. With this option set, you can specify multiple langfiles for |
| 66 | all commands. |
| 67 | Example: langtool --deprecate --id LANG_ASK --inplace *.lang |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 68 | MOO |
| 69 | } |
| 70 | |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 71 | sub error { |
| 72 | my ($msg) = @_; |
| 73 | printf("%s\n\nUse --help for usage help.\n", $msg); |
| 74 | exit(1); |
| 75 | } |
| 76 | |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 77 | use Getopt::Long; |
| 78 | use strict; |
| 79 | |
| 80 | # Actions |
| 81 | my $deprecate = ''; |
| 82 | my $changesource = ''; |
| 83 | my $changeid = ''; |
| 84 | my $changetarget = ''; |
| 85 | my $changedesc = ''; |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 86 | my $delete = ''; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 87 | my $inplace = ''; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 88 | my $help = ''; |
| 89 | # Parameters |
| 90 | my @ids = (); |
| 91 | my $from = ''; |
| 92 | my $to = ''; |
| 93 | my $s_target = ''; |
| 94 | |
| 95 | GetOptions( |
| 96 | 'deprecate' => \$deprecate, |
| 97 | 'changesource' => \$changesource, |
| 98 | 'changeid' => \$changeid, |
| 99 | 'changetarget' => \$changetarget, |
| 100 | 'changedesc' => \$changedesc, |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 101 | 'delete' => \$delete, |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 102 | 'help' => \$help, |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 103 | 'inplace' => \$inplace, |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 104 | |
| 105 | 'ids=s' => \@ids, |
| 106 | 'from=s' => \$from, |
| 107 | 'to=s' => \$to, |
| 108 | 'target=s' => \$s_target, |
| 109 | ); |
| 110 | # Allow comma-separated ids as well as several --id switches |
| 111 | @ids = split(/,/,join(',',@ids)); |
| 112 | my $numids = @ids; |
| 113 | my $numfiles = @ARGV; |
| 114 | |
| 115 | # Show help if necessary |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 116 | if ($help) { |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 117 | usage(); |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 118 | exit(); |
| 119 | } |
| 120 | # More than one option set (or none) |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 121 | elsif (($deprecate + $changesource + $changeid + $changetarget + $changedesc +$delete) != 1) { |
| 122 | error("Exactly one of --deprecate, --changesource, --changeid, --changetarget,\n--changedesc, --delete must be used."); |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 123 | } |
| 124 | # Do changeid, but either from or to is empty |
| 125 | elsif ($changeid and ($from eq "" or $to eq "")) { |
| 126 | error("--changid used, but either --from or --to not set"); |
| 127 | } |
| 128 | # Do changedesc, but to isn't set |
| 129 | elsif ($changedesc and $to eq "") { |
| 130 | error("--changedesc used, but --to not set"); |
| 131 | } |
| 132 | # Do changetarget, but from or to is empty |
| 133 | elsif ($changetarget and ($from eq "" or $to eq "")) { |
| 134 | error("--changetarget used, but --from or --to not set"); |
| 135 | } |
| 136 | # Do deprecate, but no ids set |
| 137 | elsif ($deprecate and $numids < 1) { |
| 138 | error("--deprecate used, but no IDs specified"); |
| 139 | } |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 140 | # Do delete, but no ids set |
| 141 | elsif ($delete and $numids < 1) { |
| 142 | error("--delete used, but no IDs specified"); |
| 143 | } |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 144 | # Do changesource, but either target or to not set |
| 145 | elsif ($changesource and ($s_target eq "" or $to eq "")) { |
| 146 | error("--changesource used, but --target or --to not set"); |
| 147 | } |
| 148 | # More than one file passed, but inplace isn't set |
| 149 | elsif ($numfiles > 1 and not $inplace) { |
| 150 | error("More than one file specified - this only works with --inplace"); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | # Check that all supplied files exist before doing anything |
| 154 | foreach my $file (@ARGV) { |
| 155 | if (not -f $file) { |
| 156 | printf("File doesn't exist: %s\n", $file); |
| 157 | exit(2); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | if ($changesource and not $to =~ /none|deprecated/) { |
| 162 | $to = sprintf('"%s"', $to); |
| 163 | } |
| 164 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 165 | foreach my $file (@ARGV) { |
| 166 | print(STDERR "$file\n"); |
| 167 | open(LANGFILE, $file) or die(sprintf("Couldn't open file for reading: %s", $file)); |
| 168 | my $id = ""; |
| 169 | my $desc = ""; |
| 170 | my $location = ""; |
| 171 | my $target = ""; |
| 172 | my $string = ""; |
| 173 | my $open = 0; |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 174 | my @output; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 175 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 176 | for (<LANGFILE>) { |
| 177 | my $line = $_; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 178 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 179 | ### Set up values when a tag starts or ends ### |
| 180 | if ($line =~ /^\s*<(\/?)([^>]+)>\s*$/) { |
| 181 | my $tag = $2; |
| 182 | $open = $1 eq "/" ? 0 : 1; |
| 183 | if ($open) { |
| 184 | $location = $tag; |
| 185 | ($target, $string) = ("", ""); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 186 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 187 | if ($open and $tag eq "phrase") { |
| 188 | $id = ""; |
| 189 | } |
| 190 | if (not $open) { |
| 191 | $location = ""; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 192 | } |
| 193 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 194 | ### Set up values when a key: value pair is found ### |
| 195 | elsif ($line =~ /^\s*([^:]*?)\s*:\s*(.*?)\s*$/) { |
| 196 | my ($key, $val) = ($1, $2); |
| 197 | if ($location =~ /source|dest|voice/) { |
| 198 | ($target, $string) = ($key, $val); |
| 199 | } |
| 200 | if ($key eq "id") { |
| 201 | $id = $val; |
| 202 | } |
| 203 | elsif ($key eq "desc") { |
| 204 | $desc = $val; |
| 205 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 206 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 207 | |
| 208 | if ($deprecate) { |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 209 | if ($id ne "" and grep(/^$id$/, @ids)) { |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 210 | # Set desc |
| 211 | $line =~ s/\s*desc:.*/ desc: deprecated/; |
Nils Wallménius | 3799020 | 2011-04-07 07:50:29 +0000 | [diff] [blame] | 212 | # Leave user field alone |
| 213 | if ($location =~ /source|dest|voice/) { |
| 214 | $line =~ s/".*"/""/; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 215 | } |
| 216 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 217 | } |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 218 | elsif ($delete) { |
| 219 | if ($id ne "" and grep(/^$id$/, @ids)) { |
| 220 | if ($location eq "phrase" and $line =~ /id:/) { |
| 221 | # Kluge to nuke the <phrase> line |
| 222 | pop(@output); |
| 223 | } |
| 224 | # Set the whole phrase to empty string. |
| 225 | $line = ""; |
| 226 | } |
| 227 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 228 | elsif ($changetarget) { |
| 229 | # Change target if set and it's the same as $from |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 230 | if ($id ne "" and grep(/^$id$/, @ids) and $location =~ /source|dest|voice/ and $target eq $from) { |
Jonas Häggqvist | 03e90f8 | 2009-01-25 15:32:03 +0000 | [diff] [blame] | 231 | $line =~ s/\Q$from/$to/; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 232 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 233 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 234 | elsif ($changesource) { |
| 235 | # Change string if $target is set and matches $s_target |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 236 | if ($id ne "" and grep(/^$id$/, @ids) and $target eq $s_target and $location eq "source") { |
Jonas Häggqvist | 03e90f8 | 2009-01-25 15:32:03 +0000 | [diff] [blame] | 237 | $line =~ s/\Q$string/$to/; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 238 | } |
| 239 | } |
| 240 | elsif ($changedesc) { |
| 241 | # Simply change the desc line if the id matches |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 242 | if ($id ne "" and grep(/^$id$/, @ids)) { |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 243 | $line =~ s/\s*desc:.*/ desc: $to/; |
| 244 | } |
| 245 | } |
| 246 | elsif ($changeid) { |
| 247 | $line =~ s/^\s*id:\s*$from.*$/ id: $to/; |
| 248 | } |
| 249 | else { |
| 250 | print("This should never happen.\n"); |
| 251 | exit(3); |
| 252 | } |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 253 | |
| 254 | push(@output, $line); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 255 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 256 | close(LANGFILE); |
| 257 | if ($inplace) { |
| 258 | open(LANGFILE, ">", $file) or die(sprintf("Couldn't open file for writing: %s\n", $file)); |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 259 | print(LANGFILE @output); |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 260 | close(LANGFILE); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 261 | } |
Nils Wallménius | b91fa04 | 2010-06-04 20:40:49 +0000 | [diff] [blame] | 262 | else { |
| 263 | print(@output); |
| 264 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 265 | } |