From aa6ff4c8be4e745431e976c5298cf98b006c9ef0 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Sat, 26 Jun 2010 00:44:24 +0000 Subject: [PATCH] lib: setprogname() + getsubopt() --- include/stdlib.h | 1 + lib/libc/other/Makefile.inc | 1 + lib/libc/other/getprogname.c | 9 +++ lib/libc/other/getsubopt.c | 103 +++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 lib/libc/other/getsubopt.c diff --git a/include/stdlib.h b/include/stdlib.h index 2a693f4f7..85c6487ec 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -79,6 +79,7 @@ _PROTOTYPE( int putenv, (char *string) ); _PROTOTYPE( int setenv, (const char *envname, const char *envval, int overwrite) ); _PROTOTYPE( int unsetenv, (const char *name) ); +_PROTOTYPE( int getsubopt, (char **optionp, char * const *keylistp, char **valuep)); #ifdef __LONG_LONG_SUPPORTED _PROTOTYPE( long long strtoll, (const char *_nptr, char **_endptr, diff --git a/lib/libc/other/Makefile.inc b/lib/libc/other/Makefile.inc index 77965f7b7..835fc4244 100644 --- a/lib/libc/other/Makefile.inc +++ b/lib/libc/other/Makefile.inc @@ -62,6 +62,7 @@ SRCS+= \ getpass.c \ getprogname.c \ getpwent.c \ + getsubopt.c \ getttyent.c \ getw.c \ hypot.c \ diff --git a/lib/libc/other/getprogname.c b/lib/libc/other/getprogname.c index 9eed738d3..102642547 100644 --- a/lib/libc/other/getprogname.c +++ b/lib/libc/other/getprogname.c @@ -44,6 +44,7 @@ __RCSID("$NetBSD: getprogname.c,v 1.3 2003/07/26 19:24:42 salo Exp $"); #include #include +static const char *theprogname = NULL; extern const char **__prognamep; /* Copy of argv[]. */ extern int __argc; /* Copy of argc. */ @@ -51,6 +52,8 @@ const char * getprogname(void) { const char *pn = NULL, *component; + if(theprogname) + return theprogname; if(__argc > 0 && __prognamep) pn = __prognamep[0]; else @@ -60,3 +63,9 @@ getprogname(void) return component+1; return pn; } + +void +setprogname(const char *newprogname) +{ + theprogname = newprogname; +} diff --git a/lib/libc/other/getsubopt.c b/lib/libc/other/getsubopt.c new file mode 100644 index 000000000..765f59562 --- /dev/null +++ b/lib/libc/other/getsubopt.c @@ -0,0 +1,103 @@ +/* $NetBSD: getsubopt.c,v 1.8 2004/05/09 19:34:11 kleink Exp $ */ + +/*- + * Copyright (c) 1990, 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 + +#include "namespace.h" + +#include +#include +#include +#include + +/* + * The SVID interface to getsubopt provides no way of figuring out which + * part of the suboptions list wasn't matched. This makes error messages + * tricky... The extern variable suboptarg is a pointer to the token + * which didn't match. + */ +char *suboptarg; + +int +getsubopt(optionp, tokens, valuep) + char **optionp, **valuep; + char * const *tokens; +{ + int cnt; + char *p; + + _DIAGASSERT(tokens != NULL); + _DIAGASSERT(valuep != NULL); + /* optionp is tested below */ + + suboptarg = *valuep = NULL; + + if (!optionp || !*optionp) + return(-1); + + /* skip leading white-space, commas */ + for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + + if (!*p) { + *optionp = p; + return(-1); + } + + /* save the start of the token, and skip the rest of the token. */ + for (suboptarg = p; + *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';); + + if (*p) { + /* + * If there's an equals sign, set the value pointer, and + * skip over the value part of the token. Terminate the + * token. + */ + if (*p == '=') { + *p = '\0'; + for (*valuep = ++p; + *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); + if (*p) + *p++ = '\0'; + } else + *p++ = '\0'; + /* Skip any whitespace or commas after this token. */ + for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + } + + /* set optionp for next round. */ + *optionp = p; + + for (cnt = 0; *tokens; ++tokens, ++cnt) + if (!strcmp(suboptarg, *tokens)) + return(cnt); + return(-1); +} -- 2.44.0