xref: /PHP-5.5/sapi/milter/getopt.c (revision 0244ca1d)
1 /* Borrowed from Apache NT Port */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include <assert.h>
6 #include <stdlib.h>
7 #include "php_getopt.h"
8 #define OPTERRCOLON (1)
9 #define OPTERRNF (2)
10 #define OPTERRARG (3)
11 
12 
13 char *ap_php_optarg;
14 int ap_php_optind = 1;
15 static int ap_php_opterr = 1;
16 
17 static int
ap_php_optiserr(int argc,char * const * argv,int oint,const char * optstr,int optchr,int err)18 ap_php_optiserr(int argc, char * const *argv, int oint, const char *optstr,
19          int optchr, int err)
20 {
21     if (ap_php_opterr)
22     {
23         fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
24         switch(err)
25         {
26         case OPTERRCOLON:
27             fprintf(stderr, ": in flags\n");
28             break;
29         case OPTERRNF:
30             fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
31             break;
32         case OPTERRARG:
33             fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
34             break;
35         default:
36             fprintf(stderr, "unknown\n");
37             break;
38         }
39     }
40     return('?');
41 }
42 
ap_php_getopt(int argc,char * const * argv,const char * optstr)43 int ap_php_getopt(int argc, char* const *argv, const char *optstr)
44 {
45     static int optchr = 0;
46     static int dash = 0; /* have already seen the - */
47 
48     char *cp;
49 
50     if (ap_php_optind >= argc)
51         return(EOF);
52     if (!dash && (argv[ap_php_optind][0] !=  '-'))
53         return(EOF);
54     if (!dash && (argv[ap_php_optind][0] ==  '-') && !argv[ap_php_optind][1])
55     {
56         /*
57          * use to specify stdin. Need to let pgm process this and
58          * the following args
59          */
60         return(EOF);
61     }
62     if ((argv[ap_php_optind][0] == '-') && (argv[ap_php_optind][1] == '-'))
63     {
64         /* -- indicates end of args */
65         ap_php_optind++;
66         return(EOF);
67     }
68     if (!dash)
69     {
70         assert((argv[ap_php_optind][0] == '-') && argv[ap_php_optind][1]);
71         dash = 1;
72         optchr = 1;
73     }
74 
75     /* Check if the guy tries to do a -: kind of flag */
76     assert(dash);
77     if (argv[ap_php_optind][optchr] == ':')
78     {
79         dash = 0;
80         ap_php_optind++;
81         return(ap_php_optiserr(argc, argv, ap_php_optind-1, optstr, optchr, OPTERRCOLON));
82     }
83     if (!(cp = strchr(optstr, argv[ap_php_optind][optchr])))
84     {
85         int errind = ap_php_optind;
86         int errchr = optchr;
87 
88         if (!argv[ap_php_optind][optchr+1])
89         {
90             dash = 0;
91             ap_php_optind++;
92         }
93         else
94             optchr++;
95         return(ap_php_optiserr(argc, argv, errind, optstr, errchr, OPTERRNF));
96     }
97     if (cp[1] == ':')
98     {
99         /* Check for cases where the value of the argument
100            is in the form -<arg> <val> or in the form -<arg><val> */
101         dash = 0;
102         if(!argv[ap_php_optind][2]) {
103             ap_php_optind++;
104             if (ap_php_optind == argc)
105                 return(ap_php_optiserr(argc, argv, ap_php_optind-1, optstr, optchr, OPTERRARG));
106             ap_php_optarg = argv[ap_php_optind++];
107         }
108         else
109         {
110             ap_php_optarg = &argv[ap_php_optind][2];
111             ap_php_optind++;
112         }
113         return(*cp);
114     }
115     else
116     {
117         if (!argv[ap_php_optind][optchr+1])
118         {
119             dash = 0;
120             ap_php_optind++;
121         }
122         else
123             optchr++;
124         return(*cp);
125     }
126     assert(0);
127     return(0);	/* never reached */
128 }
129 
130 #ifdef TESTGETOPT
131 int
main(int argc,char ** argv)132  main (int argc, char **argv)
133  {
134       int c;
135       extern char *ap_php_optarg;
136       extern int ap_php_optind;
137       int aflg = 0;
138       int bflg = 0;
139       int errflg = 0;
140       char *ofile = NULL;
141 
142       while ((c = ap_php_getopt(argc, argv, "abo:")) != EOF)
143            switch (c) {
144            case 'a':
145                 if (bflg)
146                      errflg++;
147                 else
148                      aflg++;
149                 break;
150            case 'b':
151                 if (aflg)
152                      errflg++;
153                 else
154                      bflg++;
155                 break;
156            case 'o':
157                 ofile = ap_php_optarg;
158                 (void)printf("ofile = %s\n", ofile);
159                 break;
160            case '?':
161                 errflg++;
162            }
163       if (errflg) {
164            (void)fprintf(stderr,
165                 "usage: cmd [-a|-b] [-o <filename>] files...\n");
166            exit (2);
167       }
168       for ( ; ap_php_optind < argc; ap_php_optind++)
169            (void)printf("%s\n", argv[ap_php_optind]);
170       return 0;
171  }
172 
173 #endif /* TESTGETOPT */
174