]> Zhao Yanbai Git Server - minix.git/commitdiff
lib: setprogname() + getsubopt()
authorBen Gras <ben@minix3.org>
Sat, 26 Jun 2010 00:44:24 +0000 (00:44 +0000)
committerBen Gras <ben@minix3.org>
Sat, 26 Jun 2010 00:44:24 +0000 (00:44 +0000)
include/stdlib.h
lib/libc/other/Makefile.inc
lib/libc/other/getprogname.c
lib/libc/other/getsubopt.c [new file with mode: 0644]

index 2a693f4f7aa6c17e25d78ea9ec845d15fd32586b..85c6487ec7abc8283808b431993cdd57f7d4556b 100644 (file)
@@ -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,
index 77965f7b70f620b5f599740c2ccf1720cdc7318d..835fc4244a01e25039b8964f5cd8981ca8d6783a 100644 (file)
@@ -62,6 +62,7 @@ SRCS+=  \
        getpass.c \
        getprogname.c \
        getpwent.c \
+       getsubopt.c \
        getttyent.c \
        getw.c \
        hypot.c \
index 9eed738d3bd821bc87ce16deef888e28a01fccbb..1026425479dae672e3f76c5630204496352c1e56 100644 (file)
@@ -44,6 +44,7 @@ __RCSID("$NetBSD: getprogname.c,v 1.3 2003/07/26 19:24:42 salo Exp $");
 #include <stdlib.h>
 #include <string.h>
 
+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 (file)
index 0000000..765f595
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * 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);
+}