root/main/getopt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_opt_error
  2. php_getopt

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Author: Marcus Boerger <helly@php.net>                               |
  16    +----------------------------------------------------------------------+
  17 */
  18 
  19 /* $Id$ */
  20 
  21 #include <stdio.h>
  22 #include <string.h>
  23 #include <assert.h>
  24 #include <stdlib.h>
  25 #include "php_getopt.h"
  26 
  27 #define OPTERRCOLON (1)
  28 #define OPTERRNF (2)
  29 #define OPTERRARG (3)
  30 
  31 static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err) /* {{{ */
  32 {
  33         if (show_err)
  34         {
  35                 fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
  36                 switch(err)
  37                 {
  38                 case OPTERRCOLON:
  39                         fprintf(stderr, ": in flags\n");
  40                         break;
  41                 case OPTERRNF:
  42                         fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
  43                         break;
  44                 case OPTERRARG:
  45                         fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
  46                         break;
  47                 default:
  48                         fprintf(stderr, "unknown\n");
  49                         break;
  50                 }
  51         }
  52         return('?');
  53 }
  54 /* }}} */
  55 
  56 PHPAPI int php_optidx = -1;
  57 
  58 PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start) /* {{{ */
  59 {
  60         static int optchr = 0;
  61         static int dash = 0; /* have already seen the - */
  62         static char **prev_optarg = NULL;
  63 
  64         php_optidx = -1;
  65 
  66         if(prev_optarg && prev_optarg != optarg) {
  67                 /* reset the state */
  68                 optchr = 0;
  69                 dash = 0;
  70         }
  71         prev_optarg = optarg;
  72 
  73         if (*optind >= argc) {
  74                 return(EOF);
  75         }
  76         if (!dash) {
  77                 if ((argv[*optind][0] !=  '-')) {
  78                         return(EOF);
  79                 } else {
  80                         if (!argv[*optind][1])
  81                         {
  82                                 /*
  83                                 * use to specify stdin. Need to let pgm process this and
  84                                 * the following args
  85                                 */
  86                                 return(EOF);
  87                         }
  88                 }
  89         }
  90         if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
  91                 const char *pos;
  92                 int arg_end = (int)strlen(argv[*optind])-1;
  93 
  94                 /* '--' indicates end of args if not followed by a known long option name */
  95                 if (argv[*optind][2] == '\0') {
  96                         (*optind)++;
  97                         return(EOF);
  98                 }
  99 
 100                 arg_start = 2;
 101 
 102                 /* Check for <arg>=<val> */
 103                 if ((pos = php_memnstr(&argv[*optind][arg_start], "=", 1, argv[*optind]+arg_end)) != NULL) {
 104                         arg_end = pos-&argv[*optind][arg_start];
 105                         arg_start++;
 106                 } else {
 107                         arg_end--;
 108                 }
 109 
 110                 while (1) {
 111                         php_optidx++;
 112                         if (opts[php_optidx].opt_char == '-') {
 113                                 (*optind)++;
 114                                 return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
 115                         } else if (opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end) && arg_end == strlen(opts[php_optidx].opt_name)) {
 116                                 break;
 117                         }
 118                 }
 119 
 120                 optchr = 0;
 121                 dash = 0;
 122                 arg_start += (int)strlen(opts[php_optidx].opt_name);
 123         } else {
 124                 if (!dash) {
 125                         dash = 1;
 126                         optchr = 1;
 127                 }
 128                 /* Check if the guy tries to do a -: kind of flag */
 129                 if (argv[*optind][optchr] == ':') {
 130                         dash = 0;
 131                         (*optind)++;
 132                         return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
 133                 }
 134                 arg_start = 1 + optchr;
 135         }
 136         if (php_optidx < 0) {
 137                 while (1) {
 138                         php_optidx++;
 139                         if (opts[php_optidx].opt_char == '-') {
 140                                 int errind = *optind;
 141                                 int errchr = optchr;
 142 
 143                                 if (!argv[*optind][optchr+1]) {
 144                                         dash = 0;
 145                                         (*optind)++;
 146                                 } else {
 147                                         optchr++;
 148                                         arg_start++;
 149                                 }
 150                                 return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
 151                         } else if (argv[*optind][optchr] == opts[php_optidx].opt_char) {
 152                                 break;
 153                         }
 154                 }
 155         }
 156         if (opts[php_optidx].need_param) {
 157                 /* Check for cases where the value of the argument
 158                 is in the form -<arg> <val>, -<arg>=<varl> or -<arg><val> */
 159                 dash = 0;
 160                 if (!argv[*optind][arg_start]) {
 161                         (*optind)++;
 162                         if (*optind == argc) {
 163                                 /* Was the value required or is it optional? */
 164                                 if (opts[php_optidx].need_param == 1) {
 165                                         return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
 166                                 }
 167                         /* Optional value is not supported with -<arg> <val> style */
 168                         } else if (opts[php_optidx].need_param == 1) {
 169                                 *optarg = argv[(*optind)++];
 170                         }
 171                 } else if (argv[*optind][arg_start] == '=') {
 172                         arg_start++;
 173                         *optarg = &argv[*optind][arg_start];
 174                         (*optind)++;
 175                 } else {
 176                         *optarg = &argv[*optind][arg_start];
 177                         (*optind)++;
 178                 }
 179                 return opts[php_optidx].opt_char;
 180         } else {
 181                 /* multiple options specified as one (exclude long opts) */
 182                 if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
 183                         if (!argv[*optind][optchr+1])
 184                         {
 185                                 dash = 0;
 186                                 (*optind)++;
 187                         } else {
 188                                 optchr++;
 189                         }
 190                 } else {
 191                         (*optind)++;
 192                 }
 193                 return opts[php_optidx].opt_char;
 194         }
 195         assert(0);
 196         return(0);      /* never reached */
 197 }
 198 /* }}} */
 199 
 200 /*
 201  * Local variables:
 202  * tab-width: 4
 203  * c-basic-offset: 4
 204  * End:
 205  * vim600: sw=4 ts=4 fdm=marker
 206  * vim<600: sw=4 ts=4
 207  */

/* [<][>][^][v][top][bottom][index][help] */