0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/export.h>
0013 #include <linux/kernel.h>
0014 #include <linux/string.h>
0015 #include <linux/ctype.h>
0016
0017
0018
0019
0020
0021
0022
0023 static int get_range(char **str, int *pint, int n)
0024 {
0025 int x, inc_counter, upper_range;
0026
0027 (*str)++;
0028 upper_range = simple_strtol((*str), NULL, 0);
0029 inc_counter = upper_range - *pint;
0030 for (x = *pint; n && x < upper_range; x++, n--)
0031 *pint++ = x;
0032 return inc_counter;
0033 }
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 int get_option(char **str, int *pint)
0057 {
0058 char *cur = *str;
0059 int value;
0060
0061 if (!cur || !(*cur))
0062 return 0;
0063 if (*cur == '-')
0064 value = -simple_strtoull(++cur, str, 0);
0065 else
0066 value = simple_strtoull(cur, str, 0);
0067 if (pint)
0068 *pint = value;
0069 if (cur == *str)
0070 return 0;
0071 if (**str == ',') {
0072 (*str)++;
0073 return 2;
0074 }
0075 if (**str == '-')
0076 return 3;
0077
0078 return 1;
0079 }
0080 EXPORT_SYMBOL(get_option);
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 char *get_options(const char *str, int nints, int *ints)
0108 {
0109 bool validate = (nints == 0);
0110 int res, i = 1;
0111
0112 while (i < nints || validate) {
0113 int *pint = validate ? ints : ints + i;
0114
0115 res = get_option((char **)&str, pint);
0116 if (res == 0)
0117 break;
0118 if (res == 3) {
0119 int n = validate ? 0 : nints - i;
0120 int range_nums;
0121
0122 range_nums = get_range((char **)&str, pint, n);
0123 if (range_nums < 0)
0124 break;
0125
0126
0127
0128
0129
0130 i += (range_nums - 1);
0131 }
0132 i++;
0133 if (res == 1)
0134 break;
0135 }
0136 ints[0] = i - 1;
0137 return (char *)str;
0138 }
0139 EXPORT_SYMBOL(get_options);
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 unsigned long long memparse(const char *ptr, char **retptr)
0151 {
0152 char *endptr;
0153
0154 unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
0155
0156 switch (*endptr) {
0157 case 'E':
0158 case 'e':
0159 ret <<= 10;
0160 fallthrough;
0161 case 'P':
0162 case 'p':
0163 ret <<= 10;
0164 fallthrough;
0165 case 'T':
0166 case 't':
0167 ret <<= 10;
0168 fallthrough;
0169 case 'G':
0170 case 'g':
0171 ret <<= 10;
0172 fallthrough;
0173 case 'M':
0174 case 'm':
0175 ret <<= 10;
0176 fallthrough;
0177 case 'K':
0178 case 'k':
0179 ret <<= 10;
0180 endptr++;
0181 fallthrough;
0182 default:
0183 break;
0184 }
0185
0186 if (retptr)
0187 *retptr = endptr;
0188
0189 return ret;
0190 }
0191 EXPORT_SYMBOL(memparse);
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 bool parse_option_str(const char *str, const char *option)
0204 {
0205 while (*str) {
0206 if (!strncmp(str, option, strlen(option))) {
0207 str += strlen(option);
0208 if (!*str || *str == ',')
0209 return true;
0210 }
0211
0212 while (*str && *str != ',')
0213 str++;
0214
0215 if (*str == ',')
0216 str++;
0217 }
0218
0219 return false;
0220 }
0221
0222
0223
0224
0225
0226
0227 char *next_arg(char *args, char **param, char **val)
0228 {
0229 unsigned int i, equals = 0;
0230 int in_quote = 0, quoted = 0;
0231
0232 if (*args == '"') {
0233 args++;
0234 in_quote = 1;
0235 quoted = 1;
0236 }
0237
0238 for (i = 0; args[i]; i++) {
0239 if (isspace(args[i]) && !in_quote)
0240 break;
0241 if (equals == 0) {
0242 if (args[i] == '=')
0243 equals = i;
0244 }
0245 if (args[i] == '"')
0246 in_quote = !in_quote;
0247 }
0248
0249 *param = args;
0250 if (!equals)
0251 *val = NULL;
0252 else {
0253 args[equals] = '\0';
0254 *val = args + equals + 1;
0255
0256
0257 if (**val == '"') {
0258 (*val)++;
0259 if (args[i-1] == '"')
0260 args[i-1] = '\0';
0261 }
0262 }
0263 if (quoted && args[i-1] == '"')
0264 args[i-1] = '\0';
0265
0266 if (args[i]) {
0267 args[i] = '\0';
0268 args += i + 1;
0269 } else
0270 args += i;
0271
0272
0273 return skip_spaces(args);
0274 }
0275 EXPORT_SYMBOL(next_arg);