2005-04-17 02:20:36 +04:00
/*
* linux / lib / cmdline . c
* Helper functions generally used for parsing kernel command line
* and module options .
*
* Code and copyrights come from init / main . c and arch / i386 / kernel / setup . c .
*
* This source code is licensed under the GNU General Public License ,
* Version 2. See the file COPYING for more details .
*
* GNU Indent formatting options for this file : - kr - i8 - npsl - pcs
*
*/
2011-11-17 06:29:17 +04:00
# include <linux/export.h>
2005-04-17 02:20:36 +04:00
# include <linux/kernel.h>
# include <linux/string.h>
2017-04-17 16:34:56 +03:00
# include <linux/ctype.h>
2005-04-17 02:20:36 +04:00
2006-12-07 07:37:11 +03:00
/*
* If a hyphen was found in get_option , this will handle the
* range of numbers , M - N . This will expand the range and insert
* the values [ M , M + 1 , . . . , N ] into the ints array in get_options .
*/
2017-06-24 01:08:49 +03:00
static int get_range ( char * * str , int * pint , int n )
2006-12-07 07:37:11 +03:00
{
int x , inc_counter , upper_range ;
( * str ) + + ;
upper_range = simple_strtol ( ( * str ) , NULL , 0 ) ;
inc_counter = upper_range - * pint ;
2017-06-24 01:08:49 +03:00
for ( x = * pint ; n & & x < upper_range ; x + + , n - - )
2006-12-07 07:37:11 +03:00
* pint + + = x ;
return inc_counter ;
}
2005-04-17 02:20:36 +04:00
/**
* get_option - Parse integer from an option string
* @ str : option string
* @ pint : ( output ) integer value parsed from @ str
*
* Read an int from an option string ; if available accept a subsequent
* comma as well .
*
* Return values :
2007-02-10 12:45:59 +03:00
* 0 - no int in string
* 1 - int found , no subsequent comma
* 2 - int found including a subsequent comma
* 3 - hyphen found to denote a range
2005-04-17 02:20:36 +04:00
*/
2014-01-24 03:54:35 +04:00
int get_option ( char * * str , int * pint )
2005-04-17 02:20:36 +04:00
{
char * cur = * str ;
if ( ! cur | | ! ( * cur ) )
return 0 ;
2014-01-24 03:54:35 +04:00
* pint = simple_strtol ( cur , str , 0 ) ;
2005-04-17 02:20:36 +04:00
if ( cur = = * str )
return 0 ;
if ( * * str = = ' , ' ) {
( * str ) + + ;
return 2 ;
}
2006-12-07 07:37:11 +03:00
if ( * * str = = ' - ' )
return 3 ;
2005-04-17 02:20:36 +04:00
return 1 ;
}
2014-01-24 03:54:36 +04:00
EXPORT_SYMBOL ( get_option ) ;
2005-04-17 02:20:36 +04:00
/**
* get_options - Parse a string into a list of integers
* @ str : String to be parsed
* @ nints : size of integer array
* @ ints : integer array
*
* This function parses a string containing a comma - separated
2006-12-07 07:37:11 +03:00
* list of integers , a hyphen - separated range of _positive_ integers ,
* or a combination of both . The parse halts when the array is
2005-04-17 02:20:36 +04:00
* full , or when no more numbers can be retrieved from the
* string .
*
* Return value is the character in the string which caused
* the parse to end ( typically a null terminator , if @ str is
* completely parseable ) .
*/
2014-01-24 03:54:35 +04:00
2005-04-17 02:20:36 +04:00
char * get_options ( const char * str , int nints , int * ints )
{
int res , i = 1 ;
while ( i < nints ) {
2014-01-24 03:54:35 +04:00
res = get_option ( ( char * * ) & str , ints + i ) ;
2005-04-17 02:20:36 +04:00
if ( res = = 0 )
break ;
2006-12-07 07:37:11 +03:00
if ( res = = 3 ) {
int range_nums ;
2017-06-24 01:08:49 +03:00
range_nums = get_range ( ( char * * ) & str , ints + i , nints - i ) ;
2006-12-07 07:37:11 +03:00
if ( range_nums < 0 )
break ;
/*
* Decrement the result by one to leave out the
* last number in the range . The next iteration
* will handle the upper number in the range
*/
i + = ( range_nums - 1 ) ;
}
2005-04-17 02:20:36 +04:00
i + + ;
if ( res = = 1 )
break ;
}
ints [ 0 ] = i - 1 ;
return ( char * ) str ;
}
2014-01-24 03:54:36 +04:00
EXPORT_SYMBOL ( get_options ) ;
2005-04-17 02:20:36 +04:00
/**
* memparse - parse a string with mem suffixes into a number
* @ ptr : Where parse begins
2008-07-25 12:45:31 +04:00
* @ retptr : ( output ) Optional pointer to next char after parse completes
2005-04-17 02:20:36 +04:00
*
* Parses a string into a number . The number stored at @ ptr is
2014-08-07 03:09:29 +04:00
* potentially suffixed with K , M , G , T , P , E .
2005-04-17 02:20:36 +04:00
*/
2008-07-25 03:27:46 +04:00
unsigned long long memparse ( const char * ptr , char * * retptr )
2005-04-17 02:20:36 +04:00
{
2008-07-25 12:45:31 +04:00
char * endptr ; /* local pointer to end of parsed string */
2005-04-17 02:20:36 +04:00
2008-07-25 12:45:31 +04:00
unsigned long long ret = simple_strtoull ( ptr , & endptr , 0 ) ;
switch ( * endptr ) {
2014-08-07 03:09:29 +04:00
case ' E ' :
case ' e ' :
ret < < = 10 ;
case ' P ' :
case ' p ' :
ret < < = 10 ;
case ' T ' :
case ' t ' :
ret < < = 10 ;
2005-04-17 02:20:36 +04:00
case ' G ' :
case ' g ' :
ret < < = 10 ;
case ' M ' :
case ' m ' :
ret < < = 10 ;
case ' K ' :
case ' k ' :
ret < < = 10 ;
2008-07-25 12:45:31 +04:00
endptr + + ;
2005-04-17 02:20:36 +04:00
default :
break ;
}
2008-07-25 12:45:31 +04:00
if ( retptr )
* retptr = endptr ;
2005-04-17 02:20:36 +04:00
return ret ;
}
EXPORT_SYMBOL ( memparse ) ;
2014-08-14 13:15:27 +04:00
/**
* parse_option_str - Parse a string and check an option is set or not
* @ str : String to be parsed
* @ option : option name
*
* This function parses a string containing a comma - separated list of
* strings like a = b , c .
*
* Return true if there ' s such option in the string , or return false .
*/
bool parse_option_str ( const char * str , const char * option )
{
while ( * str ) {
if ( ! strncmp ( str , option , strlen ( option ) ) ) {
str + = strlen ( option ) ;
if ( ! * str | | * str = = ' , ' )
return true ;
}
while ( * str & & * str ! = ' , ' )
str + + ;
if ( * str = = ' , ' )
str + + ;
}
return false ;
}
2017-04-17 16:34:56 +03:00
/*
* Parse a string to get a param value pair .
* You can use " around spaces, but can't escape " .
* Hyphens and underscores equivalent in parameter names .
*/
char * next_arg ( char * args , char * * param , char * * val )
{
unsigned int i , equals = 0 ;
int in_quote = 0 , quoted = 0 ;
char * next ;
if ( * args = = ' " ' ) {
args + + ;
in_quote = 1 ;
quoted = 1 ;
}
for ( i = 0 ; args [ i ] ; i + + ) {
if ( isspace ( args [ i ] ) & & ! in_quote )
break ;
if ( equals = = 0 ) {
if ( args [ i ] = = ' = ' )
equals = i ;
}
if ( args [ i ] = = ' " ' )
in_quote = ! in_quote ;
}
* param = args ;
if ( ! equals )
* val = NULL ;
else {
args [ equals ] = ' \0 ' ;
* val = args + equals + 1 ;
/* Don't include quotes in value. */
if ( * * val = = ' " ' ) {
( * val ) + + ;
if ( args [ i - 1 ] = = ' " ' )
args [ i - 1 ] = ' \0 ' ;
}
}
if ( quoted & & args [ i - 1 ] = = ' " ' )
args [ i - 1 ] = ' \0 ' ;
if ( args [ i ] ) {
args [ i ] = ' \0 ' ;
next = args + i + 1 ;
} else
next = args + i ;
/* Chew up trailing spaces. */
return skip_spaces ( next ) ;
//return next;
}