File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / main / getopt.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:04:01 2014 UTC (10 years ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 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: getopt.c,v 1.1.1.4 2014/06/15 20:04:01 misho Exp $ */
   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: 
   63: 	php_optidx = -1;
   64: 
   65: 	if (*optind >= argc) {
   66: 		return(EOF);
   67: 	}
   68: 	if (!dash) {
   69: 		if ((argv[*optind][0] !=  '-')) {
   70: 			return(EOF);
   71: 		} else {
   72: 			if (!argv[*optind][1])
   73: 			{
   74: 				/*
   75: 				* use to specify stdin. Need to let pgm process this and
   76: 				* the following args
   77: 				*/
   78: 				return(EOF);
   79: 			}
   80: 		}
   81: 	}
   82: 	if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
   83: 		char *pos;
   84: 		int arg_end = strlen(argv[*optind])-1;
   85: 
   86: 		/* '--' indicates end of args if not followed by a known long option name */
   87: 		if (argv[*optind][2] == '\0') {
   88: 			(*optind)++;
   89: 			return(EOF);
   90: 		}
   91: 
   92: 		arg_start = 2;
   93: 
   94: 		/* Check for <arg>=<val> */
   95: 		if ((pos = php_memnstr(&argv[*optind][arg_start], "=", 1, argv[*optind]+arg_end)) != NULL) {
   96: 			arg_end = pos-&argv[*optind][arg_start];
   97: 			arg_start++;
   98: 		} else {
   99: 			arg_end--;
  100: 		}
  101: 
  102: 		while (1) {
  103: 			php_optidx++;
  104: 			if (opts[php_optidx].opt_char == '-') {
  105: 				(*optind)++;
  106: 				return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  107: 			} 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)) {
  108: 				break;
  109: 			}
  110: 		}
  111: 
  112: 		optchr = 0;
  113: 		dash = 0;
  114: 		arg_start += strlen(opts[php_optidx].opt_name);
  115: 	} else {
  116: 		if (!dash) {
  117: 			dash = 1;
  118: 			optchr = 1;
  119: 		}
  120: 		/* Check if the guy tries to do a -: kind of flag */
  121: 		if (argv[*optind][optchr] == ':') {
  122: 			dash = 0;
  123: 			(*optind)++;
  124: 			return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
  125: 		}
  126: 		arg_start = 1 + optchr;
  127: 	}
  128: 	if (php_optidx < 0) {
  129: 		while (1) {
  130: 			php_optidx++;
  131: 			if (opts[php_optidx].opt_char == '-') {
  132: 				int errind = *optind;
  133: 				int errchr = optchr;
  134: 
  135: 				if (!argv[*optind][optchr+1]) {
  136: 					dash = 0;
  137: 					(*optind)++;
  138: 				} else {
  139: 					optchr++;
  140: 					arg_start++;
  141: 				}
  142: 				return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
  143: 			} else if (argv[*optind][optchr] == opts[php_optidx].opt_char) {
  144: 				break;
  145: 			}
  146: 		}
  147: 	}
  148: 	if (opts[php_optidx].need_param) {
  149: 		/* Check for cases where the value of the argument
  150: 		is in the form -<arg> <val>, -<arg>=<varl> or -<arg><val> */
  151: 		dash = 0;
  152: 		if (!argv[*optind][arg_start]) {
  153: 			(*optind)++;
  154: 			if (*optind == argc) {
  155: 				/* Was the value required or is it optional? */
  156: 				if (opts[php_optidx].need_param == 1) {
  157: 					return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  158: 				}
  159: 			/* Optional value is not supported with -<arg> <val> style */
  160: 			} else if (opts[php_optidx].need_param == 1) {
  161: 				*optarg = argv[(*optind)++];
  162:  			}
  163: 		} else if (argv[*optind][arg_start] == '=') {
  164: 			arg_start++;
  165: 			*optarg = &argv[*optind][arg_start];
  166: 			(*optind)++;
  167: 		} else {
  168: 			*optarg = &argv[*optind][arg_start];
  169: 			(*optind)++;
  170: 		}
  171: 		return opts[php_optidx].opt_char;
  172: 	} else {
  173: 		/* multiple options specified as one (exclude long opts) */
  174: 		if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
  175: 			if (!argv[*optind][optchr+1])
  176: 			{
  177: 				dash = 0;
  178: 				(*optind)++;
  179: 			} else {
  180: 				optchr++;
  181: 			}
  182: 		} else {
  183: 			(*optind)++;
  184: 		}
  185: 		return opts[php_optidx].opt_char;
  186: 	}
  187: 	assert(0);
  188: 	return(0);	/* never reached */
  189: }
  190: /* }}} */
  191: 
  192: /*
  193:  * Local variables:
  194:  * tab-width: 4
  195:  * c-basic-offset: 4
  196:  * End:
  197:  * vim600: sw=4 ts=4 fdm=marker
  198:  * vim<600: sw=4 ts=4
  199:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>