|
Packit |
857059 |
#! perl -w
|
|
Packit |
857059 |
# BEGIN_ICS_COPYRIGHT8 ****************************************
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Copyright (c) 2015, Intel Corporation
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Redistribution and use in source and binary forms, with or without
|
|
Packit |
857059 |
# modification, are permitted provided that the following conditions are met:
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
857059 |
# this list of conditions and the following disclaimer.
|
|
Packit |
857059 |
# * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
857059 |
# notice, this list of conditions and the following disclaimer in the
|
|
Packit |
857059 |
# documentation and/or other materials provided with the distribution.
|
|
Packit |
857059 |
# * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
857059 |
# may be used to endorse or promote products derived from this software
|
|
Packit |
857059 |
# without specific prior written permission.
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
857059 |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
857059 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit |
857059 |
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
Packit |
857059 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
857059 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
857059 |
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
Packit |
857059 |
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit |
857059 |
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
857059 |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# END_ICS_COPYRIGHT8 ****************************************
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Converts a message file to a pair of C files (a source file and a header)
|
|
Packit |
857059 |
# that define macros and data structures for use with the Err module for error
|
|
Packit |
857059 |
# reporting.
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# If you encounter any problems with this program please notify Frank Szczerba
|
|
Packit |
857059 |
# (fszczerba@infiniconsys.com).
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
|
|
Packit |
857059 |
use strict;
|
|
Packit |
857059 |
use integer;
|
|
Packit |
857059 |
use FileHandle;
|
|
Packit |
857059 |
use File::Basename;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# list of supported languages ( LOG_LANG_ is prepended on output ) must be uppercase
|
|
Packit |
857059 |
my @languages = qw( ENGLISH );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#### end configuration
|
|
Packit |
857059 |
my %languages; # @languages by name
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@languages); $i++) {
|
|
Packit |
857059 |
$languages{$languages[$i]} = $i;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $msgFile;
|
|
Packit |
857059 |
my $msgFileLine;
|
|
Packit |
857059 |
my $warnCount = 0;
|
|
Packit |
857059 |
my $errorCount = 0;
|
|
Packit |
857059 |
my $context;
|
|
Packit |
857059 |
my $testMode = 0;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
sub output {
|
|
Packit |
857059 |
my $level = shift;
|
|
Packit |
857059 |
my $out = $testMode ? *STDOUT : *STDERR;
|
|
Packit |
857059 |
print $out ("$msgFile:$msgFileLine: $level: ",
|
|
Packit |
857059 |
defined $context ? "$context: ": "", @_, "\n");
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
sub warning {
|
|
Packit |
857059 |
output "WARNING", @_;
|
|
Packit |
857059 |
$warnCount++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
sub error {
|
|
Packit |
857059 |
output "ERROR", @_;
|
|
Packit |
857059 |
$errorCount++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $defModName;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
sub validate_format($);
|
|
Packit |
857059 |
sub get_names(\%);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# file format definition
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# All sections and attributes should be ucfirst(lower($_)) case
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
my $Format = {
|
|
Packit |
857059 |
File => { # default scope
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Module => {
|
|
Packit |
857059 |
Singular => 1,
|
|
Packit |
857059 |
Attributes => {
|
|
Packit |
857059 |
Name => { Required => 1, Type => "Ident", Min => 1},
|
|
Packit |
857059 |
Ucname => { Type => "UcIdent", Calculate => sub { uc $_[0]->{Name}; } },
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Calculate => sub { {Name => $defModName}; },
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Message => {
|
|
Packit |
857059 |
Key => "Name",
|
|
Packit |
857059 |
Attributes => {
|
|
Packit |
857059 |
Name => { Required => 1, Type => "UcIdent" },
|
|
Packit |
857059 |
Comment => { },
|
|
Packit |
857059 |
Arglist => { Type => "CSV", Max => 6 },
|
|
Packit |
857059 |
Unitarg => { Type => "Int", Min => 0, Max => 6, Default => 0, },
|
|
Packit |
857059 |
Trapfunc => { Type => "Ident", Default => "LOG_TRAP_NONE" },
|
|
Packit |
857059 |
Severity => {
|
|
Packit |
857059 |
Recomended => 1,
|
|
Packit |
857059 |
Type => "Picklist",
|
|
Packit |
857059 |
Transform => sub { $_[0] =~ tr/ /_/;
|
|
Packit |
857059 |
$_[0] =~ s/PARTIAL/ADD_PART/; },
|
|
Packit |
857059 |
Set => "Class",
|
|
Packit |
857059 |
# Class is set to the RHS below:
|
|
Packit |
857059 |
Values => {
|
|
Packit |
857059 |
ADD_PART => "LOG_PART",
|
|
Packit |
857059 |
ALARM => "LOG_FINAL",
|
|
Packit |
857059 |
ERROR => "LOG_FINAL",
|
|
Packit |
857059 |
WARNING => "LOG_FINAL",
|
|
Packit |
857059 |
FATAL => "LOG_FINAL",
|
|
Packit |
857059 |
DUMP => "LOG",
|
|
Packit |
857059 |
CONFIG => "LOG",
|
|
Packit |
857059 |
PROGRAM_INFO => "LOG",
|
|
Packit |
857059 |
PERIODIC_INFO => "LOG",
|
|
Packit |
857059 |
DEBUG1_INFO => "LOG",
|
|
Packit |
857059 |
DEBUG2_INFO => "LOG",
|
|
Packit |
857059 |
DEBUG3_INFO => "LOG",
|
|
Packit |
857059 |
DEBUG4_INFO => "LOG",
|
|
Packit |
857059 |
DEBUG5_INFO => "LOG",
|
|
Packit |
857059 |
NOTICE => "LOG_FINAL",
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Description => {
|
|
Packit |
857059 |
Required => 1,
|
|
Packit |
857059 |
Type => "FmtStr",
|
|
Packit |
857059 |
i18n => 1,
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Response => {
|
|
Packit |
857059 |
i18n => 1,
|
|
Packit |
857059 |
Type => "FmtStr",
|
|
Packit |
857059 |
Default => "NULL",
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
Correction => {
|
|
Packit |
857059 |
i18n => 1,
|
|
Packit |
857059 |
Type => "FmtStr",
|
|
Packit |
857059 |
Default => "NULL",
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
String => {
|
|
Packit |
857059 |
Key => "Name",
|
|
Packit |
857059 |
Attributes => {
|
|
Packit |
857059 |
Name => { Required => 1, Type => "UcIdent" },
|
|
Packit |
857059 |
Comment => { },
|
|
Packit |
857059 |
Arglist => { Type => "CSV", Max => 6 },
|
|
Packit |
857059 |
String => {
|
|
Packit |
857059 |
Required => 1,
|
|
Packit |
857059 |
Type => "FmtStr",
|
|
Packit |
857059 |
i18n => 1,
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
},
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $File = {}; # the master object
|
|
Packit |
857059 |
my $object = {}; # temp object
|
|
Packit |
857059 |
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
my $scope = 'File';
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Completes and validates and object and adds it to $File
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub new_scope($) {
|
|
Packit |
857059 |
VALIDATE_OBJ: {
|
|
Packit |
857059 |
# validate the object
|
|
Packit |
857059 |
#print "new_scope: $scope -> $_[0]\n";
|
|
Packit |
857059 |
foreach my $attr (keys(%{$Format->{$scope}{Attributes}})) {
|
|
Packit |
857059 |
my $def = $Format->{$scope}{Attributes}{$attr};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (not defined $object->{$attr}) {
|
|
Packit |
857059 |
if ($def->{Required}) {
|
|
Packit |
857059 |
error "Missing $attr attribute";
|
|
Packit |
857059 |
last VALIDATE_OBJ;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if ($def->{Recomended}) {
|
|
Packit |
857059 |
warning "Missing $attr attribute";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $def->{Default} or defined $def->{Calculate}) {
|
|
Packit |
857059 |
my $default = defined $def->{Default} ? $def->{Default}
|
|
Packit |
857059 |
: &{$def->{Calculate}}($object);
|
|
Packit |
857059 |
if ($def->{i18n}) {
|
|
Packit |
857059 |
# set default for all languages
|
|
Packit |
857059 |
$object->{$attr} = {};
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
$object->{$attr}{$lang} = $default;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
# set default
|
|
Packit |
857059 |
$object->{$attr} = $default;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($def->{i18n}) {
|
|
Packit |
857059 |
# if a message is provided for one language, it must be provided for all
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
if (not $object->{$attr}{$lang}) {
|
|
Packit |
857059 |
error "$attr: Missing $lang translation";
|
|
Packit |
857059 |
last VALIDATE_OBJ;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (defined $object->{FmtArgs}) {
|
|
Packit |
857059 |
my $numArgs = $object->{FmtArgs};
|
|
Packit |
857059 |
if (not defined $object->{Arglist}) {
|
|
Packit |
857059 |
error "Missing Arglist ($numArgs args used)";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
my $listLen = scalar(@{$object->{Arglist}});
|
|
Packit |
857059 |
if (defined $Format->{$scope}{Attributes}{Unitarg} and $object->{Unitarg} > $listLen) {
|
|
Packit |
857059 |
error "Insufficient arguments ($listLen) for UnitArg ($object->{Unitarg})";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($numArgs > $listLen) {
|
|
Packit |
857059 |
error "Insufficient arguments ($listLen) for format ($numArgs args used)";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($numArgs < $listLen) {
|
|
Packit |
857059 |
warning "Extra arguments ($listLen) for format ($numArgs args used)";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
# check argument names
|
|
Packit |
857059 |
get_names(%$object);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($Format->{$scope}{Singular}) {
|
|
Packit |
857059 |
$File->{$scope} = $object;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if (not exists $File->{$scope}) {
|
|
Packit |
857059 |
$File->{$scope} = [];
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($Format->{$scope}{Key}) {
|
|
Packit |
857059 |
my $key = $Format->{$scope}{Key};
|
|
Packit |
857059 |
foreach my $exist (@{$File->{$scope}}) {
|
|
Packit |
857059 |
if ($exist->{$key} eq $object->{$key}) {
|
|
Packit |
857059 |
error "Duplicate $scope definition with $key=$object->{$key}";
|
|
Packit |
857059 |
last VALIDATE_OBJ;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
push @{$File->{$scope}}, $object;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
} # VALIDATE_OBJ
|
|
Packit |
857059 |
$object = {};
|
|
Packit |
857059 |
$scope = $_[0];
|
|
Packit |
857059 |
$context = $scope;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Parser
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub parse_line($) {
|
|
Packit |
857059 |
my $line = $_[0];
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#print "$scope: $line\n";
|
|
Packit |
857059 |
# parse the line
|
|
Packit |
857059 |
LINE: for ($line) {
|
|
Packit |
857059 |
# attribute assignement
|
|
Packit |
857059 |
/^(\w+)(?:.(\w+))?\s*=\s*(.*)$/ and do {
|
|
Packit |
857059 |
my $attr = ucfirst lc $1;
|
|
Packit |
857059 |
my $lang;
|
|
Packit |
857059 |
my $val = $3;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (defined $2) {
|
|
Packit |
857059 |
$lang = uc $2;
|
|
Packit |
857059 |
if (not defined $languages{$lang}) {
|
|
Packit |
857059 |
error "Unknown language '$lang'";
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (not exists $Format->{$scope}{Attributes}{$attr}) {
|
|
Packit |
857059 |
error "Unknown attribute $attr for section $scope";
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $def = $Format->{$scope}{Attributes}{$attr};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# type and range check
|
|
Packit |
857059 |
for ($def->{Type} ? $def->{Type} : "Str") {
|
|
Packit |
857059 |
/Int/ and do {
|
|
Packit |
857059 |
if ($val !~ /^\d*$/) {
|
|
Packit |
857059 |
error "Non-integer value $val for $attr";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (defined $def->{Min} and $val < $def->{Min}) {
|
|
Packit |
857059 |
error "$attr must be >= $def->{Min}";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (defined $def->{Max} and $val > $def->{Max}) {
|
|
Packit |
857059 |
error "$attr must be <= $def->{Max}";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/CSV/ and do {
|
|
Packit |
857059 |
# convert to a list ref
|
|
Packit |
857059 |
$val = [split /\s*,\s*/, $val];
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (defined $def->{Min} and scalar(@$val) < $def->{Min}) {
|
|
Packit |
857059 |
error "$attr must be at least $def->{Min} element(s)";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (defined $def->{Max} and scalar(@$val) > $def->{Max}) {
|
|
Packit |
857059 |
error "$attr must be no more than $def->{Max} elements";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/CStr|FmtStr/ and do {
|
|
Packit |
857059 |
# strip continuation sequences
|
|
Packit |
857059 |
$val =~ s/([^\\])(?:"\s*")+/$1/g;
|
|
Packit |
857059 |
# and validate
|
|
Packit |
857059 |
if ($val !~ /^"(?:[^"\\]*|\\.)*"$/) {
|
|
Packit |
857059 |
error "$attr must be a double-quoted C string";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
# Use Str length check for now, but it will over-count escape sequences
|
|
Packit |
857059 |
# and the quotes
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# Fallthrough
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/FmtStr/ and do {
|
|
Packit |
857059 |
my $numArgs = validate_format($val);
|
|
Packit |
857059 |
$object->{FmtArgs} = $numArgs if (($object->{FmtArgs} || 0) < $numArgs);
|
|
Packit |
857059 |
# Fallthrough
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/UcIdent/ and do {
|
|
Packit |
857059 |
if ($val !~ /^[A-Z_][A-Z0-9_]*$/) {
|
|
Packit |
857059 |
error "$attr must be an uppercase identifier";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
# Fallthrough
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/Ident/ and do {
|
|
Packit |
857059 |
if ($val !~ /^[A-Za-z_][A-Za-z0-9_]*$/) {
|
|
Packit |
857059 |
error "$attr must be an identifier";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
# Fallthrough
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/Ident|Str/ and do {
|
|
Packit |
857059 |
if (defined $def->{Min} and length($val) < $def->{Min}) {
|
|
Packit |
857059 |
error "$attr must be at least $def->{Min} character(s)";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (defined $def->{Max} and length($val) > $def->{Max}) {
|
|
Packit |
857059 |
error "$attr must be no more than $def->{Max} characters";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
/Picklist/ and do {
|
|
Packit |
857059 |
$val = uc $val;
|
|
Packit |
857059 |
if (exists $def->{Transform}) {
|
|
Packit |
857059 |
&{$def->{Transform}}($val);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (not exists $def->{Values}{$val}) {
|
|
Packit |
857059 |
error "Invalid $attr";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
$object->{$def->{Set}} = $def->{Values}{$val};
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
die "Internal Error, Bad type $def->{Type}\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ($Format->{$scope}{Attributes}{$attr}{i18n}) {
|
|
Packit |
857059 |
if (not defined $lang) {
|
|
Packit |
857059 |
error "Missing language";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (not exists $object->{$attr}) {
|
|
Packit |
857059 |
$object->{$attr} = { $lang => $val };
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if (exists $object->{$attr}{$lang}) {
|
|
Packit |
857059 |
error "Duplicate";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
$object->{$attr}{$lang} = $val;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if (defined $lang) {
|
|
Packit |
857059 |
error "Non-internationalized attribute $attr";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (exists $object->{$attr}) {
|
|
Packit |
857059 |
error "Duplicate attribute $attr";
|
|
Packit |
857059 |
last LINE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
$object->{$attr} = $val;
|
|
Packit |
857059 |
if ($attr eq "Name") {
|
|
Packit |
857059 |
$context = "$scope $val";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# section header
|
|
Packit |
857059 |
/^\[(\w+)\]$/ and do {
|
|
Packit |
857059 |
my $new_scope = ucfirst lc $1;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ($new_scope eq "Done") {
|
|
Packit |
857059 |
# flush
|
|
Packit |
857059 |
new_scope("Done");
|
|
Packit |
857059 |
# validate sections
|
|
Packit |
857059 |
foreach my $check_scope (keys %$Format) {
|
|
Packit |
857059 |
#print "check $check_scope: ";
|
|
Packit |
857059 |
if (not exists $File->{$check_scope}) {
|
|
Packit |
857059 |
#print "Missing ";
|
|
Packit |
857059 |
if ($Format->{$check_scope}{Required}) {
|
|
Packit |
857059 |
#print "Required\n";
|
|
Packit |
857059 |
error "Missing required section $check_scope";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($Format->{$check_scope}{Default} or
|
|
Packit |
857059 |
$Format->{$check_scope}{Calculate})
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
#print "Defaulting ";
|
|
Packit |
857059 |
$object = $Format->{$check_scope}{Default}
|
|
Packit |
857059 |
? $Format->{$check_scope}{Default}
|
|
Packit |
857059 |
: &{$Format->{$check_scope}{Calculate}};
|
|
Packit |
857059 |
#print "Validating ";
|
|
Packit |
857059 |
$scope = $check_scope;
|
|
Packit |
857059 |
new_scope("Done");
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#print "Done\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($scope eq "Done") {
|
|
Packit |
857059 |
# internal use
|
|
Packit |
857059 |
$scope = $new_scope;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif (not exists $Format->{$new_scope}) {
|
|
Packit |
857059 |
error "Unknown section $new_scope";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if ($Format->{$new_scope}{Singular} and
|
|
Packit |
857059 |
(exists $File->{$new_scope} or $scope eq $new_scope))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
error "Only one $new_scope section is permitted";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
new_scope($new_scope);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
last;
|
|
Packit |
857059 |
};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
error "Syntax Error";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
my $f_posarg = '[1-9]\d*\$';
|
|
Packit |
857059 |
my $f_flags = '[ #+0\-]';
|
|
Packit |
857059 |
my $f_width = "(?:[1-9]\\d*|\\*(?:$f_posarg)?)";
|
|
Packit |
857059 |
my $f_precis = "(?:\\.(?:\\d*|\\*(?:$f_posarg)?))";
|
|
Packit |
857059 |
my $f_size = '[hq]|(?:ll?)';
|
|
Packit |
857059 |
my $f_type = '[cCdiFopsSuxXM]';
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# $1 $2 $3 $4 $5 $6 $7 $8
|
|
Packit |
857059 |
my $fmt = "($f_posarg)?($f_flags*)($f_posarg)?($f_width)?($f_precis)?($f_posarg)?($f_size)?($f_type)";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Scan a string and validate printf format specifiers. Returns the number of
|
|
Packit |
857059 |
# arguments on success, dies with a descriptive string on error.
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub validate_format($) {
|
|
Packit |
857059 |
my $str = $_[0];
|
|
Packit |
857059 |
my $have_pos = 0;
|
|
Packit |
857059 |
my $pos_mixed = 0;
|
|
Packit |
857059 |
my $numargs = 0;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
$testMode and print "validate_format($str)\n";
|
|
Packit |
857059 |
while (length($str) and not $pos_mixed) {
|
|
Packit |
857059 |
# strip stuff before the first %
|
|
Packit |
857059 |
$str =~ s/^[^%]*//;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (length($str)) {
|
|
Packit |
857059 |
# is it a valid format?
|
|
Packit |
857059 |
if ($str =~ s/^(?:\%\%|\%$fmt)//o) {
|
|
Packit |
857059 |
my $numPos = (defined $1) + (defined $3) + (defined $6);
|
|
Packit |
857059 |
if ($numPos > 1) {
|
|
Packit |
857059 |
error "Multiple positional specifiers '", defined $1 ? $1 : $3,
|
|
Packit |
857059 |
$numPos == 3 ? "', '$3'," : "'",
|
|
Packit |
857059 |
" and '", defined $5 ? $5 : $3, "' in format specifier";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
my $pos = defined $1 ? $1 : defined $3 ? $3 : $6;
|
|
Packit |
857059 |
my $flags = $2;
|
|
Packit |
857059 |
my $width = $4;
|
|
Packit |
857059 |
my $precis = $5;
|
|
Packit |
857059 |
my $size = $7;
|
|
Packit |
857059 |
my $type = $8;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# check for repeating flags (not really a problem, but ugly)
|
|
Packit |
857059 |
$flags = join('', sort(split //, $flags));
|
|
Packit |
857059 |
$testMode and print "Flags are: '$flags'\n";
|
|
Packit |
857059 |
if ($flags =~ /(.)\1/) {
|
|
Packit |
857059 |
warning "Repeated flag '$1' in format specifier";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# check for positional and non-positional parameters
|
|
Packit |
857059 |
if (defined $pos) {
|
|
Packit |
857059 |
my $arg = substr($pos, 0, length($pos) - 1);
|
|
Packit |
857059 |
$testMode and print "positional $pos, arg is $arg\n";
|
|
Packit |
857059 |
$numargs = $arg if ($arg > $numargs);
|
|
Packit |
857059 |
$have_pos = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
$pos_mixed = $have_pos;
|
|
Packit |
857059 |
$numargs++; # not the right place, but gets the right count
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $width and $width =~ /^\*($f_posarg)?$/o) {
|
|
Packit |
857059 |
if (defined $1) {
|
|
Packit |
857059 |
my $arg = substr($1, 0, length($1) - 1);
|
|
Packit |
857059 |
$testMode and print "width $width, arg is $arg\n";
|
|
Packit |
857059 |
$numargs = $arg if ($arg > $numargs);
|
|
Packit |
857059 |
$have_pos = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
$pos_mixed = $have_pos;
|
|
Packit |
857059 |
$numargs++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $precis and $precis =~ /^\.\*($f_posarg)?$/o) {
|
|
Packit |
857059 |
if (defined $1) {
|
|
Packit |
857059 |
my $arg = substr($1, 0, length($1) - 1);
|
|
Packit |
857059 |
$testMode and print "precision $precis, arg is $arg\n";
|
|
Packit |
857059 |
$numargs = $arg if ($arg > $numargs);
|
|
Packit |
857059 |
$have_pos = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
$pos_mixed = $have_pos;
|
|
Packit |
857059 |
$numargs++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($have_pos and not defined $pos) {
|
|
Packit |
857059 |
$pos_mixed = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# TODO: validate size-type combos?
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
error "Invalid format specifier at \"$str\"";
|
|
Packit |
857059 |
# strip the '%' so we can recover
|
|
Packit |
857059 |
$str = substr($str, 1);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($pos_mixed) {
|
|
Packit |
857059 |
error "Format mixes positional and non positional parameters";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return $numargs;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Scan a string and return a list of arguments which are IFormattable objects
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub find_formattable($) {
|
|
Packit |
857059 |
my $str = $_[0];
|
|
Packit |
857059 |
my $nextarg = 1;
|
|
Packit |
857059 |
my %formattable = ();
|
|
Packit |
857059 |
|
|
Packit |
857059 |
while ($str =~ /\G(?:[^\%]|\%\%)*\%$fmt/go)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
my $pos = defined $1 ? $1 : defined $3 ? $3 : $6;
|
|
Packit |
857059 |
my $width = $4;
|
|
Packit |
857059 |
my $precis = $5;
|
|
Packit |
857059 |
my $type = $8;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (defined $pos) {
|
|
Packit |
857059 |
substr($pos, -1) = '';
|
|
Packit |
857059 |
$nextarg = $pos;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $width and $width eq '*') {
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $precis and substr($precis, 1) eq '*') {
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($type eq 'F') {
|
|
Packit |
857059 |
$formattable{$nextarg}++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return sort keys %formattable;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Scan a string and return a list of arguments which are pointers
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub find_pointer($) {
|
|
Packit |
857059 |
my $str = $_[0];
|
|
Packit |
857059 |
my $nextarg = 1;
|
|
Packit |
857059 |
my %pointer = ();
|
|
Packit |
857059 |
|
|
Packit |
857059 |
while ($str =~ /\G(?:[^\%]|\%\%)*\%$fmt/go)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
my $pos = defined $1 ? $1 : defined $3 ? $3 : $6;
|
|
Packit |
857059 |
my $width = $4;
|
|
Packit |
857059 |
my $precis = $5;
|
|
Packit |
857059 |
my $type = $8;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (defined $pos) {
|
|
Packit |
857059 |
substr($pos, -1) = '';
|
|
Packit |
857059 |
$nextarg = $pos;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $width and $width eq '*') {
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $precis and substr($precis, 1) eq '*') {
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($type eq 's' or $type eq 'p') {
|
|
Packit |
857059 |
$pointer{$nextarg}++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
$nextarg++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return sort keys %pointer;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Extract names of arguments from an argument list
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub get_names(\%) {
|
|
Packit |
857059 |
my $obj = $_[0];
|
|
Packit |
857059 |
my @list;
|
|
Packit |
857059 |
my %seen = ();
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (not defined $obj->{Arglist}) {
|
|
Packit |
857059 |
return ();
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
for (my $i = 1; $i <= scalar(@{$obj->{Arglist}}); $i++) {
|
|
Packit |
857059 |
if ($obj->{Arglist}[$i-1] =~ /^([a-zA-Z_]\w+)(?:\s*:.*)?$/) {
|
|
Packit |
857059 |
$list[$i-1] = $1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
warning "No name given for $obj->{Name} argument $i, defaulting to arg$i";
|
|
Packit |
857059 |
$list[$i-1] = "arg$i";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($seen{$list[$i-1]}) {
|
|
Packit |
857059 |
error "Duplicate argument name ", $list[$i-1], " for $obj->{Name}";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
$seen{$list[$i-1]} = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return @list;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Find the union of two (or more) lists
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
sub union {
|
|
Packit |
857059 |
my %union = ();
|
|
Packit |
857059 |
|
|
Packit |
857059 |
foreach my $i (@_) {
|
|
Packit |
857059 |
$union{$i}++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return sort keys %union;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Main Loop
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#main()
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $cur_line = "";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (scalar @ARGV != 1) {
|
|
Packit |
857059 |
print "Usage: buildmsgs.pl Module.msg\n";
|
|
Packit |
857059 |
print "\nCreates/overwrites Module_Messages.c and Module_Messages.h.\n";
|
|
Packit |
857059 |
exit(1);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
$msgFile = shift;
|
|
Packit |
857059 |
($defModName,undef,undef) = fileparse($msgFile, '\..*');
|
|
Packit |
857059 |
$msgFileLine = 0;
|
|
Packit |
857059 |
my $fileBase = $defModName . "_Messages";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ($msgFile eq '--test') {
|
|
Packit |
857059 |
$testMode = 1;
|
|
Packit |
857059 |
while (<>) {
|
|
Packit |
857059 |
my $line = $_;
|
|
Packit |
857059 |
chomp $line;
|
|
Packit |
857059 |
++$msgFileLine;
|
|
Packit |
857059 |
my $rslt = validate_format($line);
|
|
Packit |
857059 |
print "$rslt arguments\n";
|
|
Packit |
857059 |
my @formattable = find_formattable($line);
|
|
Packit |
857059 |
my @pointer = find_pointer($line);
|
|
Packit |
857059 |
print "IFormattable args: ", join(', ', @formattable), "\n" if (@formattable);
|
|
Packit |
857059 |
print "Pointer args: ", join(', ', @pointer), "\n" if (@pointer);
|
|
Packit |
857059 |
print "\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
exit 0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $msg_file = new FileHandle "$msgFile" or die "$msgFile: ERROR: $!\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
while (<$msg_file>) {
|
|
Packit |
857059 |
s/((?:".*")*)\s*(?:#.*)?$/$1/; # strip comments
|
|
Packit |
857059 |
s/\s*$//; # strip trailing whitespace
|
|
Packit |
857059 |
if (s/^\t[ \t]*/ /) { # continuation line
|
|
Packit |
857059 |
$cur_line .= $_;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
if (length($cur_line)) {
|
|
Packit |
857059 |
parse_line($cur_line);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
$cur_line = $_;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
++$msgFileLine;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# handle last line
|
|
Packit |
857059 |
if (length($cur_line)) {
|
|
Packit |
857059 |
parse_line($cur_line);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# flush any in-progress object
|
|
Packit |
857059 |
parse_line("[Done]");
|
|
Packit |
857059 |
|
|
Packit |
857059 |
close $msg_file;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# ensure we have a MODNAME str as the first string
|
|
Packit |
857059 |
if (not exists $File->{String} or $File->{String}[0]{Name} ne "MODNAME") {
|
|
Packit |
857059 |
if (exists $File->{String}) {
|
|
Packit |
857059 |
for (my $i = 1; $i < scalar(@{$File->{String}}); $i++) {
|
|
Packit |
857059 |
if ($File->{String}[$i]{Name} eq "MODNAME") {
|
|
Packit |
857059 |
error "MODNAME must be the first string";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
parse_line("[String]");
|
|
Packit |
857059 |
parse_line("Name=MODNAME");
|
|
Packit |
857059 |
parse_line("comment=first entry must be 1-6 character package name");
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
parse_line("String.$lang=\"$File->{Module}{Name}\"");
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
parse_line("[Done]");
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# rotate to the beginning of the list
|
|
Packit |
857059 |
unshift @{$File->{String}}, pop @{$File->{String}};
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# ensure MODNAME str is 1-6 characters
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
my $str = $File->{String}[0]{String}{$lang};
|
|
Packit |
857059 |
|
|
Packit |
857059 |
# value includes quotes
|
|
Packit |
857059 |
if (length $str < 3 or length $str > 9) {
|
|
Packit |
857059 |
error "MODNAME string must be 1-6 characters ($lang string $str is ",
|
|
Packit |
857059 |
length($str)- 2, " characters";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ($errorCount) {
|
|
Packit |
857059 |
die "$msgFile: $warnCount warnings, $errorCount errors\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
elsif ($warnCount) {
|
|
Packit |
857059 |
warn "$msgFile: $warnCount warnings\n"
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# generate output
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $modName = $File->{Module}{Name};
|
|
Packit |
857059 |
my $ucModName = $File->{Module}{Ucname};
|
|
Packit |
857059 |
my $lcModName = lcfirst $modName;
|
|
Packit |
857059 |
my $mod = "MOD_$ucModName";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $header = new FileHandle ">$fileBase.h" or die "$msgFile: ERROR: Could not open $fileBase.h for write\n";
|
|
Packit |
857059 |
my $source = new FileHandle ">$fileBase.c" or die "$msgFile: ERROR: Could not open $fileBase.c for write\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Mod_Messages.h
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
my $oldfh = select $header;
|
|
Packit |
857059 |
print <<"EOF";
|
|
Packit |
857059 |
#ifndef ${ucModName}_MESSAGES_H_INCLUDED
|
|
Packit |
857059 |
#define ${ucModName}_MESSAGES_H_INCLUDED
|
|
Packit |
857059 |
|
|
Packit |
857059 |
/*!
|
|
Packit |
857059 |
\@file $modName/$fileBase.h
|
|
Packit |
857059 |
\@brief Nationalizable Strings and Messages for $modName Package generated from $msgFile
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#include "Gen_Arch.h"
|
|
Packit |
857059 |
#include "Gen_Macros.h"
|
|
Packit |
857059 |
#include "Log.h"
|
|
Packit |
857059 |
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (exists $File->{Message}) {
|
|
Packit |
857059 |
my $need_macros = 0;
|
|
Packit |
857059 |
print "/* Messages */\n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$File->{Message}}); $i++) {
|
|
Packit |
857059 |
printf "#define %s_MSG_%-25s LOG_BUILD_MSGID(%s, %d)\n",
|
|
Packit |
857059 |
$ucModName, $File->{Message}->[$i]->{Name}, $mod, $i;
|
|
Packit |
857059 |
$need_macros = 1 if (exists $File->{Message}->[$i]->{Severity});
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($need_macros) {
|
|
Packit |
857059 |
print "\n/* Logging Macros */\n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$File->{Message}}); $i++) {
|
|
Packit |
857059 |
my $msg = $File->{Message}->[$i];
|
|
Packit |
857059 |
|
|
Packit |
857059 |
next if (not exists $msg->{Severity});
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my $msgName = $msg->{Name};
|
|
Packit |
857059 |
my @args = get_names(%$msg);
|
|
Packit |
857059 |
my @fmt = find_formattable($msg->{Description}{$languages[0]});
|
|
Packit |
857059 |
my @ptr = find_pointer($msg->{Description}{$languages[0]});
|
|
Packit |
857059 |
if (defined $msg->{Response}) {
|
|
Packit |
857059 |
@fmt = union(@fmt, find_formattable($msg->{Response}{$languages[0]}));
|
|
Packit |
857059 |
@ptr = union(@ptr, find_pointer($msg->{Response}{$languages[0]}));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (defined $msg->{Correction}) {
|
|
Packit |
857059 |
@fmt = union(@fmt, find_formattable($msg->{Correction}{$languages[0]}));
|
|
Packit |
857059 |
@ptr = union(@ptr, find_pointer($msg->{Correction}{$languages[0]}));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
my @rvArgs = @args;
|
|
Packit |
857059 |
foreach my $arg (@fmt) {
|
|
Packit |
857059 |
$rvArgs[$arg-1] = 'LOG_FORMATTABLE('. $rvArgs[$arg-1] . ')';
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
foreach my $arg (@ptr) {
|
|
Packit |
857059 |
$rvArgs[$arg-1] = 'LOG_PTR('. $rvArgs[$arg-1] . ')';
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
for (my $arg = scalar(@rvArgs); $arg < 6; $arg++) {
|
|
Packit |
857059 |
$rvArgs[$arg] = 0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#printf STDOUT "%s: %d, %d\n", $msgName, scalar(@args), scalar(@rvArgs);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
printf "/* %s_MSG_%s", $ucModName, $msgName;
|
|
Packit |
857059 |
if (exists $msg->{Comment}) {
|
|
Packit |
857059 |
print ": $msg->{Comment}";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (exists $msg->{Arglist}) {
|
|
Packit |
857059 |
print "\n * Arguments: \n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$msg->{Arglist}}); $i++) {
|
|
Packit |
857059 |
printf " *\t%s\n", $msg->{Arglist}[$i];
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print " */\n";
|
|
Packit |
857059 |
printf "#define %s_%s_%s(%s)\\\n\tLOG_%s(MOD_%s, %s_MSG_%s, %s)\n",
|
|
Packit |
857059 |
$ucModName, $msg->{Class}, $msgName, join(', ', @args),
|
|
Packit |
857059 |
$msg->{Severity}, $ucModName, $ucModName, $msgName, join(', ', @rvArgs);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
print "\n/* Constant Strings for use as substitutionals in Messages */\n";
|
|
Packit |
857059 |
my $need_macros = 0;
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$File->{String}}); $i++) {
|
|
Packit |
857059 |
printf "#define %s_STR_%-25s LOG_BUILD_STRID(%s, %d)\n",
|
|
Packit |
857059 |
$ucModName, $File->{String}->[$i]->{Name}, $mod, $i;
|
|
Packit |
857059 |
$need_macros = 1 if (exists $File->{String}->[$i]->{Arglist});
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if ($need_macros) {
|
|
Packit |
857059 |
print "\n/* String Formatting Macros */\n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$File->{String}}); $i++) {
|
|
Packit |
857059 |
my $str = $File->{String}->[$i];
|
|
Packit |
857059 |
|
|
Packit |
857059 |
next if (not exists $str->{Arglist});
|
|
Packit |
857059 |
|
|
Packit |
857059 |
my @args = get_names(%$str);
|
|
Packit |
857059 |
my @fmt = find_formattable($str->{String}{$languages[0]});
|
|
Packit |
857059 |
my @ptr = find_pointer($str->{String}{$languages[0]});
|
|
Packit |
857059 |
my @rvArgs = @args;
|
|
Packit |
857059 |
foreach my $arg (@fmt) {
|
|
Packit |
857059 |
$rvArgs[$arg-1] = 'LOG_FORMATTABLE('. $rvArgs[$arg-1] . ')';
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
foreach my $arg (@ptr) {
|
|
Packit |
857059 |
$rvArgs[$arg-1] = 'LOG_PTR('. $rvArgs[$arg-1] . ')';
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
for (my $arg = scalar(@rvArgs); $arg < 6; $arg++) {
|
|
Packit |
857059 |
$rvArgs[$arg] = 0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
printf "/* %s_STR_%s", $ucModName, $str->{Name};
|
|
Packit |
857059 |
if (exists $str->{Comment}) {
|
|
Packit |
857059 |
print ": $str->{Comment}";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (exists $str->{Arglist}) {
|
|
Packit |
857059 |
print "\n * Arguments: \n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@{$str->{Arglist}}); $i++) {
|
|
Packit |
857059 |
printf " *\t%s\n", $str->{Arglist}[$i];
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print " */\n";
|
|
Packit |
857059 |
printf "#define %s_FMT_%s(buffer, %s)\\\n\t", $ucModName, $str->{Name}, join(', ', @args);
|
|
Packit |
857059 |
printf "LOG_FORMATBUF(buffer, Log_GetString(%s_STR_%s, (buffer).GetLanguage()), %s)\n",
|
|
Packit |
857059 |
$ucModName, $str->{Name}, join(', ', @rvArgs);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
print <<"EOF";
|
|
Packit |
857059 |
GEN_EXTERNC(extern void ${modName}_AddMessages();)
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#endif /* ${ucModName}_MESSAGES_H_INCLUDED */
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
# Mod_Messages.c
|
|
Packit |
857059 |
#
|
|
Packit |
857059 |
select $source;
|
|
Packit |
857059 |
print <<"EOF";
|
|
Packit |
857059 |
/*!
|
|
Packit |
857059 |
\@file $modName/$fileBase.c
|
|
Packit |
857059 |
\@brief Nationalizable Strings and Messages for $modName Package generated from $msgFile
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#include "$fileBase.h"
|
|
Packit |
857059 |
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (exists $File->{Message}) {
|
|
Packit |
857059 |
# Loop through and add all the trap fun ptr prototypes at the top
|
|
Packit |
857059 |
foreach my $msg (@{$File->{Message}}) {
|
|
Packit |
857059 |
if(not $msg->{Trapfunc} eq "LOG_TRAP_NONE"){
|
|
Packit |
857059 |
printf "extern Log_TrapFunc_t %s;\n", $msg->{Trapfunc};
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\n\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
print <<"EOF";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
/*!
|
|
Packit |
857059 |
Module specific message table, referenced by Log_MessageId_t.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
The entries in the table must provide equivalent argument usage for
|
|
Packit |
857059 |
all languages. Argument usage in format strings is used to determine
|
|
Packit |
857059 |
which arguments may need to be freed
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
static Log_MessageEntry_t ${lcModName}_messageTable[] =
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
foreach my $msg (@{$File->{Message}}) {
|
|
Packit |
857059 |
printf "\t{\t%s_MSG_%s,%s\n", $ucModName, $msg->{Name},
|
|
Packit |
857059 |
exists $msg->{Comment} ? "\t/* $msg->{'comment'} */" : '';
|
|
Packit |
857059 |
printf "\t\t%d,\t/* argument number which holds unit number, 0 -> none */\n", $msg->{Unitarg};
|
|
Packit |
857059 |
printf "\t\t%s,\t/* trap func associated with message */\n", $msg->{Trapfunc};
|
|
Packit |
857059 |
print "\t\t/* FUTURE - Binary Data */\n";
|
|
Packit |
857059 |
if (exists $msg->{Arglist}) {
|
|
Packit |
857059 |
my $args = $msg->{Arglist};
|
|
Packit |
857059 |
print "\t\t/* Arguments: \n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@$args); $i++) {
|
|
Packit |
857059 |
printf "\t\t *\targ%d -> %s\n", $i + 1, $args->[$i];
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\t\t */\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else {
|
|
Packit |
857059 |
print "\t\t/* Arguments: None */\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\t\t{ /* Language Specific Entries */\n";
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
print "\t\t\t{ /* LOG_LANG_$lang */\n";
|
|
Packit |
857059 |
printf "\t\t\t\t/* description */ %s,\n", $msg->{Description}->{$lang};
|
|
Packit |
857059 |
printf "\t\t\t\t/* response */ %s,\n", $msg->{Response}->{$lang};
|
|
Packit |
857059 |
printf "\t\t\t\t/* correction */ %s,\n", $msg->{Correction}->{$lang};
|
|
Packit |
857059 |
print "\t\t\t},\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\t\t},\n\t},\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "};\n\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
print <<"EOF";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
/*!
|
|
Packit |
857059 |
Module specific string table, referenced by Log_StringId_t.
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
static Log_StringEntry_t ${lcModName}_stringTable[] =
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
foreach my $str (@{$File->{String}}) {
|
|
Packit |
857059 |
printf "\t{\t%s_STR_%s,%s\n", $ucModName, $str->{Name},
|
|
Packit |
857059 |
exists $str->{Comment} ? "\t/* $str->{Comment} */" : '';
|
|
Packit |
857059 |
if (defined $str->{Arglist}) {
|
|
Packit |
857059 |
my $args = $str->{Arglist};
|
|
Packit |
857059 |
print "\t\t/* Arguments: \n";
|
|
Packit |
857059 |
for (my $i = 0; $i < scalar(@$args); $i++) {
|
|
Packit |
857059 |
printf "\t\t *\targ%d -> %s\n", $i + 1, $args->[$i];
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\t\t */\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
my $lch = '{';
|
|
Packit |
857059 |
foreach my $lang (@languages) {
|
|
Packit |
857059 |
printf "\t\t$lch /* LOG_LANG_$lang */ %s,\n", $str->{String}->{$lang};
|
|
Packit |
857059 |
$lch = ' ';
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "\t\t},\n\t},\n";
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "};\n\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
print <<'EOF';
|
|
Packit |
857059 |
/*!
|
|
Packit |
857059 |
Add String table to logging subsystem's tables.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
This must be run early in the boot to initialize tables prior to
|
|
Packit |
857059 |
any logging functions being available.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
@return None
|
|
Packit |
857059 |
|
|
Packit |
857059 |
@heading Concurrency Considerations
|
|
Packit |
857059 |
Must be run once, early in boot
|
|
Packit |
857059 |
|
|
Packit |
857059 |
@heading Special Cases and Error Handling
|
|
Packit |
857059 |
None
|
|
Packit |
857059 |
|
|
Packit |
857059 |
@see Log_AddStringTable
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
EOF
|
|
Packit |
857059 |
|
|
Packit |
857059 |
printf "void\n%s_AddMessages()\n{\n", $modName;
|
|
Packit |
857059 |
printf "\tLog_AddStringTable(MOD_%s, %s_stringTable,\n".
|
|
Packit |
857059 |
"\t\t\t\t\t\tGEN_NUMENTRIES(%s_stringTable));\n",
|
|
Packit |
857059 |
$ucModName, $lcModName, $lcModName;
|
|
Packit |
857059 |
if (exists $File->{Message}) {
|
|
Packit |
857059 |
printf "\tLog_AddMessageTable(MOD_%s, %s_messageTable,\n".
|
|
Packit |
857059 |
"\t\t\t\t\t\tGEN_NUMENTRIES(%s_messageTable));\n",
|
|
Packit |
857059 |
$ucModName, $lcModName, $lcModName;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
print "}\n";
|
|
Packit |
857059 |
|
|
Packit |
857059 |
select $oldfh;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
close $header;
|
|
Packit |
857059 |
close $source;
|