[PATCH] Split config name parse functions into parse.c
[fio.git] / parse.c
CommitLineData
cb2c86fd
JA
1/*
2 * This file contains the ini and command liner parser main.
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <ctype.h>
8#include <string.h>
9#include <errno.h>
10#include <limits.h>
11
12#include "parse.h"
13
14static unsigned long get_mult_time(char c)
15{
16 switch (c) {
17 case 'm':
18 case 'M':
19 return 60;
20 case 'h':
21 case 'H':
22 return 60 * 60;
23 case 'd':
24 case 'D':
25 return 24 * 60 * 60;
26 default:
27 return 1;
28 }
29}
30
31static unsigned long get_mult_bytes(char c)
32{
33 switch (c) {
34 case 'k':
35 case 'K':
36 return 1024;
37 case 'm':
38 case 'M':
39 return 1024 * 1024;
40 case 'g':
41 case 'G':
42 return 1024 * 1024 * 1024;
43 default:
44 return 1;
45 }
46}
47
48/*
49 * convert string after '=' into decimal value, noting any size suffix
50 */
51static int str_to_decimal(char *p, unsigned long long *val, int kilo)
52{
53 char *str;
54 int len;
55
56 str = strchr(p, '=');
57 if (!str)
58 return 1;
59
60 str++;
61 len = strlen(str);
62
63 *val = strtoul(str, NULL, 10);
64 if (*val == ULONG_MAX && errno == ERANGE)
65 return 1;
66
67 if (kilo)
68 *val *= get_mult_bytes(str[len - 1]);
69 else
70 *val *= get_mult_time(str[len - 1]);
71 return 0;
72}
73
74int check_str_bytes(char *p, char *name, unsigned long long *val)
75{
76 if (strncmp(p, name, strlen(name) - 1))
77 return 1;
78
79 return str_to_decimal(p, val, 1);
80}
81
82int check_str_time(char *p, char *name, unsigned long long *val)
83{
84 if (strncmp(p, name, strlen(name) - 1))
85 return 1;
86
87 return str_to_decimal(p, val, 0);
88}
89
90void strip_blank_front(char **p)
91{
92 char *s = *p;
93
94 while (isspace(*s))
95 s++;
96}
97
98void strip_blank_end(char *p)
99{
100 char *s = p + strlen(p) - 1;
101
102 while (isspace(*s) || iscntrl(*s))
103 s--;
104
105 *(s + 1) = '\0';
106}
107
108int check_str(char *p, char *name, str_cb_fn *cb, void *data)
109{
110 char *s;
111
112 if (strncmp(p, name, strlen(name)))
113 return 1;
114
115 s = strstr(p, name);
116 if (!s)
117 return 1;
118
119 s = strchr(s, '=');
120 if (!s)
121 return 1;
122
123 s++;
124 strip_blank_front(&s);
125 return cb(data, s);
126}
127
128int check_strstore(char *p, char *name, char *dest)
129{
130 char *s;
131
132 if (strncmp(p, name, strlen(name)))
133 return 1;
134
135 s = strstr(p, name);
136 if (!s)
137 return 1;
138
139 s = strchr(p, '=');
140 if (!s)
141 return 1;
142
143 s++;
144 strip_blank_front(&s);
145
146 strcpy(dest, s);
147 return 0;
148}
149
150static int __check_range_bytes(char *str, unsigned long *val)
151{
152 char suffix;
153
154 if (sscanf(str, "%lu%c", val, &suffix) == 2) {
155 *val *= get_mult_bytes(suffix);
156 return 0;
157 }
158
159 if (sscanf(str, "%lu", val) == 1)
160 return 0;
161
162 return 1;
163}
164
165int check_range_bytes(char *p, char *name, unsigned long *s, unsigned long *e)
166{
167 char option[128];
168 char *str, *p1, *p2;
169
170 if (strncmp(p, name, strlen(name)))
171 return 1;
172
173 strcpy(option, p);
174 p = option;
175
176 str = strstr(p, name);
177 if (!str)
178 return 1;
179
180 p += strlen(name);
181
182 str = strchr(p, '=');
183 if (!str)
184 return 1;
185
186 /*
187 * 'p' now holds whatever is after the '=' sign
188 */
189 p1 = str + 1;
190
191 /*
192 * terminate p1 at the '-' sign
193 */
194 p = strchr(p1, '-');
195 if (!p)
196 return 1;
197
198 p2 = p + 1;
199 *p = '\0';
200
201 if (!__check_range_bytes(p1, s) && !__check_range_bytes(p2, e))
202 return 0;
203
204 return 1;
205}
206
207int check_int(char *p, char *name, unsigned int *val)
208{
209 char *str;
210
211 if (strncmp(p, name, strlen(name)))
212 return 1;
213
214 str = strstr(p, name);
215 if (!str)
216 return 1;
217
218 str = strchr(p, '=');
219 if (!str)
220 return 1;
221
222 str++;
223
224 if (sscanf(str, "%u", val) == 1)
225 return 0;
226
227 return 1;
228}
229
230int check_strset(char *p, char *name)
231{
232 return strncmp(p, name, strlen(name));
233}
234