+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif
+
+#define START_VSNBUFF 16
+
+/*
+ * This dynamic string module is adapted from TclResult.c in the Tcl library.
+ * Here is the copyright notice from the library:
+ *
+ * This software is copyrighted by the Regents of the University of
+ * California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
+ * Corporation and other parties. The following terms apply to all files
+ * associated with the software unless explicitly disclaimed in
+ * individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+ * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+ * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+ * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+ * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense, the
+ * software shall be classified as "Commercial Computer Software" and the
+ * Government shall have only "Restricted Rights" as defined in Clause
+ * 252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the
+ * authors grant the U.S. Government and others acting in its behalf
+ * permission to use and distribute the software in accordance with the
+ * terms specified in this license.
+ */
+
+typedef struct _internal_arg_dstr {
+ char* data;
+ arg_dstr_freefn* free_proc;
+ char sbuf[ARG_DSTR_SIZE + 1];
+ char* append_data;
+ int append_data_size;
+ int append_used;
+} _internal_arg_dstr_t;
+
+static void setup_append_buf(arg_dstr_t res, int newSpace);
+
+arg_dstr_t arg_dstr_create(void) {
+ _internal_arg_dstr_t* h = (_internal_arg_dstr_t*)xmalloc(sizeof(_internal_arg_dstr_t));
+ memset(h, 0, sizeof(_internal_arg_dstr_t));
+ h->sbuf[0] = 0;
+ h->data = h->sbuf;
+ h->free_proc = ARG_DSTR_STATIC;
+ return h;
+}
+
+void arg_dstr_destroy(arg_dstr_t ds) {
+ if (ds == NULL)
+ return;
+
+ arg_dstr_reset(ds);
+ xfree(ds);
+ return;
+}
+
+void arg_dstr_set(arg_dstr_t ds, char* str, arg_dstr_freefn* free_proc) {
+ int length;
+ register arg_dstr_freefn* old_free_proc = ds->free_proc;
+ char* old_result = ds->data;
+
+ if (str == NULL) {
+ ds->sbuf[0] = 0;
+ ds->data = ds->sbuf;
+ ds->free_proc = ARG_DSTR_STATIC;
+ } else if (free_proc == ARG_DSTR_VOLATILE) {
+ length = (int)strlen(str);
+ if (length > ARG_DSTR_SIZE) {
+ ds->data = (char*)xmalloc((unsigned)length + 1);
+ ds->free_proc = ARG_DSTR_DYNAMIC;
+ } else {
+ ds->data = ds->sbuf;
+ ds->free_proc = ARG_DSTR_STATIC;
+ }
+ strcpy(ds->data, str);
+ } else {
+ ds->data = str;
+ ds->free_proc = free_proc;
+ }
+
+ /*
+ * If the old result was dynamically-allocated, free it up. Do it here,
+ * rather than at the beginning, in case the new result value was part of
+ * the old result value.
+ */
+
+ if ((old_free_proc != 0) && (old_result != ds->data)) {
+ if (old_free_proc == ARG_DSTR_DYNAMIC) {
+ xfree(old_result);
+ } else {
+ (*old_free_proc)(old_result);
+ }
+ }
+
+ if ((ds->append_data != NULL) && (ds->append_data_size > 0)) {
+ xfree(ds->append_data);
+ ds->append_data = NULL;
+ ds->append_data_size = 0;
+ }
+}
+
+char* arg_dstr_cstr(arg_dstr_t ds) /* Interpreter whose result to return. */
+{
+ return ds->data;
+}
+
+void arg_dstr_cat(arg_dstr_t ds, const char* str) {
+ setup_append_buf(ds, (int)strlen(str) + 1);
+ memcpy(ds->data + strlen(ds->data), str, strlen(str));
+}
+
+void arg_dstr_catc(arg_dstr_t ds, char c) {
+ setup_append_buf(ds, 2);
+ memcpy(ds->data + strlen(ds->data), &c, 1);
+}
+
+/*
+ * The logic of the `arg_dstr_catf` function is adapted from the `bformat`
+ * function in The Better String Library by Paul Hsieh. Here is the copyright
+ * notice from the library:
+ *
+ * Copyright (c) 2014, Paul Hsieh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of bstrlib 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+void arg_dstr_catf(arg_dstr_t ds, const char* fmt, ...) {
+ va_list arglist;
+ char* buff;
+ int n, r;
+ size_t slen;
+
+ if (fmt == NULL)
+ return;
+
+ /* Since the length is not determinable beforehand, a search is
+ performed using the truncating "vsnprintf" call (to avoid buffer
+ overflows) on increasing potential sizes for the output result. */
+
+ if ((n = (int)(2 * strlen(fmt))) < START_VSNBUFF)
+ n = START_VSNBUFF;
+
+ buff = (char*)xmalloc(n + 2);
+ memset(buff, 0, n + 2);
+
+ for (;;) {
+ va_start(arglist, fmt);
+ r = vsnprintf(buff, n + 1, fmt, arglist);
+ va_end(arglist);
+
+ slen = strlen(buff);
+ if (slen < (size_t)n)
+ break;
+
+ if (r > n)
+ n = r;
+ else
+ n += n;
+
+ xfree(buff);
+ buff = (char*)xmalloc(n + 2);
+ memset(buff, 0, n + 2);
+ }
+
+ arg_dstr_cat(ds, buff);
+ xfree(buff);
+}
+
+static void setup_append_buf(arg_dstr_t ds, int new_space) {
+ int total_space;
+
+ /*
+ * Make the append buffer larger, if that's necessary, then copy the
+ * data into the append buffer and make the append buffer the official
+ * data.
+ */
+ if (ds->data != ds->append_data) {
+ /*
+ * If the buffer is too big, then free it up so we go back to a
+ * smaller buffer. This avoids tying up memory forever after a large
+ * operation.
+ */
+ if (ds->append_data_size > 500) {
+ xfree(ds->append_data);
+ ds->append_data = NULL;
+ ds->append_data_size = 0;
+ }
+ ds->append_used = (int)strlen(ds->data);
+ } else if (ds->data[ds->append_used] != 0) {
+ /*
+ * Most likely someone has modified a result created by
+ * arg_dstr_cat et al. so that it has a different size. Just
+ * recompute the size.
+ */
+ ds->append_used = (int)strlen(ds->data);
+ }
+
+ total_space = new_space + ds->append_used;
+ if (total_space >= ds->append_data_size) {
+ char* newbuf;
+
+ if (total_space < 100) {
+ total_space = 200;
+ } else {
+ total_space *= 2;
+ }
+ newbuf = (char*)xmalloc((unsigned)total_space);
+ memset(newbuf, 0, total_space);
+ strcpy(newbuf, ds->data);
+ if (ds->append_data != NULL) {
+ xfree(ds->append_data);
+ }
+ ds->append_data = newbuf;
+ ds->append_data_size = total_space;
+ } else if (ds->data != ds->append_data) {
+ strcpy(ds->append_data, ds->data);
+ }
+
+ arg_dstr_free(ds);
+ ds->data = ds->append_data;
+}
+
+void arg_dstr_free(arg_dstr_t ds) {
+ if (ds->free_proc != NULL) {
+ if (ds->free_proc == ARG_DSTR_DYNAMIC) {
+ xfree(ds->data);
+ } else {
+ (*ds->free_proc)(ds->data);
+ }
+ ds->free_proc = NULL;
+ }
+}
+
+void arg_dstr_reset(arg_dstr_t ds) {
+ arg_dstr_free(ds);
+ if ((ds->append_data != NULL) && (ds->append_data_size > 0)) {
+ xfree(ds->append_data);
+ ds->append_data = NULL;
+ ds->append_data_size = 0;
+ }
+
+ ds->data = ds->sbuf;
+ ds->sbuf[0] = 0;
+}
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+/* $FreeBSD$ */
+
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-NetBSD
+ *
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 ARG_REPLACE_GETOPT == 1
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+/*
+ * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
+ * getopt() is declared here too for GNU programs.
+ */
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+int getopt_long_only(int, char * const *, const char *,
+ const struct option *, int *);
+#ifndef _GETOPT_DECLARED
+#define _GETOPT_DECLARED
+int getopt(int, char * const [], const char *);
+
+extern char *optarg; /* getopt(3) external variables */
+extern int optind, opterr, optopt;
+#endif
+#ifndef _OPTRESET_DECLARED
+#define _OPTRESET_DECLARED
+extern int optreset; /* getopt(3) external variable */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_GETOPT_H_ */
+
+#endif /* ARG_REPLACE_GETOPT == 1 */
+/* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ */
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "argtable3.h"
+
+#if ARG_REPLACE_GETOPT == 1
+
+#ifndef ARG_AMALGAMATION
+#include "arg_getopt.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>