| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #  You may distribute under the terms of either the GNU General Public License | 
| 2 |  |  |  |  |  |  | #  or the Artistic License (the same terms as Perl itself) | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | #  (C) Paul Evans, 2015 -- leonerd@leonerd.org.uk | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | package IO::Async::Debug; | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 83 |  |  | 83 |  | 595 | use strict; | 
|  | 83 |  |  |  |  | 196 |  | 
|  | 83 |  |  |  |  | 2556 |  | 
| 9 | 83 |  |  | 83 |  | 452 | use warnings; | 
|  | 83 |  |  |  |  | 166 |  | 
|  | 83 |  |  |  |  | 38621 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | our $VERSION = '0.79'; | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | our $DEBUG = $ENV{IO_ASYNC_DEBUG} || 0; | 
| 14 |  |  |  |  |  |  | our $DEBUG_FD   = $ENV{IO_ASYNC_DEBUG_FD}; | 
| 15 |  |  |  |  |  |  | our $DEBUG_FILE = $ENV{IO_ASYNC_DEBUG_FILE}; | 
| 16 |  |  |  |  |  |  | our $DEBUG_FH; | 
| 17 |  |  |  |  |  |  | our %DEBUG_FLAGS = map { $_ => 1 } split m/,/, $ENV{IO_ASYNC_DEBUG_FLAGS} || ""; | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | =head1 NAME | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | C - debugging control and support for L | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | The following methods and behaviours are still experimental and may change or | 
| 26 |  |  |  |  |  |  | even be removed in future. | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | Debugging support is enabled by an environment variable called | 
| 29 |  |  |  |  |  |  | C having a true value. | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | When debugging is enabled, the C and C methods | 
| 32 |  |  |  |  |  |  | on L (and their C variants) are altered such that | 
| 33 |  |  |  |  |  |  | when the event is fired, a debugging line is printed, using the C | 
| 34 |  |  |  |  |  |  | method. This identifes the name of the event. | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | By default, the line is only printed if the caller of one of these methods is | 
| 37 |  |  |  |  |  |  | the same package as the object is blessed into, allowing it to print the | 
| 38 |  |  |  |  |  |  | events of the most-derived class, without the extra verbosity of the | 
| 39 |  |  |  |  |  |  | lower-level events of its parent class used to create it. All calls regardless | 
| 40 |  |  |  |  |  |  | of caller can be printed by setting a number greater than 1 as the value of | 
| 41 |  |  |  |  |  |  | C. | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | By default the debugging log goes to C, but two other environment | 
| 44 |  |  |  |  |  |  | variables can redirect it. If C is set, it names a file | 
| 45 |  |  |  |  |  |  | which will be opened for writing, and logging written into it. Otherwise, if | 
| 46 |  |  |  |  |  |  | C is set, it gives a file descriptor number that logging | 
| 47 |  |  |  |  |  |  | should be written to. If opening the named file or file descriptor fails then | 
| 48 |  |  |  |  |  |  | the log will be written to C as normal. | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | Extra debugging flags can be set in a comma-separated list in an environment | 
| 51 |  |  |  |  |  |  | variable called C. The presence of these flags can cause | 
| 52 |  |  |  |  |  |  | extra information to be written to the log. Full details on these flags will | 
| 53 |  |  |  |  |  |  | be documented by the implementing classes. Typically these flags take the form | 
| 54 |  |  |  |  |  |  | of one or more capital letters indicating the class, followed by one or more | 
| 55 |  |  |  |  |  |  | lowercase letters enabling some particular feature within that class. | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | =cut | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | sub logf | 
| 60 |  |  |  |  |  |  | { | 
| 61 | 0 |  |  | 0 | 0 |  | my ( $fmt, @args ) = @_; | 
| 62 |  |  |  |  |  |  |  | 
| 63 | 0 |  | 0 |  |  |  | $DEBUG_FH ||= do { | 
| 64 | 0 |  |  |  |  |  | my $fh; | 
| 65 | 0 | 0 |  |  |  |  | if( $DEBUG_FILE ) { | 
|  |  | 0 |  |  |  |  |  | 
| 66 | 0 | 0 |  |  |  |  | open $fh, ">", $DEBUG_FILE or undef $fh; | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  | elsif( $DEBUG_FD ) { | 
| 69 | 0 |  |  |  |  |  | $fh = IO::Handle->new; | 
| 70 | 0 | 0 |  |  |  |  | $fh->fdopen( $DEBUG_FD, "w" ) or undef $fh; | 
| 71 |  |  |  |  |  |  | } | 
| 72 | 0 |  | 0 |  |  |  | $fh ||= \*STDERR; | 
| 73 | 0 |  |  |  |  |  | $fh->autoflush; | 
| 74 | 0 |  |  |  |  |  | $fh; | 
| 75 |  |  |  |  |  |  | }; | 
| 76 |  |  |  |  |  |  |  | 
| 77 | 0 |  |  |  |  |  | printf $DEBUG_FH $fmt, @args; | 
| 78 |  |  |  |  |  |  | } | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | sub log_hexdump | 
| 81 |  |  |  |  |  |  | { | 
| 82 | 0 |  |  | 0 | 0 |  | my ( $bytes ) = @_; | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 0 |  |  |  |  |  | foreach my $chunk ( $bytes =~ m/(.{1,16})/sg ) { | 
| 85 | 0 |  |  |  |  |  | my $chunk_hex = join " ", map { sprintf "%02X", ord $_ } split //, $chunk; | 
|  | 0 |  |  |  |  |  |  | 
| 86 | 0 |  |  |  |  |  | ( my $chunk_safe = $chunk ) =~ s/[^\x20-\x7e]/./g; | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 0 |  |  |  |  |  | logf "  | %-48s | %-16s |\n", $chunk_hex, $chunk_safe; | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  | } | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | =head1 AUTHOR | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | Paul Evans | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | =cut | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | 0x55AA; |