###########################################################################
#
# Formatting.pm
#
# Copyright (C) 1999 Raphael Manfredi.
# Copyright (C) 2002-2017 Mark Rogaski, mrogaski@cpan.org;
# all rights reserved.
#
# See the README file included with the
# distribution for license information.
#
##########################################################################
use
strict;
require
Exporter;
########################################################################
package
Log::Agent::Formatting;
@ISA
=
qw(Exporter)
;
@EXPORT_OK
=
qw(format_args tag_format_args)
;
require
Log::Agent::Message;
#
# adjust_fmt
#
# We process syslog's %m macro as being the current error message ($!) in
# the first argument only. Doing it at this level means it will be supported
# independently from the driver they'll choose. It's also done BEFORE any
# log-related system call, thus ensuring that $! retains its original value.
#
if
($] >= 5.005) {
eval
q{ # if VERSION >= 5.005
# 5.005 and later version grok /(?<!)/
sub adjust_fmt {
my $fmt = shift;
$fmt =~ s/((?<!%)(?:%%)*)%m/$Log::Agent::OS_Error/g;
return $fmt;
}
}
}
else
{
eval
q{ # else /* VERSION < 5.005 */
# pre-5.005 does not grok /(?<!)/
sub adjust_fmt {
my $fmt = shift;
$fmt =~ s/%%/\01/g;
$fmt =~ s/%m/$Log::Agent::OS_Error/g;
$fmt =~ s/\01/%%/g;
return $fmt;
}
}
}
# endif /* VERSION >= 5.005 */
#
# whine
#
# This is a local hack of carp
#
sub
whine {
my
$msg
=
shift
;
unless
(
chomp
$msg
) {
my
(
$package
,
$filename
,
$line
) =
caller
2;
$msg
.=
" at $filename line $line."
;
}
warn
"$msg\n"
;
}
#
# tag_format_args
#
# Arguments:
#
# $caller caller information, done firstly
# $priority priority information, done secondly
# $tags list of user-defined tags, done lastly
# $ary arguments for sprintf()
#
# Returns a Log::Agent::Message object, which, when stringified, prints
# the string itself.
#
sub
tag_format_args {
my
(
$caller
,
$priority
,
$tags
,
$ary
) =
@_
;
my
$msg
= adjust_fmt(
shift
@$ary
);
# This bit of tomfoolery is intended to make debugging of
# programs a bit easier by prechecking input to sprintf()
# for errors. I usually prefer lazy error checking, but
# this seems to be an appropriate exception.
if
(
my
@arglist
=
$msg
=~ /\%[^\%]*[csduoxefgXEGbpniDUOF]|\%\%/g) {
BEGIN {
no
warnings }
my
$argcnt
=
grep
!/\%\%/,
@arglist
;
if
(
grep
{!
defined
}
@$ary
[0..(
$argcnt
- 1)]) {
whine(
"Use of uninitialized value in sprintf"
);
}
$msg
=
sprintf
$msg
,
@$ary
;
}
my
$str
= Log::Agent::Message->make(
$msg
);
$caller
->insert(
$str
)
if
defined
$caller
;
$priority
->insert(
$str
)
if
defined
$priority
;
if
(
defined
$tags
) {
foreach
my
$tag
(
@$tags
) {
$tag
->insert(
$str
);
}
}
return
$str
;
}
1;