diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 1998-03-25 08:45:26 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 1998-03-25 08:45:26 +0000 |
commit | 72c66b699c2c099f6c53ac34c47657263f12df71 (patch) | |
tree | 543965eca698270fb3e8802430b85a125555cb75 /games/number | |
parent | ddc8a01cb9f1a4e25776691f1a03fa45034da2ff (diff) |
handle exponents, leading whitespace, and +
Diffstat (limited to 'games/number')
-rw-r--r-- | games/number/number.6 | 11 | ||||
-rw-r--r-- | games/number/number.c | 97 |
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); } |