aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/jot
diff options
context:
space:
mode:
authorSheldon Hearn <sheldonh@FreeBSD.org>1999-07-22 17:11:59 +0000
committerSheldon Hearn <sheldonh@FreeBSD.org>1999-07-22 17:11:59 +0000
commit8db8a33bb9e4a14a47e7985ebe683a32641ca0d2 (patch)
treefadfc41c3a70dc4e6c85fca114d4da06a6fadfd8 /usr.bin/jot
parent7dea97485b4a8ba672f953045a6221a0443b5137 (diff)
Notes
Diffstat (limited to 'usr.bin/jot')
-rw-r--r--usr.bin/jot/jot.116
-rw-r--r--usr.bin/jot/jot.c100
2 files changed, 97 insertions, 19 deletions
diff --git a/usr.bin/jot/jot.1 b/usr.bin/jot/jot.1
index da3928322dc9..d0f0ce457fc2 100644
--- a/usr.bin/jot/jot.1
+++ b/usr.bin/jot/jot.1
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)jot.1 8.1 (Berkeley) 6/6/93
-.\" $Id$
+.\" $Id: jot.1,v 1.5 1999/07/12 20:23:37 nik Exp $
.\"
.Dd June 6, 1993
.Dt JOT 1
@@ -191,3 +191,17 @@ and to print all lines 80 characters or longer,
.Xr yes 1 ,
.Xr printf 3 ,
.Xr random 3
+.Sh BUGS
+Conversion format specifiers for
+.Xr printf 3
+are limited to those of the form
+.Dl %[#][ ][{+,-}][0-9]*[.[0-9]*]?
+where
+.Dq ?
+must be one of
+.Dl [l]{d,i,o,u,x}
+or
+.Dl {c,e,f,g,D,E,G,O,U,X}
+.Pp
+No bounds-checking is performed on numeric values, so arithmetic overflow
+will cause a fatal error.
diff --git a/usr.bin/jot/jot.c b/usr.bin/jot/jot.c
index 5b67862e7998..7dd4261bb12e 100644
--- a/usr.bin/jot/jot.c
+++ b/usr.bin/jot/jot.c
@@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
- "$Id: jot.c,v 1.8 1997/11/03 07:45:33 charnier Exp $";
+ "$Id: jot.c,v 1.9 1999/05/13 12:18:24 kris Exp $";
#endif /* not lint */
/*
@@ -75,8 +75,9 @@ int randomize;
int infinity;
int boring;
int prec;
-int dox;
+int intdata;
int chardata;
+int nosign;
int nofinalnl;
char *sepstring = "\n";
char format[BUFSIZ];
@@ -105,8 +106,7 @@ main(argc, argv)
*y = (double) arc4random() / ULONG_MAX;
putdata(*y * *x + begin, reps - *i);
}
- }
- else
+ } else
for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
putdata(*x, reps - *i);
if (!nofinalnl)
@@ -310,13 +310,15 @@ putdata(x, notlast)
double x;
long notlast;
{
- long d = x;
- register long *dp = &d;
if (boring) /* repeated word */
printf(format);
- else if (dox) /* scalar */
- printf(format, *dp);
+ else if (chardata) /* character representation */
+ printf(format, (int)x);
+ else if (intdata && nosign) /* scalar */
+ printf(format, (unsigned long)x);
+ else if (intdata)
+ printf(format, (long)x);
else /* real */
printf(format, x);
if (notlast != 0)
@@ -354,6 +356,8 @@ void
getformat()
{
register char *p;
+ int dot, hash, space, sign, numbers, islong = 0;
+ char *s;
if (boring) /* no need to bother */
return;
@@ -364,24 +368,84 @@ getformat()
sprintf(p, "%%.%df", prec);
else if (!*p && chardata) {
strcpy(p, "%c");
- dox = 1;
- }
- else if (!*(p+1))
+ intdata = 1;
+ } else if (!*(p+1))
strcat(format, "%"); /* cannot end in single '%' */
else {
- while (!isalpha(*p))
- p++;
+ /*
+ * Allow conversion format specifiers of the form
+ * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of
+ * [l]{d,i,o,u,x} or {f,e,g,E,G,d,o,x,D,O,U,X,c,u}
+ */
+ s = p++;
+ dot = hash = space = sign = numbers = 0;
+ while (!isalpha(*p)) {
+ if (isdigit(*p)) {
+ numbers++;
+ p++;
+ } else if ((*p == '#' && !(numbers|dot|sign|space|
+ hash++)) ||
+ (*p == ' ' && !(numbers|dot|space++)) ||
+ ((*p == '+' || *p == '-') && !(numbers|dot|sign++))
+ || (*p == '.' && !(dot++)))
+ p++;
+ else if (*p == '$' || *p == '*')
+ errx(1, "unsupported format character %c", *p);
+ else if (*p == '\0')
+ errx(1, "missing format character");
+ else
+ errx(1, "illegal format character %c", *p);
+ }
switch (*p) {
- case 'f': case 'e': case 'g': case '%':
+ case 'l':
+ islong = 1;
+ p++;
+ /* FALLTHROUGH */
+ case 'o': case 'u': case 'x': case 'X':
+ intdata = nosign = 1;
+ break;
+ case 'd': case 'i':
+ intdata = 1;
break;
+ case 'D':
+ if (!islong) {
+ intdata = 1;
+ break;
+ }
+ case 'O': case 'U':
+ if (!islong) {
+ intdata = nosign = 1;
+ break;
+ }
+ case 'c':
+ if (!(intdata | islong)) {
+ chardata = 1;
+ break;
+ }
case 's':
errx(1, "cannot convert numeric data to strings");
break;
- /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
- case 'c': case 'u': */
+ case 'h': case 'n': case 'p': case 'q': case 'L':
+ case '$': case '*':
+ errx(1, "unsupported format character %c", *p);
+ /* NOTREACHED */
+ case 'f': case 'e': case 'g': case 'E': case 'G':
+ if (!islong)
+ break;
+ /* FALLTHROUGH */
default:
- dox = 1;
- break;
+ *++p = '\0';
+ errx(1, "illegal or unsupported format '%s'", s);
+ /* NOTREACHED */
}
+ while (*++p)
+ if (*p == '%' && *(p+1) && *(p+1) != '%')
+ errx(1, "too many conversions");
+ else if (*p == '%' && *(p+1) == '%')
+ p++;
+ else if (*p == '%' && !*(p+1)) {
+ strcat(format, "%");
+ break;
+ }
}
}