Importing usr.bin/jot
No Minix-specific changes needed. Change-Id: I0f45ea7f45d6a254de9383fc4f9ff5e35a013d6b
This commit is contained in:
parent
d44a5ed1c1
commit
075dbe55f3
6 changed files with 616 additions and 1 deletions
|
@ -363,6 +363,7 @@
|
||||||
./usr/bin/isoinfo minix-sys
|
./usr/bin/isoinfo minix-sys
|
||||||
./usr/bin/isoread minix-sys
|
./usr/bin/isoread minix-sys
|
||||||
./usr/bin/join minix-sys
|
./usr/bin/join minix-sys
|
||||||
|
./usr/bin/jot minix-sys
|
||||||
./usr/bin/kill minix-sys obsolete
|
./usr/bin/kill minix-sys obsolete
|
||||||
./usr/bin/kyua minix-sys kyua
|
./usr/bin/kyua minix-sys kyua
|
||||||
./usr/bin/lam minix-sys
|
./usr/bin/lam minix-sys
|
||||||
|
@ -1941,6 +1942,7 @@
|
||||||
./usr/man/man1/isoread.1 minix-sys
|
./usr/man/man1/isoread.1 minix-sys
|
||||||
./usr/man/man1/jobs.1 minix-sys
|
./usr/man/man1/jobs.1 minix-sys
|
||||||
./usr/man/man1/join.1 minix-sys
|
./usr/man/man1/join.1 minix-sys
|
||||||
|
./usr/man/man1/jot.1 minix-sys
|
||||||
./usr/man/man1/kill.1 minix-sys
|
./usr/man/man1/kill.1 minix-sys
|
||||||
./usr/man/man1/ksh.1 minix-sys
|
./usr/man/man1/ksh.1 minix-sys
|
||||||
./usr/man/man1/kyua.1 minix-sys kyua
|
./usr/man/man1/kyua.1 minix-sys kyua
|
||||||
|
|
|
@ -176,6 +176,7 @@
|
||||||
2012/10/17 12:00:00,usr.bin/indent
|
2012/10/17 12:00:00,usr.bin/indent
|
||||||
2012/10/17 12:00:00,usr.bin/infocmp
|
2012/10/17 12:00:00,usr.bin/infocmp
|
||||||
2012/10/17 12:00:00,usr.bin/join
|
2012/10/17 12:00:00,usr.bin/join
|
||||||
|
2012/10/17 12:00:00,usr.bin/jot
|
||||||
2012/10/17 12:00:00,usr.bin/lam
|
2012/10/17 12:00:00,usr.bin/lam
|
||||||
2011/01/17 18:11:10,usr.bin/ldd
|
2011/01/17 18:11:10,usr.bin/ldd
|
||||||
2013/10/18 12:00:00,usr.bin/leave
|
2013/10/18 12:00:00,usr.bin/leave
|
||||||
|
|
|
@ -12,7 +12,7 @@ SUBDIR= asa \
|
||||||
env expand \
|
env expand \
|
||||||
finger fold from \
|
finger fold from \
|
||||||
fsplit ftp genassym getopt \
|
fsplit ftp genassym getopt \
|
||||||
head hexdump indent infocmp join \
|
head hexdump indent infocmp join jot \
|
||||||
lam ldd leave \
|
lam ldd leave \
|
||||||
lock login logname lorder m4 \
|
lock login logname lorder m4 \
|
||||||
machine make man menuc mesg \
|
machine make man menuc mesg \
|
||||||
|
|
10
usr.bin/jot/Makefile
Normal file
10
usr.bin/jot/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# $NetBSD: Makefile,v 1.6 2011/08/16 10:37:21 christos Exp $
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||||
|
|
||||||
|
PROG= jot
|
||||||
|
DPADD= ${LIBMATH}
|
||||||
|
LDADD= -lm
|
||||||
|
|
||||||
|
COPTS.jot.c += -Wno-format-nonliteral
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
203
usr.bin/jot/jot.1
Normal file
203
usr.bin/jot/jot.1
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
.\" $NetBSD: jot.1,v 1.12 2012/04/08 22:00:39 wiz Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" 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.
|
||||||
|
.\"
|
||||||
|
.\" @(#)jot.1 8.1 (Berkeley) 6/6/93
|
||||||
|
.\"
|
||||||
|
.Dd January 5, 2010
|
||||||
|
.Dt JOT 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm jot
|
||||||
|
.Nd print sequential or random data
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl cnr
|
||||||
|
.Op Fl b Ar word
|
||||||
|
.Op Fl p Ar precision
|
||||||
|
.Op Fl s Ar string
|
||||||
|
.Op Fl w Ar word
|
||||||
|
.Oo Ar reps
|
||||||
|
.Oo Ar begin
|
||||||
|
.Oo Ar end
|
||||||
|
.Op Ar s
|
||||||
|
.Oc
|
||||||
|
.Oc
|
||||||
|
.Oc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm jot
|
||||||
|
utility is used to print out increasing, decreasing, random,
|
||||||
|
or redundant data (usually numbers) one per line.
|
||||||
|
.Pp
|
||||||
|
The following options are available:
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl b Ar word
|
||||||
|
Just print
|
||||||
|
.Ar word
|
||||||
|
repetitively.
|
||||||
|
.It Fl c
|
||||||
|
This is an abbreviation for
|
||||||
|
.Fl w Ar %c .
|
||||||
|
.It Fl n
|
||||||
|
Do not print the final newline normally appended to the output.
|
||||||
|
.It Fl p Ar precision
|
||||||
|
Print only as many digits or characters of the data
|
||||||
|
as indicated by the integer
|
||||||
|
.Ar precision .
|
||||||
|
In the absence of
|
||||||
|
.Fl p ,
|
||||||
|
the precision is the greater of the precisions of
|
||||||
|
.Ar begin
|
||||||
|
and
|
||||||
|
.Ar end .
|
||||||
|
The
|
||||||
|
.Fl p
|
||||||
|
option is overridden by whatever appears in a
|
||||||
|
.Xr printf 3
|
||||||
|
conversion following
|
||||||
|
.Fl w .
|
||||||
|
.It Fl r
|
||||||
|
Generate random data instead of sequential data, the default.
|
||||||
|
.It Fl s Ar string
|
||||||
|
Print data separated by
|
||||||
|
.Ar string .
|
||||||
|
Normally, newlines separate data.
|
||||||
|
.It Fl w Ar word
|
||||||
|
Print
|
||||||
|
.Ar word
|
||||||
|
with the generated data appended to it.
|
||||||
|
Octal, hexadecimal, exponential, ASCII, zero padded,
|
||||||
|
and right-adjusted representations
|
||||||
|
are possible by using the appropriate
|
||||||
|
.Xr printf 3
|
||||||
|
conversion specification inside
|
||||||
|
.Ar word ,
|
||||||
|
in which case the data are inserted rather than appended.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The last four arguments indicate, respectively,
|
||||||
|
the number of data, the lower bound, the upper bound,
|
||||||
|
and the step size or, for random data, the seed.
|
||||||
|
While at least one of them must appear,
|
||||||
|
any of the other three may be omitted, and
|
||||||
|
will be considered as such if given as
|
||||||
|
.Dq - .
|
||||||
|
Any three of these arguments determines the fourth.
|
||||||
|
If four are specified and the given and computed values of
|
||||||
|
.Ar reps
|
||||||
|
conflict, the lower value is used.
|
||||||
|
If fewer than three are specified, defaults are assigned
|
||||||
|
left to right, except for
|
||||||
|
.Ar s ,
|
||||||
|
which assumes its default unless both
|
||||||
|
.Ar begin
|
||||||
|
and
|
||||||
|
.Ar end
|
||||||
|
are given.
|
||||||
|
.Pp
|
||||||
|
Defaults for the four arguments are, respectively,
|
||||||
|
100, 1, 100, and 1, except that when random data are requested,
|
||||||
|
.Ar s
|
||||||
|
defaults to a seed depending upon the time of day.
|
||||||
|
.Ar reps
|
||||||
|
is expected to be an unsigned integer,
|
||||||
|
and if given as zero is taken to be infinite.
|
||||||
|
.Ar begin
|
||||||
|
and
|
||||||
|
.Ar end
|
||||||
|
may be given as real numbers or as characters
|
||||||
|
representing the corresponding value in ASCII.
|
||||||
|
The last argument must be a real number.
|
||||||
|
.Pp
|
||||||
|
Random numbers are obtained through
|
||||||
|
.Xr random 3 .
|
||||||
|
The name
|
||||||
|
.Nm jot
|
||||||
|
derives in part from
|
||||||
|
.Nm iota ,
|
||||||
|
a function in APL.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
The command:
|
||||||
|
.Dl "jot - 42 87 1"
|
||||||
|
prints the integers from 42 to 87, inclusive.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot 21 \-1 1.00"
|
||||||
|
prints 21 evenly spaced numbers increasing from \-1 to 1.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-c 128 0"
|
||||||
|
prints the ASCII character set.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-w xa%c 26 a"
|
||||||
|
prints the strings
|
||||||
|
.Dq xaa
|
||||||
|
through
|
||||||
|
.Dq xaz .
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-r \-c 160 a z | rs \-g 0 8"
|
||||||
|
prints 20 random 8-letter strings.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-b y 0"
|
||||||
|
is equivalent to
|
||||||
|
.Xr yes 1 .
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-w %ds/old/new/ 30 2 \- 5"
|
||||||
|
prints thirty
|
||||||
|
.Xr ed 1
|
||||||
|
substitution commands applying to lines 2, 7, 12, etc.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot 0 9 \- \-.5"
|
||||||
|
prints the stuttering sequence 9, 8, 8, 7, etc.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "jot \-b x 512 \*[Gt] block"
|
||||||
|
creates a file containing exactly 1024 bytes.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "expand \-\`jot \-s, \- 10 132 4\`"
|
||||||
|
sets tabs four spaces apart starting
|
||||||
|
from column 10 and ending in column 132.
|
||||||
|
.Pp
|
||||||
|
The command:
|
||||||
|
.Dl "grep \`jot \-s """" \-b . 80\`"
|
||||||
|
prints all lines 80 characters or longer.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ed 1 ,
|
||||||
|
.Xr expand 1 ,
|
||||||
|
.Xr rs 1 ,
|
||||||
|
.Xr seq 1 ,
|
||||||
|
.Xr yes 1 ,
|
||||||
|
.Xr printf 3 ,
|
||||||
|
.Xr random 3
|
399
usr.bin/jot/jot.c
Normal file
399
usr.bin/jot/jot.c
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
/* $NetBSD: jot.c,v 1.25 2009/04/12 11:19:18 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
__COPYRIGHT("@(#) Copyright (c) 1993\
|
||||||
|
The Regents of the University of California. All rights reserved.");
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93";
|
||||||
|
#endif
|
||||||
|
__RCSID("$NetBSD: jot.c,v 1.25 2009/04/12 11:19:18 lukem Exp $");
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* jot - print sequential or random data
|
||||||
|
*
|
||||||
|
* Author: John Kunze, Office of Comp. Affairs, UCB
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define REPS_DEF 100
|
||||||
|
#define BEGIN_DEF 1
|
||||||
|
#define ENDER_DEF 100
|
||||||
|
#define STEP_DEF 1
|
||||||
|
|
||||||
|
#define is_default(s) (strcmp((s), "-") == 0)
|
||||||
|
|
||||||
|
static double begin = BEGIN_DEF;
|
||||||
|
static double ender = ENDER_DEF;
|
||||||
|
static double step = STEP_DEF;
|
||||||
|
static long reps = REPS_DEF;
|
||||||
|
static int randomize;
|
||||||
|
static int boring;
|
||||||
|
static int prec = -1;
|
||||||
|
static int dox;
|
||||||
|
static int chardata;
|
||||||
|
static int nofinalnl;
|
||||||
|
static const char *sepstring = "\n";
|
||||||
|
static char format[BUFSIZ];
|
||||||
|
|
||||||
|
static void getargs(int, char *[]);
|
||||||
|
static void getformat(void);
|
||||||
|
static int getprec(char *);
|
||||||
|
static void putdata(double, long);
|
||||||
|
static void usage(void) __dead;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
double x;
|
||||||
|
long i;
|
||||||
|
|
||||||
|
getargs(argc, argv);
|
||||||
|
if (randomize) {
|
||||||
|
x = ender - begin;
|
||||||
|
if (x < 0) {
|
||||||
|
x = -x;
|
||||||
|
begin = ender;
|
||||||
|
}
|
||||||
|
if (dox == 0)
|
||||||
|
/*
|
||||||
|
* We are printing floating point, generate random
|
||||||
|
* number that include both supplied limits.
|
||||||
|
* Due to FP routing for display the low and high
|
||||||
|
* values are likely to occur half as often as all
|
||||||
|
* the others.
|
||||||
|
*/
|
||||||
|
x /= (1u << 31) - 1.0;
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* We are printing integers increase the range by
|
||||||
|
* one but ensure we never generate it.
|
||||||
|
* This makes all the integer values equally likely.
|
||||||
|
*/
|
||||||
|
x += 1.0;
|
||||||
|
x /= (1u << 31);
|
||||||
|
}
|
||||||
|
srandom((unsigned long) step);
|
||||||
|
for (i = 1; i <= reps || reps == 0; i++)
|
||||||
|
putdata(random() * x + begin, reps - i);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If we are going to display as integer, add 0.5 here
|
||||||
|
* and use floor(x) later to get sane rounding.
|
||||||
|
*/
|
||||||
|
x = begin;
|
||||||
|
if (dox)
|
||||||
|
x += 0.5;
|
||||||
|
for (i = 1; i <= reps || reps == 0; i++, x += step)
|
||||||
|
putdata(x, reps - i);
|
||||||
|
}
|
||||||
|
if (!nofinalnl)
|
||||||
|
putchar('\n');
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
getargs(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int have = 0;
|
||||||
|
#define BEGIN 1
|
||||||
|
#define STEP 2 /* seed if -r */
|
||||||
|
#define REPS 4
|
||||||
|
#define ENDER 8
|
||||||
|
int n = 0;
|
||||||
|
long t;
|
||||||
|
char *ep;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
switch (getopt(argc, argv, "b:cnp:rs:w:")) {
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
case -1:
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
chardata = 1;
|
||||||
|
continue;
|
||||||
|
case 'n':
|
||||||
|
nofinalnl = 1;
|
||||||
|
continue;
|
||||||
|
case 'p':
|
||||||
|
prec = strtol(optarg, &ep, 0);
|
||||||
|
if (*ep != 0 || prec < 0)
|
||||||
|
errx(EXIT_FAILURE, "Bad precision value");
|
||||||
|
continue;
|
||||||
|
case 'r':
|
||||||
|
randomize = 1;
|
||||||
|
continue;
|
||||||
|
case 's':
|
||||||
|
sepstring = optarg;
|
||||||
|
continue;
|
||||||
|
case 'b':
|
||||||
|
boring = 1;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 'w':
|
||||||
|
strlcpy(format, optarg, sizeof(format));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
switch (argc) { /* examine args right to left, falling thru cases */
|
||||||
|
case 4:
|
||||||
|
if (!is_default(argv[3])) {
|
||||||
|
step = strtod(argv[3], &ep);
|
||||||
|
if (*ep != 0)
|
||||||
|
errx(EXIT_FAILURE, "Bad step value: %s",
|
||||||
|
argv[3]);
|
||||||
|
have |= STEP;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if (!is_default(argv[2])) {
|
||||||
|
if (!sscanf(argv[2], "%lf", &ender))
|
||||||
|
ender = argv[2][strlen(argv[2])-1];
|
||||||
|
have |= ENDER;
|
||||||
|
if (prec < 0)
|
||||||
|
n = getprec(argv[2]);
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if (!is_default(argv[1])) {
|
||||||
|
if (!sscanf(argv[1], "%lf", &begin))
|
||||||
|
begin = argv[1][strlen(argv[1])-1];
|
||||||
|
have |= BEGIN;
|
||||||
|
if (prec < 0)
|
||||||
|
prec = getprec(argv[1]);
|
||||||
|
if (n > prec) /* maximum precision */
|
||||||
|
prec = n;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if (!is_default(argv[0])) {
|
||||||
|
reps = strtoul(argv[0], &ep, 0);
|
||||||
|
if (*ep != 0 || reps < 0)
|
||||||
|
errx(EXIT_FAILURE, "Bad reps value: %s",
|
||||||
|
argv[0]);
|
||||||
|
have |= REPS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Too many arguments. What do you mean by %s?", argv[4]);
|
||||||
|
}
|
||||||
|
getformat();
|
||||||
|
|
||||||
|
if (prec == -1)
|
||||||
|
prec = 0;
|
||||||
|
|
||||||
|
if (randomize) {
|
||||||
|
/* 'step' is the seed here, use pseudo-random default */
|
||||||
|
if (!(have & STEP))
|
||||||
|
step = time(NULL) * getpid();
|
||||||
|
/* Take the default values for everything else */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The loop we run uses begin/step/reps, so if we have been
|
||||||
|
* given an end value (ender) we must use it to replace the
|
||||||
|
* default values of the others.
|
||||||
|
* We will assume a begin of 0 and step of 1 if necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (have) {
|
||||||
|
|
||||||
|
case ENDER | STEP:
|
||||||
|
case ENDER | STEP | BEGIN:
|
||||||
|
/* Calculate reps */
|
||||||
|
if (step == 0.0)
|
||||||
|
reps = 0; /* ie infinite */
|
||||||
|
else {
|
||||||
|
reps = (ender - begin + step) / step;
|
||||||
|
if (reps <= 0)
|
||||||
|
errx(EXIT_FAILURE, "Impossible stepsize");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REPS | ENDER:
|
||||||
|
case REPS | ENDER | STEP:
|
||||||
|
/* Calculate begin */
|
||||||
|
if (reps == 0)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Must specify begin if reps == 0");
|
||||||
|
begin = ender - reps * step + step;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REPS | BEGIN | ENDER:
|
||||||
|
/* Calculate step */
|
||||||
|
if (reps == 0)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Infinite sequences cannot be bounded");
|
||||||
|
if (reps == 1)
|
||||||
|
step = 0.0;
|
||||||
|
else
|
||||||
|
step = (ender - begin) / (reps - 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REPS | BEGIN | ENDER | STEP:
|
||||||
|
/* reps given and implied - take smaller */
|
||||||
|
if (step == 0.0)
|
||||||
|
break;
|
||||||
|
t = (ender - begin + step) / step;
|
||||||
|
if (t <= 0)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Impossible stepsize");
|
||||||
|
if (t < reps)
|
||||||
|
reps = t;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* No values can be calculated, use defaults */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putdata(double x, long notlast)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (boring) /* repeated word */
|
||||||
|
printf("%s", format);
|
||||||
|
else if (dox) /* scalar */
|
||||||
|
printf(format, (long)floor(x));
|
||||||
|
else /* real */
|
||||||
|
printf(format, x);
|
||||||
|
if (notlast != 0)
|
||||||
|
fputs(sepstring, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
__dead static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
(void)fprintf(stderr, "usage: %s [-cnr] [-b word] [-p precision] "
|
||||||
|
"[-s string] [-w word] [reps [begin [end [step | seed]]]]\n",
|
||||||
|
getprogname());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getprec(char *num_str)
|
||||||
|
{
|
||||||
|
|
||||||
|
num_str = strchr(num_str, '.');
|
||||||
|
if (num_str == NULL)
|
||||||
|
return 0;
|
||||||
|
return strspn(num_str + 1, "0123456789");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
getformat(void)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
|
if (boring) /* no need to bother */
|
||||||
|
return;
|
||||||
|
for (p = format; *p; p++) { /* look for '%' */
|
||||||
|
if (*p == '%') {
|
||||||
|
if (*(p+1) != '%')
|
||||||
|
break;
|
||||||
|
p++; /* leave %% alone */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sz = sizeof(format) - strlen(format) - 1;
|
||||||
|
if (!*p) {
|
||||||
|
if (chardata || prec == 0) {
|
||||||
|
if ((size_t)snprintf(p, sz, "%%%s", chardata ? "c" : "ld") >= sz)
|
||||||
|
errx(EXIT_FAILURE, "-w word too long");
|
||||||
|
dox = 1;
|
||||||
|
} else {
|
||||||
|
if (snprintf(p, sz, "%%.%df", prec) >= (int)sz)
|
||||||
|
errx(EXIT_FAILURE, "-w word too long");
|
||||||
|
}
|
||||||
|
} else if (!*(p+1)) {
|
||||||
|
if (sz <= 0)
|
||||||
|
errx(EXIT_FAILURE, "-w word too long");
|
||||||
|
strcat(format, "%"); /* cannot end in single '%' */
|
||||||
|
} else {
|
||||||
|
p++; /* skip leading % */
|
||||||
|
for(; *p && !isalpha((unsigned char)*p); p++) {
|
||||||
|
/* allow all valid printf(3) flags, but deny '*' */
|
||||||
|
if (!strchr("0123456789#-+. ", *p))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Allow 'l' prefix, but no other. */
|
||||||
|
if (*p == 'l')
|
||||||
|
p++;
|
||||||
|
switch (*p) {
|
||||||
|
case 'f': case 'e': case 'g': case '%':
|
||||||
|
case 'E': case 'G':
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"cannot convert numeric data to strings");
|
||||||
|
break;
|
||||||
|
case 'd': case 'o': case 'x': case 'u':
|
||||||
|
case 'D': case 'O': case 'X': case 'U':
|
||||||
|
case 'c': case 'i':
|
||||||
|
dox = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errx(EXIT_FAILURE, "unknown or invalid format `%s'",
|
||||||
|
format);
|
||||||
|
}
|
||||||
|
/* Need to check for trailing stuff to print */
|
||||||
|
for (; *p; p++) /* look for '%' */
|
||||||
|
if (*p == '%') {
|
||||||
|
if (*(p+1) != '%')
|
||||||
|
break;
|
||||||
|
p++; /* leave %% alone */
|
||||||
|
}
|
||||||
|
if (*p)
|
||||||
|
errx(EXIT_FAILURE, "unknown or invalid format `%s'",
|
||||||
|
format);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue