19a9c8359SMichael Walsh#!/usr/bin/wish
29a9c8359SMichael Walsh
3410b1787SMichael Walsh# This file provides many valuable quote and metachar escape processing procedures.
49a9c8359SMichael Walsh
59a9c8359SMichael Walsh
69a9c8359SMichael Walshproc escape_bash_quotes { buffer } {
79a9c8359SMichael Walsh
8410b1787SMichael Walsh  # Do a bash-style escape of all single quotes in the buffer and return the result.
99a9c8359SMichael Walsh
10410b1787SMichael Walsh  # In bash, if you wish to have a single quote (i.e. apostrophe) inside single quotes, you must escape it.
119a9c8359SMichael Walsh
129a9c8359SMichael Walsh  # For example, the following bash command:
139a9c8359SMichael Walsh  # echo 'Mike'\''s dog'
149a9c8359SMichael Walsh  # Will produce the following output.
159a9c8359SMichael Walsh  # Mike's dog
169a9c8359SMichael Walsh
179a9c8359SMichael Walsh  # So, if you pass the following string to this procedure:
189a9c8359SMichael Walsh  # Mike's dog
199a9c8359SMichael Walsh  # This procedure will return the following:
209a9c8359SMichael Walsh  # Mike'\''s dog
219a9c8359SMichael Walsh
229a9c8359SMichael Walsh  # Description of argument(s):
23410b1787SMichael Walsh  # buffer                          The string whose single quotes are to be escaped.
249a9c8359SMichael Walsh
259a9c8359SMichael Walsh  regsub -all {'} $buffer {'\''} new_buffer
269a9c8359SMichael Walsh  return $new_buffer
279a9c8359SMichael Walsh
289a9c8359SMichael Walsh}
299a9c8359SMichael Walsh
309a9c8359SMichael Walsh
319a9c8359SMichael Walshproc quotes_to_curly_braces { buffer } {
329a9c8359SMichael Walsh
33410b1787SMichael Walsh  # Convert a single-quoted string to a curly brace-quoted string and return the result.
349a9c8359SMichael Walsh
35410b1787SMichael Walsh  # This procedure can help in converting bash expressions, which are quoted with single quotes, to
36410b1787SMichael Walsh  # equivalent TCL expressions which are quoted with curly braces.  This procedure will recognize and
37410b1787SMichael Walsh  # preserve a bash single quote escape sequence: '\''
389a9c8359SMichael Walsh
399a9c8359SMichael Walsh  # Description of argument(s):
40410b1787SMichael Walsh  # buffer                          The string whose quotes are to be converted to curly braces.
419a9c8359SMichael Walsh
429a9c8359SMichael Walsh  # For example, the following code...
439a9c8359SMichael Walsh
449a9c8359SMichael Walsh  # set buffer {'Mike'\''s dog'}
459a9c8359SMichael Walsh  # print_var buffer
469a9c8359SMichael Walsh  # set buffer [quotes_to_curly_braces $buffer]
479a9c8359SMichael Walsh  # print_var buffer
489a9c8359SMichael Walsh
499a9c8359SMichael Walsh  # Would produce the following result:
509a9c8359SMichael Walsh  # buffer:     'Mike'\''s dog'
519a9c8359SMichael Walsh  # buffer:     {Mike's dog}
529a9c8359SMichael Walsh
539a9c8359SMichael Walsh  set quote {'}
549a9c8359SMichael Walsh
559a9c8359SMichael Walsh  set return_buffer {}
569a9c8359SMichael Walsh
579a9c8359SMichael Walsh  set inside_quotes 0
589a9c8359SMichael Walsh
59410b1787SMichael Walsh  # In a bash string "'\''" is an escaped quote which we wish to convert to a single quote.
609a9c8359SMichael Walsh  set place_holder {supercaliforniaplace_holder}
619a9c8359SMichael Walsh  regsub -all {'\\''} $buffer ${place_holder} buffer
629a9c8359SMichael Walsh
639a9c8359SMichael Walsh  # Walk the string one character at a time.
649a9c8359SMichael Walsh  for {set ix 0} {$ix < [string length $buffer]} {incr ix} {
659a9c8359SMichael Walsh    set char [string index $buffer $ix]
669a9c8359SMichael Walsh    if { $char == $quote } {
67410b1787SMichael Walsh      # Processing a quote.  inside_quotes will tell us whether we've come across a left quote or a right
68410b1787SMichael Walsh      # quote.
699a9c8359SMichael Walsh      if { $inside_quotes == 0 } {
70410b1787SMichael Walsh        # Processing closing quote.  Add a left curly brace to return_buffer and discard the quote char.
719a9c8359SMichael Walsh        set return_buffer "${return_buffer}\{"
729a9c8359SMichael Walsh        # Set inside_quotes to indicate we are now waiting for a closing quote.
739a9c8359SMichael Walsh        set inside_quotes 1
749a9c8359SMichael Walsh      } else {
75410b1787SMichael Walsh        # Processing opening quote.  Add a right curly brace to return_buffer and discard the quote char.
769a9c8359SMichael Walsh        set return_buffer "${return_buffer}\}"
779a9c8359SMichael Walsh        # Clear inside_quotes to indicate we have found our closing quote.
789a9c8359SMichael Walsh        set inside_quotes 0
799a9c8359SMichael Walsh      }
809a9c8359SMichael Walsh    } else {
819a9c8359SMichael Walsh      # For non-quote character, simply add it to the return buffer/
829a9c8359SMichael Walsh      set return_buffer "${return_buffer}${char}"
839a9c8359SMichael Walsh    }
849a9c8359SMichael Walsh  }
859a9c8359SMichael Walsh
869a9c8359SMichael Walsh  regsub -all ${place_holder} $return_buffer {'} return_buffer
879a9c8359SMichael Walsh
889a9c8359SMichael Walsh  return $return_buffer
899a9c8359SMichael Walsh
909a9c8359SMichael Walsh}
919a9c8359SMichael Walsh
929a9c8359SMichael Walsh
939a9c8359SMichael Walshproc curly_braces_to_quotes { buffer } {
949a9c8359SMichael Walsh
95410b1787SMichael Walsh  # Convert a curly brace-quoted string to a single-quoted string and return the result.
969a9c8359SMichael Walsh
97410b1787SMichael Walsh  # This procedure can help in converting TCL expressions, which are quoted with curly braces, to equivalent
98410b1787SMichael Walsh  # bash expressions which are quoted with single quotes.  This procedure will first convert single quotes to
99410b1787SMichael Walsh  # the bash escaped single quote sequence: '\''
1009a9c8359SMichael Walsh
1019a9c8359SMichael Walsh  # Description of argument(s):
102410b1787SMichael Walsh  # buffer                          The string whose curly braces are to be converted to single quotes.
1039a9c8359SMichael Walsh
1049a9c8359SMichael Walsh  # For example, the following buffer value:
1059a9c8359SMichael Walsh  # echo {Mike's dog}
1069a9c8359SMichael Walsh  # Will be changed to this:
1079a9c8359SMichael Walsh  # echo 'Mike'\''s dog'
1089a9c8359SMichael Walsh
1099a9c8359SMichael Walsh  regsub -all {[\{\}]} [escape_bash_quotes $buffer] {'} new_buffer
1109a9c8359SMichael Walsh  return $new_buffer
1119a9c8359SMichael Walsh
1129a9c8359SMichael Walsh}
1139a9c8359SMichael Walsh
1149a9c8359SMichael Walsh
115*721f970aSDavid Shawproc escape_regex_metachars { buffer } {
116*721f970aSDavid Shaw
117*721f970aSDavid Shaw  # Escape every regex metacharacter found in buffer and return the result.
118*721f970aSDavid Shaw
119*721f970aSDavid Shaw  # Example code:
120*721f970aSDavid Shaw
121*721f970aSDavid Shaw  # set var1 {john*sm(]ith}
122*721f970aSDavid Shaw  # print_vars var1
123*721f970aSDavid Shaw  # set var1 [escape_regex_metachars $var1]
124*721f970aSDavid Shaw  # print_vars var1
125*721f970aSDavid Shaw
126*721f970aSDavid Shaw  # Example output:
127*721f970aSDavid Shaw
128*721f970aSDavid Shaw  # var1:                        john*sm(]ith
129*721f970aSDavid Shaw  # var1:                        john\*sm\(\]ith
130*721f970aSDavid Shaw
131*721f970aSDavid Shaw  # Description of argument(s):
132*721f970aSDavid Shaw  # buffer                          The string whose regex metacharacters are to be escaped.
133*721f970aSDavid Shaw
134*721f970aSDavid Shaw  set escape_chars_regex {[\\\^\$\/\(\)\|\?\+\*\[\]\{\}\,\.]}
135*721f970aSDavid Shaw  regsub -all ${escape_chars_regex} ${buffer} {\\\0} buffer
136*721f970aSDavid Shaw  return ${buffer}
137*721f970aSDavid Shaw
138*721f970aSDavid Shaw}
139