From: Tim Kientzle Date: Sun, 15 Jun 2008 03:20:28 +0000 (-0400) Subject: Back out change 143007; go back to using platform getopt_long X-Git-Tag: v2.6.0~172 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=644408fca942d148d71c062a811973f7b4dc2426;p=thirdparty%2Flibarchive.git Back out change 143007; go back to using platform getopt_long if it exists. (I intend to re-add this getopt_long implementation at a later date, but I'm trying to stabilize the libarchive 2.5 release and this is a bit disruptive.) SVN-Revision: 120 --- diff --git a/tar/Makefile b/tar/Makefile index 579282a9e..d65b23a9a 100644 --- a/tar/Makefile +++ b/tar/Makefile @@ -2,7 +2,7 @@ PROG= bsdtar BSDTAR_VERSION_STRING=2.5.4b -SRCS= bsdtar.c getdate.y getopt.c matching.c read.c siginfo.c subst.c tree.c util.c write.c +SRCS= bsdtar.c getdate.y matching.c read.c siginfo.c subst.c tree.c util.c write.c WARNS?= 5 DPADD= ${LIBARCHIVE} ${LIBBZ2} ${LIBZ} LDADD= -larchive -lbz2 -lz diff --git a/tar/bsdtar.c b/tar/bsdtar.c index bcf14185c..1c13cc6bf 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -38,6 +38,18 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.91 2008/05/26 17:10:10 kientzle #ifdef HAVE_FCNTL_H #include #endif +#ifdef HAVE_GETOPT_LONG +#include +#else +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; +#define no_argument 0 +#define required_argument 1 +#endif #ifdef HAVE_LANGINFO_H #include #endif @@ -65,7 +77,6 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.91 2008/05/26 17:10:10 kientzle #endif #include "bsdtar.h" -#include "getopt.h" #if !HAVE_DECL_OPTARG extern int optarg; @@ -788,7 +799,11 @@ usage(struct bsdtar *bsdtar) fprintf(stderr, " List: %s -tf \n", p); fprintf(stderr, " Extract: %s -xf \n", p); fprintf(stderr, " Create: %s -cf [filenames...]\n", p); +#ifdef HAVE_GETOPT_LONG fprintf(stderr, " Help: %s --help\n", p); +#else + fprintf(stderr, " Help: %s -h\n", p); +#endif exit(1); } @@ -813,7 +828,11 @@ static const char *long_help_msg = " , add these items to archive\n" " -z, -j Compress archive with gzip/bzip2\n" " --format {ustar|pax|cpio|shar} Select archive format\n" +#ifdef HAVE_GETOPT_LONG " --exclude Skip files that match pattern\n" +#else + " -W exclude= Skip files that match pattern\n" +#endif " -C Change to before processing remaining files\n" " @ Add entries from to output\n" "List: %p -t [options] []\n" @@ -875,10 +894,14 @@ bsdtar_getopt(struct bsdtar *bsdtar, const char *optstring, option_index = -1; *poption = NULL; +#ifdef HAVE_GETOPT_LONG opt = getopt_long(bsdtar->argc, bsdtar->argv, optstring, tar_longopts, &option_index); if (option_index > -1) *poption = tar_longopts + option_index; +#else + opt = getopt(bsdtar->argc, bsdtar->argv, optstring); +#endif /* Support long options through -W longopt=value */ if (opt == 'W') { diff --git a/tar/config_freebsd.h b/tar/config_freebsd.h index 5a9a673e1..b12b623b1 100644 --- a/tar/config_freebsd.h +++ b/tar/config_freebsd.h @@ -52,6 +52,7 @@ #define HAVE_FNMATCH_H 1 #define HAVE_FNM_LEADING_DIR 1 #define HAVE_FTRUNCATE 1 +#define HAVE_GETOPT_LONG 1 #undef HAVE_GETXATTR #define HAVE_GRP_H 1 #define HAVE_INTTYPES_H 1 diff --git a/tar/getopt.c b/tar/getopt.c deleted file mode 100644 index 2f9e5514b..000000000 --- a/tar/getopt.c +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************** - -getopt.c - Read command line options - -AUTHOR: Gregory Pietsch -CREATED Fri Jan 10 21:13:05 1997 - -DESCRIPTION: - -The getopt() function parses the command line arguments. Its arguments argc -and argv are the argument count and array as passed to the main() function -on program invocation. The argument optstring is a list of available option -characters. If such a character is followed by a colon (`:'), the option -takes an argument, which is placed in optarg. If such a character is -followed by two colons, the option takes an optional argument, which is -placed in optarg. If the option does not take an argument, optarg is NULL. - -The external variable optind is the index of the next array element of argv -to be processed; it communicates from one call to the next which element to -process. - -The getopt_long() function works like getopt() except that it also accepts -long options started by two dashes `--'. If these take values, it is either -in the form - ---arg=value - - or - ---arg value - -It takes the additional arguments longopts which is a pointer to the first -element of an array of type struct option. The last element of the -array has to be filled with NULL for the name field. - -The longind pointer points to the index of the current long option relative -to longopts if it is non-NULL. - -The getopt() function returns the option character if the option was found -successfully, `:' if there was a missing parameter for one of the options, -`?' for an unknown option character, and EOF for the end of the option list. - -The getopt_long() function's return value is described in the header file. - -The function getopt_long_only() is identical to getopt_long(), except that a -plus sign `+' can introduce long options as well as `--'. - -The following describes 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 optstring -parameter. - -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 optstring parameter 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() and friends to return EOF with optind != argc. - -COPYRIGHT NOTICE AND DISCLAIMER: - -Copyright (C) 1997 Gregory Pietsch - -This file and the accompanying getopt.h header file are hereby placed in the -public domain without restrictions. Just give the author credit, don't -claim you wrote it or prevent anyone else from using it. - -Gregory Pietsch's current e-mail address: -gpietsch@comcast.net -****************************************************************************/ - -/* For use in bsdtar. */ -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD$"); - -/* include files */ -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "getopt.h" - -/* macros */ - -/* types */ -typedef enum GETOPT_ORDERING_T -{ - PERMUTE, - RETURN_IN_ORDER, - REQUIRE_ORDER -} GETOPT_ORDERING_T; - -/* globally-defined variables */ -char *optarg = NULL; -int optind = 0; -int opterr = 1; -int optopt = '?'; - -/* functions */ - -/* reverse_argv_elements: reverses num elements starting at argv */ -static void -reverse_argv_elements (char **argv, int num) -{ - int i; - char *tmp; - - for (i = 0; i < (num >> 1); i++) - { - tmp = argv[i]; - argv[i] = argv[num - i - 1]; - argv[num - i - 1] = tmp; - } -} - -/* permute: swap two blocks of argv-elements given their lengths */ -static void -permute (char **argv, int len1, int len2) -{ - reverse_argv_elements (argv, len1); - reverse_argv_elements (argv, len1 + len2); - reverse_argv_elements (argv, len2); -} - -/* is_option: is this argv-element an option or the end of the option list? */ -static int -is_option (char *argv_element, int only) -{ - return ((argv_element == NULL) - || (argv_element[0] == '-') || (only && argv_element[0] == '+')); -} - -/* getopt_internal: the function that does all the dirty work */ -static int -getopt_internal (int argc, char ** argv, const char *shortopts, - const struct option *longopts, int *longind, int only) -{ - GETOPT_ORDERING_T ordering = PERMUTE; - static size_t optwhere = 0; - size_t permute_from = 0; - int num_nonopts = 0; - int optindex = 0; - size_t match_chars = 0; - char *possible_arg = NULL; - int longopt_match = -1; - int has_arg = -1; - char *cp = NULL; - int arg_next = 0; - enum { NO_ARG, REQUIRED_ARG, OPTIONAL_ARG }; - - /* first, deal with silly parameters and easy stuff */ - if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL)) - return (optopt = '?'); - if (optind >= argc || argv[optind] == NULL) - return EOF; - if (strcmp (argv[optind], "--") == 0) - { - optind++; - return EOF; - } - /* if this is our first time through */ - if (optind == 0) - optind = optwhere = 1; - - /* define ordering */ - if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+')) - { - ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER; - shortopts++; - } - else - ordering = (getenv ("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE; - - /* - * based on ordering, find our next option, if we're at the beginning of - * one - */ - if (optwhere == 1) - { - switch (ordering) - { - case PERMUTE: - permute_from = optind; - num_nonopts = 0; - while (!is_option (argv[optind], only)) - { - optind++; - num_nonopts++; - } - if (argv[optind] == NULL) - { - /* no more options */ - optind = permute_from; - return EOF; - } - else if (strcmp (argv[optind], "--") == 0) - { - /* no more options, but have to get `--' out of the way */ - permute (argv + permute_from, num_nonopts, 1); - optind = permute_from + 1; - return EOF; - } - break; - case RETURN_IN_ORDER: - if (!is_option (argv[optind], only)) - { - optarg = argv[optind++]; - return (optopt = 1); - } - break; - case REQUIRE_ORDER: - if (!is_option (argv[optind], only)) - return EOF; - break; - } - } - /* we've got an option, so parse it */ - - /* first, is it a long option? */ - if (longopts != NULL - && (memcmp (argv[optind], "--", 2) == 0 - || (only && argv[optind][0] == '+')) && optwhere == 1) - { - /* handle long options */ - if (memcmp (argv[optind], "--", 2) == 0) - optwhere = 2; - longopt_match = -1; - possible_arg = strchr (argv[optind] + optwhere, '='); - if (possible_arg == NULL) - { - /* no =, so next argv might be arg */ - match_chars = strlen (argv[optind]); - possible_arg = argv[optind] + match_chars; - match_chars = match_chars - optwhere; - } - else - match_chars = (possible_arg - argv[optind]) - optwhere; - for (optindex = 0; longopts[optindex].name != NULL; optindex++) - { - if (memcmp (argv[optind] + optwhere, - longopts[optindex].name, match_chars) == 0) - { - /* do we have an exact match? */ - if (match_chars == strlen (longopts[optindex].name)) - { - longopt_match = optindex; - break; - } - /* do any characters match? */ - else - { - if (longopt_match < 0) - longopt_match = optindex; - else - { - /* we have ambiguous options */ - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous " - "(could be `--%s' or `--%s')\n", - argv[0], - argv[optind], - longopts[longopt_match].name, - longopts[optindex].name); - return (optopt = '?'); - } - } - } - } - if (longopt_match >= 0) - has_arg = longopts[longopt_match].has_arg; - } - /* if we didn't find a long option, is it a short option? */ - if (longopt_match < 0 && shortopts != NULL) - { - cp = strchr (shortopts, argv[optind][optwhere]); - if (cp == NULL) - { - /* couldn't find option in shortopts */ - if (opterr) - fprintf (stderr, - "%s: invalid option -- `-%c'\n", - argv[0], argv[optind][optwhere]); - optwhere++; - if (argv[optind][optwhere] == '\0') - { - optind++; - optwhere = 1; - } - return (optopt = '?'); - } - has_arg = ((cp[1] == ':') - ? ((cp[2] == ':') ? OPTIONAL_ARG : REQUIRED_ARG) : NO_ARG); - possible_arg = argv[optind] + optwhere + 1; - optopt = *cp; - } - /* get argument and reset optwhere */ - arg_next = 0; - switch (has_arg) - { - case OPTIONAL_ARG: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') - { - optarg = possible_arg; - optwhere = 1; - } - else - optarg = NULL; - break; - case REQUIRED_ARG: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') - { - optarg = possible_arg; - optwhere = 1; - } - else if (optind + 1 >= argc) - { - if (opterr) - { - fprintf (stderr, "%s: argument required for option `", argv[0]); - if (longopt_match >= 0) - fprintf (stderr, "--%s'\n", longopts[longopt_match].name); - else - fprintf (stderr, "-%c'\n", *cp); - } - optind++; - return (optopt = ':'); - } - else - { - optarg = argv[optind + 1]; - arg_next = 1; - optwhere = 1; - } - break; - case NO_ARG: - if (longopt_match < 0) - { - optwhere++; - if (argv[optind][optwhere] == '\0') - optwhere = 1; - } - else - optwhere = 1; - optarg = NULL; - break; - } - - /* do we have to permute or otherwise modify optind? */ - if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0) - { - permute (argv + permute_from, num_nonopts, 1 + arg_next); - optind = permute_from + 1 + arg_next; - } - else if (optwhere == 1) - optind = optind + 1 + arg_next; - - /* finally return */ - if (longopt_match >= 0) - { - if (longind != NULL) - *longind = longopt_match; - if (longopts[longopt_match].flag != NULL) - { - *(longopts[longopt_match].flag) = longopts[longopt_match].val; - return 0; - } - else - return longopts[longopt_match].val; - } - else - return optopt; -} - -int -getopt (int argc, char *const argv[], const char *optstring) -{ - /* - * Historically, getopt() did not permute elements, so the - * char * const * declaration made sense. Standards still - * require the char * const * declaration, so we need to - * cast away a const here. Yes, it's yucky. - */ - char **a = (char **)(uintptr_t)argv; - return getopt_internal (argc, a, optstring, NULL, NULL, 0); -} - -int -getopt_long (int argc, char *const argv[], const char *shortopts, - const struct option *longopts, int *longind) -{ - /* See comments above for an explanation of this cast. */ - char **a = (char **)(uintptr_t)argv; - return getopt_internal (argc, a, shortopts, longopts, longind, 0); -} - -int -getopt_long_only (int argc, char * const argv[], const char *shortopts, - const struct option *longopts, int *longind) -{ - /* See comments above for an explanation of this cast. */ - char **a = (char **)(uintptr_t)argv; - return getopt_internal (argc, a, shortopts, longopts, longind, 1); -} - -/* end of file GETOPT.C */ - diff --git a/tar/getopt.h b/tar/getopt.h deleted file mode 100644 index 2cadce3c7..000000000 --- a/tar/getopt.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** - -getopt.h - Read command line options - -AUTHOR: Gregory Pietsch -CREATED Thu Jan 09 22:37:00 1997 - -DESCRIPTION: - -The getopt() function parses the command line arguments. Its arguments argc -and argv are the argument count and array as passed to the main() function -on program invocation. The argument optstring is a list of available option -characters. If such a character is followed by a colon (`:'), the option -takes an argument, which is placed in optarg. If such a character is -followed by two colons, the option takes an optional argument, which is -placed in optarg. If the option does not take an argument, optarg is NULL. - -The external variable optind is the index of the next array element of argv -to be processed; it communicates from one call to the next which element to -process. - -The getopt_long() function works like getopt() except that it also accepts -long options started by two dashes `--'. If these take values, it is either -in the form - ---arg=value - - or - ---arg value - -It takes the additional arguments longopts which is a pointer to the first -element of an array of type GETOPT_LONG_OPTION_T, defined below. The last -element of the array has to be filled with NULL for the name field. - -The longind pointer points to the index of the current long option relative -to longopts if it is non-NULL. - -The getopt() function returns the option character if the option was found -successfully, `:' if there was a missing parameter for one of the options, -`?' for an unknown option character, and EOF for the end of the option list. - -The getopt_long() function's return value is described below. - -The function getopt_long_only() is identical to getopt_long(), except that a -plus sign `+' can introduce long options as well as `--'. - -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 optstring -parameter. - -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 optstring parameter 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() and friends to return EOF with optind != argc. - -COPYRIGHT NOTICE AND DISCLAIMER: - -Copyright (C) 1997 Gregory Pietsch - -This file and the accompanying getopt.c implementation file are hereby -placed in the public domain without restrictions. Just give the author -credit, don't claim you wrote it or prevent anyone else from using it. - -Gregory Pietsch's current e-mail address: -gpietsch@comcast.net -****************************************************************************/ - -#ifndef GETOPT_H -#define GETOPT_H - -/* include files needed by this include file */ - -/* macros defined by this include file */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -/* types defined by this include file */ - -/* struct option: The type of long option */ -struct option -{ - const char *name; /* the name of the long option */ - int has_arg; /* one of the above macros */ - int *flag; /* determines if getopt_long() returns a - * value for a long option; if it is - * non-NULL, 0 is returned as a function - * value and the value of val is stored in - * the area pointed to by flag. Otherwise, - * val is returned. */ - int val; /* determines the value to return if flag is - * NULL. */ -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* externally-defined variables */ - extern char *optarg; - extern int optind; - extern int opterr; - extern int optopt; - - /* function prototypes */ - int getopt (int argc, char * const argv[], const char *optstring); - int getopt_long (int argc, char * const argv[], const char *shortopts, - const struct option * longopts, int *longind); - int getopt_long_only (int argc, char * const argv[], const char *shortopts, - const struct option * longopts, int *longind); - -#ifdef __cplusplus -}; - -#endif - -#endif /* GETOPT_H */ - -/* END OF FILE getopt.h */