From 939a59ffc6c844e1697a1cc99f6a6b6c0fa09eb5 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 6 Jan 2003 18:53:25 +0000 Subject: [PATCH] Use our own version of getopt_long() if the OS doesn't have one. --- configure | 6 +- configure.in | 6 +- doc/src/sgml/ref/pg_dump.sgml | 6 +- doc/src/sgml/ref/pg_dumpall.sgml | 6 +- doc/src/sgml/ref/pg_restore.sgml | 4 +- doc/src/sgml/ref/psql-ref.sgml | 6 +- doc/src/sgml/release.sgml | 3 +- src/bin/pg_dump/pg_dump.c | 70 ++--------- src/bin/pg_dump/pg_dumpall.c | 31 +---- src/bin/pg_dump/pg_restore.c | 61 ++-------- src/bin/psql/startup.c | 44 ++----- src/include/getopt_long.h | 33 +++++ src/port/getopt.c | 5 +- src/port/getopt_long.c | 199 +++++++++++++++++++++++++++++++ 14 files changed, 280 insertions(+), 200 deletions(-) create mode 100644 src/include/getopt_long.h create mode 100644 src/port/getopt_long.c diff --git a/configure b/configure index ad14d244be..060c0e762c 100755 --- a/configure +++ b/configure @@ -9819,8 +9819,7 @@ test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext" - -for ac_func in cbrt fcvt getopt_long getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync +for ac_func in cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -10644,7 +10643,8 @@ fi -for ac_func in fseeko gethostname getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul + +for ac_func in fseeko gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 4c8512bd0e..d55be86ec2 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.227 2003/01/06 06:06:04 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.228 2003/01/06 18:53:22 petere Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -782,7 +782,7 @@ PGAC_FUNC_GETTIMEOFDAY_1ARG # SunOS doesn't handle negative byte comparisons properly with +/- return AC_FUNC_MEMCMP -AC_CHECK_FUNCS([cbrt fcvt getopt_long getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync]) +AC_CHECK_FUNCS([cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync]) AC_CHECK_DECLS(fdatasync, [], [], [#include ]) @@ -842,7 +842,7 @@ else AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break]) fi -AC_REPLACE_FUNCS([fseeko gethostname getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul]) +AC_REPLACE_FUNCS([fseeko gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul]) # BSD/OS & NetBSD use a custom fseeko/ftello built on fsetpos/fgetpos # We override the previous test that said fseeko/ftello didn't exist diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 64b2e00b8b..66a2e00073 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1,5 +1,5 @@ @@ -537,10 +537,6 @@ PostgreSQL documentation - - - Long option forms are only available on some platforms. - diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index 2556f6f6bf..64cea1f4a6 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -1,5 +1,5 @@ @@ -223,10 +223,6 @@ PostgreSQL documentation - - - Long options are only available on some platforms. - diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index c63fc085c3..9430ec580a 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -1,4 +1,4 @@ - + @@ -74,7 +74,7 @@ pg_restore accepts the following command - line arguments. (Long option forms are only available on some platforms.) + line arguments. diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 66a92802ba..1644cd8350 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ @@ -446,10 +446,6 @@ PostgreSQL documentation - - - Long options are not available on all platforms. - diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index 57fa4052b8..2f3295cab8 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ @@ -34,6 +34,7 @@ Statement-level triggers System can use either hash- or sort-based strategy for grouped aggregation ON COMMIT options for temp tables extra_float_digits option allows pg_dump to dump float data accurately +Long options for psql and pg_dump are now available on all platforms ]]> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 6c611f22bf..809fe0216a 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.313 2002/12/27 17:10:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.314 2003/01/06 18:53:24 petere Exp $ * *------------------------------------------------------------------------- */ @@ -40,6 +40,11 @@ #include "strdup.h" #endif +#ifndef HAVE_GETOPT_LONG +#include "getopt_long.h" +int optreset; +#endif + #include "access/attnum.h" #include "access/htup.h" #include "catalog/pg_class.h" @@ -179,7 +184,6 @@ main(int argc, char **argv) RestoreOptions *ropt; -#ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"data-only", no_argument, NULL, 'a'}, {"blobs", no_argument, NULL, 'b'}, @@ -218,7 +222,6 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; int optindex; -#endif #ifdef ENABLE_NLS setlocale(LC_ALL, ""); @@ -260,12 +263,8 @@ main(int argc, char **argv) } } -#ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:", long_options, &optindex)) != -1) -#else - while ((c = getopt(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:-")) != -1) -#endif - + while ((c = getopt_long(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:", + long_options, &optindex)) != -1) { switch (c) { @@ -415,23 +414,15 @@ main(int argc, char **argv) exit(1); } break; + case 'Z': /* Compression Level */ compressLevel = atoi(optarg); break; - -#ifndef HAVE_GETOPT_LONG - case '-': - fprintf(stderr, - _("%s was compiled without support for long options.\n" - "Use --help for help on invocation options.\n"), - progname); - exit(1); - break; -#else /* This covers the long options equivalent to -X xxx. */ + case 0: break; -#endif + default: fprintf(stderr, _("Try '%s --help' for more information.\n"), progname); exit(1); @@ -658,26 +649,16 @@ help(const char *progname) printf(_(" %s [OPTION]... [DBNAME]\n"), progname); printf(_("\nGeneral options:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -f, --file=FILENAME output file name\n")); printf(_(" -F, --format=c|t|p output file format (custom, tar, plain text)\n")); printf(_(" -i, --ignore-version proceed even when server version mismatches\n" " pg_dump version\n")); printf(_(" -v, --verbose verbose mode\n")); printf(_(" -Z, --compress=0-9 compression level for compressed formats\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -f FILENAME output file name\n")); - printf(_(" -F c|t|p output file format (custom, tar, plain text)\n")); - printf(_(" -i proceed even when server version mismatches\n" - " pg_dump version\n")); - printf(_(" -v verbose mode\n")); - printf(_(" -Z 0-9 compression level for compressed formats\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n")); printf(_("\nOptions controlling the output content:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -a, --data-only dump only the data, not the schema\n")); printf(_(" -b, --blobs include large objects in dump\n")); printf(_(" -c, --clean clean (drop) schema prior to create\n")); @@ -699,41 +680,12 @@ help(const char *progname) " than \\connect commands\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -a dump only the data, not the schema\n")); - printf(_(" -b include large objects in dump\n")); - printf(_(" -c clean (drop) schema prior to create\n")); - printf(_(" -C include commands to create database in dump\n")); - printf(_(" -d dump data as INSERT, rather than COPY, commands\n")); - printf(_(" -D dump data as INSERT commands with column names\n")); - printf(_(" -o include OIDs in dump\n")); - printf(_(" -O do not output \\connect commands in plain\n" - " text format\n")); - printf(_(" -R disable ALL reconnections to the database in\n" - " plain text format\n")); - printf(_(" -s dump only the schema, no data\n")); - printf(_(" -S NAME specify the superuser user name to use in\n" - " plain text format\n")); - printf(_(" -t TABLE dump this table only (* for all)\n")); - printf(_(" -x do not dump privileges (grant/revoke)\n")); - printf(_(" -X use-set-session-authorization\n" - " output SET SESSION AUTHORIZATION commands rather\n" - " than \\connect commands\n")); - printf(_(" -X disable-triggers disable triggers during data-only restore\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_("\nConnection options:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -h, --host=HOSTNAME database server host name\n")); printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -h HOSTNAME database server host name\n")); - printf(_(" -p PORT database server port number\n")); - printf(_(" -U NAME connect as specified database user\n")); - printf(_(" -W force password prompt (should happen automatically)\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_("\nIf no database name is not supplied, then the PGDATABASE environment\n" "variable value is used.\n\n")); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c3a7692374..ebea128a45 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.11 2002/11/29 16:38:42 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.12 2003/01/06 18:53:25 petere Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,11 @@ #endif #include +#ifndef HAVE_GETOPT_LONG +#include "getopt_long.h" +int optreset; +#endif + #include "dumputils.h" #include "libpq-fe.h" #include "pg_backup.h" @@ -71,7 +76,6 @@ main(int argc, char *argv[]) PGconn *conn; int c; -#ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"clean", no_argument, NULL, 'c'}, {"inserts", no_argument, NULL, 'd'}, @@ -88,7 +92,6 @@ main(int argc, char *argv[]) }; int optindex; -#endif #ifdef ENABLE_NLS setlocale(LC_ALL, ""); @@ -118,11 +121,7 @@ main(int argc, char *argv[]) pgdumploc = findPgDump(argv[0]); pgdumpopts = createPQExpBuffer(); -#ifdef HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, "cdDgh:iop:U:vW", long_options, &optindex)) != -1) -#else - while ((c = getopt(argc, argv, "cdDgh:iop:U:vW")) != -1) -#endif { switch (c) { @@ -216,7 +215,6 @@ help(void) printf(_(" %s [OPTION]...\n"), progname); printf(_("\nOptions:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -c, --clean clean (drop) databases prior to create\n")); printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n")); printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); @@ -225,31 +223,14 @@ help(void) " pg_dumpall version\n")); printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -v, --verbose verbose mode\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -c clean (drop) databases prior to create\n")); - printf(_(" -d dump data as INSERT, rather than COPY, commands\n")); - printf(_(" -D dump data as INSERT commands with column names\n")); - printf(_(" -g dump only global objects, no databases\n")); - printf(_(" -i proceed even when server version mismatches\n" - " pg_dumpall version\n")); - printf(_(" -o include OIDs in dump\n")); - printf(_(" -v verbose mode\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n")); printf(_("\nConnection options:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -h, --host=HOSTNAME database server host name\n")); printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -h HOSTNAME database server host name\n")); - printf(_(" -p PORT database server port number\n")); - printf(_(" -U NAME connect as specified database user\n")); - printf(_(" -W force password prompt (should happen automatically)\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_("\nThe SQL script will be written to the standard output.\n\n")); printf(_("Report bugs to .\n")); diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 46a3ee8b2e..fe1471ff99 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -34,7 +34,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.43 2002/10/18 22:05:36 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.44 2003/01/06 18:53:25 petere Exp $ * *------------------------------------------------------------------------- */ @@ -59,6 +59,11 @@ #include #endif +#ifndef HAVE_GETOPT_LONG +#include "getopt_long.h" +int optreset; +#endif + #ifdef ENABLE_NLS #include #endif @@ -85,7 +90,6 @@ main(int argc, char **argv) static int use_setsessauth = 0; static int disable_triggers = 0; -#ifdef HAVE_GETOPT_LONG struct option cmdopts[] = { {"clean", 0, NULL, 'c'}, {"create", 0, NULL, 'C'}, @@ -124,8 +128,6 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; -#endif /* HAVE_GETOPT_LONG */ - #ifdef ENABLE_NLS setlocale(LC_ALL, ""); @@ -154,11 +156,8 @@ main(int argc, char **argv) } } -#ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "acCd:f:F:h:iI:lL:NoOp:P:rRsS:t:T:uU:vWxX:", cmdopts, NULL)) != -1) -#else - while ((c = getopt(argc, argv, "acCd:f:F:h:iI:lL:NoOp:P:rRsS:t:T:uU:vWxX:")) != -1) -#endif + while ((c = getopt_long(argc, argv, "acCd:f:F:h:iI:lL:NoOp:P:rRsS:t:T:uU:vWxX:", + cmdopts, NULL)) != -1) { switch (c) { @@ -285,11 +284,9 @@ main(int argc, char **argv) } break; -#ifdef HAVE_GETOPT_LONG /* This covers the long options equivalent to -X xxx. */ case 0: break; -#endif default: fprintf(stderr, _("Try '%s --help' for more information.\n"), progname); @@ -378,26 +375,16 @@ usage(const char *progname) printf(_(" %s [OPTION]... [FILE]\n"), progname); printf(_("\nGeneral options:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -d, --dbname=NAME output database name\n")); printf(_(" -f, --file=FILENAME output file name\n")); printf(_(" -F, --format=c|t specify backup file format\n")); printf(_(" -i, --ignore-version proceed even when server version mismatches\n")); printf(_(" -l, --list print summarized TOC of the archive\n")); printf(_(" -v, --verbose verbose mode\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -d NAME output database name\n")); - printf(_(" -f FILENAME output file name\n")); - printf(_(" -F c|t specify backup file format\n")); - printf(_(" -i proceed even when server version mismatches\n")); - printf(_(" -l print summarized TOC of the archive\n")); - printf(_(" -v verbose mode\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n")); printf(_("\nOptions controlling the output content:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -a, --data-only restore only the data, no schema\n")); printf(_(" -c, --clean clean (drop) schema prior to create\n")); printf(_(" -C, --create issue commands to create the database\n")); @@ -423,44 +410,12 @@ usage(const char *progname) " of reconnecting, if possible\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -a restore only the data, no schema\n")); - printf(_(" -c clean (drop) schema prior to create\n")); - printf(_(" -C issue commands to create the database\n")); - printf(_(" -I NAME restore named index\n")); - printf(_(" -L FILENAME use specified table of contents for ordering\n" - " output from this file\n")); - printf(_(" -N restore in original dump order\n")); - printf(_(" -o restore in OID order\n")); - printf(_(" -O do not reconnect to database to match\n" - " object owner\n")); - printf(_(" -P NAME(args) restore named function\n")); - printf(_(" -r rearrange output to put indexes etc. at end\n")); - printf(_(" -R disallow ALL reconnections to the database\n")); - printf(_(" -s restore only the schema, no data\n")); - printf(_(" -S NAME specify the superuser user name to use for\n" - " disabling triggers\n")); - printf(_(" -t NAME restore named table\n")); - printf(_(" -T NAME restore named trigger\n")); - printf(_(" -x skip restoration of access privileges (grant/revoke)\n")); - printf(_(" -X use-set-session-authorization\n" - " use SET SESSION AUTHORIZATION commands instead\n" - " of reconnecting, if possible\n")); - printf(_(" -X disable-triggers disable triggers during data-only restore\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_("\nConnection options:\n")); -#ifdef HAVE_GETOPT_LONG printf(_(" -h, --host=HOSTNAME database server host name\n")); printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); -#else /* not HAVE_GETOPT_LONG */ - printf(_(" -h HOSTNAME database server host name\n")); - printf(_(" -p PORT database server port number\n")); - printf(_(" -U NAME connect as specified database user\n")); - printf(_(" -W force password prompt (should happen automatically)\n")); -#endif /* not HAVE_GETOPT_LONG */ printf(_("\nIf no input file name is supplied, then standard input is used.\n\n")); printf(_("Report bugs to .\n")); diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 3a9ab01e0e..28bbf3cc5e 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.69 2002/11/08 19:12:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.70 2003/01/06 18:53:25 petere Exp $ */ #include "postgres_fe.h" @@ -21,6 +21,11 @@ #include #endif +#ifndef HAVE_GETOPT_LONG +#include "getopt_long.h" +int optreset; +#endif + #include #include "libpq-fe.h" @@ -312,18 +317,9 @@ main(int argc, char *argv[]) * Parse command line options */ -#ifdef WIN32 -/* getopt is not in the standard includes on Win32 */ -int getopt(int, char *const[], const char *); - -/* And it requires progname to be set */ -char *__progname = "psql"; -#endif - static void parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) { -#ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"echo-all", no_argument, NULL, 'a'}, @@ -359,8 +355,6 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) }; int optindex; -#endif /* HAVE_GETOPT_LONG */ - extern char *optarg; extern int optind; int c; @@ -368,16 +362,8 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) memset(options, 0, sizeof *options); -#ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:Hlno:p:P:qR:sStT:uU:v:VWxX?", long_options, &optindex)) != -1) -#else /* not HAVE_GETOPT_LONG */ - - /* - * Be sure to leave the '-' in here, so we can catch accidental long - * options. - */ - while ((c = getopt(argc, argv, "aAc:d:eEf:F:h:Hlno:p:P:qR:sStT:uU:v:VWxX?-")) != -1) -#endif /* not HAVE_GETOPT_LONG */ + while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:Hlno:p:P:qR:sStT:uU:v:VWxX?", + long_options, &optindex)) != -1) { switch (c) { @@ -541,20 +527,6 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) exit(EXIT_FAILURE); } break; -#ifndef HAVE_GETOPT_LONG - - /* - * FreeBSD has a broken getopt that causes this test to - * fail. - */ - case '-': - fprintf(stderr, - gettext("%s was compiled without support for long options.\n" - "Use --help for help on invocation options.\n"), - pset.progname); - exit(EXIT_FAILURE); - break; -#endif default: fprintf(stderr, gettext("Try '%s --help' for more information.\n"), pset.progname); diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h new file mode 100644 index 0000000000..5b20622cee --- /dev/null +++ b/src/include/getopt_long.h @@ -0,0 +1,33 @@ +/* + * Portions Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Portions Copyright (c) 2003 + * PostgreSQL Global Development Group + * + * $Header: /cvsroot/pgsql/src/include/getopt_long.h,v 1.1 2003/01/06 18:53:25 petere Exp $ + */ + +/* These are picked up from the system's getopt() facility. */ +extern int opterr; +extern int optind; +extern int optopt; +extern char *optarg; + +/* Some systems have this, otherwise you need to define it somewhere. */ +extern int optreset; + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument 0 +#define required_argument 1 + +int +getopt_long(int argc, char * const argv[], + const char *optstring, + const struct option *longopts, int *longindex); diff --git a/src/port/getopt.c b/src/port/getopt.c index 52692f63ce..bfb6b30077 100644 --- a/src/port/getopt.c +++ b/src/port/getopt.c @@ -61,7 +61,6 @@ int nargc; char *const * nargv; const char *ostr; { - extern char *__progname; static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ @@ -93,7 +92,7 @@ const char *ostr; ++optind; if (opterr && *ostr != ':') (void) fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); + "%s: illegal option -- %c\n", argv[0], optopt); return BADCH; } if (*++oli != ':') @@ -114,7 +113,7 @@ const char *ostr; if (opterr) (void) fprintf(stderr, "%s: option requires an argument -- %c\n", - __progname, optopt); + argv[0], optopt); return BADCH; } else diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c new file mode 100644 index 0000000000..bc6779e852 --- /dev/null +++ b/src/port/getopt_long.c @@ -0,0 +1,199 @@ +/* + * getopt_long() -- long options parser + * + * Portions Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Portions Copyright (c) 2003 + * PostgreSQL Global Development Group + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Header: /cvsroot/pgsql/src/port/getopt_long.c,v 1.1 2003/01/06 18:53:25 petere Exp $ + */ + +#include +#include +#include + +#include "getopt_long.h" + +#define BADCH '?' +#define BADARG ':' +#define EMSG "" + +int +getopt_long(int argc, char * const argv[], + const char *optstring, + const struct option *longopts, int *longindex) +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) + { /* update scanning pointer */ + optreset = 0; + + if (optind >= argc) + { + place = EMSG; + return -1; + } + + place = argv[optind]; + + if (place[0] != '-') + { + place = EMSG; + return -1; + } + + place++; + + if (place[0] && place[0] == '-' && place[1] == '\0') + { /* found "--" */ + ++optind; + place = EMSG; + return -1; + } + + if (place[0] && place[0] == '-' && place[1]) + { + /* long option */ + size_t namelen; + int i; + + place++; + + namelen = strcspn(place, "="); + for (i = 0; longopts[i].name != NULL; i++) + { + if (strlen(longopts[i].name) == namelen + && strncmp(place, longopts[i].name, namelen) == 0) + { + if (longopts[i].has_arg) + { + if (place[namelen] == '=') + optarg = place + namelen + 1; + else if (optind < argc-1) + { + optind++; + optarg = argv[optind]; + } + else + { + if (optstring[0] == ':') + return BADARG; + if (opterr) + fprintf(stderr, + "%s: option requires an argument -- %s\n", + argv[0], place); + place = EMSG; + optind++; + return BADCH; + } + } + else + { + optarg = NULL; + if (place[namelen] != 0) + { + /* XXX error? */ + } + } + + optind++; + + if (longindex) + *longindex = i; + + place = EMSG; + + if (longopts[i].flag == NULL) + return longopts[i].val; + else + { + *longopts[i].flag = longopts[i].val; + return 0; + } + } + } + + if (opterr && optstring[0] != ':') + fprintf(stderr, + "%s: illegal option -- %s\n", argv[0], place); + place = EMSG; + optind++; + return BADCH; + } + } + + /* short option */ + optopt = (int) *place++; + + oli = strchr(optstring, optopt); + if (!oli) + { + if (!*place) + ++optind; + if (opterr && *optstring != ':') + fprintf(stderr, + "%s: illegal option -- %c\n", argv[0], optopt); + return BADCH; + } + + if (oli[1] != ':') + { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else + { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (argc <= ++optind) + { /* no arg */ + place = EMSG; + if (*optstring == ':') + return BADARG; + if (opterr) + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], optopt); + return BADCH; + } + else + /* white space */ + optarg = argv[optind]; + place = EMSG; + ++optind; + } + return optopt; +} -- GitLab