]> git.vpit.fr Git - perl/scripts/xchat.git/blob - Xchat/XPI.pm
No trailing whitespace
[perl/scripts/xchat.git] / Xchat / XPI.pm
1 package Xchat::XPI;
2
3 use strict;
4 use warnings;
5
6 use Tie::RefHash;
7
8 use Xchat;
9
10 our $VERSION = '0.05';
11
12 use constant { COLOR_TAG => "\00307" };
13
14 my @attributes;
15 BEGIN {
16  @attributes = qw<tag name version desc author email url banner>;
17 }
18
19 local *PH;
20
21 sub new {
22  my $class = shift;
23  $class    = ref($class) || $class;
24  my %opts  = @_;
25
26  my $caller = (caller 0)[0];
27  unless (defined $opts{tag}) {
28   $opts{tag}     = ($caller =~ /([^:]*):*$/) ? $1 : 'UNKNOWN';
29  }
30  unless (defined $opts{name}) {
31   $opts{name}    = $opts{tag};
32  }
33  unless (defined $opts{desc}) {
34   $opts{desc}    = $opts{name};
35  }
36  unless (defined $opts{version}) {
37   my $version    = do { no strict 'refs'; ${$caller.'::VERSION'} };
38   $version       = '0.01' unless defined $version;
39   $opts{version} = $version;
40  }
41  unless (defined $opts{banner}) {
42   my $email      = $opts{email};
43   $email         = "<$email>" if defined $email;
44   my $who        = join ', ', grep defined, $opts{author}, $email, $opts{url};
45   $who           = " ($who)"  if length $who;
46   $opts{banner}  = $opts{desc} . $who;
47  }
48
49  my $ph = bless \do { local *PH }, $class;
50  tie *$ph, $ph, @_;
51
52  *$ph->{$_}  = $opts{$_} for @attributes;
53  *$ph->{buf} = '';
54
55  Xchat::register(@opts{qw<name version banner>}, sub {
56   $ph->flush;
57   if (*$ph->{atexit_id}) {
58    my @callbacks = sort { *$ph->{atexit}{$b} <=> *$ph->{atexit}{$a} }
59                     keys %{*$ph->{atexit}};
60    $_->($ph) for @callbacks;
61   }
62   undef $ph;
63  });
64  $ph->add_atexit($opts{unload}) if $opts{unload};
65
66  $ph->print("\002", $ph->name, ' v', $ph->version,
67             " loaded\002 (", $ph->banner, ")\n");
68
69  return $ph;
70 }
71
72 BEGIN {
73  local $@;
74  eval "sub $_ { my \$ph = \$_[0]; *\$ph->{$_} }; 1" or die $@ for @attributes;
75 }
76
77 sub print {
78  my $ph = shift;
79
80  @_ = ($_) unless @_;
81
82  my $ret  = 0;
83  my $data = join '', *$ph->{buf}, @_;
84
85  while ((my $i = index $data, "\n") >= 0) {
86   Xchat::print(COLOR_TAG . $ph->tag . "\t" . (substr $data, 0, ($i + 1), ''));
87   $ret = 1;
88  }
89
90  *$ph->{buf} = $data;
91
92  return $ret;
93 }
94
95 sub printf { shift->print(sprintf @_) }
96
97 sub flush {
98  my ($ph) = @_;
99
100  if (length $ph->{buf}) {
101   $ph->print("\n");
102  } else {
103   return;
104  }
105 }
106
107 sub add_atexit {
108  my ($ph, $callback) = @_;
109
110  if (!*$ph->{atexit_id}) {
111   tie my %h, 'Tie::RefHash';
112   *$ph->{atexit} = \%h;
113  }
114
115  return *$ph->{atexit}{$callback} = ++*$ph->{atexit_id};
116 }
117
118 sub remove_atexit {
119  my ($ph, $callback) = @_;
120
121  if (exists *$ph->{atexit}{$callback}) {
122   delete *$ph->{atexit}{$callback};
123   return 1;
124  }
125
126  return 0;
127 }
128
129 sub TIEHANDLE {
130  my $ph = shift;
131  (defined $ph && $ph->isa(__PACKAGE__)) ? $ph : shift->new(@_);
132 }
133
134 sub PRINT  { shift->print(@_) }
135
136 sub PRINTF { shift->printf(@_) }
137
138 1;