fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/drivers/options.c *
7 * Created: 2009-10-17 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2009-2011 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <config.h>
24
25#include <stdlib.h>
26#include <string.h>
27
28#include <drivers/options.h>
29
30
31static
32const char *drv_skip_option (const char *str)
33{
34 while (*str != 0) {
35 if (*str == ':') {
36 if (*(str + 1) == ':') {
37 str += 2;
38 }
39 else {
40 return (str + 1);
41 }
42 }
43 else {
44 str += 1;
45 }
46 }
47
48 return (NULL);
49}
50
51static
52const char *drv_skip_space (const char *str)
53{
54 while (1) {
55 if (*str == ' ') {
56 str += 1;
57 }
58 else if (*str == '\t') {
59 str += 1;
60 }
61 else {
62 return (str);
63 }
64 }
65}
66
67static
68const char *drv_get_option_value (const char *str, const char *name)
69{
70 str = drv_skip_space (str);
71
72 while (*name != 0) {
73 if (*str != *name) {
74 return (NULL);
75 }
76
77 str += 1;
78 name += 1;
79 }
80
81 str = drv_skip_space (str);
82
83 if (*str == '=') {
84 str = drv_skip_space (str + 1);
85
86 return (str);
87 }
88
89 return (NULL);
90}
91
92static
93char *drv_option_dup (const char *str)
94{
95 unsigned i, j, n;
96 char *ret;
97
98 n = 0;
99 while (str[n] != 0) {
100 if (str[n] == ':') {
101 if (str[n + 1] == ':') {
102 n += 2;
103 }
104 else {
105 break;
106 }
107 }
108 else {
109 n += 1;
110 }
111 }
112
113 while (n > 0) {
114 if (str[n - 1] == ' ') {
115 n -= 1;
116 }
117 else if (str[n - 1] == '\t') {
118 n -= 1;
119 }
120 else {
121 break;
122 }
123 }
124
125 ret = malloc (n + 1);
126 if (ret == NULL) {
127 return (NULL);
128 }
129
130 i = 0;
131 j = 0;
132
133 while (i < n) {
134 if ((str[i] == ':') && (str[i + 1] == ':')) {
135 ret[j] = ':';
136 i += 2;
137 }
138 else {
139 ret[j] = str[i];
140 i += 1;
141 }
142
143 j += 1;
144 }
145
146 ret[j] = 0;
147
148 return (ret);
149}
150
151char *drv_get_option (const char *str, const char *name)
152{
153 const char *val;
154
155 while (str != NULL) {
156 val = drv_get_option_value (str, name);
157
158 if (val != NULL) {
159 return (drv_option_dup (val));
160 }
161
162 str = drv_skip_option (str);
163 }
164
165 return (NULL);
166}
167
168int drv_get_option_bool (const char *str, const char *name, int def)
169{
170 int r;
171 char *s;
172
173 s = drv_get_option (str, name);
174
175 if (s == NULL) {
176 return (def);
177 }
178
179 r = def;
180
181 if (strcmp (s, "1") == 0) {
182 r = 1;
183 }
184 else if (strcmp (s, "true") == 0) {
185 r = 1;
186 }
187 else if (strcmp (s, "yes") == 0) {
188 r = 1;
189 }
190 else if (strcmp (s, "0") == 0) {
191 r = 0;
192 }
193 else if (strcmp (s, "false") == 0) {
194 r = 0;
195 }
196 else if (strcmp (s, "no") == 0) {
197 r = 0;
198 }
199
200 free (s);
201
202 return (r);
203}
204
205unsigned long drv_get_option_uint (const char *str, const char *name, unsigned long def)
206{
207 unsigned long val;
208 char *end;
209 char *s;
210
211 s = drv_get_option (str, name);
212
213 if (s == NULL) {
214 return (def);
215 }
216
217 val = strtoul (s, &end, 0);
218
219 if ((end != NULL) && (*end != 0)) {
220 free (s);
221 return (def);
222 }
223
224 free (s);
225
226 return (val);
227}
228
229long drv_get_option_sint (const char *str, const char *name, long def)
230{
231 unsigned long val;
232 char *end;
233 char *s;
234
235 s = drv_get_option (str, name);
236
237 if (s == NULL) {
238 return (def);
239 }
240
241 val = strtol (s, &end, 0);
242
243 if ((end != NULL) && (*end != 0)) {
244 free (s);
245 return (def);
246 }
247
248 free (s);
249
250 return (val);
251}