antsexprs.pl
author Andreas Thurnherr <ant@ldeo.columbia.edu>
Mon, 13 Apr 2020 11:06:22 -0400
changeset 40 c1803ae2540f
parent 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
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
     5
#                    dlm: Thu Mar  9 10:12:48 2017
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
     6
#                    uE-Info: 46 74 NIL 0 0 72 0 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
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    46
#	Mar  9, 2017: - removed perl 5.22 warning about re (non-quoted braces)
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
$DEBUG = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
# Address Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
#	- return value indicates whether current record matches
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
# 	- any valid PERL expression can be an addr expr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
# 	- $id are assumed to be fields (use $$id for perl vars)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
# 	- %id are assumed to be PARAMs (use %% to get %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
# 	- ABBREVIATIONS:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
#		- id1 relop id2 becomes numberp(id1) && numberp(id2) && $id1 relop $id2
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
#		- id1 relop id2 relop id3 is analogous
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
#		- id? can only be restricted field name ([\w\.] chars and, possibly, leading %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
#		- non-perl relops ~=, <> become !=
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
sub antsCompileAddrExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
	my($expr,$bufVar) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
	$bufVar = '$ants_[0]' unless (length($bufVar) > 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
	#---------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
	# handle abbreviations
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
	#---------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
	print(STDERR "IN  AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
	goto QUOTED_ADDR_EXPR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
		if ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
		    (substr($expr,0,1) eq substr($expr,-1)));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
	# NB: update following code if -S extensions in [list] change
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
	croak("$0: unsupported list(1)-specific address expression <$expr>\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
		if ($expr =~ /^\$?([\w\.]+)\s*~(([nN][aA][nN])|(([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?))/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
			$expr =~ /^\$?([\w\.]+)\s*<$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
			$expr =~ /^<\$?([\w\.]+)$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
			$expr =~ /^\$?([\w\.]+)\s*>$/ ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
			$expr =~ /^>\$?([\w\.]+)$/);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    85
	$expr =~ s/::/QquOte/g;										# new-style :: %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    86
	if ($expr =~ /^(%?[\w\.]+):/ || $expr =~ /^(\$\d+):/) {		# old -G syntax
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
		my($fname) = $1; my($range) = $';
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    88
		$fname =~ s/QquOte/::/g;
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
		if ($range =~ /(.*)\.\.(.*)/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
			my($min) = ($1 eq '*') ? -1e99 : $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
			my($max) = ($2 eq '*') ?  1e99 : $2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
			croak("$0: illegal addr-expr $expr\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
				unless ((numberp($min) || $min =~ /^%/) &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
						(numberp($max) || $max =~ /^%/));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
			$expr = "$min<=$fname<=$max";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
		} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
			if ($range eq '*') {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
				$expr = "numberp(\$$fname)";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
			} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
				my(@vl) = split(/,/,$range);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
				$vl[0] = str2num($vl[0]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
				if (numberp($vl[0]) || $vl[0] =~ /^%/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
					$expr = "\$$fname==$vl[0]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
				} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
					$expr = "\$$fname=~/$vl[0]/";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
				}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
				for (my($vi)=1; $vi<=$#vl; $vi++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
					$vl[$vi] = str2num($vl[$vi]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
					if (numberp($vl[$vi]) || $vl[$vi] =~ /^%/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
						$expr .= "||\$$fname==$vl[$vi]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
					} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
						$expr .= "||\$$fname=~/$vl[$vi]/";
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
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   117
		print(STDERR "-G  AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   118
	}
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   119
	$expr =~ s/QquOte/::/g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   120
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   121
	my($relop) 	  = '<|<=|>|>=|!=|~=|<>|==';		# relational ops
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   122
	my($comparee) = '-?%?\$?[\w\.\+\-]+';			# nums, fields, PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   123
	my($numvar)	  = '^[\w\.]+$';					# fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   124
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   125
	if ($expr =~ /^($comparee)\s*($relop)\s*($comparee)$/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   126
		my($c1) = $1; my($c2) = $3; my($ro) = $2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   127
		$c1 =~ s/^0*(\d)/\1/; $c2 =~ s/^0*(\d)/\1/;	# de-octalize
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   128
		$ro = '!=' if ($ro eq '<>' || $ro eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   129
		$expr = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   130
		if (!numberp($c1) && $c1 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   131
			$c1 = "\$$c1";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   132
			$expr .= "numberp($c1) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   133
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   134
		if (!numberp($c2) && $c2 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   135
			$c2 = "\$$c2";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   136
			$expr .= "numberp($c2) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   137
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   138
		$expr .= "($c1 $ro $c2)";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   139
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   140
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   141
	elsif ($expr =~ /^($comparee)\s*($relop)\s*($comparee)\s*($relop)\s*($comparee)$/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   142
		my($c1) = $1; my($c2) = $3; my($c3) = $5; my($ro1) = $2; my($ro2) = $4;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   143
		$c1 =~ s/^0*(\d)/\1/; $c2 =~ s/^0*(\d)/\1/;	$c3 =~ s/^0*(\d)/\1/;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   144
		$ro1 = '!=' if ($ro1 eq '<>' || $ro1 eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   145
		$ro2 = '!=' if ($ro2 eq '<>' || $ro2 eq '~=');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   146
		$expr = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   147
		if (!numberp($c1) && $c1 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   148
			$c1 = "\$$c1";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   149
			$expr .= "numberp($c1) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   150
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   151
		if (!numberp($c2) && $c2 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   152
			$c2 = "\$$c2";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   153
			$expr .= "numberp($c2) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   154
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   155
		if (!numberp($c3) && $c3 =~ /$numvar/) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   156
			$c3 = "\$$c3";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   157
			$expr .= "numberp($c3) && ";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   158
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   159
		$expr .= "($c1 $ro1 $c2) && ($c2 $ro2 $c3)";
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
	#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   163
	# substitute ANTS fields and %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   164
	#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   165
	print(STDERR "MID AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   166
	$expr =~ s{\$%}{%}g;								# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   167
	$expr =~ s{\$\$}{ AnTsDoLlAr }g;					# escape
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
   168
	while ($expr =~ /\$\{([^}]*)\}/) {					# ${field}
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   169
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   170
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   171
		$expr =~ s(\${$1})(AnTsDtArEf\[$fnr\]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   172
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   173
	while ($expr =~ /\$([\w\.]+)/) {					# $field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   174
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   175
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   176
		$expr =~ s{\$$1}{AnTsDtArEf\[$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   177
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   178
	while ($expr =~ /\$\+([\w\.]+)/) {					# $+field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   179
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   180
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   181
		$expr =~ s{\$\+$1}{(AnTsDtArEf\[$fnr\]-AnTsDtArEf0\[$fnr\])};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   182
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   183
	$expr =~ s{%%}{ AnTsPeRcEnT }g;						# escape
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   184
	while ($expr =~ /%([\w\.:]+)/) {					# %PARAMs
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   185
		my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   186
		croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   187
			unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   188
		$expr =~ s{%$p}{\$P\{'$p'\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   189
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   190
	$expr =~ s{AnTsDtArEf}{$bufVar}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   191
	$expr =~ s{ AnTsPeRcEnT} {%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   192
	$expr =~ s{ AnTsDoLlAr }{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   193
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   194
	#--------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   195
	# compile and return
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   196
	#--------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   197
QUOTED_ADDR_EXPR:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   198
	print(STDERR "OUT AddrExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   199
    my($subR) = eval("sub { return $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   200
	print(STDERR "sub { return $expr };\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   201
    croak("sub { return $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   202
    return $subR;
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
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   206
# Edit Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   207
#	- execute calculation based on and/or modify current record
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   208
# 	- any valid PERL expression can be an edit expr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   209
# 	- $id are assumed to be fields (use $$id for perl vars)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   210
# 	- %id are assumed to be PARAMs (use %% to get %)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   211
#	- ${field} are fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   212
#	- ${field..field} are field ranges
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   213
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   214
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   215
$antsEditExprUsesFields;								# flag
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   216
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   217
sub antsCompileEditExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   218
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   219
	my($expr,$bufVar) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   220
	$bufVar = '$ants_[0]' unless defined($bufVar);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   221
	$antsEditExprUsesFields = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   222
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   223
	print(STDERR "IN  EditExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   224
	goto QUOTED_EDIT_EXPR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   225
		if ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   226
		    (substr($expr,0,1) eq substr($expr,-1)));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   227
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   228
	$expr =~ s{\$%}{%}g;								# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   229
	$expr =~ s{\$\$}{AnTsDoLlAr}g;						# escape
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
   230
	while ($expr =~ /\$\{([^}]*)\.\.([^}]*)\}/) {			# ${field..field}
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   231
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   232
		my($ffnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   233
		croak("$0: unknown field $1\n") unless ($ffnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   234
		my($lfnr) = cardinalp($2) ? $2-1 : fnr($2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   235
		croak("$0: unknown field $2\n") unless ($lfnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   236
		croak("$0: empty field range $1..$2\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   237
			unless ($lfnr >= $ffnr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   238
		my($expanded) = '';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   239
		for (my($f)=$ffnr; $f<=$lfnr; $f++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   240
			$expanded .= "AnTsDtArEf[$f]";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   241
			$expanded .= "," unless ($f == $lfnr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   242
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   243
		$expr =~ s(\${$1\.\.$2})($expanded);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   244
	}
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
   245
	while ($expr =~ /\$\{([^}]*)\}/) {					# ${field}
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   246
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   247
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   248
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   249
		$expr =~ s(\${$1})(AnTsDtArEf\[$fnr\]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   250
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   251
	while ($expr =~ /\$(-?[\w\.]+)/) {					# $field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   252
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   253
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   254
		if ($fnr < 0) {									# should only happen on $antsFnrNegativeOk
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   255
			$expr =~ s{\$$1}{AnTsDtArEf\[AnTsDtAlEn$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   256
		} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   257
			croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   258
			$expr =~ s{\$$1}{AnTsDtArEf\[$fnr\]};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   259
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   260
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   261
	while ($expr =~ /\$\+([\w\.]+)/) {					# $+field
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   262
		$antsEditExprUsesFields |= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   263
		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   264
		croak("$0: unknown field $1\n") unless ($fnr >= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   265
		$expr =~ s{\$\+$1}{(AnTsDtArEf\[$fnr\]-AnTsDtArEf0\[$fnr\])};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   266
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   267
	$expr =~ s{%%}{AnTsPeRcEnT}g;						# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   268
	while ($expr =~ /%([\w\.:]+)/) {					# %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   269
		my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   270
		croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   271
			unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   272
		$expr =~ s{%$p}{\$P\{"$p"\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   273
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   274
    if ($bufVar =~ m{\]$}) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   275
    	my($adl) = '@{' . $bufVar . '}';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   276
		$expr =~ s{AnTsDtAlEn}{$adl}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   277
    } else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   278
    	my($adl) = '@' . substr($bufVar,1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   279
		$expr =~ s{AnTsDtAlEn}{$adl}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   280
    }
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{AnTsDtArEf}{$bufVar}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   283
	$expr =~ s{AnTsPeRcEnT}{%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   284
	$expr =~ s{AnTsDoLlAr}{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   285
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   286
QUOTED_EDIT_EXPR:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   287
	$expr = "return $expr";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   288
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   289
	print(STDERR "OUT EditExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   290
    my($subR) = eval("sub { $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   291
    croak("sub { $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   292
    return $subR;
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
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   296
# Constant Expressions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   297
#	- carry out calculation based on const and %PARAMs only
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   298
# 	- same as edit expressions without field substitutions (%PARAMs ok, though)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   299
#	- $ must still be escaped ($$), although this is unlikely to be used ever
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   300
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   301
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   302
sub antsCompileConstExpr($)								# subst fields/%PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   303
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   304
	my($expr) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   305
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   306
	print(STDERR "IN  ConstExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   307
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   308
	unless ((substr($expr,0,1) eq "'" || substr($expr,0,1) eq '"') &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   309
		(substr($expr,0,1) eq substr($expr,-1))) {		# quoted string
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   310
		$expr =~ s{\$%}{%}g;							# allow for $%param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   311
		$expr =~ s{\$\$}{AnTsDoLlAr}g;					# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   312
		$expr =~ s{%%}{AnTsPeRcEnT}g;					# escape
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   313
		while ($expr =~ /%([\w\.:]+)/) {				# %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   314
			my($p) = $1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   315
			croak("$0: Undefined PARAM %$p\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   316
				unless defined($P{$p});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   317
			$expr =~ s{%$p}{\$P\{"$p"\}};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   318
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   319
		$expr =~ s{AnTsPeRcEnT}{%}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   320
	    $expr =~ s{AnTsDoLlAr}{\$}g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   321
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   322
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   323
	$expr = "return $expr";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   324
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   325
	print(STDERR "OUT ConstExpr = $expr\n") if ($DEBUG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   326
    my($subR) = eval("sub { $expr };");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   327
    croak("sub { $expr }; => $@\n") if ($@);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   328
    return $subR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   329
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   330
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   331
1;