diff options
Diffstat (limited to 'lib/libc/stdlib')
| -rw-r--r-- | lib/libc/stdlib/Makefile.inc | 6 | ||||
| -rw-r--r-- | lib/libc/stdlib/bsearch.3 | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/exit.c | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/getopt.3 | 164 | ||||
| -rw-r--r-- | lib/libc/stdlib/getopt.c | 44 | ||||
| -rw-r--r-- | lib/libc/stdlib/rand48.3 | 3 | ||||
| -rw-r--r-- | lib/libc/stdlib/random.3 | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/realloc.3 | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/setenv.c | 3 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtol.c | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtoq.c | 136 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtoul.c | 2 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtouq.c | 114 |
13 files changed, 403 insertions, 79 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 972887fbd82a..0bd1a90ab56a 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -3,17 +3,17 @@ # stdlib sources .PATH: ${.CURDIR}/${MACHINE}/stdlib ${.CURDIR}/stdlib -SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c div.c exit.c \ +SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c exit.c \ getenv.c getopt.c heapsort.c malloc.c multibyte.c \ putenv.c qsort.c radixsort.c rand.c random.c setenv.c strtod.c \ strtol.c strtoul.c system.c \ _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ - mrand48.c nrand48.c seed48.c srand48.c + mrand48.c nrand48.c seed48.c srand48.c strtoq.c strtouq.c .if (${MACHINE} == "hp300") SRCS+= abs.s div.c labs.c ldiv.c atof.c .elif (${MACHINE} == "i386") -SRCS+= abs.s div.s labs.s ldiv.s atof.c +SRCS+= abs.S div.S labs.S ldiv.S atof.c .elif (${MACHINE} == "tahoe") SRCS+= abs.s div.c labs.c ldiv.c atof.c .elif (${MACHINE} == "vax") diff --git a/lib/libc/stdlib/bsearch.3 b/lib/libc/stdlib/bsearch.3 index 35c5a426f522..b1de330f2429 100644 --- a/lib/libc/stdlib/bsearch.3 +++ b/lib/libc/stdlib/bsearch.3 @@ -50,7 +50,7 @@ The .Fn bsearch function searches an array of .Fa nmemb -objects, the inital member of which is +objects, the initial member of which is pointed to by .Fa base , for a member that matches the object pointed to by diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c index 0d3c72520f46..50c872afe529 100644 --- a/lib/libc/stdlib/exit.c +++ b/lib/libc/stdlib/exit.c @@ -57,4 +57,6 @@ exit(status) if (__cleanup) (*__cleanup)(); _exit(status); + /* We'll never get here; this just surpresses a warning. */ + while(1) { ; } } diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3 index c21a0a725faf..c028465b992f 100644 --- a/lib/libc/stdlib/getopt.3 +++ b/lib/libc/stdlib/getopt.3 @@ -29,7 +29,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getopt.3 6.16 (Berkeley) 4/19/91 +.\" from: @(#)getopt.3 6.16 (Berkeley) 4/19/91 +.\" $Id: getopt.3,v 1.2 1993/11/23 00:08:36 jtc Exp $ .\" .Dd April 19, 1991 .Dt GETOPT 3 @@ -38,12 +39,13 @@ .Nm getopt .Nd get option letter from argv .Sh SYNOPSIS -.Fd #include <stdlib.h> -.Vt extern char *optarg -.Vt extern int optind -.Vt extern int opterr +.Fd #include <unistd.h> .Ft int .Fn getopt "int argc" "char * const *argv" "const char *optstring" +.Vt extern char *optarg; +.Vt extern int optind; +.Vt extern int opterr; +.Vt extern int optopt; .Sh DESCRIPTION The .Fn getopt @@ -93,68 +95,137 @@ evaluation. The .Fn getopt function -returns an -.Dv EOF -when the argument list is exhausted, or a non-recognized -option is encountered. +returns \-1 +when the argument list is exhausted. The interpretation of options in the argument list may be cancelled by the option .Ql -- (double dash) which causes .Fn getopt -to signal the end of argument processing and return an -.Dv EOF . +to signal the end of argument processing and return \-1. When all options have been processed (i.e., up to the first non-option argument), .Fn getopt -returns -.Dv EOF . +returns \-1. .Sh DIAGNOSTICS -If the +If the .Fn getopt -function encounters a character not found in the string -.Va optarg -or detects -a missing option argument -it writes error message -.Ql ? -to the -.Em stderr . -Setting +function encounters an option character that is not contained in +.Fa optstring , +it returns a question mark +.Pq ? +character. +If it detects a missing option argument, it returns a colon +.Pq \: +character if the first character of +.Fa optstring +is a colon, otherwise it returns a question mark. +In either case, a diagnostic message is written to +.Em stderr +unless the application has set .Va opterr -to a zero will disable these error messages. +to zero or the first character of +.Fa optstring +is a colon. .Sh EXAMPLE +.\" The following example comes from section E.9.7 of the IEEE 1003.2-90 +.\" standard (POSIX.2). +The following code fragment shows how one might process the arguments for +a utility that can take the mutually exclusive options +.Em a +and +.Em b +and the options +.Em f +and +.Em o , +both of which require arguments: +.Pp .Bd -literal -compact -extern char *optarg; -extern int optind; -int bflag, ch, fd; +#include <unistd.h> -bflag = 0; -while ((ch = getopt(argc, argv, "bf:")) != EOF) - switch(ch) { - case 'b': - bflag = 1; - break; - case 'f': - if ((fd = open(optarg, O_RDONLY, 0)) < 0) { - (void)fprintf(stderr, - "myname: unable to read file %s.\en", optarg); - exit(1) ; +int +main (argc, argv) + int argc; + char *argv[]; +{ + int c, bflg, aflg, errflg = 0; + char *ifile, *ofile; + extern char *optarg; + extern int optind, optopt; + + . . . + + while ((c = getopt(argc, argv, ":abf:o:")) != -1) { + switch(ch) { + case 'a': + if (bflg) + errflg = 1; + else + aflg = 1; + break; + case 'b': + if (aflg) + errflg = 1; + else + bflg = 1; + break; + case 'f': + ifile = optarg; + break; + case 'o': + ofile = optarg; + break; + case ':': /* -f or -o without option-arg */ + fprintf (stderr, + "Option -%c requires an option-argument\\n", + optopt); + errflg = 1; + break; + case '?': + fprintf (stderr, + "Unrecognized option: -%c\\n", + optopt); + errflg = 1; + break; } - break; - case '?': - default: - usage(); + } + + if (errflg) { + fprintf (stderr, "usage: . . .\\n"); + exit (2); + } + + argc -= optind; + argv += optind; + + . . . + } -argc -= optind; -argv += optind; .Ed +.Sh STANDARDS +The +.Fn getopt +function conforms to +.St -p1003.2-92 . .Sh HISTORY The .Fn getopt function appeared .Bx 4.3 . .Sh BUGS +The +.Fn getopt +function was once specified to return +.Dv EOF +instead of \-1. +This was changed by +.St -p1003.2-92 +to decouple +.Fn getopt +from +.Pa <stdio.h> . +.Pp Option arguments are allowed to begin with .Dq Li \- ; this is reasonable but @@ -177,8 +248,7 @@ It is provided for backward compatibility .Em only . By default, a single dash causes .Fn getopt -to return -.Dv EOF . +to returns \-1. This is, we believe, compatible with System V. .Pp It is also possible to handle digits as option letters. @@ -195,7 +265,7 @@ The following code fragment works fairly well. int length; char *p; -while ((c = getopt(argc, argv, "0123456789")) != EOF) +while ((c = getopt(argc, argv, "0123456789")) != -1) switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': diff --git a/lib/libc/stdlib/getopt.c b/lib/libc/stdlib/getopt.c index 7126cc1da95a..7d1d9802156f 100644 --- a/lib/libc/stdlib/getopt.c +++ b/lib/libc/stdlib/getopt.c @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; +/*static char *sccsid = "from: @(#)getopt.c 4.13 (Berkeley) 2/23/91";*/ +static char *rcsid = "$Id: getopt.c,v 1.2 1993/11/23 00:08:37 jtc Exp $"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> @@ -42,11 +43,12 @@ static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; /* * get option letter from argument vector */ -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt; /* character checked for validity */ char *optarg; /* argument associated with option */ +#define NOOPT (int)':' /* No option */ #define BADCH (int)'?' #define EMSG "" @@ -63,26 +65,27 @@ getopt(nargc, nargv, ostr) if (!*place) { /* update scanning pointer */ if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; - return(EOF); + return(-1); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; - return(EOF); + return(-1); } - } /* option letter okay? */ + } + /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || - !(oli = index(ostr, optopt))) { + !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, - * assume it means EOF. + * assume it means -1. */ if (optopt == (int)'-') - return(EOF); + return(-1); if (!*place) ++optind; - if (opterr) { - if (!(p = rindex(*nargv, '/'))) + if (opterr && *ostr != ':') { + if (!(p = strrchr(*nargv, '/'))) p = *nargv; else ++p; @@ -91,25 +94,26 @@ getopt(nargc, nargv, ostr) } return(BADCH); } + if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; - } - else { /* need an argument */ + } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; - if (!(p = rindex(*nargv, '/'))) - p = *nargv; - else - ++p; - if (opterr) + if (opterr && *ostr != ':') { + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; (void)fprintf(stderr, "%s: option requires an argument -- %c\n", p, optopt); - return(BADCH); + } + return((*ostr == ':') ? NOOPT : BADCH); } else /* white space */ optarg = nargv[optind]; diff --git a/lib/libc/stdlib/rand48.3 b/lib/libc/stdlib/rand48.3 index fead60db46e2..176303dcf795 100644 --- a/lib/libc/stdlib/rand48.3 +++ b/lib/libc/stdlib/rand48.3 @@ -158,6 +158,3 @@ Martin Birgmeier .Sh SEE ALSO .Xr rand 3 , .Xr random 3 . -============================== cut here ============================== - - diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3 index 872983cd9e86..17a31b2aae45 100644 --- a/lib/libc/stdlib/random.3 +++ b/lib/libc/stdlib/random.3 @@ -41,7 +41,7 @@ .Nm setstate .Nd better random number generator; routines for changing generators .Sh SYNOPSIS -.Fd #include <stdlib> +.Fd #include <stdlib.h> .Ft long .Fn random void .Ft void diff --git a/lib/libc/stdlib/realloc.3 b/lib/libc/stdlib/realloc.3 index ee3e64018fc7..ba2ccc9180fb 100644 --- a/lib/libc/stdlib/realloc.3 +++ b/lib/libc/stdlib/realloc.3 @@ -72,7 +72,7 @@ by a call to the or .Fn realloc function, unpredictable and usually detrimental -behaviour will occur. +behavior will occur. If the space cannot be allocated, the object pointed to by .Fa ptr diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c index 14efac37b37c..9cade228c687 100644 --- a/lib/libc/stdlib/setenv.c +++ b/lib/libc/stdlib/setenv.c @@ -39,6 +39,8 @@ static char sccsid[] = "@(#)setenv.c 5.6 (Berkeley) 6/4/91"; #include <stdlib.h> #include <string.h> +extern char *_findenv(); + /* * setenv -- * Set the value of the environmental variable "name" to be @@ -53,7 +55,6 @@ setenv(name, value, rewrite) static int alloced; /* if allocated space before */ register char *C; int l_value, offset; - char *_findenv(); if (*value == '=') /* no `=' in value */ ++value; diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index 000d87647af6..1c1d5c96ee9a 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -124,6 +124,6 @@ strtol(nptr, endptr, base) } else if (neg) acc = -acc; if (endptr != 0) - *endptr = any ? s - 1 : (char *)nptr; + *endptr = any ? (char *)s - 1 : (char *)nptr; return (acc); } diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c new file mode 100644 index 000000000000..af02765d6c98 --- /dev/null +++ b/lib/libc/stdlib/strtoq.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1992 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> + +#include <limits.h> +#include <errno.h> +#include <ctype.h> +#include <stdlib.h> + +/* + * Convert a string to a quad integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +quad_t +strtoq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + qbase = (unsigned)base; + cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? QUAD_MIN : QUAD_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = any ? (char *)s - 1 : (char *)nptr; + return (acc); +} diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index ed8c1080ba6e..284c182ef71c 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -102,6 +102,6 @@ strtoul(nptr, endptr, base) } else if (neg) acc = -acc; if (endptr != 0) - *endptr = any ? s - 1 : (char *)nptr; + *endptr = any ? (char *)s - 1 : (char *)nptr; return (acc); } diff --git a/lib/libc/stdlib/strtouq.c b/lib/libc/stdlib/strtouq.c new file mode 100644 index 000000000000..14e37e07f324 --- /dev/null +++ b/lib/libc/stdlib/strtouq.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 1992 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> + +#include <limits.h> +#include <errno.h> +#include <ctype.h> +#include <stdlib.h> + +/* + * Convert a string to an unsigned quad integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +u_quad_t +strtouq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s = nptr; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + qbase = (unsigned)base; + cutoff = (u_quad_t)UQUAD_MAX / qbase; + cutlim = (u_quad_t)UQUAD_MAX % qbase; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = UQUAD_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = any ? (char *)s - 1 : (char *)nptr; + return (acc); +} |
