antsexprs.pl
author A.M. Thurnherr <athurnherr@yahoo.com>
Fri, 12 Jun 2015 15:25:28 +0000
changeset 20 7ea1fd9d64e6
parent 0 a5233793bf69
child 30 1a1a12d5edc1
permissions -rw-r--r--
.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    A N T S E X P R S . P L 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#					 (c) 2005 Andreas Thurnherr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     4
#                    doc: Sat Dec 31 18:35:33 2005
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     5
#                    dlm: Fri May 15 20:12:34 2015
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     6
#                    uE-Info: 183 56 NIL 0 0 70 2 2 4 NIL ofnI
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     7
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     8
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     9
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
#	Dec 31, 2005: - extracted from [list]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
#	Jan  2, 2006: - re-written to use anonymous funs instead of eval()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	Jan  3, 2006: - added $DEBUG
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	Jan  4, 2006: - removed NaN_handling_out
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#	Jan  9, 2006: - made $bufvar param to antsCompileExpr optional
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	Jan 13, 2006: - separated AddrExpr from EditExpr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
#				  - implemented abbreviated addr exprs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#	Jan 14, 2006: - added old -G syntax to -S
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
#	Jan 17, 2006: - BUG: $1, $2, did not work in abbrevs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#	Jan 31, 2006: - added de-octalization code for abbrevs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
#	Apr 11, 2006: - added ,-separated list (again?)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
#	May 18, 2006: - fiddled
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
#	Jun 20, 2006: - simplified regexprs; fields can now begin with _
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#   Jul  1, 2006: - Version 3.3 [HISTORY]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#	Jul 24, 2006: - BUG: $$ did not work as advertised
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
#	Dec 11, 2006: - BUG: 1e-3 was not recognized as a valid number in
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
#						 abbreviations
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
#	Dec  1, 2007: - improved to allow -S%PARAM:... (mainly for %RECNO)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
#	Jan 20, 2007: - pointless debugging (BUGs in [fnr] [list])
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
#	Mar 26, 2008: - BUG: . were not allowed in field names
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
#	Mar 27, 2008: - added &antsCompileConstExpr()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
#	Mar 28, 2008: - made compile funs bomb on undefined %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
#	Aug 27, 2008: - generate error on list(1)-specific address expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
#	Oct 12, 2008: - BUG: -S%RECNO%%6==1 did not work because %-escape magic
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
#						 word continued RECNO word to form undefined PARAM
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
#						 name. Solution: begin/end escape magic words for %
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
#					     and $ with a space (nonword character)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
#	Oct  5, 2009: - improved documentation
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
#				  - added $antsEditExprUsesFields flag
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
#	Dec 10, 2009: - BUG: debug output had been wrong for ConstExprs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
#				  - modified semantics to allow for : in param names
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
#	May 21, 2011: - added support for $antsFnrNegativeOk
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
#	May 22, 2011: - made it work
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
#	Feb 20, 2012: - BUG: quoting had not been implemented
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
#	Mar 10, 2012: - added ${field..field} syntax to edit exprs
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    45
#	May 15, 2015: - BUG: -S did not work with :: %PARAMs
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
$DEBUG = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
# Address Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
#	- return value indicates whether current record matches
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
# 	- any valid PERL expression can be an addr expr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
# 	- $id are assumed to be fields (use $$id for perl vars)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
# 	- %id are assumed to be PARAMs (use %% to get %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
# 	- ABBREVIATIONS:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
#		- id1 relop id2 becomes numberp(id1) && numberp(id2) && $id1 relop $id2
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
#		- id1 relop id2 relop id3 is analogous
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
#		- id? can only be restricted field name ([\w\.] chars and, possibly, leading %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
#		- non-perl relops ~=, <> become !=
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
sub antsCompileAddrExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
	my($expr,$bufVar) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
	$bufVar = '$ants_[0]' unless (length($bufVar) > 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
	#---------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
	# handle abbreviations
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
	#---------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
	print(STDERR "IN  AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
	goto QUOTED_ADDR_EXPR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
		if ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
		    (substr($expr,0,1) eq substr($expr,-1)));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
	# NB: update following code if -S extensions in [list] change
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
	croak("$0: unsupported list(1)-specific address expression <$expr>\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
		if ($expr =~ /^\$?([\w\.]+)\s*~(([nN][aA][nN])|(([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?))/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
			$expr =~ /^\$?([\w\.]+)\s*<$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
			$expr =~ /^<\$?([\w\.]+)$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
			$expr =~ /^\$?([\w\.]+)\s*>$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
			$expr =~ /^>\$?([\w\.]+)$/);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    84
	$expr =~ s/::/QquOte/g;										# new-style :: %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    85
	if ($expr =~ /^(%?[\w\.]+):/ || $expr =~ /^(\$\d+):/) {		# old -G syntax
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
		my($fname) = $1; my($range) = $';
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    87
		$fname =~ s/QquOte/::/g;
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
		if ($range =~ /(.*)\.\.(.*)/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
			my($min) = ($1 eq '*') ? -1e99 : $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
			my($max) = ($2 eq '*') ?  1e99 : $2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
			croak("$0: illegal addr-expr $expr\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
				unless ((numberp($min) || $min =~ /^%/) &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
						(numberp($max) || $max =~ /^%/));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
			$expr = "$min<=$fname<=$max";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
		} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
			if ($range eq '*') {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
				$expr = "numberp(\$$fname)";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
			} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
				my(@vl) = split(/,/,$range);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
				$vl[0] = str2num($vl[0]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
				if (numberp($vl[0]) || $vl[0] =~ /^%/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
					$expr = "\$$fname==$vl[0]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
				} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
					$expr = "\$$fname=~/$vl[0]/";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
				}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
				for (my($vi)=1; $vi<=$#vl; $vi++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
					$vl[$vi] = str2num($vl[$vi]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
					if (numberp($vl[$vi]) || $vl[$vi] =~ /^%/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
						$expr .= "||\$$fname==$vl[$vi]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
					} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
						$expr .= "||\$$fname=~/$vl[$vi]/";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
	                }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   113
				}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   114
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   115
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   116
		print(STDERR "-G  AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   117
	}
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   118
	$expr =~ s/QquOte/::/g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   119
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   120
	my($relop) 	  = '<|<=|>|>=|!=|~=|<>|==';		# relational ops
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   121
	my($comparee) = '-?%?\$?[\w\.\+\-]+';			# nums, fields, PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   122
	my($numvar)	  = '^[\w\.]+$';					# fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   123
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   124
	if ($expr =~ /^($comparee)\s*($relop)\s*($comparee)$/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   125
		my($c1) = $1; my($c2) = $3; my($ro) = $2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   126
		$c1 =~ s/^0*(\d)/\1/; $c2 =~ s/^0*(\d)/\1/;	# de-octalize
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   127
		$ro = '!=' if ($ro eq '<>' || $ro eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   128
		$expr = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   129
		if (!numberp($c1) && $c1 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   130
			$c1 = "\$$c1";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   131
			$expr .= "numberp($c1) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   132
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   133
		if (!numberp($c2) && $c2 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   134
			$c2 = "\$$c2";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   135
			$expr .= "numberp($c2) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   136
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   137
		$expr .= "($c1 $ro $c2)";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   138
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   139
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   140
	elsif ($expr =~ /^($comparee)\s*($relop)\s*($comparee)\s*($relop)\s*($comparee)$/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   141
		my($c1) = $1; my($c2) = $3; my($c3) = $5; my($ro1) = $2; my($ro2) = $4;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   142
		$c1 =~ s/^0*(\d)/\1/; $c2 =~ s/^0*(\d)/\1/;	$c3 =~ s/^0*(\d)/\1/;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   143
		$ro1 = '!=' if ($ro1 eq '<>' || $ro1 eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   144
		$ro2 = '!=' if ($ro2 eq '<>' || $ro2 eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   145
		$expr = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   146
		if (!numberp($c1) && $c1 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   147
			$c1 = "\$$c1";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   148
			$expr .= "numberp($c1) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   149
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   150
		if (!numberp($c2) && $c2 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   151
			$c2 = "\$$c2";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   152
			$expr .= "numberp($c2) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   153
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   154
		if (!numberp($c3) && $c3 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   155
			$c3 = "\$$c3";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   156
			$expr .= "numberp($c3) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   157
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   158
		$expr .= "($c1 $ro1 $c2) && ($c2 $ro2 $c3)";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   159
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   160
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   161
	#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   162
	# substitute ANTS fields and %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   163
	#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   164
	print(STDERR "MID AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   165
	$expr =~ s{\$%}{%}g;								# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   166
	$expr =~ s{\$\$}{ AnTsDoLlAr }g;					# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   167
	while ($expr =~ /\${([^}]*)}/) {					# ${field}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   168
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   169
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   170
		$expr =~ s(\${$1})(AnTsDtArEf\[$fnr\]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   171
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   172
	while ($expr =~ /\$([\w\.]+)/) {					# $field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   173
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   174
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   175
		$expr =~ s{\$$1}{AnTsDtArEf\[$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   176
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   177
	while ($expr =~ /\$\+([\w\.]+)/) {					# $+field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   178
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   179
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   180
		$expr =~ s{\$\+$1}{(AnTsDtArEf\[$fnr\]-AnTsDtArEf0\[$fnr\])};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   181
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   182
	$expr =~ s{%%}{ AnTsPeRcEnT }g;						# escape
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   183
	while ($expr =~ /%([\w\.:]+)/) {					# %PARAMs
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   184
		my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   185
		croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   186
			unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   187
		$expr =~ s{%$p}{\$P\{'$p'\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   188
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   189
	$expr =~ s{AnTsDtArEf}{$bufVar}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   190
	$expr =~ s{ AnTsPeRcEnT} {%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   191
	$expr =~ s{ AnTsDoLlAr }{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   192
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   193
	#--------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   194
	# compile and return
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   195
	#--------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   196
QUOTED_ADDR_EXPR:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   197
	print(STDERR "OUT AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   198
    my($subR) = eval("sub { return $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   199
	print(STDERR "sub { return $expr };\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   200
    croak("sub { return $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   201
    return $subR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   202
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   203
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   204
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   205
# Edit Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   206
#	- execute calculation based on and/or modify current record
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   207
# 	- any valid PERL expression can be an edit expr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   208
# 	- $id are assumed to be fields (use $$id for perl vars)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   209
# 	- %id are assumed to be PARAMs (use %% to get %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   210
#	- ${field} are fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   211
#	- ${field..field} are field ranges
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   212
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   213
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   214
$antsEditExprUsesFields;								# flag
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   215
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   216
sub antsCompileEditExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   217
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   218
	my($expr,$bufVar) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   219
	$bufVar = '$ants_[0]' unless defined($bufVar);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   220
	$antsEditExprUsesFields = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   221
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   222
	print(STDERR "IN  EditExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   223
	goto QUOTED_EDIT_EXPR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   224
		if ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   225
		    (substr($expr,0,1) eq substr($expr,-1)));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   226
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   227
	$expr =~ s{\$%}{%}g;								# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   228
	$expr =~ s{\$\$}{AnTsDoLlAr}g;						# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   229
	while ($expr =~ /\${([^}]*)\.\.([^}]*)}/) {			# ${field..field}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   230
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   231
		my($ffnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   232
		croak("$0: unknown field $1\n") unless ($ffnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   233
		my($lfnr) = cardinalp($2) ? $2-1 : fnr($2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   234
		croak("$0: unknown field $2\n") unless ($lfnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   235
		croak("$0: empty field range $1..$2\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   236
			unless ($lfnr >= $ffnr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   237
		my($expanded) = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   238
		for (my($f)=$ffnr; $f<=$lfnr; $f++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   239
			$expanded .= "AnTsDtArEf[$f]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   240
			$expanded .= "," unless ($f == $lfnr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   241
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   242
		$expr =~ s(\${$1\.\.$2})($expanded);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   243
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   244
	while ($expr =~ /\${([^}]*)}/) {					# ${field}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   245
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   246
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   247
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   248
		$expr =~ s(\${$1})(AnTsDtArEf\[$fnr\]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   249
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   250
	while ($expr =~ /\$(-?[\w\.]+)/) {					# $field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   251
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   252
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   253
		if ($fnr < 0) {									# should only happen on $antsFnrNegativeOk
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   254
			$expr =~ s{\$$1}{AnTsDtArEf\[AnTsDtAlEn$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   255
		} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   256
			croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   257
			$expr =~ s{\$$1}{AnTsDtArEf\[$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   258
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   259
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   260
	while ($expr =~ /\$\+([\w\.]+)/) {					# $+field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   261
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   262
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   263
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   264
		$expr =~ s{\$\+$1}{(AnTsDtArEf\[$fnr\]-AnTsDtArEf0\[$fnr\])};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   265
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   266
	$expr =~ s{%%}{AnTsPeRcEnT}g;						# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   267
	while ($expr =~ /%([\w\.:]+)/) {					# %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   268
		my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   269
		croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   270
			unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   271
		$expr =~ s{%$p}{\$P\{"$p"\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   272
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   273
    if ($bufVar =~ m{\]$}) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   274
    	my($adl) = '@{' . $bufVar . '}';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   275
		$expr =~ s{AnTsDtAlEn}{$adl}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   276
    } else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   277
    	my($adl) = '@' . substr($bufVar,1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   278
		$expr =~ s{AnTsDtAlEn}{$adl}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   279
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   280
	$expr =~ s{AnTsDtArEf}{$bufVar}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   281
	$expr =~ s{AnTsDtArEf}{$bufVar}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   282
	$expr =~ s{AnTsPeRcEnT}{%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   283
	$expr =~ s{AnTsDoLlAr}{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   284
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   285
QUOTED_EDIT_EXPR:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   286
	$expr = "return $expr";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   287
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   288
	print(STDERR "OUT EditExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   289
    my($subR) = eval("sub { $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   290
    croak("sub { $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   291
    return $subR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   292
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   293
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   294
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   295
# Constant Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   296
#	- carry out calculation based on const and %PARAMs only
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   297
# 	- same as edit expressions without field substitutions (%PARAMs ok, though)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   298
#	- $ must still be escaped ($$), although this is unlikely to be used ever
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   299
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   300
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   301
sub antsCompileConstExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   302
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   303
	my($expr) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   304
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   305
	print(STDERR "IN  ConstExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   306
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   307
	unless ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   308
		(substr($expr,0,1) eq substr($expr,-1))) {		# quoted string
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   309
		$expr =~ s{\$%}{%}g;							# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   310
		$expr =~ s{\$\$}{AnTsDoLlAr}g;					# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   311
		$expr =~ s{%%}{AnTsPeRcEnT}g;					# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   312
		while ($expr =~ /%([\w\.:]+)/) {				# %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   313
			my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   314
			croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   315
				unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   316
			$expr =~ s{%$p}{\$P\{"$p"\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   317
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   318
		$expr =~ s{AnTsPeRcEnT}{%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   319
	    $expr =~ s{AnTsDoLlAr}{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   320
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   321
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   322
	$expr = "return $expr";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   323
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   324
	print(STDERR "OUT ConstExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   325
    my($subR) = eval("sub { $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   326
    croak("sub { $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   327
    return $subR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   328
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   329
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   330
1;