1 #!/usr/local/bin/perl -wC
9 use Digest::SHA qw(sha1_hex);
10 require "charmaps.pm";
14 print "Usage: $0 --cldr=<cldrdir> --unidata=<unidatadir> --etc=<etcdir> --type=<type> [--lc=<la_CC>]\n";
18 my $DEFENCODING = "UTF-8";
22 my $UNIDATADIR = undef;
27 my $result = GetOptions (
28 "cldr=s" => \$CLDRDIR,
29 "unidata=s" => \$UNIDATADIR,
41 my %translations = ();
43 my %alternativemonths = ();
48 get_unidata($UNIDATADIR);
49 get_utf8map("$CLDRDIR/posix/$DEFENCODING.cm");
50 get_encodings("$ETCDIR/charmaps");
53 tie(%keys, "Tie::IxHash");
54 tie(%hashtable, "Tie::IxHash");
57 "monetdef" => "LC_MONETARY",
58 "timedef" => "LC_TIME",
59 "msgdef" => "LC_MESSAGES",
60 "numericdef" => "LC_NUMERIC",
61 "colldef" => "LC_COLLATE",
62 "ctypedef" => "LC_CTYPE"
66 mdorder => \&callback_mdorder,
67 altmon => \&callback_altmon,
68 cformat => \&callback_cformat,
69 cbabmon => \&callback_abmon,
76 "decimal_point" => "decimal_point",
77 "thousands_sep" => "thousands_sep",
78 "grouping" => "grouping",
81 "int_curr_symbol" => "int_curr_symbol (last character always " .
83 "currency_symbol" => "currency_symbol",
84 "mon_decimal_point" => "mon_decimal_point",
85 "mon_thousands_sep" => "mon_thousands_sep",
86 "mon_grouping" => "mon_grouping",
87 "positive_sign" => "positive_sign",
88 "negative_sign" => "negative_sign",
89 "int_frac_digits" => "int_frac_digits",
90 "frac_digits" => "frac_digits",
91 "p_cs_precedes" => "p_cs_precedes",
92 "p_sep_by_space" => "p_sep_by_space",
93 "n_cs_precedes" => "n_cs_precedes",
94 "n_sep_by_space" => "n_sep_by_space",
95 "p_sign_posn" => "p_sign_posn",
96 "n_sign_posn" => "n_sign_posn",
99 "yesexpr" => "yesexpr",
100 "noexpr" => "noexpr",
101 "yesstr" => "yesstr",
105 "abmon" => "Short month names",
106 "mon" => "Long month names (as in a date)",
107 "abday" => "Short weekday names",
108 "day" => "Long weekday names",
113 "d_t_fmt" => "date_fmt",
114 "altmon" => "Long month names (without case ending)",
115 "md_order" => "md_order",
116 "t_fmt_ampm" => "ampm_fmt",
119 if ($TYPE eq "colldef") {
120 transform_collation();
124 if ($TYPE eq "ctypedef") {
129 if ($TYPE eq "numericdef") {
131 "decimal_point" => "s",
132 "thousands_sep" => "s",
140 if ($TYPE eq "monetdef") {
142 "int_curr_symbol" => "s",
143 "currency_symbol" => "s",
144 "mon_decimal_point" => "s",
145 "mon_thousands_sep" => "s",
146 "mon_grouping" => "ai",
147 "positive_sign" => "s",
148 "negative_sign" => "s",
149 "int_frac_digits" => "i",
150 "frac_digits" => "i",
151 "p_cs_precedes" => "i",
152 "p_sep_by_space" => "i",
153 "n_cs_precedes" => "i",
154 "n_sep_by_space" => "i",
155 "p_sign_posn" => "i",
163 if ($TYPE eq "msgdef") {
175 if ($TYPE eq "timedef") {
177 "abmon" => "<cbabmon<abmon<as",
183 "c_fmt" => "<cformat<d_t_fmt<s",
187 "altmon" => "<altmon<mon<as",
188 "md_order" => "<mdorder<d_fmt<s",
196 sub callback_cformat {
203 sub callback_mdorder {
205 return undef if (!defined $s);
210 sub callback_altmon {
211 # if the language/country is known in %alternative months then
212 # return that, otherwise repeat mon
215 if (defined $alternativemonths{$callback{data}{l}}{$callback{data}{c}}) {
216 my @altnames = split(";",$alternativemonths{$callback{data}{l}}{$callback{data}{c}});
224 return join(";",@cleaned);
231 # for specified CJK locales, pad result with a space to enable
232 # columns to line up (style established in FreeBSD in 2001)
234 my $nl = $callback{data}{l} . "_" . $callback{data}{c};
236 if ($nl eq 'ja_JP' || $nl eq 'ko_KR' || $nl eq 'zh_CN' ||
237 $nl eq 'zh_HK' || $nl eq 'zh_TW') {
238 my @monthnames = split(";", $s);
240 foreach (@monthnames)
242 if ($_ =~ /^"<(two|three|four|five|six|seven|eight|nine)>/ ||
243 ($_ =~ /^"<one>/ && $_ !~ /^"<one>(<zero>|<one>|<two>)/))
245 $_ =~ s/^"/"<space>/;
249 return join(";",@cleaned);
254 ############################
257 my $directory = shift;
259 open(FIN, "$directory/UnicodeData.txt")
260 or die("Cannot open $directory/UnicodeData.txt");;
265 foreach my $l (@lines) {
266 my @a = split(/;/, $l);
268 $ucd{code2name}{"$a[0]"} = $a[1]; # Unicode name
269 $ucd{name2code}{"$a[1]"} = $a[0]; # Unicode code
284 foreach my $l (@lines) {
286 next if ($l =~ /^\#/);
289 if ($l eq "CHARMAP") {
294 next if (!$incharmap);
295 last if ($l eq "END CHARMAP");
297 $l =~ /^<([^\s]+)>\s+(.*)/;
300 $k =~ s/_/ /g; # unicode char string
301 $v =~ s/\\x//g; # UTF-8 char code
304 $utf8aliases{$k} = $prev_k if ($prev_v eq $v);
313 foreach my $e (sort(keys(%encodings))) {
314 if (!open(FIN, "$dir/$e.TXT")) {
315 print "Cannot open charmap for $e\n";
323 foreach my $l (@lines) {
325 next if ($l =~ /^\#/);
328 my @a = split(" ", $l);
330 $a[0] =~ s/^0[xX]//; # local char code
331 $a[1] =~ s/^0[xX]//; # unicode char code
332 $convertors{$e}{uc($a[1])} = uc($a[0]);
338 my %data = get_xmldata($ETCDIR);
339 %languages = %{$data{L}};
340 %translations = %{$data{T}};
341 %alternativemonths = %{$data{AM}};
342 %encodings = %{$data{E}};
344 return if (!defined $doonly);
346 my @a = split(/_/, $doonly);
357 print Dumper(@filter);
361 sub transform_ctypes {
362 foreach my $l (sort keys(%languages)) {
363 foreach my $f (sort keys(%{$languages{$l}})) {
364 foreach my $c (sort keys(%{$languages{$l}{$f}{data}})) {
365 next if ($#filter == 2 && ($filter[0] ne $l
366 || $filter[1] ne $f || $filter[2] ne $c));
367 next if (defined $languages{$l}{$f}{definitions}
368 && $languages{$l}{$f}{definitions} !~ /$TYPE/);
369 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 0; # unread
372 $file .= $f . "_" if ($f ne "x");
376 my $filename = "$CLDRDIR/posix/xx_Comm_US.UTF-8.src";
377 if (! -f $filename) {
378 print STDERR "Cannot open $filename\n";
381 open(FIN, "$filename");
382 print "Reading from $filename for ${l}_${f}_${c}\n";
383 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 1; # read
391 $shex = sha1_hex(join("\n", @lines));
392 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = $shex;
393 $hashtable{$shex}{"${l}_${f}_${c}.$DEFENCODING"} = 1;
394 open(FOUT, ">$TYPE.draft/$actfile.$DEFENCODING.src");
397 foreach my $enc (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
398 next if ($enc eq $DEFENCODING);
399 $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src";
400 if (! -f $filename) {
401 print STDERR "Cannot open $filename\n";
405 open(FIN, "$filename");
407 if ((/^comment_char\s/) || (/^escape_char\s/)){
410 if (/^LC_CTYPE/../^END LC_CTYPE/) {
415 $uhex = sha1_hex(join("\n", @lines) . $enc);
416 $languages{$l}{$f}{data}{$c}{$enc} = $uhex;
417 $hashtable{$uhex}{"${l}_${f}_${c}.$enc"} = 1;
418 open(FOUT, ">$TYPE.draft/$actfile.$enc.src");
420 # Warning: Do not edit. This file is automatically extracted from the
421 # tools in /usr/src/tools/tools/locale. The data is obtained from the
422 # CLDR project, obtained from http://cldr.unicode.org/
423 # -----------------------------------------------------------------------------
434 sub transform_collation {
435 foreach my $l (sort keys(%languages)) {
436 foreach my $f (sort keys(%{$languages{$l}})) {
437 foreach my $c (sort keys(%{$languages{$l}{$f}{data}})) {
438 next if ($#filter == 2 && ($filter[0] ne $l
439 || $filter[1] ne $f || $filter[2] ne $c));
440 next if (defined $languages{$l}{$f}{definitions}
441 && $languages{$l}{$f}{definitions} !~ /$TYPE/);
442 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 0; # unread
445 $file .= $f . "_" if ($f ne "x");
449 my $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src";
450 $filename = "$ETCDIR/$file.$DEFENCODING.src"
453 && defined $languages{$l}{$f}{fallback}) {
454 $file = $languages{$l}{$f}{fallback};
455 $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src";
457 $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src"
459 if (! -f $filename) {
461 "Cannot open $file.$DEFENCODING.src or fallback\n";
464 open(FIN, "$filename");
465 print "Reading from $filename for ${l}_${f}_${c}\n";
466 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 1; # read
470 if ((/^comment_char\s/) || (/^escape_char\s/)){
473 if (/^LC_COLLATE/../^END LC_COLLATE/) {
479 $shex = sha1_hex(join("\n", @lines));
480 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = $shex;
481 $hashtable{$shex}{"${l}_${f}_${c}.$DEFENCODING"} = 1;
482 open(FOUT, ">$TYPE.draft/$actfile.$DEFENCODING.src");
484 # Warning: Do not edit. This file is automatically extracted from the
485 # tools in /usr/src/tools/tools/locale. The data is obtained from the
486 # CLDR project, obtained from http://cldr.unicode.org/
487 # -----------------------------------------------------------------------------
492 foreach my $enc (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
493 next if ($enc eq $DEFENCODING);
494 copy ("$TYPE.draft/$actfile.$DEFENCODING.src",
495 "$TYPE.draft/$actfile.$enc.src");
496 $languages{$l}{$f}{data}{$c}{$enc} = $shex;
497 $hashtable{$shex}{"${l}_${f}_${c}.$enc"} = 1;
505 foreach my $l (sort keys(%languages)) {
506 foreach my $f (sort keys(%{$languages{$l}})) {
507 foreach my $c (sort keys(%{$languages{$l}{$f}{data}})) {
508 next if ($#filter == 2 && ($filter[0] ne $l
509 || $filter[1] ne $f || $filter[2] ne $c));
510 next if (defined $languages{$l}{$f}{definitions}
511 && $languages{$l}{$f}{definitions} !~ /$TYPE/);
513 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 0; # unread
516 $file .= $f . "_" if ($f ne "x");
519 my $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src";
520 $filename = "$ETCDIR/$file.$DEFENCODING.src"
523 && defined $languages{$l}{$f}{fallback}) {
524 $file = $languages{$l}{$f}{fallback};
525 $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src";
527 $filename = "$CLDRDIR/posix/$file.$DEFENCODING.src"
529 if (! -f $filename) {
531 "Cannot open $file.$DEFENCODING.src or fallback\n";
534 open(FIN, "$filename");
535 print "Reading from $filename for ${l}_${f}_${c}\n";
536 $languages{$l}{$f}{data}{$c}{$DEFENCODING} = 1; # read
541 foreach my $k (keys(%keys)) {
542 foreach my $line (@lines) {
544 next if (!$continue && $line !~ /^$k\s/);
551 $values{$l}{$c}{$k} = ""
552 if (!defined $values{$l}{$c}{$k});
554 $continue = ($line =~ /\/$/);
555 $line =~ s/\/$// if ($continue);
557 while ($line =~ /_/) {
559 s/\<([^>_]+)_([^>]+)\>/<$1 $2>/;
561 die "_ in data - $line" if ($line =~ /_/);
562 $values{$l}{$c}{$k} .= $line;
564 last if (!$continue);
580 # Conversion to UTF-8 can be done from the Unicode name to
581 # the UTF-8 character code.
584 die "Cannot convert $s in $e (charmap)" if (!defined $v);
587 # Conversion to these encodings can be done from the Unicode
588 # name to Unicode code to the encodings code.
591 $ucc = $ucd{name2code}{$s} if (defined $ucd{name2code}{$s});
592 $ucc = $ucd{name2code}{$utf8aliases{$s}}
595 && defined $ucd{name2code}{$utf8aliases{$s}});
598 if (defined $translations{$e}{$s}{hex}) {
599 $v = $translations{$e}{$s}{hex};
601 } elsif (defined $translations{$e}{$s}{ucc}) {
602 $ucc = $translations{$e}{$s}{ucc};
606 die "Cannot convert $s in $e (ucd string)" if (!defined $ucc);
607 $v = $convertors{$e}{$ucc} if (!defined $v);
609 $v = $translations{$e}{$s}{hex}
610 if (!defined $v && defined $translations{$e}{$s}{hex});
612 if (!defined $v && defined $translations{$e}{$s}{unicode}) {
613 my $ucn = $translations{$e}{$s}{unicode};
614 $ucc = $ucd{name2code}{$ucn}
615 if (defined $ucd{name2code}{$ucn});
616 $ucc = $ucd{name2code}{$utf8aliases{$ucn}}
618 && defined $ucd{name2code}{$utf8aliases{$ucn}});
619 $v = $convertors{$e}{$ucc};
622 die "Cannot convert $s in $e (charmap)" if (!defined $v);
625 return pack("C", hex($v)) if (length($v) == 2);
626 return pack("CC", hex(substr($v, 0, 2)), hex(substr($v, 2, 2)))
627 if (length($v) == 4);
628 return pack("CCC", hex(substr($v, 0, 2)), hex(substr($v, 2, 2)),
629 hex(substr($v, 4, 2))) if (length($v) == 6);
630 print STDERR "Cannot convert $e $s\n";
631 return "length = " . length($v);
639 return $translations{$enc}{$v} if (defined $translations{$enc}{$v});
644 foreach my $l (sort keys(%languages)) {
645 foreach my $f (sort keys(%{$languages{$l}})) {
646 foreach my $c (sort keys(%{$languages{$l}{$f}{data}})) {
647 next if ($#filter == 2 && ($filter[0] ne $l
648 || $filter[1] ne $f || $filter[2] ne $c));
649 next if (defined $languages{$l}{$f}{definitions}
650 && $languages{$l}{$f}{definitions} !~ /$TYPE/);
651 foreach my $enc (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
652 if ($languages{$l}{$f}{data}{$c}{$DEFENCODING} eq "0") {
653 print "Skipping ${l}_" .
654 ($f eq "x" ? "" : "${f}_") .
659 $file .= "_" . $f if ($f ne "x");
661 print "Writing to $file in $enc\n";
663 if ($enc ne $DEFENCODING &&
664 !defined $convertors{$enc}) {
665 print "Failed! Cannot convert to $enc.\n";
669 open(FOUT, ">$TYPE.draft/$file.$enc.new");
673 # Warning: Do not edit. This file is automatically generated from the
674 # tools in /usr/src/tools/tools/locale. The data is obtained from the
675 # CLDR project, obtained from http://cldr.unicode.org/
676 # -----------------------------------------------------------------------------
678 foreach my $k (keys(%keys)) {
681 die("Unknown $k in \%DESC")
682 if (!defined $DESC{$k});
684 $output .= "#\n# $DESC{$k}\n";
686 # Replace one row with another
694 $callback{data}{c} = $c;
695 $callback{data}{k} = $k;
696 $callback{data}{l} = $l;
697 $callback{data}{e} = $enc;
698 my @a = split(/\</, substr($f, 1));
700 &{$callback{$a[0]}}($values{$l}{$c}{$a[1]});
701 $values{$l}{$c}{$k} = $rv;
703 $callback{data} = ();
706 my $v = $values{$l}{$c}{$k};
707 $v = "undef" if (!defined $v);
721 while ($v =~ /^(.*?)<(.*?)>(.*)/) {
726 my $rv = decodecldr($enc, $cm);
727 # $rv = translate($enc, $cm)
731 "Could not convert $k ($cm) from $DEFENCODING to $enc\n";
736 $v = $p1 . $rv . $p3;
742 foreach my $v (split(/;/, $v)) {
746 while ($v =~ /^(.*?)<(.*?)>(.*)/) {
754 # $rv = translate($enc,
759 "Could not convert $k ($cm) from $DEFENCODING to $enc\n";
775 $languages{$l}{$f}{data}{$c}{$enc} = sha1_hex($output);
776 $hashtable{sha1_hex($output)}{"${l}_${f}_${c}.$enc"} = 1;
777 print FOUT "$output# EOF\n";
781 rename("$TYPE.draft/$file.$enc.new",
782 "$TYPE.draft/$file.$enc.src");
784 rename("$TYPE.draft/$file.$enc.new",
785 "$TYPE.draft/$file.$enc.failed");
794 return if ($#filter > -1);
795 print "Creating Makefile for $TYPE\n";
800 if ($TYPE eq "colldef") {
801 $SRCOUT = "localedef -D -U -i \${.IMPSRC} \\\n" .
802 "\t-f \${MAPLOC}/map.UTF-8 " .
803 "\${.OBJDIR}/\${.IMPSRC:T:R}";
804 $MAPLOC = "MAPLOC=\t\t\${.CURDIR}/../../tools/tools/" .
805 "locale/etc/final-maps\n";
806 $SRCOUT2 = "LC_COLLATE";
808 elsif ($TYPE eq "ctypedef") {
809 $SRCOUT = "localedef -D -U -c -w \${MAPLOC}/widths.txt \\\n" .
810 "\t-f \${MAPLOC}/map.\${.IMPSRC:T:R:C/^.*\\.//} " .
811 "\\\n\t-i \${.IMPSRC} \${.OBJDIR}/\${.IMPSRC:T:R} " .
813 $SRCOUT2 = "LC_CTYPE";
814 $MAPLOC = "MAPLOC=\t\t\${.CURDIR}/../../tools/tools/" .
815 "locale/etc/final-maps\n";
816 $SRCOUT3 = "## SYMPAIRS\n\n" .
817 ".for PAIR in \${SYMPAIRS}\n" .
818 "\${PAIR:C/^.*://:S/src\$/LC_CTYPE/}: " .
819 "\${PAIR:C/:.*//}\n" .
820 "\tlocaledef -D -U -c -w \${MAPLOC}/widths.txt \\\n" .
821 "\t-f \${MAPLOC}/map.\${.TARGET:T:R:C/^.*\\.//} " .
822 "\\\n\t-i \${.ALLSRC} \${.OBJDIR}/\${.TARGET:T:R} " .
827 $SRCOUT = "grep -v -E '^(\#\$\$|\#[ ])' < \${.IMPSRC} > \${.TARGET}";
831 open(FOUT, ">$TYPE.draft/Makefile");
833 # Warning: Do not edit. This file is automatically generated from the
834 # tools in /usr/src/tools/tools/locale.
836 LOCALEDIR= \${SHAREDIR}/locale
837 FILESNAME= $FILESNAMES{$TYPE}
838 .SUFFIXES: .src .${SRCOUT2}
847 foreach my $hash (keys(%hashtable)) {
848 # For colldef, weight LOCALES to UTF-8
849 # Sort as upper-case and reverse to achieve it
850 # Make en_US, ru_RU, and ca_AD preferred
852 if ($TYPE eq "colldef") {
854 if ($a eq 'en_x_US.UTF-8' ||
855 $a eq 'ru_x_RU.UTF-8' ||
856 $a eq 'ca_x_AD.UTF-8') { return -1; }
857 elsif ($b eq 'en_x_US.UTF-8' ||
858 $b eq 'ru_x_RU.UTF-8' ||
859 $b eq 'ca_x_AD.UTF-8') { return 1; }
860 else { return uc($b) cmp uc($a); }
861 } keys(%{$hashtable{$hash}});
862 } elsif ($TYPE eq "ctypedef") {
864 if ($a eq 'en_x_US.UTF-8') { return -1; }
865 elsif ($b eq 'en_x_US.UTF-8') { return 1; }
866 if ($a =~ /^en_x_US/) { return -1; }
867 elsif ($b =~ /^en_x_US/) { return 1; }
869 if ($a =~ /^en_x_GB.ISO8859-15/ ||
870 $a =~ /^ru_x_RU/) { return -1; }
871 elsif ($b =~ /^en_x_GB.ISO8859-15/ ||
872 $b =~ /ru_x_RU/) { return 1; }
873 else { return uc($b) cmp uc($a); }
875 } keys(%{$hashtable{$hash}});
878 if ($a =~ /_Comm_/ ||
879 $b eq 'en_x_US.UTF-8') { return 1; }
880 elsif ($b =~ /_Comm_/ ||
881 $a eq 'en_x_US.UTF-8') { return -1; }
882 else { return uc($b) cmp uc($a); }
883 } keys(%{$hashtable{$hash}});
886 my $link = shift(@files);
887 $link =~ s/_x_/_/; # strip family if none there
888 foreach my $file (@files) {
889 my @a = split(/_/, $file);
890 my @b = split(/\./, $a[-1]);
892 print FOUT "SAME+=\t\t$link:$file\n";
893 undef($languages{$a[0]}{$a[1]}{data}{$b[0]}{$b[1]});
898 foreach my $l (sort keys(%languages)) {
899 foreach my $f (sort keys(%{$languages{$l}})) {
900 foreach my $c (sort keys(%{$languages{$l}{$f}{data}})) {
901 next if ($#filter == 2 && ($filter[0] ne $l
902 || $filter[1] ne $f || $filter[2] ne $c));
903 next if (defined $languages{$l}{$f}{definitions}
904 && $languages{$l}{$f}{definitions} !~ /$TYPE/);
905 if (defined $languages{$l}{$f}{data}{$c}{$DEFENCODING}
906 && $languages{$l}{$f}{data}{$c}{$DEFENCODING} eq "0") {
907 print "Skipping ${l}_" . ($f eq "x" ? "" : "${f}_") .
911 foreach my $e (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
913 $file .= $f . "_" if ($f ne "x");
915 next if (!defined $languages{$l}{$f}{data}{$c}{$e});
916 print FOUT "LOCALES+=\t$file.$e\n";
919 if (defined $languages{$l}{$f}{nc_link}) {
920 foreach my $e (sort keys(%{$languages{$l}{$f}{data}{$c}})) {
922 $file .= $f . "_" if ($f ne "x");
924 print FOUT "SAME+=\t\t$file.$e:$languages{$l}{$f}{nc_link}.$e\t# legacy (lang/country change)\n";
928 if (defined $languages{$l}{$f}{e_link}) {
929 foreach my $el (split(" ", $languages{$l}{$f}{e_link})) {
930 my @a = split(/:/, $el);
932 $file .= $f . "_" if ($f ne "x");
934 print FOUT "SAME+=\t\t$file.$a[0]:$file.$a[1]\t# legacy (same charset)\n";
944 FILES= \${LOCALES:S/\$/.${SRCOUT2}/}
945 CLEANFILES= \${FILES}
948 SYMLINKS+= ../\${f:C/:.*\$//}/\${FILESNAME} \\
949 \${LOCALEDIR}/\${f:C/^.*://}/\${FILESNAME}
952 .for f in \${LOCALES}
953 FILESDIR_\${f}.${SRCOUT2}= \${LOCALEDIR}/\${f}
956 ${SRCOUT3}.include <bsd.prog.mk>