1*0Sstevel@tonic-gate;# shellwords.pl 2*0Sstevel@tonic-gate;# 3*0Sstevel@tonic-gate;# Usage: 4*0Sstevel@tonic-gate;# require 'shellwords.pl'; 5*0Sstevel@tonic-gate;# @words = &shellwords($line); 6*0Sstevel@tonic-gate;# or 7*0Sstevel@tonic-gate;# @words = &shellwords(@lines); 8*0Sstevel@tonic-gate;# or 9*0Sstevel@tonic-gate;# @words = &shellwords; # defaults to $_ (and clobbers it) 10*0Sstevel@tonic-gate 11*0Sstevel@tonic-gatesub shellwords { 12*0Sstevel@tonic-gate package shellwords; 13*0Sstevel@tonic-gate local($_) = join('', @_) if @_; 14*0Sstevel@tonic-gate local(@words,$snippet,$field); 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate s/^\s+//; 17*0Sstevel@tonic-gate while ($_ ne '') { 18*0Sstevel@tonic-gate $field = ''; 19*0Sstevel@tonic-gate for (;;) { 20*0Sstevel@tonic-gate use re 'taint'; # leave strings tainted 21*0Sstevel@tonic-gate if (s/^"(([^"\\]|\\.)*)"//) { 22*0Sstevel@tonic-gate ($snippet = $1) =~ s#\\(.)#$1#g; 23*0Sstevel@tonic-gate } 24*0Sstevel@tonic-gate elsif (/^"/) { 25*0Sstevel@tonic-gate die "Unmatched double quote: $_\n"; 26*0Sstevel@tonic-gate } 27*0Sstevel@tonic-gate elsif (s/^'(([^'\\]|\\.)*)'//) { 28*0Sstevel@tonic-gate ($snippet = $1) =~ s#\\(.)#$1#g; 29*0Sstevel@tonic-gate } 30*0Sstevel@tonic-gate elsif (/^'/) { 31*0Sstevel@tonic-gate die "Unmatched single quote: $_\n"; 32*0Sstevel@tonic-gate } 33*0Sstevel@tonic-gate elsif (s/^\\(.)//) { 34*0Sstevel@tonic-gate $snippet = $1; 35*0Sstevel@tonic-gate } 36*0Sstevel@tonic-gate elsif (s/^([^\s\\'"]+)//) { 37*0Sstevel@tonic-gate $snippet = $1; 38*0Sstevel@tonic-gate } 39*0Sstevel@tonic-gate else { 40*0Sstevel@tonic-gate s/^\s+//; 41*0Sstevel@tonic-gate last; 42*0Sstevel@tonic-gate } 43*0Sstevel@tonic-gate $field .= $snippet; 44*0Sstevel@tonic-gate } 45*0Sstevel@tonic-gate push(@words, $field); 46*0Sstevel@tonic-gate } 47*0Sstevel@tonic-gate @words; 48*0Sstevel@tonic-gate} 49*0Sstevel@tonic-gate1; 50