find-first-fail: Implemented -e end-value.

This commit is contained in:
Ole Tange 2021-01-09 16:50:05 +01:00
parent 1f068af082
commit 0d01eb1ea2
3 changed files with 62 additions and 37 deletions

View file

@ -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,11 +247,14 @@ find-first-fail() {
not='!' not='!'
fi fi
local low=$start
local high
if [ -z "$end" ] ; then
# No end value given with -e:
# exponential search for the first value that is false # exponential search for the first value that is false
# low = previous value (function($low) == true) # low = previous value (function($low) == true)
# high = low * 2 (function($high) == false) # high = low * 2 (function($high) == false)
local high=$(( $start*2 )) high=$(( $start*2 ))
local low=$start
while _run $low $high "?" "$@" ; do while _run $low $high "?" "$@" ; do
low=$high low=$high
high=$(( $high*2 )) high=$(( $high*2 ))
@ -252,6 +263,9 @@ find-first-fail() {
return return
fi fi
done 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;;

View file

@ -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'

View file

@ -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