]> Zhao Yanbai Git Server - minix.git/commitdiff
Importing usr.bin/jot 23/1123/1
authorThomas Cort <tcort@minix3.org>
Wed, 6 Nov 2013 22:23:38 +0000 (17:23 -0500)
committerThomas Cort <tcort@minix3.org>
Wed, 6 Nov 2013 22:23:38 +0000 (17:23 -0500)
No Minix-specific changes needed.

Change-Id: I0f45ea7f45d6a254de9383fc4f9ff5e35a013d6b

distrib/sets/lists/minix/mi
releasetools/nbsd_ports
usr.bin/Makefile
usr.bin/jot/Makefile [new file with mode: 0644]
usr.bin/jot/jot.1 [new file with mode: 0644]
usr.bin/jot/jot.c [new file with mode: 0644]

index 5e197e485b75299cb174269bc059105f381eb345..01096ec79b4c35e2564ec645c6dbfb08d886b559 100644 (file)
 ./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
 ./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
index b2099498b947ff823cd702182087121bb09da825..abbb18bc1dc02aa721cb7967469b13eb996ed46b 100644 (file)
 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
index e468a1797bbda70ae70b77116e461e0f5715edde..41355ddcec112aad56c1de4df1bcbcdf23bf08cc 100644 (file)
@@ -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 \
diff --git a/usr.bin/jot/Makefile b/usr.bin/jot/Makefile
new file mode 100644 (file)
index 0000000..2c57497
--- /dev/null
@@ -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>
diff --git a/usr.bin/jot/jot.1 b/usr.bin/jot/jot.1
new file mode 100644 (file)
index 0000000..523ec65
--- /dev/null
@@ -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
diff --git a/usr.bin/jot/jot.c b/usr.bin/jot/jot.c
new file mode 100644 (file)
index 0000000..120031c
--- /dev/null
@@ -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);
+       }
+}