summaryrefslogtreecommitdiffstats
path: root/primes
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1995-03-23 08:28:00 +0000
committercgd <cgd@NetBSD.org>1995-03-23 08:28:00 +0000
commit94b5353c71e7246077d468afe68d51ce85fc213d (patch)
tree0b6f70b8110f5d6650a6083460424df854c415f8 /primes
parent1c0b80f0fe7a28cd947ace3e69f5fd2ac8ed47cb (diff)
downloadbsdgames-darwin-94b5353c71e7246077d468afe68d51ce85fc213d.tar.gz
bsdgames-darwin-94b5353c71e7246077d468afe68d51ce85fc213d.tar.zst
bsdgames-darwin-94b5353c71e7246077d468afe68d51ce85fc213d.zip
merge with Lite, new RCS id conventions, etc.
Diffstat (limited to 'primes')
-rw-r--r--primes/Makefile4
-rw-r--r--primes/pattern.c13
-rw-r--r--primes/pr_tbl.c13
-rw-r--r--primes/primes.c315
-rw-r--r--primes/primes.h25
5 files changed, 152 insertions, 218 deletions
diff --git a/primes/Makefile b/primes/Makefile
index a410af94..0a6747f1 100644
--- a/primes/Makefile
+++ b/primes/Makefile
@@ -1,5 +1,5 @@
-# from: @(#)Makefile 5.1 (Berkeley) 5/11/90
-# $Id: Makefile,v 1.2 1993/08/01 05:44:42 mycroft Exp $
+# $NetBSD: Makefile,v 1.3 1995/03/23 08:35:43 cgd Exp $
+# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= primes
SRCS= pattern.c pr_tbl.c primes.c
diff --git a/primes/pattern.c b/primes/pattern.c
index 50e21ab5..c770791c 100644
--- a/primes/pattern.c
+++ b/primes/pattern.c
@@ -1,6 +1,8 @@
+/* $NetBSD: pattern.c,v 1.3 1995/03/23 08:35:47 cgd Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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.
@@ -35,8 +37,11 @@
*/
#ifndef lint
-/*static char sccsid[] = "from: @(#)pattern.c 5.2 (Berkeley) 6/1/90";*/
-static char rcsid[] = "$Id: pattern.c,v 1.2 1993/08/01 18:53:08 mycroft Exp $";
+#if 0
+static char sccsid[] = "@(#)pattern.c 8.1 (Berkeley) 5/31/93";
+#else
+static char rcsid[] = "$NetBSD: pattern.c,v 1.3 1995/03/23 08:35:47 cgd Exp $";
+#endif
#endif /* not lint */
/*
diff --git a/primes/pr_tbl.c b/primes/pr_tbl.c
index f6a42cfb..f92f21f3 100644
--- a/primes/pr_tbl.c
+++ b/primes/pr_tbl.c
@@ -1,6 +1,8 @@
+/* $NetBSD: pr_tbl.c,v 1.3 1995/03/23 08:35:52 cgd Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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.
@@ -35,8 +37,11 @@
*/
#ifndef lint
-/*static char sccsid[] = "from: @(#)pr_tbl.c 5.2 (Berkeley) 6/1/90";*/
-static char rcsid[] = "$Id: pr_tbl.c,v 1.2 1993/08/01 18:53:05 mycroft Exp $";
+#if 0
+static char sccsid[] = "@(#)pr_tbl.c 8.1 (Berkeley) 5/31/93";
+#else
+static char rcsid[] = "$NetBSD: pr_tbl.c,v 1.3 1995/03/23 08:35:52 cgd Exp $";
+#endif
#endif /* not lint */
/*
diff --git a/primes/primes.c b/primes/primes.c
index d9f27fe0..57e00731 100644
--- a/primes/primes.c
+++ b/primes/primes.c
@@ -1,6 +1,8 @@
+/* $NetBSD: primes.c,v 1.4 1995/03/23 08:35:55 cgd Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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.
@@ -35,22 +37,25 @@
*/
#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
-/*static char sccsid[] = "from: @(#)primes.c 5.4 (Berkeley) 6/1/90";*/
-static char rcsid[] = "$Id: primes.c,v 1.3 1994/03/01 01:07:48 cgd Exp $";
+#if 0
+static char sccsid[] = "@(#)primes.c 8.4 (Berkeley) 3/21/94";
+#else
+static char rcsid[] = "$NetBSD: primes.c,v 1.4 1995/03/23 08:35:55 cgd Exp $";
+#endif
#endif /* not lint */
/*
* primes - generate a table of primes between two values
*
- * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
*
- * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
*
* usage:
* primes [start [stop]]
@@ -59,16 +64,18 @@ static char rcsid[] = "$Id: primes.c,v 1.3 1994/03/01 01:07:48 cgd Exp $";
* the value 4294967295 (2^32-1) is assumed. If start is
* omitted, start is read from standard input.
*
- * Prints "ouch" if start or stop is bogus.
- *
* validation check: there are 664579 primes between 0 and 10^7
*/
-#include <stdio.h>
-#include <math.h>
-#include <memory.h>
#include <ctype.h>
+#include <err.h>
+#include <errno.h>
#include <limits.h>
+#include <math.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+
#include "primes.h"
/*
@@ -99,197 +106,112 @@ extern ubig *pr_limit; /* largest prime in the prime array */
extern char pattern[];
extern int pattern_size; /* length of pattern array */
-#define MAX_LINE 255 /* max line allowed on stdin */
-
-char *read_num_buf(); /* read a number buffer */
-void primes(); /* print the primes in range */
-char *program; /* our name */
+void primes __P((ubig, ubig));
+ubig read_num_buf __P((void));
+void usage __P((void));
+int
main(argc, argv)
- int argc; /* arg count */
- char *argv[]; /* args */
+ int argc;
+ char *argv[];
{
- char buf[MAX_LINE+1]; /* input buffer */
- char *ret; /* return result */
- ubig start; /* where to start generating */
- ubig stop; /* don't generate at or above this value */
+ ubig start; /* where to start generating */
+ ubig stop; /* don't generate at or above this value */
+ int ch;
+ char *p;
+
+ while ((ch = getopt(argc, argv, "")) != EOF)
+ switch (ch) {
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
- /*
- * parse args
- */
- program = argv[0];
start = 0;
stop = BIG;
- if (argc == 3) {
- /* convert low and high args */
- if (read_num_buf(NULL, argv[1]) == NULL) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
- if (read_num_buf(NULL, argv[2]) == NULL) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
- if (sscanf(argv[1], "%lu", &start) != 1) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
- if (sscanf(argv[2], "%lu", &stop) != 1) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
-
- } else if (argc == 2) {
- /* convert low arg */
- if (read_num_buf(NULL, argv[1]) == NULL) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
- if (sscanf(argv[1], "%lu", &start) != 1) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
-
- } else {
- /* read input until we get a good line */
- if (read_num_buf(stdin, buf) != NULL) {
- /* convert the buffer */
- if (sscanf(buf, "%lu", &start) != 1) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
- }
- } else {
- exit(0);
- }
- }
- if (start > stop) {
- fprintf(stderr, "%s: ouch\n", program);
- exit(1);
+ /*
+ * Convert low and high args. Strtoul(3) sets errno to
+ * ERANGE if the number is too large, but, if there's
+ * a leading minus sign it returns the negation of the
+ * result of the conversion, which we'd rather disallow.
+ */
+ switch (argc) {
+ case 2:
+ /* Start and stop supplied on the command line. */
+ if (argv[0][0] == '-' || argv[1][0] == '-')
+ errx(1, "negative numbers aren't permitted.");
+
+ errno = 0;
+ start = strtoul(argv[0], &p, 10);
+ if (errno)
+ err(1, "%s", argv[0]);
+ if (*p != '\0')
+ errx(1, "%s: illegal numeric format.", argv[0]);
+
+ errno = 0;
+ stop = strtoul(argv[1], &p, 10);
+ if (errno)
+ err(1, "%s", argv[1]);
+ if (*p != '\0')
+ errx(1, "%s: illegal numeric format.", argv[1]);
+ break;
+ case 1:
+ /* Start on the command line. */
+ if (argv[0][0] == '-')
+ errx(1, "negative numbers aren't permitted.");
+
+ errno = 0;
+ start = strtoul(argv[0], &p, 10);
+ if (errno)
+ err(1, "%s", argv[0]);
+ if (*p != '\0')
+ errx(1, "%s: illegal numeric format.", argv[0]);
+ break;
+ case 0:
+ start = read_num_buf();
+ break;
+ default:
+ usage();
}
+
+ if (start > stop)
+ errx(1, "start value must be less than stop value.");
primes(start, stop);
exit(0);
}
/*
- * read_num_buf - read a number buffer from a stream
- *
- * Read a number on a line of the form:
- *
- * ^[ \t]*\(+?[0-9][0-9]\)*.*$
- *
- * where ? is a 1-or-0 operator and the number is within \( \).
- *
- * If does not match the above pattern, it is ignored and a new
- * line is read. If the number is too large or small, we will
- * print ouch and read a new line.
- *
- * We have to be very careful on how we check the magnitude of the
- * input. We can not use numeric checks because of the need to
- * check values against maximum numeric values.
- *
- * This routine will return a line containing a ascii number between
- * 0 and BIG, or it will return NULL.
- *
- * If the stream is NULL then buf will be processed as if were
- * a single line stream.
- *
- * returns:
- * char * pointer to leading digit or +
- * NULL EOF or error
+ * read_num_buf --
+ * This routine returns a number n, where 0 <= n && n <= BIG.
*/
-char *
-read_num_buf(input, buf)
- FILE *input; /* input stream or NULL */
- char *buf; /* input buffer */
+ubig
+read_num_buf()
{
- static char limit[MAX_LINE+1]; /* ascii value of BIG */
- static int limit_len; /* digit count of limit */
- int len; /* digits in input (excluding +/-) */
- char *s; /* line start marker */
- char *d; /* first digit, skip +/- */
- char *p; /* scan pointer */
- char *z; /* zero scan pointer */
-
- /* form the ascii value of BIG if needed */
- if (!isascii(limit[0]) || !isdigit(limit[0])) {
- sprintf(limit, "%lu", BIG);
- limit_len = strlen(limit);
- }
-
- /*
- * the search for a good line
- */
- if (input != NULL && fgets(buf, MAX_LINE, input) == NULL) {
- /* error or EOF */
- return NULL;
- }
- do {
-
- /* ignore leading whitespace */
- for (s=buf; *s && s < buf+MAX_LINE; ++s) {
- if (!isascii(*s) || !isspace(*s)) {
- break;
- }
- }
-
- /* object if - */
- if (*s == '-') {
- fprintf(stderr, "%s: ouch for minuses\n", program);
- continue;
- }
-
- /* skip over any leading + */
- if (*s == '+') {
- d = s+1;
- } else {
- d = s;
- }
-
- /* note leading zeros */
- for (z=d; *z && z < buf+MAX_LINE; ++z) {
- if (*z != '0') {
- break;
- }
- }
-
- /* scan for the first non-digit/non-plus/non-minus */
- for (p=d; *p && p < buf+MAX_LINE; ++p) {
- if (!isascii(*p) || !isdigit(*p)) {
- break;
- }
- }
+ ubig val;
+ char *p, buf[100]; /* > max number of digits. */
- /* ignore empty lines */
- if (p == d) {
- continue;
+ for (;;) {
+ if (fgets(buf, sizeof(buf), stdin) == NULL) {
+ if (ferror(stdin))
+ err(1, "stdin");
+ exit(0);
}
- *p = '\0';
-
- /* object if too many digits */
- len = strlen(z);
- len = (len<=0) ? 1 : len;
- /* accept if digit count is below limit */
- if (len < limit_len) {
- /* we have good input */
- return s;
-
- /* reject very large numbers */
- } else if (len > limit_len) {
- fprintf(stderr, "%s: %s too big\n", program, z);
+ for (p = buf; isblank(*p); ++p);
+ if (*p == '\n' || *p == '\0')
continue;
-
- /* carefully check against near limit numbers */
- } else if (strcmp(z, limit) > 0) {
- fprintf(stderr, "%s: %s a bit too big\n", program, z);
- continue;
- }
- /* number is near limit, but is under it */
- return s;
- } while (input != NULL && fgets(buf, MAX_LINE, input) != NULL);
-
- /* error or EOF */
- return NULL;
+ if (*p == '-')
+ errx(1, "negative numbers aren't permitted.");
+ errno = 0;
+ val = strtoul(buf, &p, 10);
+ if (errno)
+ err(1, "%s", buf);
+ if (*p != '\n')
+ errx(1, "%s: illegal numeric format.", buf);
+ return (val);
+ }
}
/*
@@ -307,9 +229,9 @@ primes(start, stop)
register ubig fact_lim; /* highest prime for current block */
/*
- * NetBSD has no problems with handling conversion
- * between doubles and unsigned long, so we can go
- * all the way to BIG.
+ * A number of systems can not convert double values into unsigned
+ * longs when the values are larger than the largest signed value.
+ * We don't have this problem, so we can go all the way to BIG.
*/
if (start < 3) {
start = (ubig)2;
@@ -337,8 +259,7 @@ primes(start, stop)
if (start <= *pr_limit) {
/* skip primes up to the start value */
for (p = &prime[0], factor = prime[0];
- factor < stop && p <= pr_limit;
- factor = *(++p)) {
+ factor < stop && p <= pr_limit; factor = *(++p)) {
if (factor >= start) {
printf("%u\n", factor);
}
@@ -363,8 +284,7 @@ primes(start, stop)
memcpy(table, &pattern[factor], pattern_size-factor);
/* main block pattern copies */
for (fact_lim=pattern_size-factor;
- fact_lim+pattern_size<=TABSIZE;
- fact_lim+=pattern_size) {
+ fact_lim+pattern_size<=TABSIZE; fact_lim+=pattern_size) {
memcpy(&table[fact_lim], pattern, pattern_size);
}
/* final block pattern copy */
@@ -409,3 +329,10 @@ primes(start, stop)
}
}
}
+
+void
+usage()
+{
+ (void)fprintf(stderr, "usage: primes [start [stop]]\n");
+ exit(1);
+}
diff --git a/primes/primes.h b/primes/primes.h
index 72504c75..3197d271 100644
--- a/primes/primes.h
+++ b/primes/primes.h
@@ -1,6 +1,8 @@
+/* $NetBSD: primes.h,v 1.4 1995/03/23 08:35:58 cgd Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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.
@@ -33,25 +35,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)primes.h 5.2 (Berkeley) 6/1/90
- * $Id: primes.h,v 1.3 1994/03/01 01:07:51 cgd Exp $
+ * @(#)primes.h 8.2 (Berkeley) 3/1/94
*/
/*
* primes - generate a table of primes between two values
*
- * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
+ * By: Landon Curt Noll chongo@toad.com, ...!{sun,tolsoft}!hoptoad!chongo
*
- * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
+ * chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
*/
/* ubig is the type that holds a large unsigned value */
-typedef unsigned long ubig; /* must be >=32 bit unsigned value */
+typedef unsigned long ubig; /* must be >=32 bit unsigned value */
+#define BIG ULONG_MAX /* largest value will sieve */
-/*
- * sieve parameters
- */
-#define BIG ULONG_MAX /* highest value we will sieve */
-#define SEMIBIG ((ubig)LONG_MAX) /* highest signed value */
-#define NEG_SEMIBIG ((ubig)LONG_MIN) /* lowest signed value */
-#define TABSIZE 256*1024 /* bytes in sieve table (must be > 3*5*7*11) */
+/* bytes in sieve table (must be > 3*5*7*11) */
+#define TABSIZE 256*1024