diff options
Diffstat (limited to 'usr.bin/factor')
-rw-r--r-- | usr.bin/factor/Makefile | 19 | ||||
-rw-r--r-- | usr.bin/factor/Makefile.depend | 16 | ||||
-rw-r--r-- | usr.bin/factor/Makefile.depend.options | 5 | ||||
-rw-r--r-- | usr.bin/factor/factor.6 | 128 | ||||
-rw-r--r-- | usr.bin/factor/factor.c | 399 | ||||
-rw-r--r-- | usr.bin/factor/tests/Makefile | 4 | ||||
-rwxr-xr-x | usr.bin/factor/tests/factor_tests.sh | 85 | ||||
-rwxr-xr-x | usr.bin/factor/tests/primes_tests.sh | 75 |
8 files changed, 731 insertions, 0 deletions
diff --git a/usr.bin/factor/Makefile b/usr.bin/factor/Makefile new file mode 100644 index 000000000000..a0109462fcb3 --- /dev/null +++ b/usr.bin/factor/Makefile @@ -0,0 +1,19 @@ +.include <src.opts.mk> + +PROG= factor +SRCS= factor.c pr_tbl.c +CFLAGS+=-I${SRCTOP}/usr.bin/primes + +.if ${MK_OPENSSL} != "no" +CFLAGS+=-DHAVE_OPENSSL +LIBADD+=crypto +.endif + +MAN= factor.6 +MLINKS+=factor.6 primes.6 +.PATH: ${SRCTOP}/usr.bin/primes + +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + +.include <bsd.prog.mk> diff --git a/usr.bin/factor/Makefile.depend b/usr.bin/factor/Makefile.depend new file mode 100644 index 000000000000..577dc5747f1e --- /dev/null +++ b/usr.bin/factor/Makefile.depend @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/libthr \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/factor/Makefile.depend.options b/usr.bin/factor/Makefile.depend.options new file mode 100644 index 000000000000..b374d7a1fd52 --- /dev/null +++ b/usr.bin/factor/Makefile.depend.options @@ -0,0 +1,5 @@ +# This file is not autogenerated - take care! + +DIRDEPS_OPTIONS= OPENSSL + +.include <dirdeps-options.mk> diff --git a/usr.bin/factor/factor.6 b/usr.bin/factor/factor.6 new file mode 100644 index 000000000000..c3d00eb744a0 --- /dev/null +++ b/usr.bin/factor/factor.6 @@ -0,0 +1,128 @@ +.\" Copyright (c) 1989, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Landon Curt Noll. +.\" +.\" 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. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo +.\" +.\" chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\ +.\" +.Dd January 12, 2020 +.Dt FACTOR 6 +.Os +.Sh NAME +.Nm factor , primes +.Nd factor a number, generate primes +.Sh SYNOPSIS +.Nm +.Op Fl h +.Op Ar number ... +.Nm primes +.Op Fl h +.Op Ar start Op Ar stop +.Sh DESCRIPTION +The +.Nm +utility will factor positive integers. +When a number is factored, it is printed, followed by a +.Ql \&: , +and the list of factors on a single line. +Factors are listed in ascending order, and are preceded by a space. +If a factor divides a value more than once, it will be printed more than once. +.Pp +When +.Nm +is invoked with one or more arguments, each argument will be factored. +.Pp +When +.Nm +is invoked with no arguments, +.Nm +reads numbers, one per line, from standard input until end of file or 0 +is entered or an error occurs. +Leading white-space and empty lines are ignored. +.Pp +Numbers may be preceded by a single +.Ql + . +Numbers can be either decimal or hexadecimal strings where the longest +leading substring is used. +Numbers are terminated by a non-digit character (such as a newline). +If the string contains only decimal digits, it is treated as a +decimal representation for a number. +A hexadecimal string can contain an optional +.Em 0x +or +.Em 0X +prefix. +After a number is read, it is factored. +.Pp +The +.Nm primes +utility prints primes in ascending order, one per line, starting at or above +.Ar start +and continuing until, but not including +.Ar stop . +The +.Ar start +value must be at least 0 and not greater than +.Ar stop . +The +.Ar stop +value must not be greater than the maximum. +The default and maximum value of +.Ar stop +is 18446744073709551615. +.Pp +When the +.Nm primes +utility is invoked with no arguments, +.Ar start +is read from standard input and +.Ar stop +is taken to be the maximum. +The +.Ar start +value may be preceded by a single +.Ql + . +The +.Ar start +value is terminated by a non-digit character (such as a newline). +.Sh DIAGNOSTICS +.Bl -diag +.It "negative numbers aren't permitted" +.It "illegal numeric format" +.It "start value must be less than stop value" +.It "Result too large" +.El +.Sh BUGS +.Nm +cannot handle the +.Dq "10 most wanted" +factor list, +.Nm primes +will not get you a world record. diff --git a/usr.bin/factor/factor.c b/usr.bin/factor/factor.c new file mode 100644 index 000000000000..9d8fdbe1fb0f --- /dev/null +++ b/usr.bin/factor/factor.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Landon Curt Noll. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +/* + * factor - factor a number into primes + * + * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo + * + * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\ + * + * usage: + * factor [-h] [number] ... + * + * The form of the output is: + * + * number: factor1 factor1 factor2 factor3 factor3 factor3 ... + * + * where factor1 <= factor2 <= factor3 <= ... + * + * If no args are given, the list of numbers are read from stdin. + */ + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <inttypes.h> +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "primes.h" + +#ifdef HAVE_OPENSSL + +#include <openssl/bn.h> + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static inline int +BN_check_prime(BIGNUM *p, BN_CTX *ctx, BN_GENCB *cb) +{ + const int nchecks = 5; + + return BN_is_prime_ex(p, nchecks, ctx, cb); +} +#endif + +static void pollard_pminus1(BIGNUM *); /* print factors for big numbers */ + +#else + +typedef ubig BIGNUM; +typedef u_long BN_ULONG; + +#define BN_CTX int +#define BN_CTX_new() NULL +#define BN_new() ((BIGNUM *)calloc(sizeof(BIGNUM), 1)) +#define BN_is_zero(v) (*(v) == 0) +#define BN_is_one(v) (*(v) == 1) +#define BN_mod_word(a, b) (*(a) % (b)) + +static int BN_dec2bn(BIGNUM **, const char *); +static int BN_hex2bn(BIGNUM **, const char *); +static BN_ULONG BN_div_word(BIGNUM *, BN_ULONG); +static void BN_print_fp(FILE *, const BIGNUM *); + +#endif + +static void BN_print_dec_fp(FILE *, const BIGNUM *); +static void convert_str2bn(BIGNUM **, char *); +static bool is_hex_str(char *); +static void pr_fact(BIGNUM *); /* print factors of a value */ +static void pr_print(BIGNUM *); /* print a prime */ +static void usage(void); + +static BN_CTX *ctx; /* just use a global context */ +static int hflag; + +int +main(int argc, char *argv[]) +{ + BIGNUM *val; + int ch; + char *p, buf[LINE_MAX]; /* > max number of digits. */ + + ctx = BN_CTX_new(); + val = BN_new(); + if (val == NULL) + errx(1, "can't initialise bignum"); + + while ((ch = getopt(argc, argv, "h")) != -1) + switch (ch) { + case 'h': + hflag++; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + /* No args supplied, read numbers from stdin. */ + if (argc == 0) + for (;;) { + if (fgets(buf, sizeof(buf), stdin) == NULL) { + if (ferror(stdin)) + err(1, "stdin"); + exit (0); + } + for (p = buf; isblank(*p); ++p); + if (*p == '\n' || *p == '\0') + continue; + convert_str2bn(&val, p); + pr_fact(val); + } + /* Factor the arguments. */ + else + for (p = *argv; p != NULL; p = *++argv) { + convert_str2bn(&val, p); + pr_fact(val); + } + exit(0); +} + +/* + * pr_fact - print the factors of a number + * + * Print the factors of the number, from the lowest to the highest. + * A factor will be printed multiple times if it divides the value + * multiple times. + * + * Factors are printed with leading tabs. + */ +static void +pr_fact(BIGNUM *val) +{ + const ubig *fact; /* The factor found. */ + + /* Firewall - catch 0 and 1. */ + if (BN_is_zero(val)) /* Historical practice; 0 just exits. */ + exit(0); + if (BN_is_one(val)) { + printf("1: 1\n"); + return; + } + + /* Factor value. */ + + if (hflag) { + fputs("0x", stdout); + BN_print_fp(stdout, val); + } else + BN_print_dec_fp(stdout, val); + putchar(':'); + for (fact = &prime[0]; !BN_is_one(val); ++fact) { + /* Look for the smallest factor. */ + do { + if (BN_mod_word(val, (BN_ULONG)*fact) == 0) + break; + } while (++fact <= pr_limit); + + /* Watch for primes larger than the table. */ + if (fact > pr_limit) { +#ifdef HAVE_OPENSSL + BIGNUM *bnfact; + + bnfact = BN_new(); + BN_set_word(bnfact, *(fact - 1)); + if (!BN_sqr(bnfact, bnfact, ctx)) + errx(1, "error in BN_sqr()"); + if (BN_cmp(bnfact, val) > 0 || + BN_check_prime(val, NULL, NULL) == 1) + pr_print(val); + else + pollard_pminus1(val); +#else + pr_print(val); +#endif + break; + } + + /* Divide factor out until none are left. */ + do { + printf(hflag ? " 0x%" PRIx64 "" : " %" PRIu64 "", *fact); + BN_div_word(val, (BN_ULONG)*fact); + } while (BN_mod_word(val, (BN_ULONG)*fact) == 0); + + /* Let the user know we're doing something. */ + fflush(stdout); + } + putchar('\n'); +} + +static void +pr_print(BIGNUM *val) +{ + if (hflag) { + fputs(" 0x", stdout); + BN_print_fp(stdout, val); + } else { + putchar(' '); + BN_print_dec_fp(stdout, val); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: factor [-h] [value ...]\n"); + exit(1); +} + +#ifdef HAVE_OPENSSL + +/* pollard p-1, algorithm from Jim Gillogly, May 2000 */ +static void +pollard_pminus1(BIGNUM *val) +{ + BIGNUM *base, *rbase, *num, *i, *x; + + base = BN_new(); + rbase = BN_new(); + num = BN_new(); + i = BN_new(); + x = BN_new(); + + BN_set_word(rbase, 1); +newbase: + if (!BN_add_word(rbase, 1)) + errx(1, "error in BN_add_word()"); + BN_set_word(i, 2); + BN_copy(base, rbase); + + for (;;) { + BN_mod_exp(base, base, i, val, ctx); + if (BN_is_one(base)) + goto newbase; + + BN_copy(x, base); + BN_sub_word(x, 1); + if (!BN_gcd(x, x, val, ctx)) + errx(1, "error in BN_gcd()"); + + if (!BN_is_one(x)) { + if (BN_check_prime(x, NULL, NULL) == 1) + pr_print(x); + else + pollard_pminus1(x); + fflush(stdout); + + BN_div(num, NULL, val, x, ctx); + if (BN_is_one(num)) + return; + if (BN_check_prime(num, NULL, NULL) == 1) { + pr_print(num); + fflush(stdout); + return; + } + BN_copy(val, num); + } + if (!BN_add_word(i, 1)) + errx(1, "error in BN_add_word()"); + } +} + +/* + * Sigh.. No _decimal_ output to file functions in BN. + */ +static void +BN_print_dec_fp(FILE *fp, const BIGNUM *num) +{ + char *buf; + + buf = BN_bn2dec(num); + if (buf == NULL) + return; /* XXX do anything here? */ + fprintf(fp, "%s", buf); + free(buf); +} + +#else + +static void +BN_print_fp(FILE *fp, const BIGNUM *num) +{ + fprintf(fp, "%lx", (unsigned long)*num); +} + +static void +BN_print_dec_fp(FILE *fp, const BIGNUM *num) +{ + fprintf(fp, "%lu", (unsigned long)*num); +} + +static int +BN_dec2bn(BIGNUM **a, const char *str) +{ + char *p; + + errno = 0; + **a = strtoul(str, &p, 10); + return (errno == 0 ? 1 : 0); /* OpenSSL returns 0 on error! */ +} + +static int +BN_hex2bn(BIGNUM **a, const char *str) +{ + char *p; + + errno = 0; + **a = strtoul(str, &p, 16); + return (errno == 0 ? 1 : 0); /* OpenSSL returns 0 on error! */ +} + +static BN_ULONG +BN_div_word(BIGNUM *a, BN_ULONG b) +{ + BN_ULONG mod; + + mod = *a % b; + *a /= b; + return mod; +} + +#endif + +/* + * Scan the string from left-to-right to see if the longest substring + * is a valid hexadecimal number. + */ +static bool +is_hex_str(char *str) +{ + char c, *p; + bool saw_hex = false; + + for (p = str; *p; p++) { + if (isdigit(*p)) + continue; + c = tolower(*p); + if (c >= 'a' && c <= 'f') { + saw_hex = true; + continue; + } + break; /* Not a hexadecimal digit. */ + } + return saw_hex; +} + +/* Convert string pointed to by *str to a bignum. */ +static void +convert_str2bn(BIGNUM **val, char *p) +{ + int n = 0; + + if (*p == '+') p++; + if (*p == '-') + errx(1, "negative numbers aren't permitted."); + if (*p == '0') { + p++; + if (*p == 'x' || *p == 'X') + n = BN_hex2bn(val, ++p); + } else { + n = is_hex_str(p) ? BN_hex2bn(val, p) : BN_dec2bn(val, p); + } + if (n == 0) + errx(1, "%s: illegal numeric format.", p); +} diff --git a/usr.bin/factor/tests/Makefile b/usr.bin/factor/tests/Makefile new file mode 100644 index 000000000000..f9b13443ae92 --- /dev/null +++ b/usr.bin/factor/tests/Makefile @@ -0,0 +1,4 @@ +ATF_TESTS_SH+= factor_tests +ATF_TESTS_SH+= primes_tests + +.include <bsd.test.mk> diff --git a/usr.bin/factor/tests/factor_tests.sh b/usr.bin/factor/tests/factor_tests.sh new file mode 100755 index 000000000000..0d9156673582 --- /dev/null +++ b/usr.bin/factor/tests/factor_tests.sh @@ -0,0 +1,85 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright 2023 (C) Enji Cooper +# +# 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. + +atf_test_case float_non_prime +float_non_prime_head() +{ + atf_set "descr" "Test with a float non-prime number" +} +float_non_prime_body() +{ + atf_check -o inline:"1: 1\n" factor 1.44 +} + +atf_test_case float_prime +float_prime_head() +{ + atf_set "descr" "Test with a float prime number" +} +float_prime_body() +{ + pi="3.141592653589793238462643383279502884197" + atf_check -o inline:"3: 3\n" factor $pi +} + +atf_test_case int_non_prime +int_non_prime_head() +{ + atf_set "descr" "Test with an integral prime number" +} +int_non_prime_body() +{ + atf_check -o inline:"8: 2 2 2\n" factor 8 +} + +atf_test_case int_prime +int_prime_head() +{ + atf_set "descr" "Test with an integral prime number" +} +int_prime_body() +{ + atf_check -o inline:"31: 31\n" factor 31 +} + +atf_test_case negative_numbers_not_allowed +negative_numbers_not_allowed_head() +{ + atf_set "descr" "Verify that negative numbers are not allowed." +} +negative_numbers_not_allowed_body() +{ + atf_check -s not-exit:0 -e inline:"factor: negative numbers aren't permitted.\n" factor -- -4 +} + +atf_init_test_cases() +{ + atf_add_test_case float_non_prime + atf_add_test_case float_prime + atf_add_test_case int_non_prime + atf_add_test_case int_prime + atf_add_test_case negative_numbers_not_allowed +} diff --git a/usr.bin/factor/tests/primes_tests.sh b/usr.bin/factor/tests/primes_tests.sh new file mode 100755 index 000000000000..2b00e9ba34c8 --- /dev/null +++ b/usr.bin/factor/tests/primes_tests.sh @@ -0,0 +1,75 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright 2023 (C) Enji Cooper +# +# 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. + +atf_test_case invalid_range +invalid_range_head() +{ + atf_set "descr" "Verify that invalid ranges are not allowed." +} +invalid_range_body() +{ + atf_check -s not-exit:0 -e inline:"primes: start value must be less than stop value.\n" primes -- 2 1 +} + +atf_test_case negative_numbers_not_allowed +negative_numbers_not_allowed_head() +{ + atf_set "descr" "Verify that negative numbers are not allowed." +} +negative_numbers_not_allowed_body() +{ + atf_check -s not-exit:0 -e inline:"primes: negative numbers aren't permitted.\n" primes -- -1 0 +} + +atf_test_case no_primes_between_between_20_and_22 +no_primes_between_between_20_and_22_head() +{ + atf_set "descr" "Show that no primes exist between [20, 22]." +} + +no_primes_between_between_20_and_22_body() +{ + atf_check primes 20 22 +} + +atf_test_case primes_in_20_to_50_range +primes_in_20_to_50_range_head() +{ + atf_set "descr" "Find all primes between [20, 50]." +} + +primes_in_20_to_50_range_body() +{ + atf_check -o inline:"23\n29\n31\n37\n41\n43\n47\n" primes 20 50 +} + +atf_init_test_cases() +{ + atf_add_test_case invalid_range + atf_add_test_case negative_numbers_not_allowed + atf_add_test_case no_primes_between_between_20_and_22 + atf_add_test_case primes_in_20_to_50_range +} |