[comp.lang.perl] unctrl

fuchs@it.uka.de (Harald Fuchs) (10/16/90)

I'm looking for the most elegant (terse?) way to do an 'unctrl'
operation on a string, i. e. to replace all occurrences of
non-printable characters by a printable representation.
Examples: \001 -> ^A
          \177 -> ^?
          \232 -> M-^Z

The only way I could find was:

while (<>) {
  while (/[\200-\377]/) {
    $c1 = $&;
    $c2 = pack ('C', ord ($c1) - 0200);
    s/$c1/M-$c2/;
  }
  while (/[\000-\011\013-\037]/) {
    $c1 = $&;
    $c2 = pack ('C', ord ($c1) + 0100);
    s/$c1/^$c2/;
  }
  s/\177/^?/g;
  print;
}

How about a one-liner, Randal?
--

Harald Fuchs <fuchs@it.uka.de> <fuchs%it.uka.de@relay.cs.net> ...

merlyn@iwarp.intel.com (Randal Schwartz) (10/17/90)

In article <fuchs.656085531@tmipe1>, fuchs@it (Harald Fuchs) writes:
| How about a one-liner, Randal?

My "one-liner" for non-metachars is already in the distribution (dumpvars.pl):

sub unctrl {
	local($_) = @_;
	s/([\001-\037\177])/'^'.pack('c',ord($1)^64)/eg;
	$_;
}

To add meta to that, do something like:

sub unctrl {
	local($_) = @_;
	s/([\200-377])/'M-'.pack('c',ord($1)^128)/eg;
	s/([\001-\037\177])/'^'.pack('c',ord($1)^64)/eg;
	$_;
}

Untested, but you get the idea, I hope.

print &unctrl("Just another Perl hacker,");
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

utashiro@sran84.sra.co.jp (Kazumasa Utashiro) (10/17/90)

In article <fuchs.656085531@tmipe1> fuchs@it.uka.de (Harald Fuchs) writes:
>> I'm looking for the most elegant (terse?) way to do an 'unctrl'
>> operation on a string, i. e. to replace all occurrences of
>> non-printable characters by a printable representation.
>> Examples: \001 -> ^A
>>           \177 -> ^?
>>           \232 -> M-^Z

I'm using this script in my perlized a2ps.

	s/[\200-\377]/sprintf("M-%c",ord($&)-0200)/ge;
	s/[\000-\007\013\015-\032\034-\037]/sprintf("^%c",ord($&)+0100)/ge;
	s/\177/^?/g;

>> How about a one-liner, Randal?

I'd like to see too.

---
K. Utashiro
utashiro@sra.co.jp