dictck.pl revision f6e214c7418f43af38bd8c3a557e3d0a1d311cfa
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# CDDL HEADER START
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# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# See the License for the specific language governing permissions
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# and limitations under the License.
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# CDDL HEADER END
e7c3cdae834138050f4382e8c1b001c64e5a9be7jiang.liu@intel.com# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu# dictck -- Sanity check a .dict file and optionally the corresponding .po file
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu# example: dickck FMD.dict FMD.po
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# usage: dickck [-vp] [ -b buildcode ] dictfile [ pofile ]
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# -b specify location of "buildcode" command
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# -p print a .po file template to stdout, based on dictfile given
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf# -v verbose, show how code is assembled
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# Note: this program requires the "buildcode" program in your search path.
ae115bc77f6fcde83175c75b4206dc2e50747966mrjuse strict;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj$Myname =~ s,.*/,,;
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# Category 1 event classes
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy @cat1ev = qw(fault defect upset ereport list ireport);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# usage -- print a usage message and exit
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $msg = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj warn "usage: $Myname [-pv] [ -b buildcode ] dictfile [ pofile ]\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# the "main" for this script...
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $dictfile = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmy $pofile = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dodict -- load up a .dict file, sanity checking it as we go
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe die "dictname \"$name\" not something.dict as expected\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*#/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: first non-comment line must be FMDICT line\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless /^FMDICT:/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $s = $_;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases while ($s =~ /^\s*([^=\s]+)(.*)$/) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if ($s =~ /^\s*=\s*(.*)$/) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: property \"$lhs\" incomplete\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless $s ne "";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj $s =~ /^([^\s]*)(.*)$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for required headers
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no version property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no name property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: no maxkey property in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check version
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: unexpected version: \"$props{'version'}\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check name
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: name \"$props{'name'}\" doesn't match \"$dname\" from filename\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check format of maxkey (value checked later)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: maxkey property must be a number\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for old bits property
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: obsolete \"bits\" property found in header\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # parse entries
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: malformed entry\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unless /^([^=]+)=(\d+)$/;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu # make sure keys are sorted
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu die "$name:$line: keys not in expected format of:\n" .
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu " \"$elhs\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check for duplicate or unexpected keys
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 die "$name:$line: duplicate entry for keys\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name:$line: duplicate entry for value $rhs\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj open(B, "$buildcode $dname $rhs|") or
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "can't run buildcode: $!\n";
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $code = <B>;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# code: $code
ae115bc77f6fcde83175c75b4206dc2e50747966mrj # check maxkey
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: maxkey too low, should be $maxkey\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dobs -- handle backslashed sequences
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $s = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return $s;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj# dopo -- sanity check a po file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj my $name = shift;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (<F>) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*#/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next if /^\s*$/;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj next unless $id =~
db2bae3047e71d795bde12e3baa621f4b6cc8930Dana Myers /^(.*)\.(type|severity|description|response|impact|action)$/;
7ff178cd8db129d385d3177eb20744d3b6efc59bJimmy Vetayases die "$name:$line: no dict entry for code \"$code\"\n"
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 die "$name: missing entry for \"$code.type\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.severity\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.description\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.response\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.impact\"\n"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj die "$name: missing entry for \"$code.action\"\n"