6fcead469d0d22700515190f8b172cb7df269e11
[openjpeg.git] / src / bin / common / opj_getopt.c
1 /*
2  * Copyright (c) 1987, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /* last review : october 29th, 2002 */
31
32 #if defined(LIBC_SCCS) && !defined(lint)
33 static char sccsid[] = "@(#)opj_getopt.c        8.3 (Berkeley) 4/27/95";
34 #endif                          /* LIBC_SCCS and not lint */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "opj_getopt.h"
40
41 int opj_opterr = 1,                     /* if error message should be printed */
42  opj_optind = 1,                        /* index into parent argv vector */
43  opj_optopt,                    /* character checked for validity */
44  opj_optreset;                  /* reset getopt */
45  char *opj_optarg;                      /* argument associated with option */
46
47 #define BADCH   (int)'?'
48 #define BADARG  (int)':'
49 static char EMSG[]={""};
50
51 /* As this class remembers its values from one Java call to the other, reset the values before each use */
52 void reset_options_reading(void) {
53         opj_opterr = 1;
54         opj_optind = 1;
55 }
56
57 /*
58  * getopt --
59  *      Parse argc/argv argument vector.
60  */
61 int opj_getopt(int nargc, char *const *nargv, const char *ostr) {
62 #  define __progname nargv[0]
63   static char *place = EMSG;    /* option letter processing */
64   char *oli = NULL;                     /* option letter list index */
65
66   if (opj_optreset || !*place) {        /* update scanning pointer */
67     opj_optreset = 0;
68     if (opj_optind >= nargc || *(place = nargv[opj_optind]) != '-') {
69       place = EMSG;
70       return (-1);
71     }
72     if (place[1] && *++place == '-') {  /* found "--" */
73       ++opj_optind;
74       place = EMSG;
75       return (-1);
76     }
77   }                             /* option letter okay? */
78   if ((opj_optopt = (int) *place++) == (int) ':' ||
79       !(oli = strchr(ostr, opj_optopt))) {
80     /*
81      * if the user didn't specify '-' as an option,
82      * assume it means -1.
83      */
84     if (opj_optopt == (int) '-')
85       return (-1);
86     if (!*place)
87       ++opj_optind;
88                 if (opj_opterr && *ostr != ':') {
89       fprintf(stderr,
90                      "%s: illegal option -- %c\n", __progname, opj_optopt);
91                         return (BADCH);
92                 }
93   }
94   if (*++oli != ':') {          /* don't need argument */
95     opj_optarg = NULL;
96     if (!*place)
97       ++opj_optind;
98   } else {                      /* need an argument */
99     if (*place)                 /* no white space */
100       opj_optarg = place;
101     else if (nargc <= ++opj_optind) {   /* no arg */
102       place = EMSG;
103       if (*ostr == ':')
104         return (BADARG);
105                         if (opj_opterr) {
106                                 fprintf(stderr,
107                        "%s: option requires an argument -- %c\n",
108                        __progname, opj_optopt);
109                                 return (BADCH);
110                         }
111     } else                      /* white space */
112       opj_optarg = nargv[opj_optind];
113     place = EMSG;
114     ++opj_optind;
115   }
116   return (opj_optopt);          /* dump back option letter */
117 }
118
119
120 int opj_getopt_long(int argc, char * const argv[], const char *optstring,
121 const opj_option_t *longopts, int totlen) {
122         static int lastidx,lastofs;
123         char *tmp;
124         int i,len;
125         char param = 1;
126
127 again:
128         if (opj_optind >= argc || !argv[opj_optind] || *argv[opj_optind]!='-')
129                 return -1;
130
131         if (argv[opj_optind][0]=='-' && argv[opj_optind][1]==0) {
132                 if(opj_optind >= (argc - 1)){ /* no more input parameters */
133                         param = 0;
134                 }
135                 else{ /* more input parameters */
136                         if(argv[opj_optind + 1][0] == '-'){
137                                 param = 0; /* Missing parameter after '-' */
138                         }
139                         else{
140                                 param = 2;
141                         }
142                 }
143         }
144
145         if (param == 0) {
146                 ++opj_optind;
147                 return (BADCH);
148         }
149
150         if (argv[opj_optind][0]=='-') { /* long option */
151                 char* arg=argv[opj_optind]+1;
152                 const opj_option_t* o;
153                 o=longopts;
154                 len=sizeof(longopts[0]);
155
156                 if (param > 1){
157                         arg = argv[opj_optind+1];
158                         opj_optind++;
159                 }
160                 else
161                         arg = argv[opj_optind]+1;
162
163                 if(strlen(arg)>1){
164                         for (i=0;i<totlen;i=i+len,o++) {
165                                 if (!strcmp(o->name,arg)) {     /* match */
166                                         if (o->has_arg == 0) {
167                                                 if ((argv[opj_optind+1])&&(!(argv[opj_optind+1][0]=='-'))){
168                                                         fprintf(stderr,"%s: option does not require an argument. Ignoring %s\n",arg,argv[opj_optind+1]);
169                                                         ++opj_optind;
170                                                 }
171                                         }else{ 
172                                                 opj_optarg=argv[opj_optind+1];
173                                                 if(opj_optarg){
174                                                         if (opj_optarg[0] == '-'){ /* Has read next input parameter: No arg for current parameter */                                                            
175                                                                 if (opj_opterr) {
176                                                                         fprintf(stderr,"%s: option requires an argument\n",arg);
177                                                                         return (BADCH);
178                                                                 }
179                                                         }
180                                                 }
181                                                 if (!opj_optarg && o->has_arg==1) {     /* no argument there */
182                                                         if (opj_opterr) {
183                                                                 fprintf(stderr,"%s: option requires an argument \n",arg);
184                                                                 return (BADCH);
185                                                         }
186                                                 }
187                                                 ++opj_optind;
188                                         }
189                                         ++opj_optind;
190                                         if (o->flag)
191                                                 *(o->flag)=o->val;
192                                         else
193                                                 return o->val;
194                                         return 0;
195                                 }
196                         }/*(end for)String not found in the list*/
197                         fprintf(stderr,"Invalid option %s\n",arg);
198                         ++opj_optind;
199                         return (BADCH);
200                 }else{ /*Single character input parameter*/
201                         if (*optstring==':') return ':';
202                         if (lastidx!=opj_optind) {
203                                 lastidx=opj_optind; lastofs=0;
204                         }
205                         opj_optopt=argv[opj_optind][lastofs+1];
206                         if ((tmp=strchr(optstring,opj_optopt))) {/*Found input parameter in list*/
207                                 if (*tmp==0) {  /* apparently, we looked for \0, i.e. end of argument */
208                                         ++opj_optind;
209                                         goto again;
210                                 }
211                                 if (tmp[1]==':') {      /* argument expected */
212                                         if (tmp[2]==':' || argv[opj_optind][lastofs+2]) {       /* "-foo", return "oo" as opj_optarg */
213                                                 if (!*(opj_optarg=argv[opj_optind]+lastofs+2)) opj_optarg=0;
214                                                 goto found;
215                                         }
216                                         opj_optarg=argv[opj_optind+1];
217                                         if(opj_optarg){
218                                                 if (opj_optarg[0] == '-'){ /* Has read next input parameter: No arg for current parameter */
219                                                         if (opj_opterr) {
220                                                                 fprintf(stderr,"%s: option requires an argument\n",arg);
221                                                                 return (BADCH);
222                                                         }
223                                                 }
224                                         }
225                                         if (!opj_optarg) {      /* missing argument */
226                                                 if (opj_opterr) {
227                                                         fprintf(stderr,"%s: option requires an argument\n",arg);
228                                                         return (BADCH);
229                                                 }
230                                         }
231                                         ++opj_optind;
232                                 }else {/*Argument not expected*/
233                                         ++lastofs;
234                                         return opj_optopt;
235                                 }
236 found:
237                                 ++opj_optind;
238                                 return opj_optopt;
239                         }       else {  /* not found */
240                                 fprintf(stderr,"Invalid option %s\n",arg);
241                                 ++opj_optind;
242                                 return (BADCH);
243                         }/*end of not found*/
244                 
245                 }/* end of single character*/
246         }/*end '-'*/
247         fprintf(stderr,"Invalid option\n");
248         ++opj_optind;
249         return (BADCH);;
250 }/*end function*/