Importing usr.bin/jot
No Minix-specific changes needed. Change-Id: I0f45ea7f45d6a254de9383fc4f9ff5e35a013d6b
This commit is contained in:
parent
d44a5ed1c1
commit
075dbe55f3
|
@ -363,6 +363,7 @@
|
|||
./usr/bin/isoinfo minix-sys
|
||||
./usr/bin/isoread minix-sys
|
||||
./usr/bin/join minix-sys
|
||||
./usr/bin/jot minix-sys
|
||||
./usr/bin/kill minix-sys obsolete
|
||||
./usr/bin/kyua minix-sys kyua
|
||||
./usr/bin/lam minix-sys
|
||||
|
@ -1941,6 +1942,7 @@
|
|||
./usr/man/man1/isoread.1 minix-sys
|
||||
./usr/man/man1/jobs.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/ksh.1 minix-sys
|
||||
./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/infocmp
|
||||
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
|
||||
2011/01/17 18:11:10,usr.bin/ldd
|
||||
2013/10/18 12:00:00,usr.bin/leave
|
||||
|
|
|
@ -12,7 +12,7 @@ SUBDIR= asa \
|
|||
env expand \
|
||||
finger fold from \
|
||||
fsplit ftp genassym getopt \
|
||||
head hexdump indent infocmp join \
|
||||
head hexdump indent infocmp join jot \
|
||||
lam ldd leave \
|
||||
lock login logname lorder m4 \
|
||||
machine make man menuc mesg \
|
||||
|
|
|
@ -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>
|
|
@ -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
|
|
@ -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 New Issue