All pastes #926900 Raw Edit

decoder

public text v1 · immutable
·published 2008-03-03 22:06 UTC
rendered paste body
use strict;
use warnings;
use Class::Date qw(now);

# global tokens
my %TOKE = (
  Z => { # my title
    val => 'Data::Logger',
    prm => 1
  },
  A => { # message
    val => 'Thanks for using Data::Logger!',
    prm => 1
  },
  F => { # users current "function title"
    val => 'main',
    prm => 0
  },
  S => { # users script name, doesn't need to be anything special
    val => 'testz0rz.pl', #basename($main::0),#'super cool script.pl',#'fake name',
    prm => 1
  },
  L => { # log level: info, debug, warning, fatal
    val => 'INFO',
    prm => 1
  },
  E => { # $! from the users script, or custom error message
    val => undef,
    prm => 1
  },
  Y => {
    val => _mk_dt('year'),
    prm => 1
  },
  M => {
    val => _mk_dt('month'),
    prm => 1
  },
  D => {
    val => _mk_dt('day'),
    prm => 1
  },
  h => {
    val => _mk_dt('hour'),
    prm => 1
  },
  m => {
    val => _mk_dt('minute'),
    prm => 1
  },
  s => {
    val => _mk_dt('second'),
    prm => 1
  }
); # Y, M, D, h, m, and s are ugly but work


print _decode('\\{%Y-%M-%D\\}[%h:%m:%s]{ %F:} (%L) - %A{ \\{%E\\}}');

# the decoder
sub _decode {
  my $tdc = shift;
  while ($tdc =~ s/(?<!\\)\{(.*?)(?<!\\)\}/\\CURRENT\//o) {
    my $blk = $1;

    if ($blk =~ /\%(\S)/o) {
      my $tok = $1;
      if ($TOKE{$tok}->{prm} and defined $TOKE{$tok}->{val}) {
        if (ref $TOKE{$tok}->{val} eq 'CODE') {
          $blk =~ s/\%$tok/&{$TOKE{$tok}->{val}}/e;
        } else {
          $blk =~ s/\%$tok/$TOKE{$tok}->{val}/;
        }

        $tdc =~ s/\\CURRENT\//$blk/;
      }
    }

    $tdc =~ s/\\CURRENT\///go; # /g just for safety
  }
  while ($tdc =~ /\%(\S)/o) {
    my $tok = $1;
    if ($TOKE{$tok}->{prm}) {
      if (defined $TOKE{$tok}->{val}) {
        if (ref $TOKE{$tok}->{val} eq 'CODE') {
          $tdc =~ s/\%$tok/&{$TOKE{$tok}->{val}}/eg;
        } else {
          $tdc =~ s/\%$tok/$TOKE{$tok}->{val}/g;
        }
      } else {
        $tdc =~ s/\%$tok/\?/g; # tag is supposed to be defined
      }
    } else {
      $tdc =~ s/\%$tok//g; # tag isn't active
    }
  }

  $tdc =~ s/\\\{/\{/go; # would s/\\(\{|\}/$1/g; be faster?
  $tdc =~ s/\\\}/\}/go; #
  return $tdc;
}

# for datetime
sub _mk_dt {
  my $gm = shift or return;
  return sub {
    my %dt;
    @dt{
      qw(
        year   #0
        month  #1
        day    #2
        hour   #3
        minute #4
        second #5
      )
    } = split(/(?:\s|:|-|;)+/,now);

    return $dt{$gm};
  }
}