VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   35 Branches   59 Tags
40b0b3f8fb2d8 (Thomas Gleixner    2019-06-03 07:44:46 +0200   1) // SPDX-License-Identifier: GPL-2.0-only
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   2) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   3)  * lib/parser.c - simple parser for mount, etc. options.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   4)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   5) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   6) #include <linux/ctype.h>
8bc3bcc93a2b4 (Paul Gortmaker     2011-11-16 21:29:17 -0500   7) #include <linux/types.h>
8bc3bcc93a2b4 (Paul Gortmaker     2011-11-16 21:29:17 -0500   8) #include <linux/export.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   9) #include <linux/parser.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  10) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  11) #include <linux/string.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  12) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  13) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800  14)  * match_one - Determines if a string matches a simple pattern
25985edcedea6 (Lucas De Marchi    2011-03-30 22:57:33 -0300  15)  * @s: the string to examine for presence of the pattern
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  16)  * @p: the string containing the pattern
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  17)  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  18)  * locations.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  19)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  20)  * Description: Determines if the pattern @p is present in string @s. Can only
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  21)  * match extremely simple token=arg style patterns. If the pattern is found,
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  22)  * the location(s) of the arguments will be returned in the @args array.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  23)  */
ef4533f8af7a8 (David Howells      2007-05-03 03:10:39 -0700  24) static int match_one(char *s, const char *p, substring_t args[])
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  25) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  26) 	char *meta;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  27) 	int argc = 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  28) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  29) 	if (!p)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  30) 		return 1;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  31) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  32) 	while(1) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  33) 		int len = -1;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  34) 		meta = strchr(p, '%');
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  35) 		if (!meta)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  36) 			return strcmp(p, s) == 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  37) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  38) 		if (strncmp(p, s, meta-p))
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  39) 			return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  40) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  41) 		s += meta - p;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  42) 		p = meta + 1;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  43) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  44) 		if (isdigit(*p))
ef4533f8af7a8 (David Howells      2007-05-03 03:10:39 -0700  45) 			len = simple_strtoul(p, (char **) &p, 10);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  46) 		else if (*p == '%') {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  47) 			if (*s++ != '%')
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  48) 				return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  49) 			p++;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  50) 			continue;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  51) 		}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  52) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  53) 		if (argc >= MAX_OPT_ARGS)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  54) 			return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  55) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  56) 		args[argc].from = s;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  57) 		switch (*p++) {
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  58) 		case 's': {
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  59) 			size_t str_len = strlen(s);
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  60) 
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  61) 			if (str_len == 0)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  62) 				return 0;
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  63) 			if (len == -1 || len > str_len)
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  64) 				len = str_len;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  65) 			args[argc].to = s + len;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  66) 			break;
b5f54b07c06f6 (André Goddard Rosa 2009-12-14 18:01:08 -0800  67) 		}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  68) 		case 'd':
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  69) 			simple_strtol(s, &args[argc].to, 0);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  70) 			goto num;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  71) 		case 'u':
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  72) 			simple_strtoul(s, &args[argc].to, 0);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  73) 			goto num;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  74) 		case 'o':
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  75) 			simple_strtoul(s, &args[argc].to, 8);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  76) 			goto num;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  77) 		case 'x':
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  78) 			simple_strtoul(s, &args[argc].to, 16);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  79) 		num:
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  80) 			if (args[argc].to == args[argc].from)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  81) 				return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  82) 			break;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  83) 		default:
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  84) 			return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  85) 		}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  86) 		s = args[argc].to;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  87) 		argc++;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  88) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  89) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  90) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  91) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800  92)  * match_token - Find a token (and optional args) in a string
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  93)  * @s: the string to examine for token/argument pairs
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  94)  * @table: match_table_t describing the set of allowed option tokens and the
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  95)  * arguments that may be associated with them. Must be terminated with a
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  96)  * &struct match_token whose pattern is set to the NULL pointer.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  97)  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  98)  * locations.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  99)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 100)  * Description: Detects which if any of a set of token strings has been passed
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 101)  * to it. Tokens can include up to %MAX_OPT_ARGS instances of basic c-style
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 102)  * format identifiers which will be taken into account when matching the
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 103)  * tokens, and whose locations will be returned in the @args array.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 104)  */
a447c0932445f (Steven Whitehouse  2008-10-13 10:46:57 +0100 105) int match_token(char *s, const match_table_t table, substring_t args[])
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 106) {
ef4533f8af7a8 (David Howells      2007-05-03 03:10:39 -0700 107) 	const struct match_token *p;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 108) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 109) 	for (p = table; !match_one(s, p->pattern, args) ; p++)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 110) 		;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 111) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 112) 	return p->token;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 113) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 114) EXPORT_SYMBOL(match_token);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 115) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 116) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 117)  * match_number - scan a number in the given base from a substring_t
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 118)  * @s: substring to be scanned
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 119)  * @result: resulting integer on success
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 120)  * @base: base to use when converting string
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 121)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 122)  * Description: Given a &substring_t and a base, attempts to parse the substring
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 123)  * as a number in that base.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 124)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 125)  * Return: On success, sets @result to the integer represented by the
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 126)  * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 127)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 128) static int match_number(substring_t *s, int *result, int base)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 129) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 130) 	char *endp;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 131) 	char *buf;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 132) 	int ret;
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 133) 	long val;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 134) 
36c8d1e7a27f9 (Eric Biggers       2018-10-30 15:05:30 -0700 135) 	buf = match_strdup(s);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 136) 	if (!buf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 137) 		return -ENOMEM;
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 138) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 139) 	ret = 0;
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 140) 	val = simple_strtol(buf, &endp, base);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 141) 	if (endp == buf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 142) 		ret = -EINVAL;
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 143) 	else if (val < (long)INT_MIN || val > (long)INT_MAX)
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 144) 		ret = -ERANGE;
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 145) 	else
77dd3b0bd17a0 (Alex Elder         2012-10-04 17:13:16 -0700 146) 		*result = (int) val;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 147) 	kfree(buf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 148) 	return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 149) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 150) 
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 151) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 152)  * match_u64int - scan a number in the given base from a substring_t
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 153)  * @s: substring to be scanned
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 154)  * @result: resulting u64 on success
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 155)  * @base: base to use when converting string
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 156)  *
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 157)  * Description: Given a &substring_t and a base, attempts to parse the substring
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 158)  * as a number in that base.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 159)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 160)  * Return: On success, sets @result to the integer represented by the
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 161)  * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 162)  */
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 163) static int match_u64int(substring_t *s, u64 *result, int base)
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 164) {
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 165) 	char *buf;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 166) 	int ret;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 167) 	u64 val;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 168) 
4ed97b3c6d088 (Eric Biggers       2018-10-30 15:05:26 -0700 169) 	buf = match_strdup(s);
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 170) 	if (!buf)
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 171) 		return -ENOMEM;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 172) 
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 173) 	ret = kstrtoull(buf, base, &val);
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 174) 	if (!ret)
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 175) 		*result = val;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 176) 	kfree(buf);
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 177) 	return ret;
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 178) }
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 179) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 180) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 181)  * match_int - scan a decimal representation of an integer from a substring_t
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 182)  * @s: substring_t to be scanned
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 183)  * @result: resulting integer on success
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 184)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 185)  * Description: Attempts to parse the &substring_t @s as a decimal integer.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 186)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 187)  * Return: On success, sets @result to the integer represented by the string
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 188)  * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 189)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 190) int match_int(substring_t *s, int *result)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 191) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 192) 	return match_number(s, result, 0);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 193) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 194) EXPORT_SYMBOL(match_int);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 195) 
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 196) /**
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 197)  * match_uint - scan a decimal representation of an integer from a substring_t
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 198)  * @s: substring_t to be scanned
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 199)  * @result: resulting integer on success
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 200)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 201)  * Description: Attempts to parse the &substring_t @s as a decimal integer.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 202)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 203)  * Return: On success, sets @result to the integer represented by the string
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 204)  * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 205)  */
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 206) int match_uint(substring_t *s, unsigned int *result)
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 207) {
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 208) 	int err = -ENOMEM;
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 209) 	char *buf = match_strdup(s);
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 210) 
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 211) 	if (buf) {
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 212) 		err = kstrtouint(buf, 10, result);
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 213) 		kfree(buf);
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 214) 	}
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 215) 	return err;
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 216) }
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 217) EXPORT_SYMBOL(match_uint);
01531ac354051 (BingJing Chang     2021-01-29 12:52:42 +0800 218) 
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 219) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 220)  * match_u64 - scan a decimal representation of a u64 from
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 221)  *                  a substring_t
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 222)  * @s: substring_t to be scanned
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 223)  * @result: resulting unsigned long long on success
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 224)  *
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 225)  * Description: Attempts to parse the &substring_t @s as a long decimal
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 226)  * integer.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 227)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 228)  * Return: On success, sets @result to the integer represented by the string
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 229)  * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 230)  */
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 231) int match_u64(substring_t *s, u64 *result)
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 232) {
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 233) 	return match_u64int(s, result, 0);
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 234) }
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 235) EXPORT_SYMBOL(match_u64);
a317178e36b52 (James Smart        2016-10-21 23:51:54 +0300 236) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 237) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 238)  * match_octal - scan an octal representation of an integer from a substring_t
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 239)  * @s: substring_t to be scanned
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 240)  * @result: resulting integer on success
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 241)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 242)  * Description: Attempts to parse the &substring_t @s as an octal integer.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 243)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 244)  * Return: On success, sets @result to the integer represented by the string
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 245)  * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 246)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 247) int match_octal(substring_t *s, int *result)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 248) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 249) 	return match_number(s, result, 8);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 250) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 251) EXPORT_SYMBOL(match_octal);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 252) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 253) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 254)  * match_hex - scan a hex representation of an integer from a substring_t
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 255)  * @s: substring_t to be scanned
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 256)  * @result: resulting integer on success
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 257)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 258)  * Description: Attempts to parse the &substring_t @s as a hexadecimal integer.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 259)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 260)  * Return: On success, sets @result to the integer represented by the string
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 261)  * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 262)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 263) int match_hex(substring_t *s, int *result)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 264) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 265) 	return match_number(s, result, 16);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 266) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 267) EXPORT_SYMBOL(match_hex);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 268) 
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 269) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 270)  * match_wildcard - parse if a string matches given wildcard pattern
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 271)  * @pattern: wildcard pattern
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 272)  * @str: the string to be parsed
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 273)  *
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 274)  * Description: Parse the string @str to check if matches wildcard
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 275)  * pattern @pattern. The pattern may contain two types of wildcards:
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 276)  *   '*' - matches zero or more characters
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 277)  *   '?' - matches one character
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 278)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 279)  * Return: If the @str matches the @pattern, return true, else return false.
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 280)  */
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 281) bool match_wildcard(const char *pattern, const char *str)
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 282) {
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 283) 	const char *s = str;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 284) 	const char *p = pattern;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 285) 	bool star = false;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 286) 
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 287) 	while (*s) {
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 288) 		switch (*p) {
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 289) 		case '?':
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 290) 			s++;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 291) 			p++;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 292) 			break;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 293) 		case '*':
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 294) 			star = true;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 295) 			str = s;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 296) 			if (!*++p)
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 297) 				return true;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 298) 			pattern = p;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 299) 			break;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 300) 		default:
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 301) 			if (*s == *p) {
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 302) 				s++;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 303) 				p++;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 304) 			} else {
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 305) 				if (!star)
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 306) 					return false;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 307) 				str++;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 308) 				s = str;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 309) 				p = pattern;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 310) 			}
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 311) 			break;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 312) 		}
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 313) 	}
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 314) 
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 315) 	if (*p == '*')
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 316) 		++p;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 317) 	return !*p;
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 318) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 319) EXPORT_SYMBOL(match_wildcard);
aace05097a0fd (Changbin Du        2014-01-23 15:54:12 -0800 320) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 321) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 322)  * match_strlcpy - Copy the characters from a substring_t to a sized buffer
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 323)  * @dest: where to copy to
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 324)  * @src: &substring_t to copy
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 325)  * @size: size of destination buffer
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 326)  *
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 327)  * Description: Copy the characters in &substring_t @src to the
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 328)  * c-style string @dest.  Copy no more than @size - 1 characters, plus
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 329)  * the terminating NUL.
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 330)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 331)  * Return: length of @src.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 332)  */
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 333) size_t match_strlcpy(char *dest, const substring_t *src, size_t size)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 334) {
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 335) 	size_t ret = src->to - src->from;
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 336) 
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 337) 	if (size) {
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 338) 		size_t len = ret >= size ? size - 1 : ret;
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 339) 		memcpy(dest, src->from, len);
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 340) 		dest[len] = '\0';
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 341) 	}
b32a09db4fb9a (Markus Armbruster  2008-02-26 09:57:11 -0600 342) 	return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 343) }
a3d2cca43cd31 (Andrew Morton      2014-01-23 15:54:13 -0800 344) EXPORT_SYMBOL(match_strlcpy);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 345) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 346) /**
b9bffa10b267b (BingJing Chang     2021-01-29 13:00:37 +0800 347)  * match_strdup - allocate a new string with the contents of a substring_t
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 348)  * @s: &substring_t to copy
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 349)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 350)  * Description: Allocates and returns a string filled with the contents of
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 351)  * the &substring_t @s. The caller is responsible for freeing the returned
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 352)  * string with kfree().
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 353)  *
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 354)  * Return: the address of the newly allocated NUL-terminated string or
edd9334c8dfed (Randy Dunlap       2021-05-06 18:03:49 -0700 355)  * %NULL on error.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 356)  */
ef4533f8af7a8 (David Howells      2007-05-03 03:10:39 -0700 357) char *match_strdup(const substring_t *s)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 358) {
30f7bc99a2a97 (Eric Biggers       2018-10-30 15:05:22 -0700 359) 	return kmemdup_nul(s->from, s->to - s->from, GFP_KERNEL);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 360) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 361) EXPORT_SYMBOL(match_strdup);