File Coverage

blib/lib/Text/Quote.pm
Criterion Covered Total %
statement 248 254 97.6
branch 99 134 73.8
condition 26 37 70.2
subroutine 30 32 93.7
pod 11 11 100.0
total 414 468 88.4


line stmt bran cond sub pod time code
1             package Text::Quote;
2             $Text::Quote::VERSION = '0.32';
3 1     1   29526 use 5.006;
  1         4  
  1         40  
4 1     1   12 use strict;
  1         2  
  1         24  
5 1     1   5 use warnings;
  1         11  
  1         25  
6 1     1   1805 use Compress::Zlib;
  1         86526  
  1         308  
7 1     1   1127 use MIME::Base64;
  1         981  
  1         74  
8 1     1   8 use Carp();
  1         2  
  1         19  
9 1     1   963 use Carp::Assert;
  1         1177  
  1         5  
10 1     1   132 use warnings::register;
  1         2  
  1         2774  
11              
12              
13             =head1 NAME
14              
15             Text::Quote - Quotes strings as required for perl to eval them back correctly
16              
17             =head1 SYNOPSIS
18              
19             use Text::Quote;
20              
21             my @quotes=map{$quoter->quote($_,indent=>6,col_width=>60)}('
22             "The time has come"
23             the walrus said,
24             "to speak of many things..."
25             ',"\0\1\2\3\4\5\6\a\b\t\n\13\f\r\16\17\20\21\22\23\24\25\26\27\30\31\32\e\34\35\36\37",
26             ("\6\a\b\t\n\13\f\r\32\e\34" x 5),2/3,10,'00');
27             for my $i (1..@quotes) {
28             print "\$var$i=".$quotes[$i-1].";\n";
29             }
30              
31             Would produce:
32              
33             $var1=qq'"The time has come"\n\tthe\twalrus said,\n\t"to speak of man'.
34             qq'y things..."';
35             $var2="\0\1\2\3\4\5\6\a\b\t\n\13\f\r\16\17\20\21\22\23\24\25\26\27".
36             "\30\31\32\e\34\35\36\37";
37             $var3=("\6\a\b\t\n\13\f\r\32\e\34" x 5);
38             $var4=0.666666666666667;
39             $var5=10;
40             $var6='00';
41              
42              
43             =head1 DESCRIPTION
44              
45             Text::Quote is intended as a utility class for other classes that need to be able
46             to produce valid perl quoted strings. It posses routines to determine the ideal quote
47             character to correctly quote hash keys, to correctly quote and encode binary strings.
48              
49             This code was inspired by an analysis of L by Gisle Aas.
50             In some cases it was much more than inspired. :-)
51              
52             =head1 METHODS
53              
54             =cut
55              
56             # This code derives from a number of sources
57             # 1. Data::Dump by Gisle Aas
58             # 2. MIME::Base64 by Gisle Aas
59             # Its primary intention is to isolate out the basic functionality
60             # of correctly, succintly and neatly quoting a non reference
61             # scalar variable.
62             #
63             # In this context "quoting" has a looser definition than the standard
64             # perl idea. A string is considered by this module to be correctly
65             # quoted IFF the result of _evaling_ the resultant "quoted" text produces
66             # the exact same string.
67             # ie:
68             # my $quoted=Text::Quote->quote($string);
69             # my $result=eval($string);
70             # print "Text::Quote ",($string eq $result) ? "works!" : "sucks! :(","\n";
71             #
72             ##
73             sub _stamp {
74 126     126   141 my $i = 1;
75 126         180 my @list = ('----');
76 126         735 while ( my ( $package, $filename, $line, $subroutine ) = caller($i) ) {
77 246         429 push @list, "($i) $subroutine";
78 246         1051 $i++;
79             }
80              
81             #warn $subroutine."\n";
82             #warn join ( "\n", @list ), "\n";
83             }
84              
85              
86              
87              
88              
89              
90              
91              
92             # adds the method call and quoting symbols around a block of text.
93             sub _textquote_format_method {
94 3     3   7 my ( $self, $method, $str, %opts ) = @_;
95              
96 3 100       10 $method .= '(' . ( ( $method eq "pack" ) ? "'H*'," : "" );
97 3 100 33     25 $method = ( ref($self) || $self ) . "->" . $method
98             unless $method =~ /^pack/;
99 3         6 $opts{leading} = length($method);
100             #$opts{indent} += 2;
101 3         10 return $method . $self->quote_simple( $str, %opts, is_encoded => 1 ) . ")";
102              
103             }
104              
105             sub _textquote_compress {
106 1     1   45 my ( $self, $str, %opts ) = @_;
107 1 50       4 return unless $str;
108 1         2 my $method = "";
109 1         7 ( $method, $str ) = $self->_textquote_encode64( Compress::Zlib::compress($str), %opts );
110 1         3 $method = "decompress64";
111 1 50       5 return wantarray ? ( $method, $str ) : $self->_textquote_format_method( $method, $str, %opts );
112             }
113              
114             # Encodes a string in base64
115             sub _textquote_encode64 {
116 2     2   888 my ( $self, $str, %opts ) = @_;
117 2         21 $str = MIME::Base64::encode( $str, "" );
118             return
119             wantarray
120 2 50       12 ? ( "decode64", $str )
121             : $self->_textquote_format_method( "decode64", $str, %opts );
122             }
123              
124              
125             #
126             # _textquote_encode
127             # Encodes a string, either by compression or by pack
128             #
129             sub _textquote_encode {
130              
131 2     2   6 my ( $self, $str, %opts ) = @_;
132              
133 2         5 $self->_stamp;
134 2         3 my $method;
135             my $encoded;
136 2 50       11 my $encode_at =defined($opts{encode_at})?$opts{encode_at}:$self->quote_prop("encode_at");
137 2 100       6 if ( length($str)*2 > $encode_at ) {
138 1         6 ( $method, $encoded ) = $self->_textquote_encode64( $str, %opts );
139             } else {
140 1         2 $method = "pack";
141 1         5 $encoded = unpack( "H*", $str );
142             }
143              
144             return (wantarray)
145 2 50       9 ? ( $method, $encoded )
146             : $self->_textquote_format_method( $method, $encoded, %opts );
147             }
148              
149             #
150             # Tries to find a repeated pattern in the text
151             #
152             sub _textquote_pattern { #not a pattern, really a multiple
153 7     7   10 my $self = shift;
154              
155 7         11 $self->_stamp;
156 7         12 local $_ = shift;
157 7 50       12 return unless $_;
158 7         15 my %opts = @_;
159              
160 7 50       14 return if $opts{no_repeat};
161              
162             # Check for repeated string
163 7 50       16 my $rl = ( exists( $opts{repeat_len} ) ) ? $opts{repeat_len} : $self->quote_prop("repeat_len");
164              
165 7 100       84 if (/\A(.{1,$rl}?)(\1*)\z/s) {
166              
167 2         11 my $base = $self->quote_simple($1);
168              
169 2         9 my $repeat = length($2) / length($1) + 1;
170              
171 2         10 return "($base x $repeat)";
172             }
173              
174 5         12 return;
175             }
176              
177              
178             #
179             # Escapes a string
180             # takes the string, the type of quote (qq or q) and the symbol used
181             #
182             sub _textquote_escaped {
183 18     18   20 my $self = shift;
184              
185 18         28 $self->_stamp;
186 18         28 local $_ = ( my $str = shift );
187 18         21 my $type = shift;
188 18         17 my $qsymb = shift;
189              
190             # Now we need to escape our quote char in string.
191 18         103 ( my $escaped = $qsymb ) =~ s/(.)/\\$1/g;
192              
193             #and escape variables and our quote chars
194 18 100       35 if ( "qq" eq $type ) {
195 6         47 s/([$escaped\\\@\$])/\\$1/g;
196             } else { # dont have to escape variables
197 12         46 s/([$escaped\\])/\\$1/g;
198             }
199              
200             # fast exit for straight chars
201 18 50       34 if ($self->quote_prop("encode_high")) {
202 0 0       0 return ($_) unless /[^\t\040-\176]/;
203             } else {
204 18 100       77 return ($_) unless /[^\t\040-\377]/;
205             }
206              
207 6         40 my $esc_class = $self->quote_prop("esc_class");
208 6         12 my $esc_chars = $self->quote_prop("esc_chars");
209 6         118 s/($esc_class)/$esc_chars->{$1}/g; # escape interpolatable symbols
210              
211             # octal escapes -- harder to read but shorter
212             # no need for 3 digits in escape for these
213 6         16 s/([\0-\037])(?!\d)/'\\'.sprintf('%o',ord($1))/eg;
  129         309  
214              
215             # still go for the low ones cause there could be a digit following,
216             # either way use 3 digits
217 6         20 s/([\0-\037\177-\377])/'\\'.sprintf('%03o',ord($1))/eg;
  129         408  
218              
219 6         31 return $_;
220             }
221              
222             sub _textquote_number {
223              
224             #returns undef or the value of the number
225              
226 50     50   74 my ( $self, $num ) = @_;
227              
228 50 100 66     314 if ( defined $num && $num =~ /\A-?(?:0|[1-9]\d{0,8})(\.\d{0,18})?\z/ ) {
229 29         61 return $num;
230             }
231 21         32 return;
232             }
233              
234              
235              
236              
237             =head2 quote(STR,OPTS)
238              
239             Quotes a string. Will encode or compress or otherwise change the strings representation
240             as the options specify. If an option is omitted the class default is used if it exists then
241             an internal procedure default is used.
242              
243             Normal behaviour is as follows
244              
245             =over 4
246              
247             =item Numbers
248              
249             Not quoted
250              
251             =item Short Repeated Substr
252              
253             Converted into a repeat statement C<($str x $repeat)>
254              
255             =item Simple Strings
256              
257             Single quoted, or double quoted if multiline or containing small numbers of other
258             control characters (tabs excluded).
259              
260             =item Binary Strings
261              
262             Converted into hex using L or if larger into Base64 using L
263              
264             =item Large Strings
265              
266             Converted to a call to L.
267              
268             =back
269              
270             The output and OPTS will passed on to L for formatting if it
271             is multiline. No indentation of the first line is done.
272              
273             See L for options.
274              
275             =cut
276              
277              
278             sub quote {
279              
280             # Main routine, the essence of this is that a returns back a quoted construct
281             # it calls all the others as it needs/or can depending on the size of the string,
282             # the type of data it contains and any options passed.This can include reducing the
283             # the string to a ("ABC" x $count) or conterting it to a different format, such as
284             # hex or base64, or even compressing it.
285 41     41 1 3078 my $self = shift->_self_obj;
286 41         52 my $str = shift(@_);
287              
288 41         81 $self->_stamp;
289              
290              
291 41 100       74 return 'undef' unless defined $str;
292 40         199 $str="".$str;
293              
294 40 50       97 Carp::croak "cant use odd number of parameters:" . scalar(@_)
295             unless @_ % 2 == 0;
296 40         63 my %opts = @_;
297              
298 40 50       110 my $compress_at =
299             defined( $opts{compress_at} ) ? $opts{compress_at} : $self->quote_prop("compress_at");
300 40 50       99 my $encode_at = defined( $opts{encode_at} ) ? $opts{encode_at} : $self->quote_prop("encode_at");
301 40 50       89 my $repeat_at =
302             defined( $opts{repeat_at} ) ? $opts{repeat_at} : $self->quote_prop("repeat_at");
303              
304 40         71 my $ret = $self->_textquote_number($str);
305 40 100       221 return $ret if defined $ret;
306              
307 11   100     32 $opts{indent} ||= 0;
308              
309 11 100 66     44 if ( $compress_at && length($str) > $compress_at ) {
310              
311 1         5 my $ret = $self->_textquote_compress( $str, %opts );
312              
313 1 50       4 $opts{reqs}->{__PACKAGE__}++ if $opts{reqs};
314              
315 1 50       6 return $ret if $ret;
316             }
317              
318 10 100 66     37 if ( $repeat_at && length($str) > $repeat_at ) {
319              
320 7         23 my $ret = $self->_textquote_pattern( $str, %opts );
321 7 100       29 return $ret if defined $ret;
322              
323             }
324              
325 8         20 my ( $qq, $qb, $qe, $nqq ) = $self->best_quotes( $str, %opts );
326 8         22 my $escaped = $self->_textquote_escaped( $str, $qq, $qb . $qe );
327              
328 8 100 66     43 if ( $encode_at
      33        
329             && ( length($escaped) > $encode_at
330             && length($escaped) > ( length($str) * 2 ) ) )
331             {
332              
333             # too much binary data, better to represent as a hex string?
334             # Base64 is more compact than hex when string is longer than
335             # 17 bytes (not counting any require statement needed).
336             # But on the other hand, hex is much more readable.
337 2         8 my ( $method, $str ) = $self->_textquote_encode( $str, %opts );
338 2 50 66     17 $opts{reqs}->{__PACKAGE__}++ if $method && $method ne "pack" && $opts{reqs};
      66        
339 2 50       10 return $self->_textquote_format_method( $method, $str, %opts ) if $method;
340             }
341              
342 6 100       26 return $self->quote_columns( $escaped, ( $nqq ? $qq . $qb : $qb ), $qe, %opts );
343              
344             }
345              
346              
347             =head2 quote_simple(STR,OPTS)
348              
349             Quotes a string. Does not attempt to encode it, otherwise the same L
350              
351             =cut
352              
353             sub quote_simple {
354 10     10 1 13 my $self = shift(@_);
355 10         17 my $str = "".shift(@_);
356 10         28 my %opts = @_;
357              
358 10         16 $self->_stamp;
359 10         19 my $ret = $self->_textquote_number($str);
360 10 50       17 return $ret if $ret;
361 10 100       33 my ( $qq, $qb, $qe, $nqq ) =
362             ( $opts{is_encoded} ? ( 'q', "'", "'", 0 ) : $self->best_quotes( $str, %opts ) );
363 10         61 my $escaped = $self->_textquote_escaped( $str, $qq, $qb . $qe );
364 10 50       36 return $self->quote_columns( $escaped, ( $nqq ? $qq . $qb : $qe ), $qe, %opts );
365             }
366              
367             =head2 quote_key(STR,OPTS)
368              
369             Quotes a string as though it was a hash key. In otherwords will only quote it
370             if it contains whitespace, funky characters or reserved words.
371              
372             See L for options.
373              
374             =cut
375              
376              
377             sub quote_key {
378 12     12 1 20 my $self = shift(@_);
379 12         22 my $key = "".shift(@_);
380 12         20 my %opts = @_;
381 12         21 $self->_stamp;
382              
383             #$key="$key";
384 12         25 my $rule=$self->quote_prop("key_quote");
385 12 50       56 return "''" if $key eq "";
386 12 100       31 unless ($rule) {
    100          
387 1         5 return $key;
388             } elsif ($rule eq 'auto') {
389 10 100 66     55 if ( $key =~ /\A(?:-[A-Za-z]+\w*|[_A-Za-z]+\w*|\d+)\z/ && !$self->quote_prop("key_quote_hash")->{$key} ) {
390 6         29 return $key;
391             } else {
392 4         10 return $self->quote_simple( $key, %opts );
393             }
394             } else {
395 1         4 return $self->quote_simple( $key, %opts );
396             }
397             }
398              
399             =head2 quote_regexp(STR)
400              
401             Quotes a regexp or string as though it was a regexp, includes the qr operator.
402             Will automatically select the appropriate quoting char.
403              
404             =cut
405              
406             sub quote_regexp {
407 1     1 1 2 my $self = shift;
408 1         3 my $rex = "".shift(@_);
409              
410             # a stringified regex will look like (?-xism: ... )
411             # when it was created by an optionless //
412             # this means that if we do bf_dump(eval(bf_dump(qr/.../)))
413             # we dont get the same regex (it will be nested again)
414             # so we strip the added layer off if it is (?-xism:
415             # note this means the regexp is safe:had there been any options
416             # the prefix would be different and we would ignore it.
417 1 50       3 if ( substr( $rex, 0, 8 ) eq "(?-xism:" ) {
418 0         0 $rex = substr( $rex, 8, length($rex) - 9 );
419             }
420              
421             # find the ideal quote symbol for the regex
422 1         7 my ( $qq, $qb, $qe, $nqq ) = $self->best_quotes( $rex, chars => [qw( / ! {} - & ; )] );
423 1         3 my $qs = quotemeta $qb . $qe;
424              
425             # escape any quote symbols in the regex, ideally there shouldnt
426             # be any because of _quote_best
427 1         11 $rex =~ s/([$qs])/\\$1/g;
428 1         5 return "qr$qb$rex$qe";
429             }
430              
431             =head2 quote_columns(STR,QB,QE,OPTS)
432              
433             Takes a preescaped string and chops it into lines with a specific maximum length
434             each line is independantly quoted and concatenated together, this allows the column
435             to be set at a precise indent and maximum width. It also handles slicing the string
436             at awkward points, such as in an escape sequence that might invalidate the quote.
437             Note the first line is not indented by default.
438              
439             STR is the string to quote. QB is the begin quote pattern. QE is end quote pattern.
440             OPTS can be
441              
442             col_width (defaults 76) Width of text excl. quote symbols and cat char
443             leading (defaults 0) Width of first line offset.
444             indent (defaults 0) Width of overall indentation
445             indent_first (defaults 0) Whether the first line is indented.
446              
447             =cut
448              
449              
450             sub quote_columns {
451 16     16 1 19 my $self=shift;
452 16         25 my $str="".shift(@_);
453 16         31 my ($qb, $qe, %opts ) = @_;
454              
455 16         28 $self->_stamp;
456 16         15 my @rows;
457 16         15 my $line = "";
458 16         17 my $pos = 0;
459 16   100     42 my $width = $opts{col_width} || 76;
460 16   100     44 my $lead = $opts{leading} || 0;
461 16   100     42 my $indent = $opts{indent} || 0;
462              
463             #$lead -= 2 if $lead > 2; #???
464 16         17 my $len = $width - $lead;
465 16         538 while ( $str =~ /\G([^\\]{1,$len}|\\\d{1,3}|\\.)/gs ) {
466              
467              
468 124 100       385 if ( length($line) + length($1) > $width - $lead ) {
469 16         18 push @rows, $line;
470 16 100       29 $lead = 0 if ($lead);
471 16         21 $line = "";
472             }
473 124         152 $line .= $1;
474 124   100     222 $len = $width - $lead - length($line) || 1;
475 124         2988 $pos = pos($str);
476              
477             #warn "$pos $len $line\n";
478             }
479 16 50       49 push @rows, $line if $line;
480 16 50       35 die "pos:" . $pos . "\n" . substr( $str, $pos ) . "\n"
481             if $pos != length($str);
482              
483             #print $str;
484 16         141 return $qb . join ( $qe . ".\n" . ( " " x $indent ) . $qb, @rows ) . $qe;
485             }
486              
487              
488              
489             =head2 decompress64(STR)
490              
491             Takes a compressed string in quoted 64 representation and decompresses it.
492              
493             =cut
494              
495             # takes a compressed quoted64 string and dequotes it
496             sub decompress64 {
497 0     0 1 0 my ( $self, $str ) = @_;
498 0         0 return Compress::Zlib::uncompress( $self->decode64($str) );
499             }
500              
501             =head2 decode64(STR)
502              
503             Takes a string encoded in base 64 and decodes it.
504              
505             =cut
506              
507             # takes a quoted64 string and dequotes it
508             sub decode64 {
509 0     0 1 0 my ( $self, $str ) = @_;
510 0         0 return MIME::Base64::decode($str);
511             }
512              
513             =head2 best_quotes(STR,OPTS)
514              
515             Selects the optimal quoting character and quoting type for a given string.
516              
517             Returns a list
518              
519             $qq - Either 'q' or 'qq'
520             $qbegin - The beginning quote character
521             $qend - The ending quote character
522             $needs_type - Whether $qq is needed to make the quotes valid.
523              
524             OPTS may include the normal options as well as
525              
526             chars : a list of chars (or pairs) to be allowed for quoting.
527              
528             =cut
529              
530             sub best_quotes {
531              
532             # is capable of deciding if something should be single
533             # quoted, or double quoted and which quote character to
534             # use.
535             # A string may be single quoted if it contains no control
536             # characters or line breaks.
537             # returns ( $qsym, $qq, $qbegin, $qend,$fqbegin )
538             # needs a complete rework
539 18     18 1 1330 my $self = shift;
540              
541 18         32 $self->_stamp;
542 18         32 local $_ = "".shift(@_);
543 18         26 my %opts = @_;
544              
545 18 50       32 warnings::warnif("Undef passed at _textquote_best") unless defined($_);
546 18 50       25 warnings::warnif("Reference passed at _textquote_best") if ref $_;
547              
548             # Use double quotes if we have non tab control chars or high bit chars
549             # (\n included)
550 18 50       44 my $qq = exists( $opts{use_qq} ) ? $opts{use_qq} :
    50          
551             $self->quote_prop('encode_high') ? /[^\t\040-\176]/ : /[^\t\040-\377]/;
552              
553 18         19 my @chars; # chars we can use for quoting with
554 18 100       27 if ( $opts{chars} ) { # Did they supply a list of choices?
555 1         2 @chars = @{ $opts{chars} }; # use them
  1         4  
556             } else { # Use the defaults
557 17         34 @chars = @{ $self->quote_prop("quote_chars") };
  17         27  
558 17 100       45 unshift @chars, ($qq) ? qw( " ' ) : qw( ' " );
559             }
560              
561             #print "Using @chars\n";
562 18         33 my $char_class = "[" . join ( "", map { quotemeta } @chars ) . "]";
  227         279  
563 18         33 my %counts;
564 18         128 @counts{@chars} = (0) x @chars;
565              
566 18         308 $counts{$1}++ while /($char_class)/g;
567              
568             {
569 1     1   9 no warnings;
  1         2  
  1         796  
  18         19  
570 18 50       58 $counts{'{}'} = $counts{'{'} + $counts{'}'} if exists $counts{'{}'};
571 18 100       43 $counts{'[]'} = $counts{'['} + $counts{']'} if exists $counts{'[]'};
572 18 100       41 $counts{'()'} = $counts{'('} + $counts{')'} if exists $counts{'()'};
573 18 50       27 $counts{'<>'} = $counts{'<'} + $counts{'>'} if exists $counts{'<>'};
574             }
575 18         89 delete $counts{$_} foreach qw' { } [ ] ( ) < >';
576              
577 18         28 my $qsym = shift @chars;
578 18         19 my $low = $counts{$qsym};
579 18         22 my $lowsym = $qsym;
580 18         42 while ( $low > 0 ) {
581 16 100       26 last unless @chars;
582 15         16 $qsym = shift @chars;
583 15 100       33 if ($counts{$qsym} < $low) {
584 2         3 $low = $counts{$qsym};
585 2         5 $lowsym=$qsym;
586             }
587             }
588 18         19 $qsym=$lowsym;
589              
590 18         24 my $qbegin = substr( $qsym, 0, 1 );
591 18         17 my $qend = substr( $qsym, -1, 1 );
592 18         18 my $needs_type;
593 18 100       26 if ($qq) {
594 6         7 $qq = 'qq';
595 6 100       11 $needs_type = $qbegin eq '"' ? 0 : 1;
596             } else {
597 12         11 $qq = 'q';
598 12 100       22 $needs_type = $qbegin eq "'" ? 0 : 1;
599             }
600              
601 18         98 return ( $qq, $qbegin, $qend, $needs_type );
602             }
603              
604             =head1 OVERIDE METHODS
605              
606             These methods are defined by Text::Quote for when it runs as a stand alone.
607             Normally they would be overriden by child classes, or alternatively used by
608             the child class.
609              
610             =cut
611              
612             BEGIN {
613              
614             # things we need to escape
615             #from G.A.
616              
617 1     1   19 my %esc_chars = (
618             "\a" => "\\a",
619             "\b" => "\\b",
620             "\t" => "\\t",
621             "\n" => "\\n",
622             "\f" => "\\f",
623             "\r" => "\\r",
624             "\e" => "\\e",
625             );
626              
627 1         6 my %known_keywords = map { $_ => 1 }
  249         2083  
628             qw( __FILE__ __LINE__ __PACKAGE__ __DATA__ __END__ AUTOLOAD BEGIN CORE
629             DESTROY END EQ GE GT INIT LE LT NE abs accept alarm and atan2 bind
630             binmode bless caller chdir chmod chomp chop chown chr chroot close
631             closedir cmp connect continue cos crypt dbmclose dbmopen defined
632             delete die do dump each else elsif endgrent endhostent endnetent
633             endprotoent endpwent endservent eof eq eval exec exists exit exp fcntl
634             fileno flock for foreach fork format formline ge getc getgrent
635             getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin
636             getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid
637             getpriority getprotobyname getprotobynumber getprotoent getpwent
638             getpwnam getpwuid getservbyname getservbyport getservent getsockname
639             getsockopt glob gmtime goto grep gt hex if index int ioctl join keys
640             kill last lc lcfirst le length link listen local localtime lock log
641             lstat lt m map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct
642             open opendir or ord pack package pipe pop pos print printf prototype
643             push q qq qr quotemeta qw qx rand read readdir readline readlink
644             readpipe recv redo ref rename require reset return reverse rewinddir
645             rindex rmdir s scalar seek seekdir select semctl semget semop send
646             setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent
647             setservent setsockopt shift shmctl shmget shmread shmwrite shutdown
648             sin sleep socket socketpair sort splice split sprintf sqrt srand stat
649             study sub substr symlink syscall sysopen sysread sysseek system
650             syswrite tell telldir tie tied time times tr truncate uc ucfirst umask
651             undef unless unlink unpack unshift untie until use utime values vec
652             wait waitpid wantarray warn while write x xor y);
653              
654             =head2 init()
655              
656             Takes a list of options and uses them to initialize the quoting object.
657             Defaults are provided if an option is not specified.
658              
659             esc_chars : a hash of chars needing to be escaped and their escaped equivelent
660             esc_class : a regex class that matches the chars needing to be escaped
661             quote_chars : chars to be used as alternate quote chars
662             key_quote_hash : hash of words that must be quoted if used as a hash key
663             repeat_len : Length of pattern to look for in the string
664             encode_high : Set to 1 to cause high bits chars to be escaped. Dafaults to 0
665              
666             Set the following to 0 to disable
667              
668             repeat_at : Length of string at which Text::Quote should see if there is a repeated pattern.
669             encode_at : Length at which binary data should be quoted in Base64
670             compress_at : Length at which the string should be compressed using Compress::Zlib
671              
672             These options are set using L
673              
674             =cut
675              
676             sub init {
677 2     2 1 3 my $self = shift;
678              
679 2         8 $self->_stamp;
680 2         459 my %hash = (
681             esc_chars => {%esc_chars},
682             esc_class => join ( "", "[", keys(%esc_chars), "]" ),
683              
684             #Forbidden until best_quotes is fixed :
685             quote_chars => [ qw; / ! | - . : () [] {} ;, '#', ';' ],
686             key_quote_hash => {%known_keywords},
687             key_quote => 'auto', #auto/true/false
688             repeat_len => 20, # maximum size of repeat sequence
689             repeat_at => 20, # number of chars before we even bother
690             encode_at => 160,
691             compress_at => 512, # number of chars at which we compress no matter what
692             encode_high => 0,
693             @_
694             );
695 2         28 $self->quote_prop( \%hash );
696 2         5 return \%hash;
697             }
698             }
699              
700             =head2 new()
701              
702             Creates a hash based object and calls L afterwards
703              
704             =cut
705              
706              
707             sub new {
708 2     2 1 15 my $class = shift;
709 2         7 my $self = bless {}, $class;
710 2         9 $self->init(@_);
711 2         5 return $self;
712             }
713              
714              
715             =head2 quote_prop()
716              
717             As this class is intended to be subclassed all of its parameters are kept
718             and accessed through a single accessor.
719              
720             This hash is normally stored as $obj->{Text::Quote} however should the default
721             class type not be a hash this method may be overriden to provide access to the
722             the Text::Quote proprty hash. Or even to redirect various properties elsewhere.
723              
724             Called with no parameters it returns a reference to the property hash.
725             Called with a string as the only parameter it returns the value of that named property.
726             Called with a string as the first parameter and a value it will set the property
727             to equal the value and return the new value. Called with a reference as the only parameter
728             the passed value is substituted for the property hash.
729              
730             =cut
731              
732              
733             #use Data::Dumper;
734             sub quote_prop {
735 217     217 1 738 my $self = shift->_self_obj;
736             #$self->_stamp;
737             #print Dumper($self);
738 217         251 my $pck = __PACKAGE__;
739              
740 217 50       341 return $self->{$pck} unless @_;
741              
742              
743 217         205 my $prop = shift;
744 217 100       351 if ( ref $prop ) {
745 2 50       16 Carp::croak "Expecting HASH based property bag!"
746             unless UNIVERSAL::isa( $prop, "HASH" );
747 2         11 return $self->{$pck} = $prop;
748             }
749              
750 215         610 should( ref $self->{$pck}, "HASH" ) if DEBUG;
751              
752 215 50       948 warnings::warnif("Property '$prop' not known")
753             unless exists( $self->{$pck}->{$prop} );
754              
755 215 100       354 $self->{$pck}->{$prop} = shift if @_;
756 215         506 return $self->{$pck}->{$prop};
757              
758             }
759              
760             =head2 _self_obj()
761              
762             This is a utility method to enable Text::Quote and its descendants the ability to
763             act as both CLASS and OBJECT methods. Creates an object to act as a class object.
764              
765             If called as an object method returns the object
766              
767             If called as a class method returns a singleton, which is the result of calling
768             class->new(); The singleton is inserted into the calling classes package under
769             the global scalar $class::SINGLETON and is reused thereafter. The object is kept in
770             a closure for maximum privacy of the object data.
771              
772             =cut
773              
774              
775             sub _self_obj {
776 258 100   258   592 ref( $_[0] ) && return $_[0];
777 1     1   6 no strict 'refs';
  1         2  
  1         135  
778             #closure to keep singleton private from prying dumpers.
779             #thank dan brook.
780 7 100       8 unless (${ $_[0] . '::SINGLETON' }) {
  7         27  
781 1         6 my $obj=$_[0]->new();
782 1 50   7   5 my $sub=sub{$obj=shift if @_; $obj};
  7         16  
  7         10  
783 1         2 ${ $_[0] . '::SINGLETON' } = $sub;
  1         5  
784             }
785 7         6 return ${ $_[0] . '::SINGLETON' }->();
  7         17  
786             }
787              
788             #print __PACKAGE__->quote([]);
789             #/|'"-,!([{#;.:
790              
791             #exit;
792              
793             =head1 INTENTION
794              
795             I wrote this module to enable me to avoid having to put code for how to neatly output perl quoted
796             strings in a reasonable way in the same module as L. I've documented
797             it and packaged in the mind that others may find it useful, and or help me improve it. I was thinking
798             for example that there are a number of modules with one form of quoting or another, be it SQL
799             statements or excel CSV quoting. There are lots of modules (and ways) of reading these formats
800             but no one clear location for finding ones that output them. Perhaps they could live here?
801             Feedback welcome.
802              
803             =head1 TODO
804              
805             Better synopsis. Better Description. More tests.
806              
807             =head1 EXPORTS
808              
809             None.
810              
811             =head1 REPOSITORY
812              
813             L
814              
815             =head1 AUTHOR
816              
817             Yves Orton, Edemerphq@hotmail.comE
818              
819             Parts by Gisle Aas
820              
821             Additional testing and encouragement Dan Brook
822              
823             =head1 CAVEAT
824              
825             This module is currently in B condition. It should not be used in a
826             production enviornment, and is released with no warranty of any kind whatsoever.
827              
828             Corrections, suggestions, bugreports and tests are welcome!
829              
830             =head1 SEE ALSO
831              
832             L.
833              
834             =head1 COPYRIGHT AND LICENSE
835              
836             This software is copyright (c) 2002 by Yves Orton .
837              
838             This is free software; you can redistribute it and/or modify it under
839             the same terms as the Perl 5 programming language system itself.
840              
841             =cut
842              
843             1;