dictck.pl revision f6e214c7418f43af38bd8c3a557e3d0a1d311cfa
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#!/usr/bin/perl -w
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# CDDL HEADER START
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# The contents of this file are subject to the terms of the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# Common Development and Distribution License (the "License").
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# You may not use this file except in compliance with the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# or http://www.opensolaris.org/os/licensing.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# See the License for the specific language governing permissions
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# and limitations under the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# When distributing Covered Code, include this CDDL HEADER in each
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# If applicable, add the following below this CDDL HEADER, with the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# fields enclosed by brackets "[]" replaced with your own identifying
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# information: Portions Copyright [yyyy] [name of copyright owner]
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# CDDL HEADER END
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
e7c3cdae834138050f4382e8c1b001c64e5a9be7jiang.liu@intel.com# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
6025f1db7d005ffd81a92cbdc542e14e20b246eaHans Rosenfeld#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu# dictck -- Sanity check a .dict file and optionally the corresponding .po file
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu# example: dickck FMD.dict FMD.po
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# usage: dickck [-vp] [ -b buildcode ] dictfile [ pofile ]
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# -b specify location of "buildcode" command
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# -p print a .po file template to stdout, based on dictfile given
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf# -v verbose, show how code is assembled
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# Note: this program requires the "buildcode" program in your search path.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjuse strict;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjuse Getopt::Std;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjuse vars qw($opt_b $opt_p $opt_v);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $Myname = $0; # save our name for error messages
ae115bc77f6fcde83175c75b4206dc2e50747966mrj$Myname =~ s,.*/,,;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
41afdfa77f9af46beb3aaab2eccc0d9afe660d31Krishnendu Sadhukhan - Sun Microsystems$SIG{HUP} = $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = sub {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # although fatal, we prepend "WARNING:" to make sure the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # commonly-used "nightly" script flags this as lint on the .dict file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$Myname: WARNING: @_";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj};
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# Category 1 event classes
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy @cat1ev = qw(fault defect upset ereport list ireport);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# usage -- print a usage message and exit
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjsub usage {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $msg = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj warn "$Myname: $msg\n" if defined($msg);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj warn "usage: $Myname [-pv] [ -b buildcode ] dictfile [ pofile ]\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj exit 1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj}
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxemy %keys2val;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxemy %val2keys;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxemy %code2val;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $buildcode = 'buildcode';
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# the "main" for this script...
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjgetopts('b:pv') or usage;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $dictfile = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $pofile = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrjusage unless defined($dictfile);
ae115bc77f6fcde83175c75b4206dc2e50747966mrjusage if @ARGV;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj$buildcode = $opt_b if defined($opt_b);
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayasesdodict($dictfile);
ae115bc77f6fcde83175c75b4206dc2e50747966mrjdopo($pofile) if defined($pofile);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuexit 0;
c8589f13ba961772dd5a0d699c5bb926f3006c33sethg
55d507a98872ca680fb002fbfda82397def13241Seth Goldberg#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dodict -- load up a .dict file, sanity checking it as we go
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases#
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayasessub dodict {
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases my $name = shift;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases my $dname;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases my $line = 0;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases my $lhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $rhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my %props;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $maxkey = 1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if ($name =~ m,([^/]+)\.dict$,) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $dname = $1;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe } else {
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe die "dictname \"$name\" not something.dict as expected\n";
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe }
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe open(F, $name) or die "$name: $!\n";
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe print "parsing \"$name\"\n" if $opt_v;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $line++;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*#/;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases chomp;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: first non-comment line must be FMDICT line\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless /^FMDICT:/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print "FMDICT keyword found on line $line\n" if $opt_v;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj s/FMDICT:\s*//;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $s = $_;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases while ($s =~ /^\s*([^=\s]+)(.*)$/) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $lhs = $1;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases $rhs = "";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s = $+;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if ($s =~ /^\s*=\s*(.*)$/) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s = $+;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: property \"$lhs\" incomplete\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $s ne "";
63ea9ad24896f2939472f8f96f568086d190eb33Evan Yan }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if ($s =~ /^"((?:[^"]|\\")*)"(.*)$/) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s = $+;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $rhs = $1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj } else {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s =~ /^([^\s]*)(.*)$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s = $+;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $rhs = $1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $rhs =~ s/\\(.)/dobs($1)/ge;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $props{$lhs} = $rhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print "property \"$lhs\" value \"$rhs\"\n" if $opt_v;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj last;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for required headers
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no version property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($props{'version'});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no name property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($props{'name'});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no maxkey property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($props{'maxkey'});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check version
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: unexpected version: \"$props{'version'}\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $props{'version'} eq "1";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check name
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: name \"$props{'name'}\" doesn't match \"$dname\" from filename\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $props{'name'} eq $dname;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check format of maxkey (value checked later)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: maxkey property must be a number\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $props{'maxkey'} =~ /^\d+$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for old bits property
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: obsolete \"bits\" property found in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if defined($props{'bits'});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # parse entries
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $line++;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj chomp;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj s/#.*//;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: malformed entry\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless /^([^=]+)=(\d+)$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $lhs = $1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $rhs = $2;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu # make sure keys are sorted
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu my $elhs = join(' ', sort split(/\s/, $lhs));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu die "$name:$line: keys not in expected format of:\n" .
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu " \"$elhs\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $elhs eq $lhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for duplicate or unexpected keys
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my %keys;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $cat1pat = join('|', @cat1ev);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj foreach my $e (split(/\s/, $lhs)) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: unknown event type \"$e\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $e =~
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /^($cat1pat)\..*[^.]$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: key repeated: \"$e\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if defined($keys{$e});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $keys{$e} = 1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $maxkey = keys(%keys) if $maxkey < keys(%keys);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: duplicate entry for keys\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if defined($keys2val{$lhs});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: duplicate entry for value $rhs\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if defined($val2keys{$rhs});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $keys2val{$lhs} = $rhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $val2keys{$rhs} = $lhs;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj open(B, "$buildcode $dname $rhs|") or
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "can't run buildcode: $!\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $code = <B>;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj chomp $code;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases close(B);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print "code: $code keys: $lhs\n" if $opt_v;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases $code2val{$code} = $rhs;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases if ($opt_p) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print <<EOF;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# code: $code
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases# keys: $lhs
c8589f13ba961772dd5a0d699c5bb926f3006c33sethg#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.type"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.severity"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.description"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.response"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.impact"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgid "$code.action"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmsgstr "XXX"
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy VetayasesEOF
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print "computed maxkey: $maxkey\n" if $opt_v;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check maxkey
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: maxkey too low, should be $maxkey\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if $props{'maxkey'} < $maxkey;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases
ae115bc77f6fcde83175c75b4206dc2e50747966mrj close(F);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj}
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dobs -- handle backslashed sequences
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjsub dobs {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $s = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return "\n" if $s eq 'n';
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return "\r" if $s eq 'r';
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return "\t" if $s eq 't';
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return $s;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj}
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dopo -- sanity check a po file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#
ae115bc77f6fcde83175c75b4206dc2e50747966mrjsub dopo {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $name = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $line = 0;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $id;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $code;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $suffix;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my %ids;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj open(F, $name) or die "$name: $!\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj print "parsing \"$name\"\n" if $opt_v;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $line++;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*#/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj chomp;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next unless /^msgid\s*"([^"]+)"$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $id = $1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next unless $id =~
db2bae3047e71d795bde12e3baa621f4b6cc8930Dana Myers /^(.*)\.(type|severity|description|response|impact|action)$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $code = $1;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $suffix = $2;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases die "$name:$line: no dict entry for code \"$code\"\n"
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases unless defined($code2val{$code});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $ids{$id} = $line;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
db2bae3047e71d795bde12e3baa621f4b6cc8930Dana Myers close(F);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
db2bae3047e71d795bde12e3baa621f4b6cc8930Dana Myers # above checks while reading in file ensured that node code was
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # mentioned in .po file that didn't exist in .dict file. now
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check the other direction: make sure the full set of entries
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # exist for each code in the .dict file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj foreach $code (sort keys %code2val) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.type\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.type"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.severity\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.severity"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.description\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.description"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.response\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.response"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.impact\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.impact"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.action\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless defined($ids{"$code.action"});
ae115bc77f6fcde83175c75b4206dc2e50747966mrj }
ae115bc77f6fcde83175c75b4206dc2e50747966mrj}
ae115bc77f6fcde83175c75b4206dc2e50747966mrj