All pastes #926973 Raw Edit

decoder

public text v1 · immutable
·published 2008-03-03 22:57 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 _take_a_toke { #ha!
  my $smokin = shift;
  $smokin =~ s/(?<!\\)\{(.*?)(?<!\\)\}/_block_decode($1)/ge; #wrapper
  $smokin =~ s/(?<!\\)\%(.)/_decode($1)/ge;
  $smokin =~ s/(?<!\\)\\(.)/$1/g;
  return $smokin;
}

sub _decode {
  my $tok = shift; #enough of that joke
  if (exists $TOKE{$tok} and $TOKE{$tok}->{prm}) { #exists & active
    if (defined $TOKE{$tok}->{val}) { #defined
      return &{$TOKE{$tok}} if ref $TOKE{$tok} eq 'CODE';
      return $TOKE{$tok};
    } else {
      return '?'; # active, but no value (suggests problem)
    }
  } else {
    return; # doesn't exist or not active
  }
}

sub _block_decode {
#NO NEVER!  my $blk = _take_a_toke(shift); #recursive
  my $blk = shift;
  if ($blk =~ /(?<!\\)\%(.)/o) { # first succeeds and all are parsed
    my $dcd = _decode($1);
    return unless $dcd;
    return if $dcd eq '?';
  } else {
    return;
  }

  return $blk; # parent will parse the rest
}

# 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{lc($gm)};
  }
}