reformat_literal_perl_strings.pl 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 12 November 2017
  4. # https://github.com/trizen
  5. # Reformat the literal quoted strings in a Perl source code, using Perl::Tokenizer and Data::Dump.
  6. # Example:
  7. # 'foo姓bar' -> "foo\x{59D3}bar"
  8. # '\'foo\'' -> "'foo'"
  9. # The literal quoted strings (quoted as: q{...}, qq{...}, '...' or "...") will be reformatted as "...".
  10. # Strings which (potentially) include variable interpolations, are ignored.
  11. # The input source code must be UTF-8 encoded.
  12. use utf8;
  13. use 5.018;
  14. use warnings;
  15. use open IO => ':encoding(UTF-8)', ':std';
  16. use Data::Dump qw(pp);
  17. use Perl::Tokenizer qw(perl_tokens);
  18. # usage: perl script.pl < source.pl
  19. my $code = join('', <>);
  20. perl_tokens {
  21. my ($name, $i, $j) = @_;
  22. if ( $name eq 'single_quoted_string'
  23. or $name eq 'double_quoted_string'
  24. or $name eq 'qq_string'
  25. or $name eq 'q_string') {
  26. my $str = substr($code, $i, $j - $i);
  27. my $eval_code = join(
  28. ';',
  29. 'my $str = qq{' . quotemeta($str) . '}', # quoted string
  30. 'die if $str =~ tr/@$//', # skip strings with interpolation
  31. '$str = eval $str', # evaluate string
  32. 'die if $@', # check the status of eval()
  33. '$str', # string content
  34. );
  35. my $raw_str = eval($eval_code);
  36. if (defined($raw_str) and !$@) {
  37. print scalar pp($raw_str);
  38. return;
  39. }
  40. }
  41. print substr($code, $i, $j - $i);
  42. } $code;