diff options
author | Garrett D'Amore <garrett@damore.org> | 2014-04-27 19:51:49 -0700 |
---|---|---|
committer | Garrett D'Amore <garrett@damore.org> | 2014-05-13 15:44:40 -0700 |
commit | 598f4ceed9327d2d6c2325dd67cae3aa06f7fea6 (patch) | |
tree | 47d163039a873772b40e6999f9cf537c278b0c4b | |
parent | 7a0c0c86aaaba617e2100d0f6d28d71af41c889a (diff) | |
download | illumos-joyent-598f4ceed9327d2d6c2325dd67cae3aa06f7fea6.tar.gz |
4818 printf(1) should support n$ width and precision specifiers
4854 printf(1) doesn't support %b and \\c properly
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com>
Approved by: Gordon Ross <gordon.ross@nexenta.com>
-rw-r--r-- | usr/src/cmd/printf/printf.c | 156 | ||||
-rw-r--r-- | usr/src/man/man1/printf.1 | 88 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-test-utiltest.mf | 32 | ||||
-rw-r--r-- | usr/src/test/Makefile | 3 | ||||
-rw-r--r-- | usr/src/test/util-tests/Makefile | 21 | ||||
-rw-r--r-- | usr/src/test/util-tests/cmd/Makefile | 38 | ||||
-rw-r--r-- | usr/src/test/util-tests/cmd/utiltest.ksh | 61 | ||||
-rw-r--r-- | usr/src/test/util-tests/doc/Makefile | 36 | ||||
-rw-r--r-- | usr/src/test/util-tests/doc/README | 65 | ||||
-rw-r--r-- | usr/src/test/util-tests/runfiles/Makefile | 40 | ||||
-rw-r--r-- | usr/src/test/util-tests/runfiles/default.run | 26 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/Makefile | 19 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/printf/Makefile | 38 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/printf/printf_test.ksh | 199 |
14 files changed, 771 insertions, 51 deletions
diff --git a/usr/src/cmd/printf/printf.c b/usr/src/cmd/printf/printf.c index 7c66b03116..bf07982383 100644 --- a/usr/src/cmd/printf/printf.c +++ b/usr/src/cmd/printf/printf.c @@ -1,4 +1,5 @@ /* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -38,6 +39,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <alloca.h> +#include <ctype.h> #include <locale.h> #include <note.h> @@ -51,11 +54,6 @@ #define PF(f, func) do { \ char *b = NULL; \ - int dollar = 0; \ - if (*f == '$') { \ - dollar++; \ - *f = '%'; \ - } \ if (havewidth) \ if (haveprec) \ (void) asprintf(&b, f, fieldwidth, precision, func); \ @@ -69,8 +67,6 @@ (void) fputs(b, stdout); \ free(b); \ } \ - if (dollar) \ - *f = '$'; \ _NOTE(CONSTCOND) } while (0) static int asciicode(void); @@ -85,15 +81,18 @@ static const char static char *mknum(char *, char); static void usage(void); +static const char digits[] = "0123456789"; + static int myargc; static char **myargv; static char **gargv; +static char **maxargv; int main(int argc, char *argv[]) { size_t len; - int chopped, end, rval; + int end, rval; char *format, *fmt, *start; (void) setlocale(LC_ALL, ""); @@ -125,12 +124,12 @@ main(int argc, char *argv[]) * up the format string. */ fmt = format = *argv; - chopped = escape(fmt, 1, &len); /* backslash interpretation */ + (void) escape(fmt, 1, &len); /* backslash interpretation */ rval = end = 0; gargv = ++argv; for (;;) { - char **maxargv = gargv; + maxargv = gargv; myargv = gargv; for (myargc = 0; gargv[myargc]; myargc++) @@ -163,7 +162,7 @@ main(int argc, char *argv[]) return (1); } (void) fwrite(start, 1, PTRDIFF(fmt, start), stdout); - if (chopped || !*gargv) + if (!*gargv) return (rval); /* Restart at the beginning of the format string. */ fmt = format; @@ -174,57 +173,134 @@ main(int argc, char *argv[]) static char * -doformat(char *start, int *rval) +doformat(char *fmt, int *rval) { static const char skip1[] = "#'-+ 0"; - static const char skip2[] = "0123456789"; - char *fmt; int fieldwidth, haveprec, havewidth, mod_ldbl, precision; char convch, nextch; + char *start; + char **fargv; + char *dptr; + int l; + + start = alloca(strlen(fmt) + 1); + + dptr = start; + *dptr++ = '%'; + *dptr = 0; - fmt = start + 1; + fmt++; /* look for "n$" field index specifier */ - fmt += strspn(fmt, skip2); - if ((*fmt == '$') && (fmt != (start + 1))) { - int idx = atoi(start + 1); + l = strspn(fmt, digits); + if ((l > 0) && (fmt[l] == '$')) { + int idx = atoi(fmt); if (idx <= myargc) { gargv = &myargv[idx - 1]; } else { gargv = &myargv[myargc]; } - start = fmt; - fmt++; + if (gargv > maxargv) { + maxargv = gargv; + } + fmt += l + 1; + + /* save format argument */ + fargv = gargv; } else { - fmt = start + 1; + fargv = NULL; } /* skip to field width */ - fmt += strspn(fmt, skip1); + while (*fmt && strchr(skip1, *fmt) != NULL) { + *dptr++ = *fmt++; + *dptr = 0; + } + + if (*fmt == '*') { + + fmt++; + l = strspn(fmt, digits); + if ((l > 0) && (fmt[l] == '$')) { + int idx = atoi(fmt); + if (fargv == NULL) { + warnx1(_("incomplete use of n$"), NULL, NULL); + return (NULL); + } + if (idx <= myargc) { + gargv = &myargv[idx - 1]; + } else { + gargv = &myargv[myargc]; + } + fmt += l + 1; + } else if (fargv != NULL) { + warnx1(_("incomplete use of n$"), NULL, NULL); + return (NULL); + } + if (getint(&fieldwidth)) return (NULL); + if (gargv > maxargv) { + maxargv = gargv; + } havewidth = 1; - ++fmt; + + *dptr++ = '*'; + *dptr = 0; } else { havewidth = 0; /* skip to possible '.', get following precision */ - fmt += strspn(fmt, skip2); + while (isdigit(*fmt)) { + *dptr++ = *fmt++; + *dptr = 0; + } } + if (*fmt == '.') { /* precision present? */ - ++fmt; + fmt++; + *dptr++ = '.'; + if (*fmt == '*') { + + fmt++; + l = strspn(fmt, digits); + if ((l > 0) && (fmt[l] == '$')) { + int idx = atoi(fmt); + if (fargv == NULL) { + warnx1(_("incomplete use of n$"), + NULL, NULL); + return (NULL); + } + if (idx <= myargc) { + gargv = &myargv[idx - 1]; + } else { + gargv = &myargv[myargc]; + } + fmt += l + 1; + } else if (fargv != NULL) { + warnx1(_("incomplete use of n$"), NULL, NULL); + return (NULL); + } + if (getint(&precision)) return (NULL); + if (gargv > maxargv) { + maxargv = gargv; + } haveprec = 1; - ++fmt; + *dptr++ = '*'; + *dptr = 0; } else { haveprec = 0; /* skip to conversion char */ - fmt += strspn(fmt, skip2); + while (isdigit(*fmt)) { + *dptr++ = *fmt++; + *dptr = 0; + } } } else haveprec = 0; @@ -232,6 +308,8 @@ doformat(char *start, int *rval) warnx1(_("missing format character"), NULL, NULL); return (NULL); } + *dptr++ = *fmt; + *dptr = 0; /* * Look for a length modifier. POSIX doesn't have these, so @@ -254,8 +332,14 @@ doformat(char *start, int *rval) mod_ldbl = 0; } + /* save the current arg offset, and set to the format arg */ + if (fargv != NULL) { + gargv = fargv; + } + convch = *fmt; nextch = *++fmt; + *fmt = '\0'; switch (convch) { case 'b': { @@ -269,13 +353,11 @@ doformat(char *start, int *rval) return (NULL); } getout = escape(p, 0, &len); - *(fmt - 1) = 's'; - PF(start, p); - *(fmt - 1) = 'b'; + (void) fputs(p, stdout); free(p); if (getout) - return (fmt); + exit(*rval); break; } case 'c': { @@ -328,6 +410,8 @@ doformat(char *start, int *rval) return (NULL); } *fmt = nextch; + + /* return the gargv to the next element */ return (fmt); } @@ -385,9 +469,13 @@ escape(char *fmt, int percent, size_t *len) *store = '\b'; break; case 'c': - *store = '\0'; - *len = PTRDIFF(store, save); - return (1); + if (!percent) { + *store = '\0'; + *len = PTRDIFF(store, save); + return (1); + } + *store = 'c'; + break; case 'f': /* form-feed */ *store = '\f'; break; diff --git a/usr/src/man/man1/printf.1 b/usr/src/man/man1/printf.1 index 9a92650626..549628ab2e 100644 --- a/usr/src/man/man1/printf.1 +++ b/usr/src/man/man1/printf.1 @@ -1,16 +1,38 @@ '\" te +.\" Copyright 2014 Garrett D'Amore <garrett@damore.org> .\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved .\" Copyright 1992, X/Open Company Limited All Rights Reserved .\" Portions Copyright (c) 1982-2007 AT&T Knowledge Ventures -.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at http://www.opengroup.org/bookstore/. -.\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text -.\" are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical -.\" and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between these versions and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html. -.\" This notice shall appear on any product containing this material. -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. -.\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with -.\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH PRINTF 1 "Aug 11, 2009" +.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for +.\" permission to reproduce portions of its copyrighted documentation. +.\" Original documentation from The Open Group can be obtained online at +.\" http://www.opengroup.org/bookstore/. +.\" The Institute of Electrical and Electronics Engineers and The Open Group, +.\" have given us permission to reprint portions of their documentation. In the +.\" following statement, the phrase "this text" refers to portions of the +.\" system documentation. Portions of this text are reprinted and reproduced in +.\" electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 +.\" Edition, Standard for Information Technology -- Portable Operating System +.\" Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright +.\" (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, +.\" Inc and The Open Group. In the event of any discrepancy between these +.\" versions and the original IEEE and The Open Group Standard, the original +.\" IEEE and The Open Group Standard is the referee document. The original +.\" Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" This notice shall appear on any product containing this material. +.\" The contents of this file are subject to the terms of the Common +.\" Development and Distribution License (the "License"). You may not use this +.\" file except in compliance with the License. +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or +.\" http://www.opensolaris.org/os/licensing. See the License for the specific +.\" language governing permissions and limitations under the License. +.\" When distributing Covered Code, include this CDDL HEADER in each file and +.\" include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, +.\" add the following below this CDDL HEADER, with the fields enclosed by +.\" brackets "[]" replaced with your own identifying information: +.\" Portions Copyright [yyyy] [name of copyright owner] +.TH PRINTF 1 "May 11, 2014" .SH NAME printf \- write formatted output .SH SYNOPSIS @@ -90,6 +112,28 @@ with zeros not specified by the \fIformat\fR operand. .TP .ie t \(bu .el o +The argument used for the conversion character (or width or precision +parameters, see below) may be taken from the \fIn\fRnth argument instead +of the next unused argument, by specifying \fIn\fR\fB$\fR immediately following +the \fB%\fR character, or the \fB*\fR character (for width or precision +arguments). +If \fIn\fR\fB$\fR appears in any conversions in the format string, +then it must be used for all conversions, including any variable width or +precision specifiers. +.RE +.RS +4 +.TP +.ie t \(bu +.el o +The special character \fB*\fR may be used instead of a string of decimal digits +to indicate a minimum field width or a precision. In this case the next +available argument is used (or the \fIn\fRth if the form \fIn\fR\fB$\fR is +used), treating its value as a decimal string. +.RE +.RS +4 +.TP +.ie t \(bu +.el o An additional conversion character, \fBb\fR, is supported as follows. The argument is taken to be a string that can contain backslash-escape sequences. The following backslash-escape sequences are supported: @@ -130,7 +174,15 @@ appropriate type for the conversion as specified below. The \fIformat\fR operand is reused as often as necessary to satisfy the argument operands. Any extra \fBc\fR or \fBs\fR conversion specifications are evaluated as if a null string argument were supplied; other extra conversion specifications are -evaluated as if a zero argument were supplied. If the \fIformat\fR operand +evaluated as if a zero argument were supplied. +.sp +When there are more argument operands than format specifiers, and the +format includes \fIn\fR\fB$\fR position indicators, then the format is +reprocessed from the beginning as above, but with the argument list starting +from the next argument after the highest \fIn\fRth argument previously +encountered. +.sp +If the \fIformat\fR operand contains no conversion specifications and \fIargument\fR operands are present, the results are unspecified. If a character sequence in the \fIformat\fR operand begins with a \fB%\fR character, but does not form a valid conversion @@ -386,8 +438,8 @@ element \fIname\fR. .TP .ie t \(bu .el o -The escape sequence \fB\ex{hex}\fRexpands to the character corresponding to the -hexadecimal value \fBhex\fR. +The escape sequence \fB\ex{hex}\fR expands to the character corresponding to +the hexadecimal value \fBhex\fR. .RE .RS +4 .TP @@ -431,6 +483,13 @@ empty strings were supplied, numeric conversions are treated as if \fB0\fR was supplied, and time conversions are treated as if \fBnow\fR was supplied. .sp .LP +When there are more argument operands than format specifiers, and the +format includes \fIn\fR\fB$\fR position indicators, then the format is +reprocessed from the beginning as above, but with the argument list starting +from the next argument after the highest \fIn\fRth argument previously +encountered. +.sp +.LP \fB/usr/bin/printf\fR is equivalent to \fBksh93\fR's \fBprintf\fR built-in and \fBprint -f\fR, which allows additional options to be specified. .SH USAGE @@ -444,9 +503,6 @@ cautious using either of these features when there are multi-byte characters in the character set. .sp .LP -Field widths and precisions cannot be specified as \fB*\fR. -.sp -.LP The \fB%b\fR conversion specification is not part of the ISO C standard; it has been added here as a portable way to process backslash escapes expanded in string operands as provided by the \fBecho\fR utility. See also the USAGE @@ -838,7 +894,7 @@ Note that the '$' characters must be properly escaped, such as .sp .in +2 .nf -"%1\$s, %3\$d. %2\$s, %4\$d:%5\$.2d\en" in this case +"%1\e$s, %3\e$d. %2\e$s, %4\e$d:%5\e$.2d\en" in this case .fi .in -2 .sp diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf new file mode 100644 index 0000000000..54ec7dcc29 --- /dev/null +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -0,0 +1,32 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# + +set name=pkg.fmri value=pkg:/system/test/utiltest@$(PKGVERS) +set name=pkg.description value="Miscellaneous Utility Unit Tests" +set name=pkg.summary value="Utility Unit Test Suite" +set name=info.classification \ + value=org.opensolaris.category.2008:Development/System +set name=variant.arch value=$(ARCH) +dir path=opt/util-tests +dir path=opt/util-tests/bin +dir path=opt/util-tests/runfiles +dir path=opt/util-tests/tests +file path=opt/util-tests/README mode=0444 +file path=opt/util-tests/bin/utiltest mode=0555 +file path=opt/util-tests/runfiles/default.run mode=0444 +file path=opt/util-tests/tests/printf_test mode=0555 +license lic_CDDL license=lic_CDDL +depend fmri=system/test/testrunner type=require diff --git a/usr/src/test/Makefile b/usr/src/test/Makefile index 53740cb557..f7ec9e8d37 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/Makefile @@ -11,10 +11,11 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # .PARALLEL: $(SUBDIRS) -SUBDIRS = os-tests test-runner zfs-tests +SUBDIRS = os-tests test-runner util-tests zfs-tests include Makefile.com diff --git a/usr/src/test/util-tests/Makefile b/usr/src/test/util-tests/Makefile new file mode 100644 index 0000000000..535d00744b --- /dev/null +++ b/usr/src/test/util-tests/Makefile @@ -0,0 +1,21 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +.PARALLEL: $(SUBDIRS) + +SUBDIRS = cmd runfiles tests doc + +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/cmd/Makefile b/usr/src/test/util-tests/cmd/Makefile new file mode 100644 index 0000000000..b617ab86dd --- /dev/null +++ b/usr/src/test/util-tests/cmd/Makefile @@ -0,0 +1,38 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright (c) 2012 by Delphix. All rights reserved. +# + +include $(SRC)/Makefile.master +include $(SRC)/test/Makefile.com + +ROOTOPTPKG = $(ROOT)/opt/util-tests +ROOTBIN = $(ROOTOPTPKG)/bin + +PROGS = utiltest + +CMDS = $(PROGS:%=$(ROOTBIN)/%) +$(CMDS) := FILEMODE = 0555 + +all lint clean clobber: + +install: $(CMDS) + +$(CMDS): $(ROOTBIN) + +$(ROOTBIN): + $(INS.dir) + +$(ROOTBIN)/%: %.ksh + $(INS.rename) diff --git a/usr/src/test/util-tests/cmd/utiltest.ksh b/usr/src/test/util-tests/cmd/utiltest.ksh new file mode 100644 index 0000000000..231415fba8 --- /dev/null +++ b/usr/src/test/util-tests/cmd/utiltest.ksh @@ -0,0 +1,61 @@ +#!/usr/bin/ksh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +export MY_TESTS="/opt/util-tests" +runner="/opt/test-runner/bin/run" + +function fail +{ + echo $1 + exit ${2:-1} +} + +function find_runfile +{ + typeset distro= + if [[ -d /opt/delphix && -h /etc/delphix/version ]]; then + distro=delphix + elif [[ 0 -ne $(grep -c OpenIndiana /etc/release 2>/dev/null) ]]; then + distro=openindiana + elif [[ 0 -ne $(grep -c OmniOS /etc/release 2>/dev/null) ]]; then + distro=omnios + elif [[ -f $MY_TESTS/runfiles/default.run ]]; then + # optional catch-all + distro=default + fi + + [[ -n $distro ]] && echo $MY_TESTS/runfiles/$distro.run +} + +while getopts c: c; do + case $c in + 'c') + runfile=$OPTARG + [[ -f $runfile ]] || fail "Cannot read file: $runfile" + ;; + esac +done +shift $((OPTIND - 1)) + +[[ -z $runfile ]] && runfile=$(find_runfile) +[[ -z $runfile ]] && fail "Couldn't determine distro" + +$runner -c $runfile + +exit $? diff --git a/usr/src/test/util-tests/doc/Makefile b/usr/src/test/util-tests/doc/Makefile new file mode 100644 index 0000000000..5f56149125 --- /dev/null +++ b/usr/src/test/util-tests/doc/Makefile @@ -0,0 +1,36 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright (c) 2012 by Delphix. All rights reserved. +# + +include $(SRC)/Makefile.master + +READMES = README + +ROOTOPTPKG = $(ROOT)/opt/util-tests + +FILES = $(READMES:%=$(ROOTOPTPKG)/%) +$(FILES) := FILEMODE = 0444 + +all: $(READMES) + +install: $(ROOTOPTPKG) $(FILES) + +clean lint clobber: + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTOPTPKG)/%: % + $(INS.file) diff --git a/usr/src/test/util-tests/doc/README b/usr/src/test/util-tests/doc/README new file mode 100644 index 0000000000..96896e410c --- /dev/null +++ b/usr/src/test/util-tests/doc/README @@ -0,0 +1,65 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright (c) 2012 by Delphix. All rights reserved. +# + +Utils Unit Test Suite README + +1. What the Utils Unit Test Suite tests +2. Building and installing the Utils Unit Test Suite +3. Running the Utils Unit Test Suite +4. Test results + +-------------------------------------------------------------------------------- + +1. What the Utils Unit Test Suite tests + +The Utils unit test suite is for testing standard shell / POSIX utilities. +For example utilities such as "printf" are tested. + +2. Building and installing the Utils Unit Test Suite + +The Utils Unit Test Suite runs under the testrunner framework (which can be +installed as pkg:/system/test/testrunner). To build both the Utils Unit Test +Suite and the testrunner without running a full nightly: + + build_machine$ bldenv [-d] <your_env_file> + build_machine$ cd $SRC/test + build_machine$ dmake install + build_machine$ cd $SRC/pkg + build_machine$ dmake install + +Then set the publisher on the test machine to point to your repository and +install the Utils Unit Test Suite. + + test_machine# pkg install pkg:/system/test/utiltest + +Note, the framework will be installed automatically, as the Utils Unit Test +Suite depends on it. + +3. Running the Utils Unit Test Suite + +The pre-requisites for running the OS Unit Test Suite are: + - Any user may perform these tests. + +Once the pre-requisites are satisfied, simply run the ostest script: + + test_machine$ /opt/util-tests/bin/utiltest + +4. Test results + +While the OS Unit Test Suite is running, one informational line is printed at +the end of each test, and a results summary is printed at the end of the run. +The results summary includes the location of the complete logs, which is of the +form /var/tmp/test_results/<ISO 8601 date>. diff --git a/usr/src/test/util-tests/runfiles/Makefile b/usr/src/test/util-tests/runfiles/Makefile new file mode 100644 index 0000000000..c80bcb950b --- /dev/null +++ b/usr/src/test/util-tests/runfiles/Makefile @@ -0,0 +1,40 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +include $(SRC)/Makefile.master + +SRCS = default.run + +ROOTOPTPKG = $(ROOT)/opt/util-tests +RUNFILES = $(ROOTOPTPKG)/runfiles + +CMDS = $(SRCS:%=$(RUNFILES)/%) +$(CMDS) := FILEMODE = 0444 + +all: $(SRCS) + +install: $(CMDS) + +clean lint clobber: + +$(CMDS): $(RUNFILES) $(SRCS) + +$(RUNFILES): + $(INS.dir) + +$(RUNFILES)/%: % + $(INS.file) diff --git a/usr/src/test/util-tests/runfiles/default.run b/usr/src/test/util-tests/runfiles/default.run new file mode 100644 index 0000000000..638ba93ce1 --- /dev/null +++ b/usr/src/test/util-tests/runfiles/default.run @@ -0,0 +1,26 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +[DEFAULT] +pre = +verbose = False +quiet = False +timeout = 60 +post = +outputdir = /var/tmp/test_results + +[/opt/util-tests/tests/printf_test] + diff --git a/usr/src/test/util-tests/tests/Makefile b/usr/src/test/util-tests/tests/Makefile new file mode 100644 index 0000000000..41307ba8e4 --- /dev/null +++ b/usr/src/test/util-tests/tests/Makefile @@ -0,0 +1,19 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +SUBDIRS = printf + +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/tests/printf/Makefile b/usr/src/test/util-tests/tests/printf/Makefile new file mode 100644 index 0000000000..abcfd18a57 --- /dev/null +++ b/usr/src/test/util-tests/tests/printf/Makefile @@ -0,0 +1,38 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +PROG = printf_test + +ROOTOPTPKG = $(ROOT)/opt/util-tests +TESTDIR = $(ROOTOPTPKG)/tests + +CMDS = $(PROG:%=$(TESTDIR)/%) +$(CMDS) := FILEMODE = 0555 + +all lint clean clobber: + +install: all $(CMDS) + +$(CMDS): $(TESTDIR) $(PROG).ksh + +$(TESTDIR): + $(INS.dir) + +$(TESTDIR)/%: %.ksh + $(INS.rename) diff --git a/usr/src/test/util-tests/tests/printf/printf_test.ksh b/usr/src/test/util-tests/tests/printf/printf_test.ksh new file mode 100644 index 0000000000..22bc5d67ba --- /dev/null +++ b/usr/src/test/util-tests/tests/printf/printf_test.ksh @@ -0,0 +1,199 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +PRINTF=${PRINTF:=/usr/bin/printf} + +test_start() { + print "TEST STARTING ${1}: ${2}" +} + +test_pass() { + print "TEST PASS: ${1}" +} + +test_fail() { + print "TEST FAIL: ${1}: ${2}" + exit -1 +} + +checkrv() { + if [[ $? -ne 0 ]]; then + test_fail $1 "exit failure" + fi +} + +compare() { + if [[ "$2" != "$3" ]]; then + test_fail $1 "compare mismatch, got [$2] expected [$3]" + fi +} + +typeset -A tests=() + + +typeset -A tests[01]=() +tests[01][desc]="hexadecimal lowercase" +tests[01][format]='%04x' +tests[01][args]="255" +tests[01][result]="00ff" + +typeset -A tests[02]=() +tests[02][desc]="hexadecimal 32-bit" +tests[02][format]='%08x' +tests[02][args]='65537' +tests[02][result]=00010001 + +typeset -A tests[03]=() +tests[03][desc]="multiple arguments" +tests[03][format]='%d %s ' +tests[03][args]="1 one 2 two 3 three" +tests[03][result]='1 one 2 two 3 three ' + +typeset -A tests[04]=() +tests[04][desc]="variable position parameters" +tests[04][format]='%2$s %1$d ' +tests[04][args]="1 one 2 two 3 three" +tests[04][result]='one 1 two 2 three 3 ' + +typeset -A tests[05]=() +tests[05][desc]="width" +tests[05][format]='%10s' +tests[05][args]="abcdef" +tests[05][result]=' abcdef' + +typeset -A tests[06]=() +tests[06][desc]="width and precision" +tests[06][format]='%10.3s' +tests[06][args]="abcdef" +tests[06][result]=' abc' + +typeset -A tests[07]=() +tests[07][desc]="variable width and precision" +tests[07][format]='%*.*s' +tests[07][args]="10 3 abcdef" +tests[07][result]=' abc' + +typeset -A tests[08]=() +tests[08][desc]="variable position width and precision" +tests[08][format]='%2$*1$.*3$s' +tests[08][args]="10 abcdef 3" +tests[08][result]=' abc' + +typeset -A tests[09]=() +tests[09][desc]="multi variable position width and precision" +tests[09][format]='%2$*1$.*3$s' +tests[09][args]="10 abcdef 3 5 xyz 1" +tests[09][result]=' abc x' + +typeset -A tests[10]=() +tests[10][desc]="decimal from hex" +tests[10][format]='%d ' +tests[10][args]="0x1000 0XA" +tests[10][result]='4096 10 ' + +typeset -A tests[11]=() +tests[11][desc]="negative dec (64-bit)" +tests[11][format]='%x' +tests[11][args]="-1" +tests[11][result]='ffffffffffffffff' + +typeset -A tests[12]=() +tests[12][desc]="float (basic)" +tests[12][format]='%f' +tests[12][args]="3.14" +tests[12][result]='3.140000' + +typeset -A tests[12]=() +tests[12][desc]="float precision" +tests[12][format]='%.2f' +tests[12][args]="3.14159" +tests[12][result]='3.14' + +typeset -A tests[13]=() +tests[13][desc]="left justify" +tests[13][format]='%-5d' +tests[13][args]="45" +tests[13][result]='45 ' + +typeset -A tests[14]=() +tests[14][desc]="newlines" +tests[14][format]='%s\n%s\n%s' +tests[14][args]="one two three" +tests[14][result]='one +two +three' + +typeset -A tests[15]=() +tests[15][desc]="embedded octal escape" +tests[15][format]='%s\41%s' +tests[15][args]="one two" +tests[15][result]='one!two' + +typeset -A tests[16]=() +tests[16][desc]="backslash string (%b)" +tests[16][format]='%b' +tests[16][args]='\0101\0102\0103' +tests[16][result]='ABC' + +typeset -A tests[17]=() +tests[17][desc]="backslash c in %b" +tests[17][format]='%b%s' +tests[17][args]='\0101\cone two' +tests[17][result]='A' + +typeset -A tests[18]=() +tests[18][desc]="backslash octal in format" +tests[18][format]='HI\1120K\0112tabbed\11again' +tests[18][args]= +tests[18][result]='HIJ0K 2tabbed again' + +typeset -A tests[19]=() +tests[19][desc]="backslash octal in %b" +tests[19][format]="%b" +tests[19][args]='HI\0112K\011tabbed' +tests[19][result]='HIJK tabbed' + +typeset -A tests[20]=() +tests[20][desc]="numeric %d and ASCII conversions" +tests[20][format]='%d ' +tests[20][args]="3 +3 -3 \"3 \"+ '-" +tests[20][result]='3 3 -3 51 43 45 ' + +typeset -A tests[21]=() +tests[21][desc]="verify second arg only" +tests[21][format]='%2$s' +tests[21][args]='abc xyz' +tests[21][result]="xyz" + +#debug=yes + +for i in "${!tests[@]}"; do + t=test_$i + desc=${tests[$i][desc]} + format=${tests[$i][format]} + args="${tests[$i][args]}" + result=${tests[$i][result]} + + test_start $t "${tests[$i][desc]}" + [[ -n "$debug" ]] && echo $PRINTF "$format" "${args[@]}" + comp=$($PRINTF "$format" ${args[@]}) + checkrv $t + [[ -n "$debug" ]] && echo "got [$comp]" + good=$result + compare $t "$comp" "$good" + test_pass $t +done |