find-first-fail: Implemented -e end-value.
This commit is contained in:
parent
1f068af082
commit
0d01eb1ea2
|
@ -11,7 +11,7 @@ fragment (or numeric argument)
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<find-first-fail> [-2] [-q] [-s I<start>] [-v] [-V] I<command>
|
B<find-first-fail> [-2] [-q] [-s I<start>] [-e I<end>] [-v] [-V] I<command>
|
||||||
|
|
||||||
B<find-first-fail> -f I<inputfile> [-s I<start>] [-q] [-v] [-V] I<command>
|
B<find-first-fail> -f I<inputfile> [-s I<start>] [-q] [-v] [-V] I<command>
|
||||||
|
|
||||||
|
@ -57,7 +57,15 @@ Quiet. Ignore output from I<command>.
|
||||||
|
|
||||||
=item B<-s I<start>>
|
=item B<-s I<start>>
|
||||||
|
|
||||||
Start searching from the value I<start>. Normally searching will start from the value 1.
|
Start searching from the value I<start>. Normally searching will start
|
||||||
|
from the value 1.
|
||||||
|
|
||||||
|
|
||||||
|
=item B<-e I<end>>
|
||||||
|
|
||||||
|
End searching at the value I<end>. Normally this value will be
|
||||||
|
determined automatically, but you can limit the search to be below
|
||||||
|
the value I<end>.
|
||||||
|
|
||||||
|
|
||||||
=item B<-v>
|
=item B<-v>
|
||||||
|
@ -116,7 +124,7 @@ Complex commands can also be run:
|
||||||
=head2 Find the second limit of a program
|
=head2 Find the second limit of a program
|
||||||
|
|
||||||
Assume you have a program that is OK in the range 123..12345. How do
|
Assume you have a program that is OK in the range 123..12345. How do
|
||||||
you find the limits?
|
you find those limits?
|
||||||
|
|
||||||
myprog() { perl -e '$a=shift;if($a <= 123) { exit 0; }
|
myprog() { perl -e '$a=shift;if($a <= 123) { exit 0; }
|
||||||
else { exit ($a <= 12345) }' "$@"; }
|
else { exit ($a <= 12345) }' "$@"; }
|
||||||
|
@ -231,7 +239,7 @@ find-first-fail() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_find_in_arg() {
|
_find_in_arg() {
|
||||||
# If function(1) = false: run 'not function()' instead
|
# If function($start) == false: run 'not function()' instead
|
||||||
local not
|
local not
|
||||||
if _run "$start" "$start" "?" "$@" ; then
|
if _run "$start" "$start" "?" "$@" ; then
|
||||||
not=''
|
not=''
|
||||||
|
@ -239,19 +247,25 @@ find-first-fail() {
|
||||||
not='!'
|
not='!'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# exponential search for the first value that is false
|
|
||||||
# low = previous value (function($low) == true)
|
|
||||||
# high = low * 2 (function($high) == false)
|
|
||||||
local high=$(( $start*2 ))
|
|
||||||
local low=$start
|
local low=$start
|
||||||
while _run $low $high "?" "$@" ; do
|
local high
|
||||||
low=$high
|
if [ -z "$end" ] ; then
|
||||||
high=$(( $high*2 ))
|
# No end value given with -e:
|
||||||
if [ $high -gt 4611686018427387900 ] ; then
|
# exponential search for the first value that is false
|
||||||
echo "find-first-fail: Error: exit value does not change of '$@'" >&2
|
# low = previous value (function($low) == true)
|
||||||
return
|
# high = low * 2 (function($high) == false)
|
||||||
fi
|
high=$(( $start*2 ))
|
||||||
done
|
while _run $low $high "?" "$@" ; do
|
||||||
|
low=$high
|
||||||
|
high=$(( $high*2 ))
|
||||||
|
if [ $high -gt 4611686018427387900 ] ; then
|
||||||
|
echo "find-first-fail: Error: exit value does not change of '$@'" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
high=$end
|
||||||
|
fi
|
||||||
|
|
||||||
# low = tested good
|
# low = tested good
|
||||||
# high = tested fail
|
# high = tested fail
|
||||||
|
@ -366,8 +380,8 @@ find-first-fail() {
|
||||||
|
|
||||||
version() {
|
version() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
find-first-fail 20201222
|
find-first-fail 20210109
|
||||||
Copyright (C) 2020 Ole Tange, http://ole.tange.dk
|
Copyright (C) 2020-2021 Ole Tange, http://ole.tange.dk
|
||||||
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
|
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
find-first-fail comes with no warranty.
|
find-first-fail comes with no warranty.
|
||||||
|
@ -385,12 +399,13 @@ EOF
|
||||||
unset OPTIND
|
unset OPTIND
|
||||||
|
|
||||||
# Parse and remove options
|
# Parse and remove options
|
||||||
while getopts "2f:qs:vV" options; do
|
while getopts "2e:f:qs:vV" options; do
|
||||||
case "${options}" in
|
case "${options}" in
|
||||||
(2) opt2=true;;
|
(2) opt2=true;;
|
||||||
(f) optf=true; inputfile="$OPTARG";;
|
(f) optf=true; inputfile="$OPTARG";;
|
||||||
(q) quiet=">/dev/null 2>/dev/null";;
|
(q) quiet=">/dev/null 2>/dev/null";;
|
||||||
(s) start="$OPTARG";;
|
(s) start="$OPTARG";;
|
||||||
|
(e) end="$OPTARG";;
|
||||||
(v) verbose=true;;
|
(v) verbose=true;;
|
||||||
(V) version; exit 0;;
|
(V) version; exit 0;;
|
||||||
(-) break;;
|
(-) break;;
|
||||||
|
|
|
@ -97,6 +97,14 @@ test_file_start_middle_end() {
|
||||||
find-first-fail -s1 -f "$tmp" myparser
|
find-first-fail -s1 -f "$tmp" myparser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_end() {
|
||||||
|
echo 'Find 12'
|
||||||
|
myprog() { perl -e 'exit (shift > 12)' "$@"; }
|
||||||
|
export -f myprog
|
||||||
|
find-first-fail -v -e 13 myprog
|
||||||
|
find-first-fail -v -s 11 -e 15 myprog
|
||||||
|
}
|
||||||
|
|
||||||
export -f $(compgen -A function | grep test_)
|
export -f $(compgen -A function | grep test_)
|
||||||
compgen -A function | grep test_ | LC_ALL=C sort |
|
compgen -A function | grep test_ | LC_ALL=C sort |
|
||||||
parallel --timeout 1000% --tag -k --joblog /tmp/jl-`basename $0` '{} 2>&1'
|
parallel --timeout 1000% --tag -k --joblog /tmp/jl-`basename $0` '{} 2>&1'
|
||||||
|
|
|
@ -109,34 +109,36 @@ input.csv:
|
||||||
|
|
||||||
cat input.csv | plotpipe
|
cat input.csv | plotpipe
|
||||||
|
|
||||||
=head1 EXAMPLE
|
=head1 EXAMPLE: No x column
|
||||||
|
|
||||||
input.csv:
|
input.csv:
|
||||||
|
|
||||||
#Title line 1
|
#Plot with no x-value column
|
||||||
#This is title line 2
|
Values 1,Values 2
|
||||||
X axis header,Values 1,Values 2
|
28,32
|
||||||
1,28,32
|
12,35
|
||||||
2,12,35
|
3.5,3.5
|
||||||
3,3.5,3.5
|
|
||||||
|
|
||||||
cat input.csv | plotpipe
|
cat input.csv | plotpipe --nox
|
||||||
|
|
||||||
|
=head1 EXAMPLE: Log
|
||||||
|
|
||||||
|
input.csv:
|
||||||
|
|
||||||
|
#Plot with log y
|
||||||
|
2^n 3^n 4^n
|
||||||
|
1 1 1
|
||||||
|
2 3 4
|
||||||
|
4 9 16
|
||||||
|
8 27 64
|
||||||
|
|
||||||
|
cat input.csv | plotpipe --nox --logy
|
||||||
|
|
||||||
|
|
||||||
=head1 LIMITS
|
=head1 LIMITS
|
||||||
|
|
||||||
B<plotpipe> is limited by Gnuplot.
|
B<plotpipe> is limited by Gnuplot.
|
||||||
|
|
||||||
13x113425 = 28 MB
|
|
||||||
43x13203 = 10 MB
|
|
||||||
43x24068 = 5.8 MB
|
|
||||||
10x315636
|
|
||||||
Gnuplot will complain:
|
|
||||||
|
|
||||||
line -1: warning: Cannot find or open file "/tmp/plotXXXXX"
|
|
||||||
|
|
||||||
if the input is too big. The plot will then be incomplete.
|
|
||||||
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue