1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "getopt.h"
26 #include "strings.h"
27
28 #if 0
29 static void PrintArgs(int argc, char** argv)
30 {
31 int i;
32
33 printf("==== PrintArgs()\n");
34 printf("ARGC[%d]\n", argc);
35
36 for (i = 0; i < argc; i++)
37 {
38 printf("ARGV[%s]\n", argv[i]);
39 }
40
41 printf("\n");
42 }
43 mike 1.1 #endif
44
45 int GetOpt(
46 int* argc,
47 const char* argv[],
48 const char* opts[],
49 GetOptState* state)
50 {
51 int i;
52 int j;
53
54 /* Clear state */
55 state->opt[0] = '\0';
56 state->arg = NULL;
57 state->err[0] = '\0';
58
59 for (i = state->index; i < *argc; i++)
60 {
61 if (argv[i][0] != '-')
62 {
63 state->index++;
64 mike 1.1 continue;
65 }
66
67 /* Find option argv[i] */
68 for (j = 0; opts[j]; j++)
69 {
70 char opt[GETOPT_OPT_SIZE];
71 size_t n;
72 int hasArg;
73
74 /* Copy option name */
75 n = Strlcpy(opt, opts[j], sizeof(opt));
76
77 /* If option name too long */
78 if (n >= sizeof(opt))
79 {
80 Strlcpy(state->err, "bad parameter", sizeof(state->err));
81 return -1;
82 }
83
84 /* If option name zero-length */
85 mike 1.1 if (n == 0)
86 {
87 Strlcpy(state->err, "bad parameter", sizeof(state->err));
88 return -1;
89 }
90
91 /* If option has argument */
92 if (opt[n-1] == ':')
93 {
94 hasArg = 1;
95 opt[n-1] = '\0';
96 }
97 else
98 hasArg = 0;
99
100 /* Does argv[i] match this option? */
101 if (strcmp(argv[i], opt) == 0)
102 {
103 if (hasArg)
104 {
105 if (i + 1 == *argc)
106 mike 1.1 {
107 Strlcpy(state->err, "missing option argument: ",
108 sizeof(state->err));
109 Strlcat(state->err, opt, sizeof(state->err));
110 return -1;
111 }
112
113 Strlcpy(state->opt, argv[i], sizeof(state->opt));
114 state->arg = argv[i+1];
115 memmove((void*)&argv[i], (void*)&argv[i+2],
116 sizeof(char*) * ((*argc) - i - 1));
117 *argc -= 2;
118 return 0;
119 }
120 else
121 {
122 Strlcpy(state->opt, argv[i], sizeof(state->opt));
123 memmove((void*)&argv[i], (void*)&argv[i+1],
124 sizeof(char*) * ((*argc) - i));
125 *argc -= 1;
126 return 0;
127 mike 1.1 }
128 }
129 else if (hasArg &&
130 strncmp(argv[i], opt, n-1) == 0 && argv[i][n-1] == '=')
131 {
132 Strlcpy(state->opt, argv[i], sizeof(state->opt));
133 state->opt[n-1] = '\0';
134 state->arg = &argv[i][n];
135 memmove((void*)&argv[i], (void*)&argv[i+1],
136 sizeof(char*) * ((*argc) - i));
137 *argc -= 1;
138 return 0;
139 }
140 }
141
142 /* Unknown option */
143 Strlcpy(state->err, "unknown option: ", sizeof(state->err));
144 Strlcat(state->err, argv[i], sizeof(state->err));
145 return -1;
146 }
147
148 mike 1.1 /* Done */
149 return 1;
150 }
|