1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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 272374 2008-12-31 11:17:49Z sebastian $ */
20 :
21 : #include <stdio.h>
22 : #include <string.h>
23 : #include <assert.h>
24 : #include <stdlib.h>
25 : #include "php_getopt.h"
26 : #define OPTERRCOLON (1)
27 : #define OPTERRNF (2)
28 : #define OPTERRARG (3)
29 :
30 :
31 : static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
32 0 : {
33 0 : if (show_err)
34 : {
35 0 : fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
36 0 : switch(err)
37 : {
38 : case OPTERRCOLON:
39 0 : fprintf(stderr, ": in flags\n");
40 0 : break;
41 : case OPTERRNF:
42 0 : fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
43 0 : break;
44 : case OPTERRARG:
45 0 : fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
46 0 : break;
47 : default:
48 0 : fprintf(stderr, "unknown\n");
49 : break;
50 : }
51 : }
52 0 : return('?');
53 : }
54 :
55 : int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
56 5949 : {
57 : static int optchr = 0;
58 : static int dash = 0; /* have already seen the - */
59 5949 : int arg_start = 2;
60 :
61 5949 : int opts_idx = -1;
62 :
63 5949 : if (*optind >= argc) {
64 133 : return(EOF);
65 : }
66 5816 : if (!dash) {
67 5816 : if ((argv[*optind][0] != '-')) {
68 105 : return(EOF);
69 : } else {
70 5711 : if (!argv[*optind][1])
71 : {
72 : /*
73 : * use to specify stdin. Need to let pgm process this and
74 : * the following args
75 : */
76 0 : return(EOF);
77 : }
78 : }
79 : }
80 5711 : if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
81 : /* '--' indicates end of args if not followed by a known long option name */
82 0 : if (argv[*optind][2] == '\0') {
83 0 : (*optind)++;
84 0 : return(EOF);
85 : }
86 :
87 : while (1) {
88 0 : opts_idx++;
89 0 : if (opts[opts_idx].opt_char == '-') {
90 0 : (*optind)++;
91 0 : return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
92 0 : } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
93 0 : break;
94 : }
95 0 : }
96 0 : optchr = 0;
97 0 : dash = 0;
98 0 : arg_start = 2 + strlen(opts[opts_idx].opt_name);
99 : } else {
100 5711 : if (!dash) {
101 5711 : dash = 1;
102 5711 : optchr = 1;
103 : }
104 : /* Check if the guy tries to do a -: kind of flag */
105 5711 : if (argv[*optind][optchr] == ':') {
106 0 : dash = 0;
107 0 : (*optind)++;
108 0 : return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
109 : }
110 5711 : arg_start = 1 + optchr;
111 : }
112 5711 : if (opts_idx < 0) {
113 : while (1) {
114 29722 : opts_idx++;
115 29722 : if (opts[opts_idx].opt_char == '-') {
116 0 : int errind = *optind;
117 0 : int errchr = optchr;
118 :
119 0 : if (!argv[*optind][optchr+1]) {
120 0 : dash = 0;
121 0 : (*optind)++;
122 : } else {
123 0 : optchr++;
124 0 : arg_start++;
125 : }
126 0 : return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
127 29722 : } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
128 5711 : break;
129 : }
130 24011 : }
131 : }
132 5711 : if (opts[opts_idx].need_param) {
133 : /* Check for cases where the value of the argument
134 : is in the form -<arg> <val> or in the form -<arg><val> */
135 5370 : dash = 0;
136 5370 : if(!argv[*optind][arg_start]) {
137 5370 : (*optind)++;
138 5370 : if (*optind == argc) {
139 0 : return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
140 : }
141 5370 : *optarg = argv[(*optind)++];
142 : } else {
143 0 : *optarg = &argv[*optind][arg_start];
144 0 : (*optind)++;
145 : }
146 5370 : return opts[opts_idx].opt_char;
147 : } else {
148 : /* multiple options specified as one (exclude long opts) */
149 682 : if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
150 341 : if (!argv[*optind][optchr+1])
151 : {
152 341 : dash = 0;
153 341 : (*optind)++;
154 : } else {
155 0 : optchr++;
156 : }
157 : } else {
158 0 : (*optind)++;
159 : }
160 341 : return opts[opts_idx].opt_char;
161 : }
162 : assert(0);
163 : return(0); /* never reached */
164 : }
|