Replaced Free Getopt with getopt_port.

master
Camilla Berglund ago%!(EXTRA string=11 years)
parent af78508488
commit 18c635f474
  1. 2
      README.md
  2. 473
      deps/getopt.c
  3. 98
      deps/getopt.h

@ -38,7 +38,7 @@ The following dependencies are needed by GLFW:
The following dependencies are needed by the examples and test programs: The following dependencies are needed by the examples and test programs:
- [Free Getopt](http://freegetopt.sourceforge.net/) for getopt - [getopt\_port](https://github.com/kimgr/getopt_port/) for getopt
- [TinyCThread](https://gitorious.org/tinythread/tinycthread/) for threading - [TinyCThread](https://gitorious.org/tinythread/tinycthread/) for threading
- An OpenGL loader generated by [glad](https://github.com/Dav1dde/glad) - An OpenGL loader generated by [glad](https://github.com/Dav1dde/glad)

473
deps/getopt.c vendored

@ -1,267 +1,230 @@
/***************************************************************************** /* Copyright (c) 2012, Kim Gräsman
* getopt.c - competent and free getopt library. * All rights reserved.
* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $
*
* Copyright (c)2002-2003 Mark K. Kim
* 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 original author of this software 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 OWNER 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.
*/
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
/* 2013-01-06 Camilla Berglund <elmindreda@elmindreda.org>
* *
* Only define _CRT_SECURE_NO_WARNINGS if not already defined. * Redistribution and use in source and binary forms, with or without
*/ * modification, are permitted provided that the following conditions are met:
/* 2012-08-12 Lambert Clara <lambert.clara@yahoo.fr> * * Redistributions of source code must retain the above copyright notice,
* * this list of conditions and the following disclaimer.
* Constify third argument of getopt. * * Redistributions in binary form must reproduce the above copyright notice,
*/ * this list of conditions and the following disclaimer in the documentation
/* 2011-07-27 Camilla Berglund <elmindreda@elmindreda.org> * and/or other materials provided with the distribution.
* * * Neither the name of Kim Gräsman nor the names of contributors may be used
* Added _CRT_SECURE_NO_WARNINGS macro. * to endorse or promote products derived from this software without specific
*/ * prior written permission.
/* 2009-10-12 Camilla Berglund <elmindreda@elmindreda.org>
* *
* Removed unused global static variable 'ID'. * 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 KIM GRÄSMAN 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.
*/ */
char* optarg = NULL; #include "getopt.h"
int optind = 0;
int opterr = 1;
int optopt = '?';
static char** prev_argv = NULL; /* Keep a copy of argv and argc to */
static int prev_argc = 0; /* tell if getopt params change */
static int argv_index = 0; /* Option we're checking */
static int argv_index2 = 0; /* Option argument we're checking */
static int opt_offset = 0; /* Index into compounded "-option" */
static int dashdash = 0; /* True if "--" option reached */
static int nonopt = 0; /* How many nonopts we've found */
static void increment_index()
{
/* Move onto the next option */
if(argv_index < argv_index2)
{
while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-'
&& argv_index < argv_index2+1);
}
else argv_index++;
opt_offset = 1;
}
#include <stddef.h>
#include <string.h>
/* const int no_argument = 0;
* Permutes argv[] so that the argument currently being processed is moved const int required_argument = 1;
* to the end. const int optional_argument = 2;
*/
static int permute_argv_once()
{
/* Movability check */
if(argv_index + nonopt >= prev_argc) return 1;
/* Move the current option to the end, bring the others to front */
else
{
char* tmp = prev_argv[argv_index];
/* Move the data */
memmove(&prev_argv[argv_index], &prev_argv[argv_index+1],
sizeof(char**) * (prev_argc - argv_index - 1));
prev_argv[prev_argc - 1] = tmp;
nonopt++;
return 0;
}
}
char* optarg;
int optopt;
/* The variable optind [...] shall be initialized to 1 by the system. */
int optind = 1;
int opterr;
int getopt(int argc, char** argv, const char* optstr) static char* optcursor = NULL;
{
int c = 0; /* Implemented based on [1] and [2] for optional arguments.
optopt is handled FreeBSD-style, per [3].
/* If we have new argv, reinitialize */ Other GNU and FreeBSD extensions are purely accidental.
if(prev_argv != argv || prev_argc != argc)
{ [1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
/* Initialize variables */ [2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
prev_argv = argv; [3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
prev_argc = argc; */
argv_index = 1; int getopt(int argc, char* const argv[], const char* optstring) {
argv_index2 = 1; int optchar = -1;
opt_offset = 1; const char* optdecl = NULL;
dashdash = 0;
nonopt = 0; optarg = NULL;
} opterr = 0;
optopt = 0;
/* Jump point in case we want to ignore the current argv_index */
getopt_top: /* Unspecified, but we need it to avoid overrunning the argv bounds. */
if (optind >= argc)
/* Misc. initializations */ goto no_more_optchars;
optarg = NULL;
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
/* Dash-dash check */ shall return -1 without changing optind. */
if(argv[argv_index] && !strcmp(argv[argv_index], "--")) if (argv[optind] == NULL)
{ goto no_more_optchars;
dashdash = 1;
increment_index(); /* If, when getopt() is called *argv[optind] is not the character '-',
} getopt() shall return -1 without changing optind. */
if (*argv[optind] != '-')
/* If we're at the end of argv, that's it. */ goto no_more_optchars;
if(argv[argv_index] == NULL)
{ /* If, when getopt() is called argv[optind] points to the string "-",
c = -1; getopt() shall return -1 without changing optind. */
} if (strcmp(argv[optind], "-") == 0)
/* Are we looking at a string? Single dash is also a string */ goto no_more_optchars;
else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-"))
{ /* If, when getopt() is called argv[optind] points to the string "--",
/* If we want a string... */ getopt() shall return -1 after incrementing optind. */
if(optstr[0] == '-') if (strcmp(argv[optind], "--") == 0) {
{ ++optind;
c = 1; goto no_more_optchars;
optarg = argv[argv_index]; }
increment_index();
} if (optcursor == NULL || *optcursor == '\0')
/* If we really don't want it (we're in POSIX mode), we're done */ optcursor = argv[optind] + 1;
else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT"))
{ optchar = *optcursor;
c = -1;
/* FreeBSD: The variable optopt saves the last known option character
/* Everything else is a non-opt argument */ returned by getopt(). */
nonopt = argc - argv_index; optopt = optchar;
}
/* If we mildly don't want it, then move it back */ /* The getopt() function shall return the next option character (if one is
else found) from argv that matches a character in optstring, if there is
{ one that matches. */
if(!permute_argv_once()) goto getopt_top; optdecl = strchr(optstring, optchar);
else c = -1; if (optdecl) {
} /* [I]f a character is followed by a colon, the option takes an
} argument. */
/* Otherwise we're looking at an option */ if (optdecl[1] == ':') {
else optarg = ++optcursor;
{ if (*optarg == '\0') {
char* opt_ptr = NULL; /* GNU extension: Two colons mean an option takes an
optional arg; if there is text in the current argv-element
/* Grab the option */ (i.e., in the same word as the option name itself, for example,
c = argv[argv_index][opt_offset++]; "-oarg"), then it is returned in optarg, otherwise optarg is set
to zero. */
/* Is the option in the optstr? */ if (optdecl[2] != ':') {
if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c); /* If the option was the last character in the string pointed to by
else opt_ptr = strchr(optstr, c); an element of argv, then optarg shall contain the next element
/* Invalid argument */ of argv, and optind shall be incremented by 2. If the resulting
if(!opt_ptr) value of optind is greater than argc, this indicates a missing
{ option-argument, and getopt() shall return an error indication.
if(opterr)
{ Otherwise, optarg shall point to the string following the
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); option character in that element of argv, and optind shall be
} incremented by 1.
*/
optopt = c; if (++optind < argc) {
c = '?'; optarg = argv[optind];
} else {
/* Move onto the next option */ /* If it detects a missing option-argument, it shall return the
increment_index(); colon character ( ':' ) if the first character of optstring
} was a colon, or a question-mark character ( '?' ) otherwise.
/* Option takes argument */ */
else if(opt_ptr[1] == ':') optarg = NULL;
{ optchar = (optstring[0] == ':') ? ':' : '?';
/* ie, -oARGUMENT, -xxxoARGUMENT, etc. */ }
if(argv[argv_index][opt_offset] != '\0') } else {
{ optarg = NULL;
optarg = &argv[argv_index][opt_offset]; }
increment_index(); }
}
/* ie, -o ARGUMENT (only if it's a required argument) */ optcursor = NULL;
else if(opt_ptr[2] != ':') }
{ } else {
/* One of those "you're not expected to understand this" moment */ /* If getopt() encounters an option character that is not contained in
if(argv_index2 < argv_index) argv_index2 = argv_index; optstring, it shall return the question-mark ( '?' ) character. */
while(argv[++argv_index2] && argv[argv_index2][0] == '-'); optchar = '?';
optarg = argv[argv_index2]; }
/* Don't cross into the non-option argument list */ if (optcursor == NULL || *++optcursor == '\0')
if(argv_index2 + nonopt >= prev_argc) optarg = NULL; ++optind;
/* Move onto the next option */ return optchar;
increment_index();
} no_more_optchars:
else optcursor = NULL;
{ return -1;
/* Move onto the next option */
increment_index();
}
/* In case we got no argument for an option with required argument */
if(optarg == NULL && opt_ptr[2] != ':')
{
optopt = c;
c = '?';
if(opterr)
{
fprintf(stderr,"%s: option requires an argument -- %c\n",
argv[0], optopt);
}
}
}
/* Option does not take argument */
else
{
/* Next argv_index */
if(argv[argv_index][opt_offset] == '\0')
{
increment_index();
}
}
}
/* Calculate optind */
if(c == -1)
{
optind = argc - nonopt;
}
else
{
optind = argv_index;
}
return c;
} }
/* Implementation based on [1].
/* vim:ts=3 [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
*/ */
int getopt_long(int argc, char* const argv[], const char* optstring,
const struct option* longopts, int* longindex) {
const struct option* o = longopts;
const struct option* match = NULL;
int num_matches = 0;
size_t argument_name_length = 0;
const char* current_argument = NULL;
int retval = -1;
optarg = NULL;
optopt = 0;
if (optind >= argc)
return -1;
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
return getopt(argc, argv, optstring);
/* It's an option; starts with -- and is longer than two chars. */
current_argument = argv[optind] + 2;
argument_name_length = strcspn(current_argument, "=");
for (; o->name; ++o) {
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
match = o;
++num_matches;
}
}
if (num_matches == 1) {
/* If longindex is not NULL, it points to a variable which is set to the
index of the long option relative to longopts. */
if (longindex)
*longindex = (match - longopts);
/* If flag is NULL, then getopt_long() shall return val.
Otherwise, getopt_long() returns 0, and flag shall point to a variable
which shall be set to val if the option is found, but left unchanged if
the option is not found. */
if (match->flag)
*(match->flag) = match->val;
retval = match->flag ? 0 : match->val;
if (match->has_arg != no_argument) {
optarg = strchr(argv[optind], '=');
if (optarg != NULL)
++optarg;
if (match->has_arg == required_argument) {
/* Only scan the next argv for required arguments. Behavior is not
specified, but has been observed with Ubuntu and Mac OSX. */
if (optarg == NULL && ++optind < argc) {
optarg = argv[optind];
}
if (optarg == NULL)
retval = ':';
}
} else if (strchr(argv[optind], '=')) {
/* An argument was provided to a non-argument option.
I haven't seen this specified explicitly, but both GNU and BSD-based
implementations show this behavior.
*/
retval = '?';
}
} else {
/* Unknown option or ambiguous match. */
retval = '?';
}
++optind;
return retval;
}

98
deps/getopt.h vendored

@ -1,63 +1,57 @@
/***************************************************************************** /* Copyright (c) 2012, Kim Gräsman
* getopt.h - competent and free getopt library. * All rights reserved.
* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $ *
* * Redistribution and use in source and binary forms, with or without
* Copyright (c)2002-2003 Mark K. Kim * modification, are permitted provided that the following conditions are met:
* All rights reserved. * * Redistributions of source code must retain the above copyright notice,
* * this list of conditions and the following disclaimer.
* Redistribution and use in source and binary forms, with or without * * Redistributions in binary form must reproduce the above copyright notice,
* modification, are permitted provided that the following conditions * this list of conditions and the following disclaimer in the documentation
* are met: * and/or other materials provided with the distribution.
* * * Neither the name of Kim Gräsman nor the names of contributors may be used
* * Redistributions of source code must retain the above copyright * to endorse or promote products derived from this software without specific
* notice, this list of conditions and the following disclaimer. * prior written permission.
* *
* * Redistributions in binary form must reproduce the above copyright * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* notice, this list of conditions and the following disclaimer in * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* the documentation and/or other materials provided with the * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* distribution. * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
* * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* * Neither the original author of this software nor the names of its * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* contributors may be used to endorse or promote products derived * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* from this software without specific prior written permission. * 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
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* "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 #ifndef INCLUDED_GETOPT_PORT_H
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, #define INCLUDED_GETOPT_PORT_H
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS #if defined(__cplusplus)
* 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.
*/
#ifndef GETOPT_H_
#define GETOPT_H_
#ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern const int no_argument;
extern const int required_argument;
extern const int optional_argument;
extern char* optarg; extern char* optarg;
extern int optind; extern int optind, opterr, optopt;
extern int opterr;
extern int optopt;
int getopt(int argc, char** argv, const char* optstr); struct option {
const char* name;
int has_arg;
int* flag;
int val;
};
int getopt(int argc, char* const argv[], const char* optstring);
#ifdef __cplusplus int getopt_long(int argc, char* const argv[],
const char* optstring, const struct option* longopts, int* longindex);
#if defined(__cplusplus)
} }
#endif #endif
#endif // INCLUDED_GETOPT_PORT_H
#endif /* GETOPT_H_ */
/* vim:ts=3
*/

Loading…
Cancel
Save