]> git.pond.sub.org Git - empserver/commitdiff
w32: Provide getopt() for Visual Studio
authorRon Koenderink <rkoenderink@gmail.com>
Tue, 19 Jan 2021 18:48:23 +0000 (12:48 -0600)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 13 Feb 2021 18:25:18 +0000 (19:25 +0100)
getopt() does not exist in the Visual Studio 2019 CRT.  Provide one.

Signed-off-by: Ron Koenderink <rkoenderink@gmail.com
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Make.mk
src/client/Makefile.in
src/lib/w32/getopt.c [new file with mode: 0644]
src/lib/w32/unistd.h

diff --git a/Make.mk b/Make.mk
index 3416853cb7d69c77a1495565cd9d9404c493319f..19988c012ec1e6ae6ee50e80d57fea11e49639d5 100644 (file)
--- a/Make.mk
+++ b/Make.mk
@@ -81,8 +81,8 @@ edatadir := $(datadir)/empire
 builtindir := $(edatadir)/builtin
 einfodir := $(edatadir)/info.nr
 ehtmldir := $(edatadir)/info.html
-client/w32 := arpa/inet.h netdb.h netinet/in.h sys/time.h sys/socket.h \
-sys/uio.h unistd.h w32io.c w32sockets.c w32types.h
+client/w32 := arpa/inet.h getopt.c netdb.h netinet/in.h sys/time.h     \
+sys/socket.h sys/uio.h unistd.h w32io.c w32sockets.c w32types.h
 
 # Abbreviate make output
 # Run make with a V=1 parameter for full output.
index f935038492974847aa1a30b17cb51eddca12930d..1b1c592e413c60a36a2231764ba6fe7121879fc0 100644 (file)
@@ -53,9 +53,9 @@ srcdir = @srcdir@
 VPATH = @srcdir@
 
 prog = empire$E
-obj = expect.$O fnameat.$O getpass.$O host.$O ipglob.$O linebuf.$O     \
-login.$O main.$O play.$O ringbuf.$O secure.$O servcmd.$O termlib.$O    \
-version.$O $(LIBOBJS)
+obj = expect.$O fnameat.$O getpass.$O getopt.$O host.$O ipglob.$O      \
+linebuf.$O login.$O main.$O play.$O ringbuf.$O secure.$O servcmd.$O    \
+termlib.$O version.$O $(LIBOBJS)
 
 all: $(prog)
 
@@ -83,6 +83,7 @@ uninstall:
 expect.$O: misc.h proto.h
 fnameat.$O: fnameat.h
 getpass.$O: misc.h
+getopt.$O:
 host.$O: misc.h
 linebuf.$O: linebuf.h
 login.$O: misc.h proto.h
diff --git a/src/lib/w32/getopt.c b/src/lib/w32/getopt.c
new file mode 100644 (file)
index 0000000..d015975
--- /dev/null
@@ -0,0 +1,150 @@
+#ifdef _MSC_VER
+#define __UNCONST(a) ((void *)(a))
+#define _DIAGASSERT(cond) assert((cond))
+#define getprogname() ((const char *)nargv[0])
+
+/*     $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $     */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *     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.
+ */
+
+#if 0
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $");
+
+#include "namespace.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getopt,_getopt)
+#endif
+
+int    opterr = 1,             /* if error message should be printed */
+       optind = 1,             /* index into parent argv vector */
+       optopt,                 /* character checked for validity */
+       optreset;               /* reset getopt */
+char   *optarg;                /* argument associated with option */
+
+#define        BADCH   (int)'?'
+#define        BADARG  (int)':'
+#define        EMSG    ""
+
+/*
+ * getopt --
+ *     Parse argc/argv argument vector.
+ */
+int
+getopt(int nargc, char * const nargv[], const char *ostr)
+{
+       static const char *place = EMSG;        /* option letter processing */
+       char *oli;                              /* option letter list index */
+
+       _DIAGASSERT(nargv != NULL);
+       _DIAGASSERT(ostr != NULL);
+
+       if (optreset || *place == 0) {          /* update scanning pointer */
+               optreset = 0;
+               place = nargv[optind];
+               if (optind >= nargc || *place++ != '-') {
+                       /* Argument is absent or is not an option */
+                       place = EMSG;
+                       return (-1);
+               }
+               optopt = *place++;
+               if (optopt == '-' && *place == 0) {
+                       /* "--" => end of options */
+                       ++optind;
+                       place = EMSG;
+                       return (-1);
+               }
+               if (optopt == 0) {
+                       /* Solitary '-', treat as a '-' option
+                          if the program (eg su) is looking for it. */
+                       place = EMSG;
+                       if (strchr(ostr, '-') == NULL)
+                               return -1;
+                       optopt = '-';
+               }
+       } else
+               optopt = *place++;
+
+       /* See if option letter is one the caller wanted... */
+       if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+               if (*place == 0)
+                       ++optind;
+               if (opterr && *ostr != ':')
+                       (void)fprintf(stderr,
+                           "%s: unknown option -- %c\n", getprogname(),
+                           optopt);
+               return (BADCH);
+       }
+
+       /* Does this option need an argument? */
+       if (oli[1] != ':') {
+               /* don't need argument */
+               optarg = NULL;
+               if (*place == 0)
+                       ++optind;
+       } else {
+               /* Option-argument is either the rest of this argument or the
+                  entire next argument. */
+               if (*place)
+                       optarg = __UNCONST(place);
+               else if (oli[2] == ':')
+                       /*
+                        * GNU Extension, for optional arguments if the rest of
+                        * the argument is empty, we return NULL
+                        */
+                       optarg = NULL;
+               else if (nargc > ++optind)
+                       optarg = nargv[optind];
+               else {
+                       /* option-argument absent */
+                       place = EMSG;
+                       if (*ostr == ':')
+                               return (BADARG);
+                       if (opterr)
+                               (void)fprintf(stderr,
+                                   "%s: option requires an argument -- %c\n",
+                                   getprogname(), optopt);
+                       return (BADCH);
+               }
+               place = EMSG;
+               ++optind;
+       }
+       return (optopt);                        /* return option letter */
+}
+#endif
index 8e594ad8517bc37629c79e54bc14d75a2f515c29..6f401949f91ea4f8f43c5364aba5bfcb446e7eec 100644 (file)
@@ -27,7 +27,7 @@
  *  unistd.h: POSIX emulation for Windows
  *
  *  Known contributors to this file:
- *     Ron Koenderink, 2007
+ *     Ron Koenderink, 2007-2021
  *     Markus Armbruster, 2007-2013
  */
 
@@ -98,7 +98,13 @@ extern int (*w32_write_function)(int, const void *, unsigned);
 #define ftruncate(fd, length) _chsize((fd), (length))
 #endif
 
-#ifndef _MSC_VER
+#ifdef _MSC_VER
+extern int getopt(int, char * const [], const char *);
+extern  char *optarg;
+extern  int opterr;
+extern  int optind;
+extern  int optopt;
+#else  /* !_MSC_VER */
 #include_next <unistd.h>
 #endif