diff options
| author | Conrad Meyer <cem@FreeBSD.org> | 2018-02-27 22:01:40 +0000 |
|---|---|---|
| committer | Conrad Meyer <cem@FreeBSD.org> | 2018-02-27 22:01:40 +0000 |
| commit | 3049d4ccc031e5d4d0ff6b9a2445131f507778f2 (patch) | |
| tree | 094f042017879712bc4b9ee62ac7014e7f87e673 /usr.bin/seq | |
| parent | 3acf1760b704cf876bea0c6b0f7e0a9431328d34 (diff) | |
Notes
Diffstat (limited to 'usr.bin/seq')
| -rw-r--r-- | usr.bin/seq/Makefile | 5 | ||||
| -rw-r--r-- | usr.bin/seq/seq.c | 56 | ||||
| -rw-r--r-- | usr.bin/seq/tests/Makefile | 7 | ||||
| -rwxr-xr-x | usr.bin/seq/tests/seq_test.sh | 40 |
4 files changed, 89 insertions, 19 deletions
diff --git a/usr.bin/seq/Makefile b/usr.bin/seq/Makefile index bb3c2959a062..d12ea095fb95 100644 --- a/usr.bin/seq/Makefile +++ b/usr.bin/seq/Makefile @@ -1,8 +1,13 @@ # $NetBSD: Makefile,v 1.3 2009/04/14 22:15:26 lukem Exp $ # $FreeBSD$ +.include <src.opts.mk> + PROG= seq LIBADD= m +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + .include <bsd.prog.mk> diff --git a/usr.bin/seq/seq.c b/usr.bin/seq/seq.c index b8c3faef7bf1..3ffcb6108dd0 100644 --- a/usr.bin/seq/seq.c +++ b/usr.bin/seq/seq.c @@ -76,16 +76,19 @@ static char *unescape(char *); int main(int argc, char *argv[]) { - int c = 0, errflg = 0; - int equalize = 0; - double first = 1.0; - double last = 0.0; - double incr = 0.0; + const char *sep, *term; struct lconv *locale; - char *fmt = NULL; - const char *sep = "\n"; - const char *term = NULL; - char pad = ZERO; + char pad, *fmt, *cur_print, *last_print; + double first, last, incr, last_shown_value, cur, step; + int c, errflg, equalize; + + pad = ZERO; + fmt = NULL; + first = 1.0; + last = incr = last_shown_value = 0.0; + c = errflg = equalize = 0; + sep = "\n"; + term = NULL; /* Determine the locale's decimal point. */ locale = localeconv(); @@ -169,17 +172,32 @@ main(int argc, char *argv[]) } else fmt = generate_format(first, incr, last, equalize, pad); - if (incr > 0) { - for (; first <= last; first += incr) { - printf(fmt, first); - fputs(sep, stdout); - } - } else { - for (; first >= last; first += incr) { - printf(fmt, first); - fputs(sep, stdout); - } + for (step = 1, cur = first; incr > 0 ? cur <= last : cur >= last; + cur = first + incr * step++) { + printf(fmt, cur); + fputs(sep, stdout); + last_shown_value = cur; } + + /* + * Did we miss the last value of the range in the loop above? + * + * We might have, so check if the printable version of the last + * computed value ('cur') and desired 'last' value are equal. If they + * are equal after formatting truncation, but 'cur' and + * 'last_shown_value' are not equal, it means the exit condition of the + * loop held true due to a rounding error and we still need to print + * 'last'. + */ + asprintf(&cur_print, fmt, cur); + asprintf(&last_print, fmt, last); + if (strcmp(cur_print, last_print) == 0 && cur != last_shown_value) { + fputs(last_print, stdout); + fputs(sep, stdout); + } + free(cur_print); + free(last_print); + if (term != NULL) fputs(term, stdout); diff --git a/usr.bin/seq/tests/Makefile b/usr.bin/seq/tests/Makefile new file mode 100644 index 000000000000..08fc0ca7676f --- /dev/null +++ b/usr.bin/seq/tests/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +PACKAGE= tests + +ATF_TESTS_SH= seq_test + +.include <bsd.test.mk> diff --git a/usr.bin/seq/tests/seq_test.sh b/usr.bin/seq/tests/seq_test.sh new file mode 100755 index 000000000000..efc4396752f5 --- /dev/null +++ b/usr.bin/seq/tests/seq_test.sh @@ -0,0 +1,40 @@ +# Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +atf_test_case float_rounding +float_rounding_head() +{ + atf_set "descr" "Check for correct termination in the face of floating point rounding" +} +float_rounding_body() +{ + atf_check -o inline:'1\n1.1\n1.2\n' seq 1 0.1 1.2 +} + +atf_init_test_cases() +{ + atf_add_test_case float_rounding +} |
