فهرست منبع

replace gnu_getopt with new Panda-licensed implementation

David Rose 14 سال پیش
والد
کامیت
9d5325e05a

+ 5 - 2
dtool/src/dtoolutil/Sources.pp

@@ -19,8 +19,9 @@
     pandaFileStream.h pandaFileStream.I \
     pandaFileStreamBuf.h \
     pandaSystem.h pandaVersion.h \
+    panda_getopt.h panda_getopt_long.h panda_getopt_impl.h \
     pfstream.h pfstream.I pfstreamBuf.h \
-    vector_string.h gnu_getopt.c gnu_getopt.h gnu_getopt1.c  \
+    vector_string.h \
     vector_src.h 
 
   #define INCLUDED_SOURCES \
@@ -30,6 +31,7 @@
     dSearchPath.cxx \
     pandaFileStream.cxx pandaFileStreamBuf.cxx \
     pandaSystem.cxx \
+    panda_getopt_impl.cxx \
     pfstreamBuf.cxx pfstream.cxx \
     vector_string.cxx
 
@@ -41,8 +43,9 @@
     pandaFileStream.h pandaFileStream.I \
     pandaFileStreamBuf.h \
     pandaSystem.h pandaVersion.h \
+    panda_getopt.h panda_getopt_long.h panda_getopt_impl.h \
     pfstream.h pfstream.I pfstreamBuf.h \
-    vector_string.h gnu_getopt.h \
+    vector_string.h \
     vector_src.cxx vector_src.h
 #end lib_target
 

+ 1 - 0
dtool/src/dtoolutil/dtoolutil_composite2.cxx

@@ -1,5 +1,6 @@
 #include "pandaFileStream.cxx"
 #include "pandaFileStreamBuf.cxx"
+#include "panda_getopt_impl.cxx"
 #include "executionEnvironment.cxx"
 #include "vector_string.cxx"
 #include "pfstream.cxx"

+ 0 - 740
dtool/src/dtoolutil/gnu_getopt.c

