sub trigram # Replace each of a list of characters with its hex value, preceded # by a key character ID'ing the replacement; eg, replace blank w/%20 # Functionality duplicates trigram_utils, but latter cannot be # easily used if target characters are special to shell # # Takes 3 args: string whose characters are to be replaced # list of characters to replace # ID character (may not be null) # Returns 2 strings: status ("OK","NG","WARN") # if NG, diagnostic message # if not NG, string w/replacements # If ID character is itself to be replaced, it must be first in # replacement list. If ID character is NOT to be replaced, then # its presence in the source string results in a WARN { my ($string,$trigram_list,$trigram_char,$dummy) = @_; my ($convert_trigram_char_OK,$trigram_char_in_string,$pos_in_list); (defined $trigram_char) || return "NG","missing argument"; (defined $dummy) && return "NG","extra argument"; # Code below PROBABLY works w/null trigram_char, but didn't look into it ($trigram_char eq "") && return "NG","null trigram character"; $_ = quotemeta($trigram_char); $trigram_char_in_string = ($string =~ /$_/); $convert_trigram_char_OK = 0; $pos_in_list = 0; foreach (split ("",$trigram_list)) { if ($_ eq $trigram_char) { # If trigram_char is in conversion list, it must be first # As a corollary, it can only be converted once (not counting # multiple consec times at the beginning!). Tolerate multiples # if first time was proper, but out-of-position is an error # We could re-order the list in here, but that is probably more work # than the trigramming. As coded, all we do is an extra test per # char in trigram_list (plus a couple of statements if we find the # trigram char) if ($pos_in_list == 0) { $convert_trigram_char_OK = 1; } else { $convert_trigram_char_OK && next; return "NG", "if trigram char is itself to be trigrammed, it must lead list"; } } $trigram = $trigram_char . sprintf ("%2.X",ord); $_ = quotemeta; $string =~ s/$_/$trigram/g; $pos_in_list++; } # Probably trouble if there was a trigram char in the input that didn't # itself get trigrammed ... but I'm not REALLY sure it should be an error # That's what multiple statuses are for - let the caller worry! $status = ( $convert_trigram_char_OK || (! $trigram_char_in_string) ) ? "OK" : "WARN"; return $status,$string; } 1