1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 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.8.2.1.2.3 2007/03/22 21:35:41 johannes Exp $ */
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 15 : {
57 : static int optchr = 0;
58 : static int dash = 0; /* have already seen the - */
59 15 : int arg_start = 2;
60 :
61 15 : int opts_idx = -1;
62 :
63 15 : if (*optind >= argc) {
64 0 : return(EOF);
65 : }
66 15 : if (!dash) {
67 15 : if ((argv[*optind][0] != '-')) {
68 3 : return(EOF);
69 : } else {
70 12 : 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 12 : 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 12 : if (!dash) {
101 12 : dash = 1;
102 12 : optchr = 1;
103 : }
104 : /* Check if the guy tries to do a -: kind of flag */
105 12 : 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 : }
111 12 : if (opts_idx < 0) {
112 : while (1) {
113 60 : opts_idx++;
114 60 : if (opts[opts_idx].opt_char == '-') {
115 0 : int errind = *optind;
116 0 : int errchr = optchr;
117 :
118 0 : if (!argv[*optind][optchr+1]) {
119 0 : dash = 0;
120 0 : (*optind)++;
121 : } else {
122 0 : optchr++;
123 : }
124 0 : return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
125 60 : } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
126 12 : break;
127 : }
128 48 : }
129 : }
130 12 : if (opts[opts_idx].need_param) {
131 : /* Check for cases where the value of the argument
132 : is in the form -<arg> <val> or in the form -<arg><val> */
133 12 : dash = 0;
134 12 : if(!argv[*optind][arg_start]) {
135 12 : (*optind)++;
136 12 : if (*optind == argc) {
137 0 : return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
138 : }
139 12 : *optarg = argv[(*optind)++];
140 : } else {
141 0 : *optarg = &argv[*optind][arg_start];
142 0 : (*optind)++;
143 : }
144 12 : return opts[opts_idx].opt_char;
145 : } else {
146 0 : if (arg_start == 2) {
147 0 : if (!argv[*optind][optchr+1])
148 : {
149 0 : dash = 0;
150 0 : (*optind)++;
151 : } else {
152 0 : optchr++;
153 : }
154 : } else {
155 0 : (*optind)++;
156 : }
157 0 : return opts[opts_idx].opt_char;
158 : }
159 : assert(0);
160 : return(0); /* never reached */
161 : }
|