@@ -1,740 +0,0 @@
-/* Getopt for GNU.
-   NOTE: getopt is now part of the C library, so if you don't know what
-   "Keep this file name-space clean" means, talk to [email protected]
-   before changing it!
-
-   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
-        Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.  */
-
-
-#include "dtoolbase.h"
-
-#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_LONG_ONLY)
-
-#ifdef WIN32_VC
-/* This file seems particularly egregious with this particular warning,
-   but it's not clear why.  Disable. */
-/* C4028: formal parameter N different from declaration */
-#pragma warning (disable : 4028)
-#endif
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
-   Ditto for AIX 3.2 and <stdlib.h>.  */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifndef __STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-/* Actually, we may need to compile this anyway, even on a gnu platform. */
-#if 1 /* defined (_LIBC) || !defined (__GNU_LIBRARY__) */
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef  __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
-   contain conflicting prototypes for getopt.  */
-#include <stdlib.h>
-#endif  /* GNU C library.  */
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
-   but it behaves differently for the user, since it allows the user
-   to intersperse the options with the other arguments.
-
-   As `getopt' works, it permutes the elements of ARGV so that,
-   when it is done, all the options precede everything else.  Thus
-   all application programs are extended to handle flexible argument order.
-
-   Setting the environment variable POSIXLY_CORRECT disables permutation.
-   Then the behavior is completely standard.
-
-   GNU application programs can use a third alternative mode in which
-   they can distinguish the relative order of options and other arguments.  */
-
-#include "gnu_getopt.h"
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns EOF, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-/* XXX 1003.2 says this must be 1 before any call.  */
-int optind = 0;
-
-/* The next char to be scanned in the option-element
-   in which the last option character we returned was found.
-   This allows us to pick up the scan where we left off.
-
-   If this is zero, or a null string, it means resume the scan
-   by advancing to the next ARGV-element.  */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
-   for unrecognized options.  */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
-   This must be initialized on some systems to avoid linking in the
-   system's own getopt implementation.  */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
-   If the caller did not specify anything,
-   the default is REQUIRE_ORDER if the environment variable
-   POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
-   REQUIRE_ORDER means don't recognize them as options;
-   stop option processing when the first non-option is seen.
-   This is what Unix does.
-   This mode of operation is selected by either setting the environment
-   variable POSIXLY_CORRECT, or using `+' as the first character
-   of the list of option characters.
-
-   PERMUTE is the default.  We permute the contents of ARGV as we scan,
-   so that eventually all the non-options are at the end.  This allows options
-   to be given in any order, even with programs that were not written to
-   expect this.
-
-   RETURN_IN_ORDER is an option available to programs that were written
-   to expect options and other ARGV-elements in any order and that care about
-   the ordering of the two.  We describe each non-option ARGV-element
-   as if it were the argument of an option with character code 1.
-   Using `-' as the first character of the list of option characters
-   selects this mode of operation.
-
-   The special argument `--' forces an end of option-scanning regardless
-   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
-   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
-
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable.  */
-static char *posixly_correct;
-
-#ifdef  __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
-   because there are many ways it can cause trouble.
-   On some systems, it contains special magic macros that don't work
-   in GCC.  */
-#include <string.h>
-#define my_index        strchr
-#else
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-char *getenv ();
-
-static char *
-my_index (const char *str, int chr) {
-  while (*str)
-    {
-      if (*str == chr)
-        return (char *) str;
-      str++;
-    }
-  return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
-   If not using GCC, it is ok not to declare it.  */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
-   That was relevant to code that was here before.  */
-#ifndef __STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
-   and has done so at least since version 2.4.5. -- rms.  */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments.  */
-
-/* Describe the part of ARGV that contains non-options that have
-   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
-   `last_nonopt' is the index after the last of them.  */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
-   One subsequence is elements [first_nonopt,last_nonopt)
-   which contains all the non-options that have been skipped so far.
-   The other is elements [last_nonopt,optind), which contains all
-   the options processed since those non-options were skipped.
-
-   `first_nonopt' and `last_nonopt' are relocated so that they describe
-   the new indices of the non-options in ARGV after they are moved.  */
-
-static void
-exchange (char **argv) {
-  int bottom = first_nonopt;
-  int middle = last_nonopt;
-  int top = optind;
-  char *tem;
-
-  /* Exchange the shorter segment with the far end of the longer segment.
-     That puts the shorter segment into the right place.
-     It leaves the longer segment in the right place overall,
-     but it consists of two parts that need to be swapped next.  */
-
-  while (top > middle && middle > bottom)
-    {
-      if (top - middle > middle - bottom)
-        {
-          /* Bottom segment is the short one.  */
-          int len = middle - bottom;
-          register int i;
-
-          /* Swap it with the top part of the top segment.  */
-          for (i = 0; i < len; i++)
-            {
-              tem = argv[bottom + i];
-              argv[bottom + i] = argv[top - (middle - bottom) + i];
-              argv[top - (middle - bottom) + i] = tem;
-            }
-          /* Exclude the moved bottom segment from further swapping.  */
-          top -= len;
-        }
-      else
-        {
-          /* Top segment is the short one.  */
-          int len = top - middle;
-          register int i;
-
-          /* Swap it with the bottom part of the bottom segment.  */
-          for (i = 0; i < len; i++)
-            {
-              tem = argv[bottom + i];
-              argv[bottom + i] = argv[middle + i];
-              argv[middle + i] = tem;
-            }
-          /* Exclude the moved top segment from further swapping.  */
-          bottom += len;
-        }
-    }
-
-  /* Update records for the slots the non-options now occupy.  */
-
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made.  */
-
-static const char *
-_getopt_initialize (const char *optstring) {
-  /* Start processing options with ARGV-element 1 (since ARGV-element 0
-     is the program name); the sequence of previously skipped
-     non-option ARGV-elements is empty.  */
-
-  first_nonopt = last_nonopt = optind = 1;
-
-  nextchar = NULL;
-
-  posixly_correct = getenv ("POSIXLY_CORRECT");
-
-  /* Determine how to handle the ordering of options and nonoptions.  */
-
-  if (optstring[0] == '-')
-    {
-      ordering = RETURN_IN_ORDER;
-      ++optstring;
-    }
-  else if (optstring[0] == '+')
-    {
-      ordering = REQUIRE_ORDER;
-      ++optstring;
-    }
-  else if (posixly_correct != NULL)
-    ordering = REQUIRE_ORDER;
-  else
-    ordering = PERMUTE;
-
-  return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
-   given in OPTSTRING.
-
-   If an element of ARGV starts with '-', and is not exactly "-" or "--",
-   then it is an option element.  The characters of this element
-   (aside from the initial '-') are option characters.  If `getopt'
-   is called repeatedly, it returns successively each of the option characters
-   from each of the option elements.
-
-   If `getopt' finds another option character, it returns that character,
-   updating `optind' and `nextchar' so that the next call to `getopt' can
-   resume the scan with the following option character or ARGV-element.
-
-   If there are no more option characters, `getopt' returns `EOF'.
-   Then `optind' is the index in ARGV of the first ARGV-element
-   that is not an option.  (The ARGV-elements have been permuted
-   so that those that are not options now come last.)
-
-   OPTSTRING is a string containing the legitimate option characters.
-   If an option character is seen that is not listed in OPTSTRING,
-   return '?' after printing an error message.  If you set `opterr' to
-   zero, the error message is suppressed but we still return '?'.
-
-   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
-   so the following text in the same ARGV-element, or the text of the following
-   ARGV-element, is returned in `optarg'.  Two colons mean an option that
-   wants an optional arg; if there is text in the current ARGV-element,
-   it is returned in `optarg', otherwise `optarg' is set to zero.
-
-   If OPTSTRING starts with `-' or `+', it requests different methods of
-   handling the non-option ARGV-elements.
-   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
-   Long-named options begin with `--' instead of `-'.
-   Their names may be abbreviated as long as the abbreviation is unique
-   or is an exact match for some defined option.  If they have an
-   argument, it follows the option name in the same ARGV-element, separated
-   from the option name by a `=', or else the in next ARGV-element.
-   When `getopt' finds a long-named option, it returns 0 if that option's
-   `flag' field is nonzero, the value of the option's `val' field
-   if the `flag' field is zero.
-
-   The elements of ARGV aren't really const, because we permute them.
-   But we pretend they're const in the prototype to be compatible
-   with other systems.
-
-   LONGOPTS is a vector of `struct option' terminated by an
-   element containing a name which is zero.
-
-   LONGIND returns the index in LONGOPT of the long-named option found.
-   It is only valid when a long-named option has been found by the most
-   recent call.
-
-   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
-   long-named options.  */
-
-int
-_getopt_internal (int argc, 
-                  char *const *argv, 
-                  const char *optstring, 
-                  const struct option *longopts, 
-                  int *longind, 
-                  int long_only) {
-  optarg = NULL;
-
-  if (optind == 0)
-    optstring = _getopt_initialize (optstring);
-
-  if (nextchar == NULL || *nextchar == '\0')
-    {
-      /* Advance to the next ARGV-element.  */
-
-      if (ordering == PERMUTE)
-        {
-          /* If we have just processed some options following some non-options,
-             exchange them so that the options come first.  */
-
-          if (first_nonopt != last_nonopt && last_nonopt != optind)
-            exchange ((char **) argv);
-          else if (last_nonopt != optind)
-            first_nonopt = optind;
-
-          /* Skip any additional non-options
-             and extend the range of non-options previously skipped.  */
-
-          while (optind < argc
-                 && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
-            optind++;
-          last_nonopt = optind;
-        }
-
-      /* The special ARGV-element `--' means premature end of options.
-         Skip it like a null option,
-         then exchange with previous non-options as if it were an option,
-         then skip everything else like a non-option.  */
-
-      if (optind != argc && !strcmp (argv[optind], "--"))
-        {
-          optind++;
-
-          if (first_nonopt != last_nonopt && last_nonopt != optind)
-            exchange ((char **) argv);
-          else if (first_nonopt == last_nonopt)
-            first_nonopt = optind;
-          last_nonopt = argc;
-
-          optind = argc;
-        }
-
-      /* If we have done all the ARGV-elements, stop the scan
-         and back over any non-options that we skipped and permuted.  */
-
-      if (optind == argc)
-        {
-          /* Set the next-arg-index to point at the non-options
-             that we previously skipped, so the caller will digest them.  */
-          if (first_nonopt != last_nonopt)
-            optind = first_nonopt;
-          return EOF;
-        }
-
-      /* If we have come to a non-option and did not permute it,
-         either stop the scan or describe it to the caller and pass it by.  */
-
-      if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
-        {
-          if (ordering == REQUIRE_ORDER)
-            return EOF;
-          optarg = argv[optind++];
-          return 1;
-        }
-
-      /* We have found another option-ARGV-element.
-         Skip the initial punctuation.  */
-
-      nextchar = (argv[optind] + 1
-                  + (longopts != NULL && argv[optind][1] == '-'));
-    }
-
-  /* Decode the current option-ARGV-element.  */
-
-  /* Check whether the ARGV-element is a long option.
-
-     If long_only and the ARGV-element has the form "-f", where f is
-     a valid short option, don't consider it an abbreviated form of
-     a long option that starts with f.  Otherwise there would be no
-     way to give the -f short option.
-
-     On the other hand, if there's a long option "fubar" and
-     the ARGV-element is "-fu", do consider that an abbreviation of
-     the long option, just like "--fu", and not "-f" with arg "u".
-
-     This distinction seems to be the most useful approach.  */
-
-  if (longopts != NULL
-      && (argv[optind][1] == '-'
-          || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
-    {
-      char *nameend;
-      const struct option *p;
-      const struct option *pfound = NULL;
-      int exact = 0;
-      int ambig = 0;
-      int indfound = 0;
-      int option_index;
-
-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
-        /* Do nothing.  */ ;
-
-      /* Test all long options for either exact match
-         or abbreviated matches.  */
-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
-        if (!strncmp (p->name, nextchar, nameend - nextchar))
-          {
-            if (nameend - nextchar == (int) strlen (p->name))
-              {
-                /* Exact match found.  */
-                pfound = p;
-                indfound = option_index;
-                exact = 1;
-                break;
-              }
-            else if (pfound == NULL)
-              {
-                /* First nonexact match found.  */
-                pfound = p;
-                indfound = option_index;
-              }
-            else
-              /* Second or later nonexact match found.  */
-              ambig = 1;
-          }
-
-      if (ambig && !exact)
-        {
-          if (opterr)
-            fprintf (stderr, "%s: option `%s' is ambiguous\n",
-                     argv[0], argv[optind]);
-          nextchar += strlen (nextchar);
-          optind++;
-          return '?';
-        }
-
-      if (pfound != NULL)
-        {
-          option_index = indfound;
-          optind++;
-          if (*nameend)
-            {
-              /* Don't test has_arg with >, because some C compilers don't
-                 allow it to be used on enums.  */
-              if (pfound->has_arg)
-                optarg = nameend + 1;
-              else
-                {
-                  if (opterr)
-                    {
-                      if (argv[optind - 1][1] == '-')
-                        /* --option */
-                        fprintf (stderr,
-                                 "%s: option `--%s' doesn't allow an argument\n",
-                                 argv[0], pfound->name);
-                      else
-                        /* +option or -option */
-                        fprintf (stderr,
-                             "%s: option `%c%s' doesn't allow an argument\n",
-                             argv[0], argv[optind - 1][0], pfound->name);
-                    }
-                  nextchar += strlen (nextchar);
-                  return '?';
-                }
-            }
-          else if (pfound->has_arg == 1)
-            {
-              if (optind < argc)
-                optarg = argv[optind++];
-              else
-                {
-                  if (opterr)
-                    fprintf (stderr, "%s: option `%s' requires an argument\n",
-                             argv[0], argv[optind - 1]);
-                  nextchar += strlen (nextchar);
-                  return optstring[0] == ':' ? ':' : '?';
-                }
-            }
-          nextchar += strlen (nextchar);
-          if (longind != NULL)
-            *longind = option_index;
-          if (pfound->flag)
-            {
-              *(pfound->flag) = pfound->val;
-              return 0;
-            }
-          return pfound->val;
-        }
-
-      /* Can't find it as a long option.  If this is not getopt_long_only,
-         or the option starts with '--' or is not a valid short
-         option, then it's an error.
-         Otherwise interpret it as a short option.  */
-      if (!long_only || argv[optind][1] == '-'
-          || my_index (optstring, *nextchar) == NULL)
-        {
-          if (opterr)
-            {
-              if (argv[optind][1] == '-')
-                /* --option */
-                fprintf (stderr, "%s: unrecognized option `--%s'\n",
-                         argv[0], nextchar);
-              else
-                /* +option or -option */
-                fprintf (stderr, "%s: unrecognized option `%c%s'\n",
-                         argv[0], argv[optind][0], nextchar);
-            }
-          nextchar = (char *) "";
-          optind++;
-          return '?';
-        }
-    }
-
-  /* Look at and handle the next short option-character.  */
-
-  {
-    char c = *nextchar++;
-    char *temp = my_index (optstring, c);
-
-    /* Increment `optind' when we start to process its last character.  */
-    if (*nextchar == '\0')
-      ++optind;
-
-    if (temp == NULL || c == ':')
-      {
-        if (opterr)
-          {
-            if (posixly_correct)
-              /* 1003.2 specifies the format of this message.  */
-              fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
-            else
-              fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
-          }
-        optopt = c;
-        return '?';
-      }
-    if (temp[1] == ':')
-      {
-        if (temp[2] == ':')
-          {
-            /* This is an option that accepts an argument optionally.  */
-            if (*nextchar != '\0')
-              {
-                optarg = nextchar;
-                optind++;
-              }
-            else
-              optarg = NULL;
-            nextchar = NULL;
-          }
-        else
-          {
-            /* This is an option that requires an argument.  */
-            if (*nextchar != '\0')
-              {
-                optarg = nextchar;
-                /* If we end this ARGV-element by taking the rest as an arg,
-                   we must advance to the next element now.  */
-                optind++;
-              }
-            else if (optind == argc)
-              {
-                if (opterr)
-                  {
-                    /* 1003.2 specifies the format of this message.  */
-                    fprintf (stderr, "%s: option requires an argument -- %c\n",
-                             argv[0], c);
-                  }
-                optopt = c;
-                if (optstring[0] == ':')
-                  c = ':';
-                else
-                  c = '?';
-              }
-            else
-              /* We already incremented `optind' once;
-                 increment it again when taking next ARGV-elt as argument.  */
-              optarg = argv[optind++];
-            nextchar = NULL;
-          }
-      }
-    return c;
-  }
-}
-
-int
-getopt (int argc, char *const *argv, const char *optstring) {
-  return _getopt_internal (argc, argv, optstring,
-                           (const struct option *) 0,
-                           (int *) 0,
-                           0);
-}
-
-#endif  /* _LIBC or not __GNU_LIBRARY__.  */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
-   the above definition of `getopt'.  */
-
-int
-main (int argc, char **argv) {
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-
-      c = getopt (argc, argv, "abc:d:0123456789");
-      if (c == EOF)
-        break;
-
-      switch (c)
-        {
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-          if (digit_optind != 0 && digit_optind != this_option_optind)
-            printf ("digits occur in two different argv-elements.\n");
-          digit_optind = this_option_optind;
-          printf ("option %c\n", c);
-          break;
-
-        case 'a':
-          printf ("option a\n");
-          break;
-
-        case 'b':
-          printf ("option b\n");
-          break;
-
-        case 'c':
-          printf ("option c with value `%s'\n", optarg);
-          break;
-
-        case '?':
-          break;
-
-        default:
-          printf ("?? getopt returned character code 0%o ??\n", c);
-        }
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-        printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
-
-#endif /* HAVE_GETOPT */

+ 0 - 125
dtool/src/dtoolutil/gnu_getopt.h

@@ -1,125 +0,0 @@
-/* Declarations for getopt.
-   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.  */
-
-#ifndef _GNU_GETOPT_H
-#define _GNU_GETOPT_H 1
-
-/* We don't want to collide with a system getopt() it if it exists.
-   Redefine our symbols accordingly. */
-
-#define getopt gnu_getopt
-#define optind gnu_optind
-#define opterr gnu_opterr
-#define optopt gnu_optopt
-#define optarg gnu_optarg
-#define getopt_long gnu_getopt_long
-#define getopt_long_only gnu_getopt_long_only
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-extern char EXPCL_DTOOL *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns EOF, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-extern int EXPCL_DTOOL optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
-   for unrecognized options.  */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized.  */
-
-extern int optopt;
-
-/* Describe the long-named options requested by the application.
-   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
-   of `struct option' terminated by an element containing a name which is
-   zero.
-
-   The field `has_arg' is:
-   no_argument          (or 0) if the option does not take an argument,
-   required_argument    (or 1) if the option requires an argument,
-   optional_argument    (or 2) if the option takes an optional argument.
-
-   If the field `flag' is not NULL, it points to a variable that is set
-   to the value given in the field `val' when the option is found, but
-   left unchanged if the option is not found.
-
-   To have a long-named option do something other than set an `int' to
-   a compiled-in constant, such as set a value from `optarg', set the
-   option's `flag' field to zero and its `val' field to a nonzero
-   value (the equivalent single-letter option character, if there is
-   one).  For long options that have a zero `flag' field, `getopt'
-   returns the contents of the `val' field.  */
-
-struct option
-{
-#if     __STDC__
-  const char *name;
-#else
-  char *name;
-#endif
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'.  */
-
-#define no_argument             0
-#define required_argument       1
-#define optional_argument       2
-
-extern EXPCL_DTOOL int
-getopt (int argc, char *const *argv, const char *shortopts);
-extern EXPCL_DTOOL int
-getopt_long (int argc, char *const *argv, const char *shortopts,
-             const struct option *long_options, int *opt_index);
-extern EXPCL_DTOOL int
-getopt_long_only (int argc, char *const *argv,
-                  const char *shortopts,
-                  const struct option *long_options, 
-                  int *opt_index);
-
-/* Internal only.  Users should not call this directly.  */
-extern int _getopt_internal (int argc, char *const *argv,
-                             const char *shortopts,
-                             const struct option *longopts, int *longind,
-                             int long_only);
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */

+ 0 - 180
dtool/src/dtoolutil/gnu_getopt1.c

@@ -1,180 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
-   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
-        Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.  */
-
-
-#include "dtoolbase.h"
-
-#ifndef HAVE_GETOPT_LONG_ONLY
-
-#ifdef WIN32_VC
-/* This file seems particularly egregious with this particular warning,
-   but it's not clear why.  Disable. */
-/* C4028: formal parameter N different from declaration */
-#pragma warning (disable : 4028)
-#endif
-
-#include "gnu_getopt.h"
-
-#ifndef __STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-/* Actually, we may need to compile this anyway, even on a gnu platform. */
-#if 1 /* defined (_LIBC) || !defined (__GNU_LIBRARY__) */
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#else
-char *getenv ();
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (int argc, 
-             char *const *argv, 
-             const char *options, 
-             const struct option *long_options, 
-             int *opt_index) {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
-   If an option that starts with '-' (not '--') doesn't match a long option,
-   but does match a short option, it is parsed as a short option
-   instead.  */
-
-int
-getopt_long_only (int argc, 
-                  char *const *argv, 
-                  const char *options, 
-                  const struct option *long_options, 
-                  int *opt_index) {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-
-#endif  /* _LIBC or not __GNU_LIBRARY__.  */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (int argc, char **argv) {
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-      int option_index = 0;
-      static struct option long_options[] =
-      {
-        {"add", 1, 0, 0},
-        {"append", 0, 0, 0},
-        {"delete", 1, 0, 0},
-        {"verbose", 0, 0, 0},
-        {"create", 0, 0, 0},
-        {"file", 1, 0, 0},
-        {0, 0, 0, 0}
-      };
-
-      c = getopt_long (argc, argv, "abc:d:0123456789",
-                       long_options, &option_index);
-      if (c == EOF)
-        break;
-
-      switch (c)
-        {
-        case 0:
-          printf ("option %s", long_options[option_index].name);
-          if (optarg)
-            printf (" with arg %s", optarg);
-          printf ("\n");
-          break;
-
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-          if (digit_optind != 0 && digit_optind != this_option_optind)
-            printf ("digits occur in two different argv-elements.\n");
-          digit_optind = this_option_optind;
-          printf ("option %c\n", c);
-          break;
-
-        case 'a':
-          printf ("option a\n");
-          break;
-
-        case 'b':
-          printf ("option b\n");
-          break;
-
-        case 'c':
-          printf ("option c with value `%s'\n", optarg);
-          break;
-
-        case 'd':
-          printf ("option d with value `%s'\n", optarg);
-          break;
-
-        case '?':
-          break;
-
-        default:
-          printf ("?? getopt returned character code 0%o ??\n", c);
-        }
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-        printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
-
-#endif /* HAVE_GETOPT_LONG_ONLY */

+ 33 - 0
dtool/src/dtoolutil/panda_getopt.h

@@ -0,0 +1,33 @@
+/* Filename: panda_getopt.h
+ * Created by:  drose (19Jul11)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef PANDA_GETOPT_H
+#define PANDA_GETOPT_H
+
+#include "dtoolbase.h"
+
+/* Include this file to get a definition of getopt(). */
+
+#ifndef HAVE_GETOPT
+  /* If the system doesn't provide a getopt(), use our own implementation. */
+  #include "panda_getopt_impl.h"
+#else
+  /* We prefer to use the system version if it is available. */
+  #ifdef PHAVE_GETOPT_H
+    #include <getopt.h>
+  #endif
+#endif
+
+#endif
+

+ 536 - 0
dtool/src/dtoolutil/panda_getopt_impl.cxx

@@ -0,0 +1,536 @@
+// Filename: panda_getopt_impl.cxx
+// Created by:  drose (19Jul11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "panda_getopt_impl.h"
+#include "pvector.h"
+
+#if defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG_ONLY)
+// If the system provides both of these functions, we don't need to
+// provide our own implementation, so in that case this file does
+// nothing.
+
+#else
+// If the system does lack one or the other of these functions, then
+// we'll go ahead and provide it instead.
+
+
+char *optarg = NULL;
+int optind = 0;
+int opterr = 1;
+int optopt = 0;
+
+////////////////////////////////////////////////////////////////////
+//       Class : PandaGetopt
+// Description : The implementation within this file of the various
+//               getopt() functions.  This class is not visible
+//               outside of this file; instead, the interface is via
+//               the getopt() functions themselves.
+////////////////////////////////////////////////////////////////////
+class PandaGetopt {
+public:
+  PandaGetopt(int argc, char *const argv[], const char *optstring,
+              const struct option *longopts, bool allow_one_hyphen_long);
+
+  void permute(int argc, char **mutable_argv);
+  int process(int opterr, int *longindex, char *&optarg, int &optind, int &optopt);
+
+private:
+  size_t find_short_option(char short_option);
+  size_t find_long_option(const string &long_option);
+
+  void scan_options(const char *optstring, const struct option *longopts);
+  void scan_args(int argc, char *const argv[]);
+
+  // We build a list of Options, which correspond to the input defined
+  // in optstring and/or in the longopts list.  These are the short
+  // and long options that are available, whether or not the user
+  // tries to use any of them.  This list is populated by
+  // scan_options().
+  class Option {
+  public:
+    Option(char short_option, int has_arg);
+    Option(const struct option *longopts, int longopts_index);
+
+    char _short_option;
+    string _long_option;
+    int _has_arg;
+    const struct option *_option;
+    int _longopts_index;
+  };
+
+  // We next build a list of Params, which are the parameter options
+  // that are parsed out of the argv array--those options that the
+  // user has actually specified.  This list does not contain the
+  // non-option arguments, the words that follow the options on the
+  // command line (those end up in the _arguments list instead).  This
+  // list is populated by scan_args().
+  class Param {
+  public:
+    Param(size_t opt_index, size_t argv_index, 
+          char short_option, char *argument = NULL);
+
+    size_t _opt_index;
+    size_t _argv_index;
+    char _short_option;
+    char *_argument;
+  };
+
+  // The list of available options.
+  typedef pvector<Option> Options;
+  Options _options;
+
+  // The list of invoked options.
+  typedef pvector<Param> Params;
+  Params _params;
+
+  typedef pvector<char *> Arguments;
+
+  // The list of option arguments on the command line, with pointers
+  // back into the original argv array.  This is similar to the
+  // _params list, above, but it is the pointers to the original
+  // unprocessed strings.  We use this list to premute the argv array
+  // into proper order if needed.
+  Arguments _output_argv;
+
+  // The list of non-option arguments on the command line, following
+  // the options.  The vector contains the actual pointers back into
+  // the original argv array; we use it to permute the argv array into
+  // proper order if needed.
+  Arguments _arguments;
+
+  // See the PandaGetopt constructor for an explanation of these
+  // two flags.
+  bool _return_in_order;
+  bool _require_order;
+
+  // If we are invoked via getopt_long_only(), then a single hyphen is
+  // allowed to introduce a long option, as well as a double hyphen.
+  bool _allow_one_hyphen_long;
+
+  // This member is used to hold our place in the parameters list
+  // across multiple calls to process().
+  size_t _next_param;
+
+  // This is the index of the first non-option argument in the argv
+  // list.  It's filled into optind when process() reaches the end of
+  // its processing.
+  size_t _next_argv_index;
+};
+
+// This global pointer is used to differentiate between getopt() being
+// called the first time, vs. subsequent times.
+static PandaGetopt *pgetopt = NULL;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+PandaGetopt::
+PandaGetopt(int argc, char *const argv[], const char *optstring,
+            const struct option *longopts, bool allow_one_hyphen_long) {
+  assert(optstring != NULL);
+
+  _return_in_order = false;
+  _require_order = false;
+  _allow_one_hyphen_long = allow_one_hyphen_long;
+  _next_param = 0;
+
+  // _options[0] is used for invalid characters.
+  _options.push_back(Option('?', no_argument));
+
+  if (optstring[0] == '-') {
+    // RETURN_IN_ORDER: Non-option arguments (operands) are handled as
+    // if they were the argument to an option with the value 1
+    // ('\001').
+    ++optstring;
+    _return_in_order = true;
+
+    // _options[1] is option '\001'.
+    _options.push_back(Option('\001', required_argument));
+
+  } else if (optstring[0] == '+') {
+    // REQUIRE_ORDER: option processing stops when the first
+    // non-option argument is reached, or when the element of argv is
+    // "--".
+    ++optstring;
+    _require_order = true;
+
+  } else if (getenv("POSIXLY_CORRECT") != NULL) {
+    // REQUIRE_ORDER.
+    _require_order = true;
+
+  } else {
+    // PERMUTE: the order of arguments in argv is altered so that all
+    // options (and their arguments) are moved in front of all of the
+    // operands.
+  }
+
+  scan_options(optstring, longopts);
+  scan_args(argc, argv);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::permute
+//       Access: Public
+//  Description: Permutes the argv array so that the non-option
+//               arguments are at the end of the list (if
+//               POSIXLY_CORRECT is not set), as the gnu
+//               implementation does.
+////////////////////////////////////////////////////////////////////
+void PandaGetopt::
+permute(int argc, char **mutable_argv) {
+  if (!_require_order && !_return_in_order) {
+    // Rebuild the argv array to reflect the reordered options.
+    size_t i = 1;
+    Arguments::const_iterator gi;
+    for (gi = _output_argv.begin(); gi != _output_argv.end(); ++gi) {
+      assert((int)i < argc);
+      mutable_argv[i] = (*gi);
+      ++i;
+    }
+    _next_argv_index = i;
+    for (gi = _arguments.begin(); gi != _arguments.end(); ++gi) {
+      assert((int)i < argc);
+      mutable_argv[i] = (*gi);
+      ++i;
+    }
+    assert((int)i == argc);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::process
+//       Access: Public
+//  Description: Can be called repeatedly to extract out the option
+//               arguments scanned from the argv list, one at a time.
+//               Sets *longindex, optarg, optind, optopt.
+//               Returns EOF when finished.
+////////////////////////////////////////////////////////////////////
+int PandaGetopt::
+process(int opterr, int *longindex, char *&optarg, int &optind, int &optopt) {
+  if (_next_param >= _params.size()) {
+    optind = _next_argv_index;
+    return EOF;
+  }
+
+  const Param &param = _params[_next_param];
+  ++_next_param;
+  const Option &option = _options[param._opt_index];
+
+  optarg = param._argument;
+  optind = (int)param._argv_index;
+  if (longindex != NULL) {
+    *longindex = option._longopts_index;
+  }
+
+  if (option._option != NULL) {
+    // This was a long option.  Check the special longopt handling
+    // parameters.
+    if (option._option->flag == NULL) {
+      return option._option->val;
+    }
+    *(option._option->flag) = option._option->val;
+    return 0;
+  }
+
+  if (param._opt_index == 0 && opterr) {
+    // This was an invalid character.
+    optopt = param._short_option;
+    cerr << "Illegal option: -" << param._short_option << "\n";
+    return '?';
+  }
+
+  // This was a short option.  Return the option itself.
+  return param._short_option;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::find_short_option
+//       Access: Private
+//  Description: Returns the index within the _options array of the
+//               option with the indicated short_option letter, or 0
+//               if the option is not found.
+////////////////////////////////////////////////////////////////////
+size_t PandaGetopt::
+find_short_option(char short_option) {
+  size_t opt_index = 1;
+  while (opt_index < _options.size()) {
+    if (_options[opt_index]._short_option == short_option) {
+      return opt_index;
+    }
+    ++opt_index;
+  }
+
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::find_long_option
+//       Access: Private
+//  Description: Returns the index within the _options array of the
+//               option with the indicated long_option word, or 0
+//               if the option is not found.  If the word contains an
+//               '=' sign, only the text before this sign is
+//               considered.
+////////////////////////////////////////////////////////////////////
+size_t PandaGetopt::
+find_long_option(const string &long_option) {
+  string search = long_option;
+  size_t equals = search.find('=');
+  if (equals != string::npos) {
+    search = search.substr(0, equals);
+  }
+
+  size_t opt_index = 1;
+  while (opt_index < _options.size()) {
+    if (_options[opt_index]._long_option == search) {
+      return opt_index;
+    }
+    ++opt_index;
+  }
+
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::scan_options
+//       Access: Private
+//  Description: Parses the optstring and longopts list to understand
+//               the options we should be searching for, and populate
+//               the internal _options array.
+////////////////////////////////////////////////////////////////////
+void PandaGetopt::
+scan_options(const char *optstring, const struct option *longopts) {
+  const char *p = optstring;
+  while (*p != '\0') {
+    char short_option = *p;
+    int has_arg = no_argument;
+    ++p;
+    if (*p == ':') {
+      has_arg = required_argument;
+      ++p;
+      if (*p == ':') {
+        has_arg = optional_argument;
+        ++p;
+      }
+    }
+    
+    _options.push_back(Option(short_option, has_arg));
+  }
+
+  if (longopts != NULL) {
+    int longopts_index = 0;
+    while (longopts[longopts_index].name != NULL) {
+      _options.push_back(Option(longopts, longopts_index));
+      ++longopts_index;
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::scan_args
+//       Access: Private
+//  Description: Parses the argv list to understand the arguments
+//               passed by the user, and populates the _params and
+//               _arguments arrays.
+////////////////////////////////////////////////////////////////////
+void PandaGetopt::
+scan_args(int argc, char *const argv[]) {
+  size_t ai = 1;
+  bool end_of_processing = false;
+
+  while ((int)ai < argc) {
+    assert(argv[ai] != NULL);
+
+    if (argv[ai][0] != '-' || end_of_processing) {
+      // This is a non-option argument.
+      if (_require_order) {
+        break;
+      }
+      if (_return_in_order) {
+        // Record it as an argument of _options[1], which is '\001'.
+        _params.push_back(Param(1, ai, '\001', argv[ai]));
+        _output_argv.push_back(argv[ai]);
+      } else {
+        // Push the non-option argument onto its list, and continue scanning.
+        _arguments.push_back(argv[ai]);
+      }
+
+    } else if (strcmp(argv[ai], "--") == 0) {
+      // Special case: this ends processing.  Everything after this
+      // is a non-option argument.
+      _output_argv.push_back(argv[ai]);
+      end_of_processing = true;
+
+    } else {
+      // An option argument.
+
+      char *option = NULL;
+      char *argument = NULL;
+      size_t opt_index = 0;
+      bool is_long_option = false;
+      bool has_argument = false;
+
+      if (argv[ai][1] == '-') {
+        // This is a long option.
+        option = argv[ai] + 2;
+        opt_index = find_long_option(option);
+        is_long_option = true;
+      } else {
+        // This is one or more short options, or a short option and
+        // its argument.
+        option = argv[ai] + 1;
+        if (_allow_one_hyphen_long) {
+          // Or maybe it's a long option.
+          opt_index = find_long_option(option);
+          if (opt_index != 0) {
+            is_long_option = true;
+          }
+        }
+        if (!is_long_option) {
+          opt_index = find_short_option(option[0]);
+          while (opt_index != 0 && 
+                 _options[opt_index]._has_arg == no_argument && 
+                 option[1] != '\0') {
+            // There are multiple short options jammed into a single word.
+            _params.push_back(Param(opt_index, ai, option[0]));
+            ++option;
+            opt_index = find_short_option(option[0]);
+          }
+
+          if (opt_index != 0 && _options[opt_index]._has_arg != no_argument) {
+            if (option[1] != '\0') {
+              // There's an argument embedded in the same word.
+              argument = option + 1;
+              has_argument = true;
+            }
+          }
+        }
+      }
+
+      if (is_long_option) {
+        char *equals = strchr(option, '=');
+        if (equals != NULL) {
+          argument = equals + 1;
+          has_argument = true;
+        }
+      }
+
+      size_t argv_index = ai;
+
+      if (opt_index != 0 && _options[opt_index]._has_arg == required_argument && 
+          !has_argument) {
+        // Check the next word for an argument.
+        _output_argv.push_back(argv[ai]);
+        ++ai;
+        if ((int)ai < argc) {
+          argument = argv[ai];
+          has_argument = true;
+        }
+      }
+
+      _params.push_back(Param(opt_index, argv_index, option[0], argument));
+      _output_argv.push_back(argv[ai]);
+    }
+    ++ai;
+  }
+
+  _next_argv_index = ai;
+
+  // Now record the non-option arguments that followed the option arguments.
+  while ((int)ai < argc) {
+    assert(argv[ai] != NULL);
+    _arguments.push_back(argv[ai]);
+    ++ai;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::Option::Constructor
+//       Access: Public
+//  Description: The constructor for a short_option.  Receives the
+//               letter that is the short option, and one of
+//               no_argument, required_argument, or optional_argument.
+////////////////////////////////////////////////////////////////////
+PandaGetopt::Option::
+Option(char short_option, int has_arg) :
+  _short_option(short_option),
+  _has_arg(has_arg),
+  _option(NULL),
+  _longopts_index(-1)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::Option::Constructor
+//       Access: Public
+//  Description: The constructor for a long_option.  Receives the
+//               longopts array and the index within the array for
+//               this particular option.
+////////////////////////////////////////////////////////////////////
+PandaGetopt::Option::
+Option(const struct option *longopts, int longopts_index) :
+  _short_option(0),
+  _long_option(longopts[longopts_index].name),
+  _has_arg(longopts[longopts_index].has_arg),
+  _option(&longopts[longopts_index]),
+  _longopts_index(longopts_index)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaGetopt::Param::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PandaGetopt::Param::
+Param(size_t opt_index, size_t argv_index, char short_option, char *argument) :
+  _opt_index(opt_index),
+  _argv_index(argv_index),
+  _short_option(short_option),
+  _argument(argument)
+{
+}
+
+int
+getopt(int argc, char *const argv[], const char *optstring) {
+  if (pgetopt == NULL) {
+    pgetopt = new PandaGetopt(argc, argv, optstring, NULL, false);
+    pgetopt->permute(argc, (char **)argv);
+  }
+  return pgetopt->process(opterr, NULL, optarg, optind, optopt);
+}
+
+int
+getopt_long(int argc, char *const argv[], const char *optstring, 
+            const struct option *longopts, int *longindex) {
+  if (pgetopt == NULL) {
+    pgetopt = new PandaGetopt(argc, argv, optstring, longopts, false);
+    pgetopt->permute(argc, (char **)argv);
+  }
+  return pgetopt->process(opterr, longindex, optarg, optind, optopt);
+}
+
+int
+getopt_long_only(int argc, char *const argv[], const char *optstring, 
+                 const struct option *longopts, int *longindex) {
+  if (pgetopt == NULL) {
+    pgetopt = new PandaGetopt(argc, argv, optstring, longopts, true);
+    pgetopt->permute(argc, (char **)argv);
+  }
+  return pgetopt->process(opterr, longindex, optarg, optind, optopt);
+}
+
+#endif  // defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG_ONLY)

+ 74 - 0
dtool/src/dtoolutil/panda_getopt_impl.h

@@ -0,0 +1,74 @@
+/* Filename: panda_getopt_impl.h
+ * Created by:  drose (19Jul11)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef PANDA_GETOPT_IMPL_H
+#define PANDA_GETOPT_IMPL_H
+
+#include "dtoolbase.h"
+
+/* This file defines a reimplementation of getopt(), getopt_long(),
+   and getopt_long_only(), according to the LSB and Posix conventions.
+   It is completely new code, contributed under the Panda3D license. */
+
+#if defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG_ONLY)
+// If the system provides both of these functions, we don't need to
+// provide our own implementation, so in that case this file does
+// nothing.
+
+#else
+// If the system does lack one or the other of these functions, then
+// we'll go ahead and provide it instead.
+
+#define getopt panda_getopt
+#define optind panda_optind
+#define opterr panda_opterr
+#define optopt panda_optopt
+#define optarg panda_optarg
+#define getopt_long panda_getopt_long
+#define getopt_long_only panda_getopt_long_only
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+extern EXPCL_DTOOL char *optarg;
+extern EXPCL_DTOOL int optind, opterr, optopt;
+
+struct option {
+  const char *name;
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+extern EXPCL_DTOOL int
+getopt(int argc, char *const argv[], const char *optstring);
+extern EXPCL_DTOOL int
+getopt_long(int argc, char *const argv[], const char *optstring, 
+            const struct option *longopts, int *longindex);
+extern EXPCL_DTOOL int
+getopt_long_only(int argc, char *const argv[], const char *optstring, 
+                 const struct option *longopts, int *longindex);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG_ONLY)
+
+#endif

+ 35 - 0
dtool/src/dtoolutil/panda_getopt_long.h

@@ -0,0 +1,35 @@
+/* Filename: panda_getopt.h
+ * Created by:  drose (19Jul11)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef PANDA_GETOPT_LONG_H
+#define PANDA_GETOPT_LONG_H
+
+#include "dtoolbase.h"
+
+/* Include this file to get a definition of getopt_long() or
+   getopt_long_only(). */
+
+#ifndef HAVE_GETOPT_LONG_ONLY
+  /* If our system getopt() doesn't come with getopt_long_only(), then use
+     our own implementation. */
+  #include "panda_getopt_impl.h"
+#else
+  /* We prefer to use the system version if it is available. */
+  #ifdef PHAVE_GETOPT_H
+    #include <getopt.h>
+  #endif
+#endif
+
+#endif
+

+ 1 - 10
dtool/src/interrogate/interrogate.cxx

@@ -18,18 +18,9 @@
 #include "interrogateDatabase.h"
 #include "cppGlobals.h"
 #include "pnotify.h"
+#include "panda_getopt_long.h"
 #include <time.h>
 
-// If our system getopt() doesn't come with getopt_long_only(), then use
-// the GNU flavor that we've got in tool for this purpose.
-#ifndef HAVE_GETOPT_LONG_ONLY
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
 CPPParser parser;
 
 Filename output_code_filename;

+ 4 - 12
dtool/src/interrogate/interrogate_module.cxx

@@ -22,16 +22,8 @@
 #include "load_dso.h"
 #include "pystub.h"
 #include "pnotify.h"
-
-#include "set"
-
-// If our system getopt() doesn't come with getopt_long_only(), then use
-// the GNU flavor that we've got in tool for this purpose.
-#ifndef HAVE_GETOPT_LONG_ONLY
-#include "gnu_getopt.h"
-#else
-#include <getopt.h>
-#endif
+#include "panda_getopt_long.h"
+#include "pset.h"
 
 Filename output_code_filename;
 string module_name;
@@ -87,7 +79,7 @@ int write_python_table_native(ostream &out) {
 
   int count = 0;
 
-  std::set<std::string > Libraries;
+  pset<std::string > Libraries;
 
 //  out << "extern \"C\" {\n";
 
@@ -114,7 +106,7 @@ int write_python_table_native(ostream &out) {
     }
   }
 
-  std::set<std::string >::iterator ii;
+  pset<std::string >::iterator ii;
   for(ii = Libraries.begin(); ii != Libraries.end(); ii++) {
       printf("Referencing Library %s\n",(*ii).c_str());
       out << "extern LibrayDef "<< *ii << "_moddef ;\n";

+ 1 - 9
dtool/src/interrogate/parse_file.cxx

@@ -21,17 +21,9 @@
 #include "cppExpression.h"
 #include "cppType.h"
 #include "cppGlobals.h"
-
+#include "panda_getopt_long.h"
 #include <stdlib.h>
 
-#ifndef HAVE_GETOPT_LONG_ONLY
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
 CPPParser parser;
 
 void

+ 1 - 8
dtool/src/prckeys/makePrcKey.cxx

@@ -16,6 +16,7 @@
 #include "prcKeyRegistry.h"
 #include "filename.h"
 #include "pvector.h"
+#include "panda_getopt.h"
 #include <stdio.h>
 
 // Pick up the public key definitions.
@@ -29,14 +30,6 @@
 #include "openssl/rand.h"
 #include "openssl/bio.h"
 
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
 class KeyNumber {
 public:
   int _number;

+ 1 - 8
dtool/src/prckeys/signPrcFile_src.cxx

@@ -20,6 +20,7 @@
 
 #include "filename.h"
 #include "executionEnvironment.h"
+#include "panda_getopt.h"
 
 #include <time.h>
 
@@ -29,14 +30,6 @@
 #include "openssl/bio.h"
 #include "openssl/evp.h"
 
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
 string progname = PROGNAME;
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 10
dtool/src/test_interrogate/test_interrogate.cxx

@@ -19,19 +19,10 @@
 #include "load_dso.h"
 #include "filename.h"
 #include "pystub.h"
+#include "panda_getopt.h"
 
 #include <stdlib.h>
 
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
-
-
 static ostream &
 indent(ostream &out, int indent_level) {
   for (int i = 0; i < indent_level; i++) {

+ 0 - 4
makepanda/makepanda.py

@@ -2218,8 +2218,6 @@ TargetAdd('dtoolbase_indent.obj',     opts=OPTS, input='indent.cxx')
 #
 
 OPTS=['DIR:dtool/src/dtoolutil', 'BUILDING:DTOOL']
-TargetAdd('dtoolutil_gnu_getopt.obj',  opts=OPTS, input='gnu_getopt.c')
-TargetAdd('dtoolutil_gnu_getopt1.obj', opts=OPTS, input='gnu_getopt1.c')
 TargetAdd('dtoolutil_composite.obj',   opts=OPTS, input='dtoolutil_composite.cxx')
 if (sys.platform == 'darwin'):
   TargetAdd('dtoolutil_filename_assist.obj',   opts=OPTS, input='filename_assist.mm')
@@ -2231,8 +2229,6 @@ if (sys.platform == 'darwin'):
 OPTS=['DIR:dtool/metalibs/dtool', 'BUILDING:DTOOL']
 TargetAdd('dtool_dtool.obj', opts=OPTS, input='dtool.cxx')
 TargetAdd('libp3dtool.dll', input='dtool_dtool.obj')
-TargetAdd('libp3dtool.dll', input='dtoolutil_gnu_getopt.obj')
-TargetAdd('libp3dtool.dll', input='dtoolutil_gnu_getopt1.obj')
 TargetAdd('libp3dtool.dll', input='dtoolutil_composite.obj')
 if (sys.platform == 'darwin'):
   TargetAdd('libp3dtool.dll', input='dtoolutil_filename_assist.obj')

+ 1 - 5
panda/src/downloadertools/apply_patch.cxx

@@ -13,11 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "pandabase.h"
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #include <getopt.h>
-#endif
+#include "panda_getopt.h"
 #include "patchfile.h"
 #include "filename.h"
 

+ 1 - 5
panda/src/downloadertools/build_patch.cxx

@@ -13,11 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "pandabase.h"
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #include <getopt.h>
-#endif
+#include "panda_getopt.h"
 #include "patchfile.h"
 #include "filename.h"
 

+ 1 - 7
panda/src/downloadertools/check_md5.cxx

@@ -13,15 +13,9 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "pandabase.h"
-
 #include "hashVal.h"
 #include "filename.h"
-
-#ifndef HAVE_GETOPT
-#include "gnu_getopt.h"
-#else
-#include <getopt.h>
-#endif
+#include "panda_getopt.h"
 
 bool output_decimal = false;
 bool suppress_filename = false;

+ 1 - 5
panda/src/downloadertools/multify.cxx

@@ -13,11 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "pandabase.h"
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #include <getopt.h>
-#endif
+#include "panda_getopt.h"
 #include "multifile.h"
 #include "pointerTo.h"
 #include "filename.h"

+ 1 - 8
panda/src/downloadertools/pdecrypt.cxx

@@ -15,14 +15,7 @@
 #include "filename.h"
 #include "encrypt_string.h"
 #include "pnotify.h"
-
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
+#include "panda_getopt.h"
 
 string password;
 bool got_password = false;

+ 1 - 8
panda/src/downloadertools/pencrypt.cxx

@@ -15,14 +15,7 @@
 #include "filename.h"
 #include "encrypt_string.h"
 #include "pnotify.h"
-
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
+#include "panda_getopt.h"
 
 string password;
 bool got_password = false;

+ 1 - 8
panda/src/downloadertools/punzip.cxx

@@ -15,14 +15,7 @@
 #include "filename.h"
 #include "compress_string.h"
 #include "pnotify.h"
-
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
+#include "panda_getopt.h"
 
 void
 usage() {

+ 1 - 8
panda/src/downloadertools/pzip.cxx

@@ -15,14 +15,7 @@
 #include "filename.h"
 #include "compress_string.h"
 #include "pnotify.h"
-
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
+#include "panda_getopt.h"
 
 void
 usage() {

+ 58 - 58
panda/src/pgui/pgFrameStyle.cxx

@@ -239,10 +239,10 @@ generate_flat_geom(const LVecBase4f &frame) {
     ("PGFrame", format, Geom::UH_static);
   
   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
-  vertex.add_data3f(left, 0.0f, top);
-  vertex.add_data3f(left, 0.0f, bottom);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(right, 0.0f, bottom);
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
 
   if (has_texture()) {
     // Generate UV's.
@@ -401,14 +401,14 @@ generate_bevel_geom(const LVecBase4f &frame, bool in) {
   
   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
   // Tristrip 1.
-  vertex.add_data3f(right, 0.0f, bottom);
-  vertex.add_data3f(inner_right, 0.0f, inner_bottom);
-  vertex.add_data3f(left, 0.0f, bottom);
-  vertex.add_data3f(inner_left, 0.0f, inner_bottom);
-  vertex.add_data3f(left, 0.0f, top);
-  vertex.add_data3f(inner_left, 0.0f, inner_top);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(inner_right, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_top));
   color.add_data4f(cbottom);
   color.add_data4f(cbottom);
   color.add_data4f(cbottom);
@@ -422,12 +422,12 @@ generate_bevel_geom(const LVecBase4f &frame, bool in) {
   strip->close_primitive();
   
   // Tristrip 2.
-  vertex.add_data3f(right, 0.0f, bottom);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(inner_right, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_right, 0.0f, inner_top);
-  vertex.add_data3f(inner_left, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_left, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_top));
   color.add_data4f(cright);
   color.add_data4f(cright);
   color.add_data4f(cright);
@@ -658,14 +658,14 @@ generate_groove_geom(const LVecBase4f &frame, bool in) {
   
   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
   // Tristrip 1.
-  vertex.add_data3f(right, 0.0f, bottom);
-  vertex.add_data3f(mid_right, 0.0f, mid_bottom);
-  vertex.add_data3f(left, 0.0f, bottom);
-  vertex.add_data3f(mid_left, 0.0f, mid_bottom);
-  vertex.add_data3f(left, 0.0f, top);
-  vertex.add_data3f(mid_left, 0.0f, mid_top);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(mid_right, 0.0f, mid_top);
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_bottom));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(mid_left, 0.0f, mid_bottom));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(mid_left, 0.0f, mid_top));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_top));
   color.add_data4f(cbottom);
   color.add_data4f(cbottom);
   color.add_data4f(cbottom);
@@ -679,14 +679,14 @@ generate_groove_geom(const LVecBase4f &frame, bool in) {
   strip->close_primitive();
   
   // Tristrip 2.
-  vertex.add_data3f(mid_right, 0.0f, mid_bottom);
-  vertex.add_data3f(inner_right, 0.0f, inner_bottom);
-  vertex.add_data3f(mid_left, 0.0f, mid_bottom);
-  vertex.add_data3f(inner_left, 0.0f, inner_bottom);
-  vertex.add_data3f(mid_left, 0.0f, mid_top);
-  vertex.add_data3f(inner_left, 0.0f, inner_top);
-  vertex.add_data3f(mid_right, 0.0f, mid_top);
-  vertex.add_data3f(inner_right, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(mid_left, 0.0f, mid_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(mid_left, 0.0f, mid_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_top));
   color.add_data4f(ctop);
   color.add_data4f(ctop);
   color.add_data4f(ctop);
@@ -700,14 +700,14 @@ generate_groove_geom(const LVecBase4f &frame, bool in) {
   strip->close_primitive();
   
   // Tristrip 3.
-  vertex.add_data3f(right, 0.0f, bottom);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(mid_right, 0.0f, mid_bottom);
-  vertex.add_data3f(mid_right, 0.0f, mid_top);
-  vertex.add_data3f(inner_right, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_right, 0.0f, inner_top);
-  vertex.add_data3f(inner_left, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_left, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_bottom));
+  vertex.add_data3f(LPoint3f::rfu(mid_right, 0.0f, mid_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_top));
   color.add_data4f(cright);
   color.add_data4f(cright);
   color.add_data4f(cright);
@@ -847,25 +847,25 @@ generate_texture_border_geom(const LVecBase4f &frame) {
   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
   
   // verts 0,1,2,3
-  vertex.add_data3f(left, 0.0f, top);
-  vertex.add_data3f(left, 0.0f, inner_top);
-  vertex.add_data3f(inner_left, 0.0f, top);
-  vertex.add_data3f(inner_left, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_top));
   // verts 4,5,6,7
-  vertex.add_data3f(inner_right, 0.0f, top);
-  vertex.add_data3f(inner_right, 0.0f, inner_top);
-  vertex.add_data3f(right, 0.0f, top);
-  vertex.add_data3f(right, 0.0f, inner_top);
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_top));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, top));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, inner_top));
   // verts 8,9,10,11
-  vertex.add_data3f(left, 0.0f, inner_bottom);
-  vertex.add_data3f(left, 0.0f, bottom);
-  vertex.add_data3f(inner_left, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_left, 0.0f, bottom);
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(left, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_left, 0.0f, bottom));
   // verts 12,13,14,15
-  vertex.add_data3f(inner_right, 0.0f, inner_bottom);
-  vertex.add_data3f(inner_right, 0.0f, bottom);
-  vertex.add_data3f(right, 0.0f, inner_bottom);
-  vertex.add_data3f(right, 0.0f, bottom);
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(inner_right, 0.0f, bottom));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, inner_bottom));
+  vertex.add_data3f(LPoint3f::rfu(right, 0.0f, bottom));
 
   if (has_texture()) {
     // Generate UV's.

+ 36 - 18
panda/src/pgui/pgItem.cxx

@@ -428,14 +428,32 @@ activate_region(const LMatrix4f &transform, int sort,
   LightReMutexHolder holder(_lock);
   // Transform all four vertices, and get the new bounding box.  This
   // way the region works (mostly) even if has been rotated.
-  LPoint3f ll(_frame[0], 0.0f, _frame[2]);
-  LPoint3f lr(_frame[1], 0.0f, _frame[2]);
-  LPoint3f ul(_frame[0], 0.0f, _frame[3]);
-  LPoint3f ur(_frame[1], 0.0f, _frame[3]);
-  ll = ll * transform;
-  lr = lr * transform;
-  ul = ul * transform;
-  ur = ur * transform;
+  LPoint3f ll = LPoint3f::rfu(_frame[0], 0.0f, _frame[2]) * transform;
+  LPoint3f lr = LPoint3f::rfu(_frame[1], 0.0f, _frame[2]) * transform;
+  LPoint3f ul = LPoint3f::rfu(_frame[0], 0.0f, _frame[3]) * transform;
+  LPoint3f ur = LPoint3f::rfu(_frame[1], 0.0f, _frame[3]) * transform;
+  LVector3f up = LVector3f::up();
+  int up_axis;
+  if (up[1]) {
+    up_axis = 1;
+  }
+  else if (up[2]) {
+    up_axis = 2;
+  }
+  else {
+    up_axis = 0;
+  }
+  LVector3f right = LVector3f::right();
+  int right_axis;
+  if (right[0]) {
+    right_axis = 0;
+  }
+  else if (right[2]) {
+    right_axis = 2;
+  }
+  else {
+    right_axis = 1;
+  }
 
   LVecBase4f frame;
   if (cpa != (ClipPlaneAttrib *)NULL && cpa->get_num_on_planes() != 0) {
@@ -444,10 +462,10 @@ activate_region(const LMatrix4f &transform, int sort,
     
     pvector<LPoint2f> points;
     points.reserve(4);
-    points.push_back(LPoint2f(ll[0], ll[2]));
-    points.push_back(LPoint2f(lr[0], lr[2]));
-    points.push_back(LPoint2f(ur[0], ur[2]));
-    points.push_back(LPoint2f(ul[0], ul[2]));
+    points.push_back(LPoint2f(ll[right_axis], ll[up_axis]));
+    points.push_back(LPoint2f(lr[right_axis], lr[up_axis]));
+    points.push_back(LPoint2f(ur[right_axis], ur[up_axis]));
+    points.push_back(LPoint2f(ul[right_axis], ul[up_axis]));
 
     int num_on_planes = cpa->get_num_on_planes();
     for (int i = 0; i < num_on_planes; ++i) {
@@ -455,8 +473,8 @@ activate_region(const LMatrix4f &transform, int sort,
       Planef plane = DCAST(PlaneNode, plane_path.node())->get_plane();
       plane.xform(plane_path.get_net_transform()->get_mat());
       
-      // We ignore the y coordinate, assuming the frame is still in
-      // the X-Z plane after being transformed.  Not sure if we really
+      // We ignore the forward axis, assuming the frame is still in
+      // the right-up plane after being transformed.  Not sure if we really
       // need to support general 3-D transforms on 2-D objects.
       clip_frame(points, plane);
     }
@@ -479,10 +497,10 @@ activate_region(const LMatrix4f &transform, int sort,
     }
   } else {
     // Since there are no clip planes involved, just set the frame.
-    frame.set(min(min(ll[0], lr[0]), min(ul[0], ur[0])),
-              max(max(ll[0], lr[0]), max(ul[0], ur[0])),
-              min(min(ll[2], lr[2]), min(ul[2], ur[2])),
-              max(max(ll[2], lr[2]), max(ul[2], ur[2])));
+    frame.set(min(min(ll[right_axis], lr[right_axis]), min(ul[right_axis], ur[right_axis])),
+              max(max(ll[right_axis], lr[right_axis]), max(ul[right_axis], ur[right_axis])),
+              min(min(ll[up_axis], lr[up_axis]), min(ul[up_axis], ur[up_axis])),
+              max(max(ll[up_axis], lr[up_axis]), max(ul[up_axis], ur[up_axis])));
   }
 
   if (sa != (ScissorAttrib *)NULL) {

+ 1 - 7
panda/src/testbed/pgrid.cxx

@@ -18,13 +18,7 @@
 #include "clockObject.h"
 #include "string_utils.h"
 #include "pvector.h"
-
-#ifdef HAVE_GETOPT
-#include <getopt.h>
-#else
-#include "gnu_getopt.h"
-#endif
-
+#include "panda_getopt.h"
 
 #define RANDFRAC (rand()/(float)(RAND_MAX))
 

+ 1 - 8
panda/src/testbed/pview.cxx

@@ -22,6 +22,7 @@
 #include "partGroup.h"
 #include "cardMaker.h"
 #include "bamCache.h"
+#include "panda_getopt.h"
 
 // By including checkPandaVersion.h, we guarantee that runtime
 // attempts to run pview will fail if it inadvertently links with the
@@ -29,14 +30,6 @@
 
 #include "checkPandaVersion.h"
 
-#ifndef HAVE_GETOPT
-  #include "gnu_getopt.h"
-#else
-  #ifdef PHAVE_GETOPT_H
-    #include <getopt.h>
-  #endif
-#endif
-
 PandaFramework framework;
 
 ConfigVariableBool pview_test_hack

+ 4 - 12
pandatool/src/progbase/programBase.cxx

@@ -25,19 +25,12 @@
 #include "vector_string.h"
 #include "configVariableInt.h"
 #include "configVariableBool.h"
+#include "panda_getopt_long.h"
 
 #include <stdlib.h>
 #include <algorithm>
 #include <ctype.h>
 
-// If our system getopt() doesn't come with getopt_long_only(), then use
-// the GNU flavor that we've got in tool for this purpose.
-#ifndef HAVE_GETOPT_LONG_ONLY
-  #include "gnu_getopt.h"
-#else
-  #include <getopt.h>
-#endif
-
 // This manifest is defined if we are running on a system (e.g. most
 // any Unix) that allows us to determine the width of the terminal
 // screen via an ioctl() call.  It's just handy to know for formatting
@@ -235,10 +228,9 @@ parse_command_line(int argc, char *argv[]) {
   OptionsByName::const_iterator oi;
   int next_index = 256;
 
-  // Let's prefix the option string with "-" to tell GNU getopt that
-  // we want it to tell us the post-option arguments, instead of
-  // trying to meddle with ARGC and ARGV (which we aren't using
-  // directly).
+  // Let's prefix the option string with "-" to tell getopt that we
+  // want it to tell us the post-option arguments, instead of trying
+  // to meddle with ARGC and ARGV (which we aren't using directly).
   short_options = "-";
 
   for (oi = _options_by_name.begin(); oi != _options_by_name.end(); ++oi) {