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