in reply to VarStructor
# Copyright (c) 2004 Barry Kaminsky. All rights reserved. This program + is free software; you can redistribute it and/or modify it under the + same terms as Perl itself. # Last minute changes made May 2, 2004, 4:00 AM EST without much testi +ng # VarStructor is an alternative to Perl's reset function, which is exp +ected to be deprecated. It could also be used to print variables and +their values, including "my" variables. See comments at top of sub VA +RSTRUCTOR for configuration information. ################################# # Test variables (could be deleted) %hash1=("key1"=>"value1","key2"=>"value2"); $hash2{"key1"}="value1"; $hash2{"key2"}="value2"; $Simple_Var = 'simple'; @Simple_Arr = ('simple1','simple2'); ################################# &VARSTRUCTOR('show', 'E: subs(VARSTRUCTOR)'); # Test parameters sub VARSTRUCTOR { ########################################################## # 1st parameter: # Assign "show" to print variables and values or # "clear" to clear variables. For security reasons, the # default is clear. splice (@_,0,0,'clear') if ($_[0] !~ /^\s*(show|clear)\s*$/i); $Function = $_[0]; # 2nd parameter: # Comma-separated list of variables, subroutines, and # labels, whose variables will be included or excluded. # Labels must be of labeled blocks that are wrapped in # braces. This parameter must begin with "I:" or "E:" # (include or exclude). # # You can't include or exclude array elements, hash # keys or hash values. Legal variables for this # parameter begin with $, @, and %, followed by a # string of word characters not beginning with a digit. # # The label and subroutine name lists must be enclosed # in separate sets of parentheses, following the word # "labels" or "subs". A comma after the closing # parenthesis is necessary when another item in this # parameter follows. Commas also must separate the # labels and subroutine names within the parentheses. # Within the code to be parsed, there must be nothing # preceding the labels and the "sub"s on the # same line except for optional spaces, and the # subroutines and labeled blocks must end with the # next "}" that is at the same level of indentation as # the first character of the label or the "s" of "sub". # Within the parameters, the "&" is optional before # subroutine names and the ":" is optional after labels. splice (@_,1,0,'') if ($_[1] !~ /^\s*(i:|e:)/i); $Variables = "$_[1]"; # 3rd parameter: # Target file. Default is $0, indicating the file # VarStructor is being run from. $_[2] = "$0" if $_[2] =~ /^\s*$/; $Targ = "$_[2]"; ########################################################## open(IN, $Targ) or die 'Can not open file'; @file = <IN>; close IN; $FILE = join ('',@file); $FILE =~ s/[;\n]\s*#[^\n]*//sg; # Delete comments ### Prevent parsing of some quoted strings by deleting here docs. R +arely, a single quoted string would be mistaken for a variable if not + in a here doc. # Delete here docs with quoted identifiers $FILE =~ s/<<\s*('|"|`) ([^\n]*?([^\\]|[^\\]\\\\))\1 # Match here doc identifier, which end +s with an unescaped closing quote. Limitation: an even number of slas +hes greater than two at the end of the identifier would be wrongly in +terpreted as escaping the quote and the here doc value would probably + not get deleted. .*?\n\2\n//sgx; # Delete here docs with unquoted identifiers $FILE =~ s/<<(\w+);.*\n\1\n//sg; # Isolate subroutines to search, according to $Variables while ($Variables =~ s/(?<=subs\()\s*\&?(\w+)\s*(,+|\))//) { $FILE =~ s/(^|\n)(\s*)sub\s*\Q$1\E\s*\{.*?\n\2\}//s; $ISOLATED_SUBS .= "$&"; } # Isolate labeled blocks to search, according to $Variables while ($Variables =~ s/(?<=labels\()\s*(\w+):?\s*(,+|\))//) { $FILE =~ s/(^|\n)(\s*)\Q$1\E:.*?\{.*?\n\2\}//s; $ISOLATED_LABELS .= "$&"; } # Delete or include individual variables, according to $Variables while ($Variables =~ s/[\$|\@|\%][^\d\W]\w*//) { $ONE_VAR = "$&"; $VARS_ONLY .= "$ONE_VAR='';" if $Variables =~ /^\s*I:/i; $FILE =~ s/\Q$ONE_VAR\E//g if $Variables =~ /^\s*E:/i; } $FILE = "$VARS_ONLY $ISOLATED_SUBS $ISOLATED_LABELS" if $Variables +=~ /^\s*I:/; $FILE =~ s/\Q($ISOLATED_SUBS|$ISOLATED_LABELS)\E// if $Variables =~ + /^\s*E:/; # Find arrays. If not an array used in push, require an equals sign + to avoid quoted email addresses that look like arrays. while (($FILE =~ s/([^\\]|[^\\]\\\\)(\@[^\d\W]\w*)\s*=//)|| # Find scalars/array elements after ++ or -- ($FILE =~ s/(?:[^\\]|[^\\]\\\\)(\+\+|--)\s*(\$[^\d\W]\w*(\[.*?\])?) +//)|| # Find scalars/array elements before assignment operators, "++", "- +-", "." or ".=" ($FILE =~ s/([^\\]|[^\\]\\\\)(\$[^\d\W]\w*(\[.*?\])?)\s*(=|\+=|-=|\ +*=|\/=|\%=|\*\*=|\+\+|--|\.)//)|| # Find arrays assigned to with push. ($FILE =~ s/push[^\w_]*([^\\]|[^\\]\\\\)(\@[^\d\W]\w*)//)) { $ONE_VAR = $2; $ONE_VAR =~ s/^\$(.*)\[.*/\@$1/; # Convert element to its array ($EVAL_VAR = $ONE_VAR =~ /^\$/ ? "$ONE_VAR='';" : "$ONE_VAR=();" +) if $Function =~ /^clear$/i; # To do: print index numbers next to values ($EVAL_VAR = "\\$ONE_VAR = $ONE_VAR\\n") if $Function =~ /^show$ +/i; push (@ALL_VAR, "$EVAL_VAR"); } # Extract hashes while (($FILE =~ s/([^\\]|[^\\]\\\\)\%([^\d\W]\w*)\s*=//)|| ($FILE =~ s/([^\\]|[^\\]\\\\)\$([^\d\W]\w*)\{[^\n]*\}\s*=//)) { $ONE_HASH = "$2"; push @HASH_DISPLAY, "print \"\\n\%$ONE_HASH\\n\";" . "foreach \$key (sort(keys \%$ONE_HASH))" . "{print \$key, '=', \$$ONE_HASH\{\$key\}, \"\\n\";}" if $Function =~ /^show$/; push @HASH_DISPLAY, "\%$ONE_HASH=();" if $Function =~ /^clear$/; } @ALL_VAR = grep {++$count{$_} < 2} @ALL_VAR; @ALL_VAR = sort @ALL_VAR; $ALL_VAR = join ('',@ALL_VAR); $ALL_VAR =~ s/.*/print"$&";/ if $Function =~ /^show$/i; eval $ALL_VAR; @HASH_DISPLAY = grep {++$count{$_} < 2} @HASH_DISPLAY; @HASH_DISPLAY = sort @HASH_DISPLAY; $HASH_DISPLAY = join ('',@HASH_DISPLAY); eval $HASH_DISPLAY; }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: VarStructor
by Wassercrats (Initiate) on Sep 15, 2004 at 06:29 UTC |