summaryrefslogtreecommitdiff
path: root/games/number
diff options
context:
space:
mode:
authorPaul Janzen <pjanzen@cvs.openbsd.org>1998-03-25 08:45:26 +0000
committerPaul Janzen <pjanzen@cvs.openbsd.org>1998-03-25 08:45:26 +0000
commit72c66b699c2c099f6c53ac34c47657263f12df71 (patch)
tree543965eca698270fb3e8802430b85a125555cb75 /games/number
parentddc8a01cb9f1a4e25776691f1a03fa45034da2ff (diff)
handle exponents, leading whitespace, and +
Diffstat (limited to 'games/number')
-rw-r--r--games/number/number.611
-rw-r--r--games/number/number.c97
2 files changed, 85 insertions, 23 deletions
diff --git a/games/number/number.6 b/games/number/number.6
index c50c1fb5509..3810aaffb75 100644
--- a/games/number/number.6
+++ b/games/number/number.6
@@ -1,4 +1,4 @@
-.\" $NetBSD: number.6,v 1.4 1995/03/23 08:35:29 cgd Exp $
+.\" $OpenBSD: number.6,v 1.2 1998/03/25 08:45:24 pjanzen Exp $
.\"
.\" Copyright (c) 1989, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
@@ -56,7 +56,8 @@ The options are as follows:
.It Fl l
Display the number on a single line.
.El
-.Sh BUGS
-Although
-.Nm number
-understand fractions, it doesn't understand exponents.
+.Pp
+.Nm Number
+understands negative numbers (although they must be preceded by `--'
+if they are on the command line to avoid being mistaken for options)
+and numbers in scientific notation (e.g. 1.234E+05).
diff --git a/games/number/number.c b/games/number/number.c
index 127f216dbb0..3e56679cbb4 100644
--- a/games/number/number.c
+++ b/games/number/number.c
@@ -1,4 +1,4 @@
-/* $NetBSD: number.c,v 1.3 1995/03/23 08:35:30 cgd Exp $ */
+/* $OpenBSD: number.c,v 1.6 1998/03/25 08:45:25 pjanzen Exp $ */
/*
* Copyright (c) 1988, 1993, 1994
@@ -43,19 +43,21 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)number.c 8.2 (Berkeley) 3/31/94";
#else
-static char rcsid[] = "$NetBSD: number.c,v 1.3 1995/03/23 08:35:30 cgd Exp $";
+static char rcsid[] = "$OpenBSD: number.c,v 1.6 1998/03/25 08:45:25 pjanzen Exp $";
#endif
#endif /* not lint */
#include <sys/types.h>
#include <ctype.h>
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <err.h>
+#include <unistd.h>
#define MAXNUM 65 /* Biggest number we handle. */
+#define LINELEN 256
static char *name1[] = {
"", "one", "two", "three",
@@ -80,6 +82,7 @@ static char *name1[] = {
};
void convert __P((char *));
+void convertexp __P((char *));
int number __P((char *, int));
void pfract __P((int));
void toobig __P((void));
@@ -94,19 +97,20 @@ main(argc, argv)
char *argv[];
{
int ch, first;
- char line[256];
+ char line[LINELEN];
/* revoke */
setegid(getgid());
setgid(getgid());
lflag = 0;
- while ((ch = getopt(argc, argv, "l")) != -1)
+ while ((ch = getopt(argc, argv, "hl")) != -1)
switch (ch) {
case 'l':
lflag = 1;
break;
case '?':
+ case 'h':
default:
usage();
}
@@ -121,12 +125,16 @@ main(argc, argv)
if (!first)
(void)printf("...\n");
convert(line);
+ if (lflag)
+ (void)printf("\n");
}
else
for (first = 1; *argv != NULL; first = 0, ++argv) {
if (!first)
(void)printf("...\n");
convert(*argv);
+ if (lflag)
+ (void)printf("\n");
}
exit(0);
}
@@ -135,18 +143,22 @@ void
convert(line)
char *line;
{
- register flen, len, rval;
- register char *p, *fraction;
+ int flen, len, rval;
+ char *p, *fraction;
+ /* strip trailing and leading whitespace */
+ len = strlen(line) - 1;
+ while ((isblank(line[len])) || (line[len] == '\n'))
+ line[len--] = '\0';
+ while ((isblank(line[0])) || (line[0] == '\n'))
+ line++;
+ if (strchr(line, 'e') || strchr(line, 'E'))
+ convertexp(line);
+ else {
fraction = NULL;
for (p = line; *p != '\0' && *p != '\n'; ++p) {
- if (isblank(*p)) {
- if (p == line) {
- ++line;
- continue;
- }
+ if (isblank(*p))
goto badnum;
- }
if (isdigit(*p))
continue;
switch (*p) {
@@ -157,6 +169,7 @@ convert(line)
*p = '\0';
break;
case '-':
+ case '+':
if (p == line)
break;
/* FALLTHROUGH */
@@ -168,14 +181,19 @@ badnum: errx(1, "illegal number: %s", line);
*p = '\0';
if ((len = strlen(line)) > MAXNUM ||
- fraction != NULL && (flen = strlen(fraction)) > MAXNUM)
- errx(1, "number too large, max %d digits.", MAXNUM);
+ ((fraction != NULL) && (flen = strlen(fraction))) > MAXNUM)
+ errx(1, "number too large (max %d digits).", MAXNUM);
if (*line == '-') {
(void)printf("minus%s", lflag ? " " : "\n");
++line;
--len;
}
+ if (*line == '+') {
+ (void)printf("plus%s", lflag ? " " : "\n");
+ ++line;
+ --len;
+ }
rval = len > 0 ? unit(len, line) : 0;
if (fraction != NULL && flen != 0)
@@ -195,8 +213,51 @@ badnum: errx(1, "illegal number: %s", line);
}
if (!rval)
(void)printf("zero%s", lflag ? "" : ".\n");
- if (lflag)
- (void)printf("\n");
+ }
+}
+
+void
+convertexp(line)
+ char *line;
+{
+ char locline[LINELEN];
+ char *part1, *part2, *part3, *part4;
+ char tmp[2];
+ int i, j;
+
+ (void)strncpy(locline,line,LINELEN);
+ part3 = locline;
+ part2 = strsep(&part3, "eE"); /* part3 is the exponent */
+ part4 = part3;
+ (void)strsep(&part4, "."); /* no decimal allowed in the exponent */
+ if (part4)
+ errx(1, "illegal number: %s", line);
+ part1 = strsep(&part2, "."); /* we can have one in the mantissa */
+ /* At this point everything should be null or a digit. Check for
+ * that before starting to convert. Two characters may be + or -.
+ */
+ j = strlen(line);
+ for (i = 0; i < j; i++)
+ if ((!isdigit(locline[i])) && (locline[i]))
+ if (((locline[i] != '+') && (locline[i] != '-')) ||
+ ((i != 0) && (i != part3 - locline)))
+ errx(1, "illegal number: %s", line);
+ convert(part1);
+ printf("%s", lflag ? " " : "");
+ if (part2 && part2[0]) { /* do individual digits separately */
+ (void)printf("point%s", lflag ? " " : "\n");
+ j = strlen(part2); tmp[1] = '\0';
+ for (i = 0 ; i < j; i++ ) {
+ tmp[0] = part2[i];
+ convert(tmp);
+ (void)printf("%s", lflag ? " " : "");
+ }
+ }
+ (void)printf("times ten to the%s", lflag ? " " : "\n");
+ if (part3 && part3[0])
+ convert(part3);
+ else
+ (void)printf("zero%s", lflag ? " " : ".\n");
}
int
@@ -297,6 +358,6 @@ pfract(len)
void
usage()
{
- (void)fprintf(stderr, "usage: number [# ...]\n");
+ (void)fprintf(stderr, "usage: number [-l] [--] [# ...]\n");
exit(1);
}