summaryrefslogtreecommitdiff
path: root/sapi/cgi/getopt.c
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2003-02-16 01:23:11 +0000
committerMarcus Boerger <helly@php.net>2003-02-16 01:23:11 +0000
commitd4fd1c07b1dfac42061d96c3a7aae9f0b91d218d (patch)
treee8986edb10020c657cf7c692af02b5be53d13bd6 /sapi/cgi/getopt.c
parent824baa0384e301712ff222a60b0049a06b0bdbd4 (diff)
downloadphp-git-d4fd1c07b1dfac42061d96c3a7aae9f0b91d218d.tar.gz
- Allow long option names
- Update CLI's manpage @Added support for long options in CLI & CGI (e.g. --version). (Marcus) # In contrast to the preliminary patch this should work now completely. # If all long option names are accepted we may even think about MFHing.
Diffstat (limited to 'sapi/cgi/getopt.c')
-rw-r--r--sapi/cgi/getopt.c293
1 files changed, 136 insertions, 157 deletions
diff --git a/sapi/cgi/getopt.c b/sapi/cgi/getopt.c
index a26ca3c431..e048e95058 100644
--- a/sapi/cgi/getopt.c
+++ b/sapi/cgi/getopt.c
@@ -1,4 +1,20 @@
-/* Borrowed from Apache NT Port */
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 4 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2003 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Marcus Boerger <helly@php.net> |
+ +----------------------------------------------------------------------+
+*/
#include <stdio.h>
#include <string.h>
@@ -10,166 +26,129 @@
#define OPTERRARG (3)
-char *ap_php_optarg;
-int ap_php_optind = 1;
-static int ap_php_opterr = 1;
-static int ap_php_optopt;
-
-static int
-ap_php_optiserr(int argc, char * const *argv, int oint, const char *optstr,
- int optchr, int err)
+static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
{
- if (ap_php_opterr)
- {
- fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
- switch(err)
- {
- case OPTERRCOLON:
- fprintf(stderr, ": in flags\n");
- break;
- case OPTERRNF:
- fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
- break;
- case OPTERRARG:
- fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
- break;
- default:
- fprintf(stderr, "unknown\n");
- break;
- }
- }
- ap_php_optopt = argv[oint][optchr];
- return('?');
+ if (show_err)
+ {
+ fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
+ switch(err)
+ {
+ case OPTERRCOLON:
+ fprintf(stderr, ": in flags\n");
+ break;
+ case OPTERRNF:
+ fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
+ break;
+ case OPTERRARG:
+ fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
+ break;
+ default:
+ fprintf(stderr, "unknown\n");
+ break;
+ }
+ }
+ return('?');
}
-
-int ap_php_getopt(int argc, char* const *argv, const char *optstr)
-{
- static int optchr = 0;
- static int dash = 0; /* have already seen the - */
- char *cp;
+int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
+{
+ static int optchr = 0;
+ static int dash = 0; /* have already seen the - */
+ int arg_start = 2;
- if (ap_php_optind >= argc)
- return(EOF);
- if (!dash && (argv[ap_php_optind][0] != '-'))
- return(EOF);
- if (!dash && (argv[ap_php_optind][0] == '-') && !argv[ap_php_optind][1])
- {
- /*
- * use to specify stdin. Need to let pgm process this and
- * the following args
- */
- return(EOF);
- }
- if ((argv[ap_php_optind][0] == '-') && (argv[ap_php_optind][1] == '-'))
- {
- /* -- indicates end of args */
- ap_php_optind++;
- return(EOF);
- }
- if (!dash)
- {
- assert((argv[ap_php_optind][0] == '-') && argv[ap_php_optind][1]);
- dash = 1;
- optchr = 1;
- }
+ int opts_idx = -1;
- /* Check if the guy tries to do a -: kind of flag */
- assert(dash);
- if (argv[ap_php_optind][optchr] == ':')
- {
- dash = 0;
- ap_php_optind++;
- return(ap_php_optiserr(argc, argv, ap_php_optind-1, optstr, optchr, OPTERRCOLON));
- }
- if (!(cp = strchr(optstr, argv[ap_php_optind][optchr])))
- {
- int errind = ap_php_optind;
- int errchr = optchr;
+ if (*optind >= argc) {
+ return(EOF);
+ }
+ if (!dash) {
+ if ((argv[*optind][0] != '-')) {
+ return(EOF);
+ } else {
+ if (!argv[*optind][1])
+ {
+ /*
+ * use to specify stdin. Need to let pgm process this and
+ * the following args
+ */
+ return(EOF);
+ }
+ }
+ }
+ if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
+ /* '--' indicates end of args if not followed by a known long option name */
+ while (1) {
+ opts_idx++;
+ if (opts[opts_idx].opt_char == '-') {
+ (*optind)++;
+ return(EOF);
+ } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
+ break;
+ }
+ }
+ optchr = 0;
+ dash = 1;
+ arg_start = 2 + strlen(opts[opts_idx].opt_name);
+ }
+ if (!dash) {
+ dash = 1;
+ optchr = 1;
+ }
- if (!argv[ap_php_optind][optchr+1])
- {
- dash = 0;
- ap_php_optind++;
- }
- else
- optchr++;
- return(ap_php_optiserr(argc, argv, errind, optstr, errchr, OPTERRNF));
- }
- if (cp[1] == ':')
- {
- /* Check for cases where the value of the argument
- is in the form -<arg> <val> or in the form -<arg><val> */
- dash = 0;
- if(!argv[ap_php_optind][2]) {
- ap_php_optind++;
- if (ap_php_optind == argc)
- return(ap_php_optiserr(argc, argv, ap_php_optind-1, optstr, optchr, OPTERRARG));
- ap_php_optarg = argv[ap_php_optind++];
- }
- else
- {
- ap_php_optarg = &argv[ap_php_optind][2];
- ap_php_optind++;
- }
- return(*cp);
- }
- else
- {
- if (!argv[ap_php_optind][optchr+1])
- {
- dash = 0;
- ap_php_optind++;
- }
- else
- optchr++;
- return(*cp);
- }
- assert(0);
- return(0); /* never reached */
+ /* Check if the guy tries to do a -: kind of flag */
+ if (argv[*optind][optchr] == ':') {
+ dash = 0;
+ (*optind)++;
+ return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
+ }
+ if (opts_idx < 0) {
+ while (1) {
+ opts_idx++;
+ if (opts[opts_idx].opt_char == '-') {
+ int errind = *optind;
+ int errchr = optchr;
+
+ if (!argv[*optind][optchr+1]) {
+ dash = 0;
+ (*optind)++;
+ } else {
+ optchr++;
+ }
+ return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
+ } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
+ break;
+ }
+ }
+ }
+ if (opts[opts_idx].need_param) {
+ /* Check for cases where the value of the argument
+ is in the form -<arg> <val> or in the form -<arg><val> */
+ dash = 0;
+ if(!argv[*optind][arg_start]) {
+ (*optind)++;
+ if (*optind == argc) {
+ return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
+ }
+ *optarg = argv[(*optind)++];
+ } else {
+ *optarg = &argv[*optind][arg_start];
+ (*optind)++;
+ }
+ return opts[opts_idx].opt_char;
+ } else {
+ if (arg_start == 2) {
+ if (!argv[*optind][optchr+1])
+ {
+ dash = 0;
+ (*optind)++;
+ } else {
+ optchr++;
+ }
+ } else {
+ (*optind)++;
+ }
+ return opts[opts_idx].opt_char;
+ }
+ assert(0);
+ return(0); /* never reached */
}
-
-#ifdef TESTGETOPT
-int
- main (int argc, char **argv)
- {
- int c;
- extern char *ap_php_optarg;
- extern int ap_php_optind;
- int aflg = 0;
- int bflg = 0;
- int errflg = 0;
- char *ofile = NULL;
-
- while ((c = ap_php_getopt(argc, argv, "abo:")) != EOF)
- switch (c) {
- case 'a':
- if (bflg)
- errflg++;
- else
- aflg++;
- break;
- case 'b':
- if (aflg)
- errflg++;
- else
- bflg++;
- break;
- case 'o':
- ofile = ap_php_optarg;
- (void)printf("ofile = %s\n", ofile);
- break;
- case '?':
- errflg++;
- }
- if (errflg) {
- (void)fprintf(stderr,
- "usage: cmd [-a|-b] [-o <filename>] files...\n");
- exit (2);
- }
- for ( ; ap_php_optind < argc; ap_php_optind++)
- (void)printf("%s\n", argv[ap_php_optind]);
- return 0;
- }
-
-#endif /* TESTGETOPT */