summaryrefslogtreecommitdiff
path: root/main/getopt.c
diff options
context:
space:
mode:
authorJani Taskinen <jani@php.net>2007-10-01 12:40:54 +0000
committerJani Taskinen <jani@php.net>2007-10-01 12:40:54 +0000
commit2bc631fb4040b731388fb126c2ca76a06d3989d1 (patch)
treedbfc1e424304b881f3cb6eca8ab7d9d22b75d6b2 /main/getopt.c
parent27e8fa0d31950854c78580264e28008e7f46325d (diff)
downloadphp-git-2bc631fb4040b731388fb126c2ca76a06d3989d1.tar.gz
MFH:- Added common getopt implementation to core.
MFH:- Added long-option feature to getopt(). MFH:- Made getopt() available on win32 systems. MFH: Patch by: David Soria Parra <dsp@php.net> [DOC]: These changes will be available from 5.3+ # Note: Fixed also tests and synced basic_functions.c with HEAD.
Diffstat (limited to 'main/getopt.c')
-rw-r--r--main/getopt.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/main/getopt.c b/main/getopt.c
new file mode 100644
index 0000000000..2c00920e95
--- /dev/null
+++ b/main/getopt.c
@@ -0,0 +1,176 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2007 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.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> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "php_getopt.h"
+
+#define OPTERRCOLON (1)
+#define OPTERRNF (2)
+#define OPTERRARG (3)
+
+static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err) /* {{{ */
+{
+ 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('?');
+}
+/* }}} */
+
+PHPAPI int php_optidx = -1;
+
+PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start) /* {{{ */
+{
+ static int optchr = 0;
+ static int dash = 0; /* have already seen the - */
+
+ php_optidx = -1;
+
+ 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 */
+ if (argv[*optind][2] == '\0') {
+ (*optind)++;
+ return(EOF);
+ }
+
+ while (1) {
+ php_optidx++;
+ if (opts[php_optidx].opt_char == '-') {
+ (*optind)++;
+ return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
+ } else if (opts[php_optidx].opt_name && !strcmp(&argv[*optind][2], opts[php_optidx].opt_name)) {
+ break;
+ }
+ }
+ optchr = 0;
+ dash = 0;
+ arg_start = 2 + strlen(opts[php_optidx].opt_name);
+ } else {
+ if (!dash) {
+ dash = 1;
+ optchr = 1;
+ }
+ /* 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));
+ }
+ arg_start = 1 + optchr;
+ }
+ if (php_optidx < 0) {
+ while (1) {
+ php_optidx++;
+ if (opts[php_optidx].opt_char == '-') {
+ int errind = *optind;
+ int errchr = optchr;
+
+ if (!argv[*optind][optchr+1]) {
+ dash = 0;
+ (*optind)++;
+ } else {
+ optchr++;
+ arg_start++;
+ }
+ return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
+ } else if (argv[*optind][optchr] == opts[php_optidx].opt_char) {
+ break;
+ }
+ }
+ }
+ if (opts[php_optidx].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[php_optidx].opt_char;
+ } else {
+ /* multiple options specified as one (exclude long opts) */
+ if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
+ if (!argv[*optind][optchr+1])
+ {
+ dash = 0;
+ (*optind)++;
+ } else {
+ optchr++;
+ }
+ } else {
+ (*optind)++;
+ }
+ return opts[php_optidx].opt_char;
+ }
+ assert(0);
+ return(0); /* never reached */
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */