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 | |
| 56 | --inplace |
| 57 | |
| 58 | Perform file operations in-place, instead of outputting the result to |
| 59 | stdout. With this option set, you can specify multiple langfiles for |
| 60 | all commands. |
| 61 | Example: langtool --deprecate --id LANG_ASK --inplace *.lang |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 62 | MOO |
| 63 | } |
| 64 | |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 65 | sub error { |
| 66 | my ($msg) = @_; |
| 67 | printf("%s\n\nUse --help for usage help.\n", $msg); |
| 68 | exit(1); |
| 69 | } |
| 70 | |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 71 | use Getopt::Long; |
| 72 | use strict; |
| 73 | |
| 74 | # Actions |
| 75 | my $deprecate = ''; |
| 76 | my $changesource = ''; |
| 77 | my $changeid = ''; |
| 78 | my $changetarget = ''; |
| 79 | my $changedesc = ''; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 80 | my $inplace = ''; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 81 | my $help = ''; |
| 82 | # Parameters |
| 83 | my @ids = (); |
| 84 | my $from = ''; |
| 85 | my $to = ''; |
| 86 | my $s_target = ''; |
| 87 | |
| 88 | GetOptions( |
| 89 | 'deprecate' => \$deprecate, |
| 90 | 'changesource' => \$changesource, |
| 91 | 'changeid' => \$changeid, |
| 92 | 'changetarget' => \$changetarget, |
| 93 | 'changedesc' => \$changedesc, |
| 94 | 'help' => \$help, |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 95 | 'inplace' => \$inplace, |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 96 | |
| 97 | 'ids=s' => \@ids, |
| 98 | 'from=s' => \$from, |
| 99 | 'to=s' => \$to, |
| 100 | 'target=s' => \$s_target, |
| 101 | ); |
| 102 | # Allow comma-separated ids as well as several --id switches |
| 103 | @ids = split(/,/,join(',',@ids)); |
| 104 | my $numids = @ids; |
| 105 | my $numfiles = @ARGV; |
| 106 | |
| 107 | # Show help if necessary |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 108 | if ($help) { |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 109 | usage(); |
Jonas Häggqvist | 5fe6ca6 | 2009-06-25 23:26:17 +0000 | [diff] [blame] | 110 | exit(); |
| 111 | } |
| 112 | # More than one option set (or none) |
| 113 | elsif (($deprecate + $changesource + $changeid + $changetarget + $changedesc) != 1) { |
| 114 | error("Exactly one of --deprecate, --changesource, --changeid, --changetarget,\n--changedesc must be used."); |
| 115 | } |
| 116 | # Do changeid, but either from or to is empty |
| 117 | elsif ($changeid and ($from eq "" or $to eq "")) { |
| 118 | error("--changid used, but either --from or --to not set"); |
| 119 | } |
| 120 | # Do changedesc, but to isn't set |
| 121 | elsif ($changedesc and $to eq "") { |
| 122 | error("--changedesc used, but --to not set"); |
| 123 | } |
| 124 | # Do changetarget, but from or to is empty |
| 125 | elsif ($changetarget and ($from eq "" or $to eq "")) { |
| 126 | error("--changetarget used, but --from or --to not set"); |
| 127 | } |
| 128 | # Do deprecate, but no ids set |
| 129 | elsif ($deprecate and $numids < 1) { |
| 130 | error("--deprecate used, but no IDs specified"); |
| 131 | } |
| 132 | # Do changesource, but either target or to not set |
| 133 | elsif ($changesource and ($s_target eq "" or $to eq "")) { |
| 134 | error("--changesource used, but --target or --to not set"); |
| 135 | } |
| 136 | # More than one file passed, but inplace isn't set |
| 137 | elsif ($numfiles > 1 and not $inplace) { |
| 138 | error("More than one file specified - this only works with --inplace"); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 139 | } |
| 140 | |
| 141 | # Check that all supplied files exist before doing anything |
| 142 | foreach my $file (@ARGV) { |
| 143 | if (not -f $file) { |
| 144 | printf("File doesn't exist: %s\n", $file); |
| 145 | exit(2); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | if ($changesource and not $to =~ /none|deprecated/) { |
| 150 | $to = sprintf('"%s"', $to); |
| 151 | } |
| 152 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 153 | foreach my $file (@ARGV) { |
| 154 | print(STDERR "$file\n"); |
| 155 | open(LANGFILE, $file) or die(sprintf("Couldn't open file for reading: %s", $file)); |
| 156 | my $id = ""; |
| 157 | my $desc = ""; |
| 158 | my $location = ""; |
| 159 | my $target = ""; |
| 160 | my $string = ""; |
| 161 | my $open = 0; |
| 162 | my $output = ""; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 163 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 164 | for (<LANGFILE>) { |
| 165 | my $line = $_; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 166 | |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 167 | ### Set up values when a tag starts or ends ### |
| 168 | if ($line =~ /^\s*<(\/?)([^>]+)>\s*$/) { |
| 169 | my $tag = $2; |
| 170 | $open = $1 eq "/" ? 0 : 1; |
| 171 | if ($open) { |
| 172 | $location = $tag; |
| 173 | ($target, $string) = ("", ""); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 174 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 175 | if ($open and $tag eq "phrase") { |
| 176 | $id = ""; |
| 177 | } |
| 178 | if (not $open) { |
| 179 | $location = ""; |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 180 | } |
| 181 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 182 | ### Set up values when a key: value pair is found ### |
| 183 | elsif ($line =~ /^\s*([^:]*?)\s*:\s*(.*?)\s*$/) { |
| 184 | my ($key, $val) = ($1, $2); |
| 185 | if ($location =~ /source|dest|voice/) { |
| 186 | ($target, $string) = ($key, $val); |
| 187 | } |
| 188 | if ($key eq "id") { |
| 189 | $id = $val; |
| 190 | } |
| 191 | elsif ($key eq "desc") { |
| 192 | $desc = $val; |
| 193 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 194 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 195 | |
| 196 | if ($deprecate) { |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 197 | if ($id ne "" and grep(/^$id$/, @ids)) { |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 198 | # Set desc |
| 199 | $line =~ s/\s*desc:.*/ desc: deprecated/; |
| 200 | # Set user |
| 201 | $line =~ s/\s*user:.*/ user:/; |
| 202 | # Print an empty target line after opening tag (target isn't set) |
| 203 | if ($location =~ /source|dest|voice/ and $target eq "") { |
| 204 | $line .= " *: none\n"; |
| 205 | } |
| 206 | # Do not print target: string lines |
| 207 | elsif ($location =~ /source|dest|voice/ and $target ne "") { |
| 208 | $line = ""; |
| 209 | } |
| 210 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 211 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 212 | elsif ($changetarget) { |
| 213 | # Change target if set and it's the same as $from |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 214 | 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] | 215 | $line =~ s/\Q$from/$to/; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 216 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 217 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 218 | elsif ($changesource) { |
| 219 | # Change string if $target is set and matches $s_target |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 220 | 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] | 221 | $line =~ s/\Q$string/$to/; |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 222 | } |
| 223 | } |
| 224 | elsif ($changedesc) { |
| 225 | # Simply change the desc line if the id matches |
Jonas Häggqvist | 74bcdcc | 2009-06-21 00:03:41 +0000 | [diff] [blame] | 226 | if ($id ne "" and grep(/^$id$/, @ids)) { |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 227 | $line =~ s/\s*desc:.*/ desc: $to/; |
| 228 | } |
| 229 | } |
| 230 | elsif ($changeid) { |
| 231 | $line =~ s/^\s*id:\s*$from.*$/ id: $to/; |
| 232 | } |
| 233 | else { |
| 234 | print("This should never happen.\n"); |
| 235 | exit(3); |
| 236 | } |
| 237 | if ($inplace) { |
| 238 | $output .= $line; |
| 239 | } |
| 240 | else { |
| 241 | print($line); |
| 242 | } |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 243 | } |
Jonas Häggqvist | 387dc95 | 2008-12-15 17:12:42 +0000 | [diff] [blame] | 244 | close(LANGFILE); |
| 245 | if ($inplace) { |
| 246 | open(LANGFILE, ">", $file) or die(sprintf("Couldn't open file for writing: %s\n", $file)); |
| 247 | print(LANGFILE $output); |
| 248 | close(LANGFILE); |
Jonas Häggqvist | e4cf631 | 2008-12-15 01:12:22 +0000 | [diff] [blame] | 249 | } |
| 250 | } |