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