Skip to content
Snippets Groups Projects
cmdline.c 3.65 KiB
Newer Older
  • Learn to ignore specific revisions
  • Linus Torvalds's avatar
    Linus Torvalds committed
    /*
     * 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
     *
     */
    
    
    #include <linux/export.h>
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    #include <linux/kernel.h>
    #include <linux/string.h>
    
    
    /*
     *	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.
     */
    
    static int get_range(char **str, int *pint)
    {
    	int x, inc_counter, upper_range;
    
    	(*str)++;
    	upper_range = simple_strtol((*str), NULL, 0);
    	inc_counter = upper_range - *pint;
    	for (x = *pint; x < upper_range; x++)
    		*pint++ = x;
    	return inc_counter;
    }
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    /**
     *	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:
    
     *	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
    
    Linus Torvalds's avatar
    Linus Torvalds committed
     */
    
    int get_option (char **str, int *pint)
    {
    	char *cur = *str;
    
    	if (!cur || !(*cur))
    		return 0;
    	*pint = simple_strtol (cur, str, 0);
    	if (cur == *str)
    		return 0;
    	if (**str == ',') {
    		(*str)++;
    		return 2;
    	}
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    	return 1;
    }
    
    /**
     *	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
    
     *	list of integers, a hyphen-separated range of _positive_ integers,
     *	or a combination of both.  The parse halts when the array is
    
    Linus Torvalds's avatar
    Linus Torvalds committed
     *	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).
     */
     
    char *get_options(const char *str, int nints, int *ints)
    {
    	int res, i = 1;
    
    	while (i < nints) {
    		res = get_option ((char **)&str, ints + i);
    		if (res == 0)
    			break;
    
    		if (res == 3) {
    			int range_nums;
    			range_nums = get_range((char **)&str, ints + i);
    			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);
    		}
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    		i++;
    		if (res == 1)
    			break;
    	}
    	ints[0] = i - 1;
    	return (char *)str;
    }
    
    /**
     *	memparse - parse a string with mem suffixes into a number
     *	@ptr: Where parse begins
    
     *	@retptr: (output) Optional pointer to next char after parse completes
    
    Linus Torvalds's avatar
    Linus Torvalds committed
     *
     *	Parses a string into a number.  The number stored at @ptr is
     *	potentially suffixed with %K (for kilobytes, or 1024 bytes),
     *	%M (for megabytes, or 1048576 bytes), or %G (for gigabytes, or
     *	1073741824).  If the number is suffixed with K, M, or G, then
     *	the return value is the number multiplied by one kilobyte, one
     *	megabyte, or one gigabyte, respectively.
     */
    
    
    unsigned long long memparse(const char *ptr, char **retptr)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    
    	char *endptr;	/* local pointer to end of parsed string */
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    
    	unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
    
    	switch (*endptr) {
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	case 'G':
    	case 'g':
    		ret <<= 10;
    	case 'M':
    	case 'm':
    		ret <<= 10;
    	case 'K':
    	case 'k':
    		ret <<= 10;
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	default:
    		break;
    	}
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return ret;
    }
    
    
    EXPORT_SYMBOL(memparse);
    EXPORT_SYMBOL(get_option);
    EXPORT_SYMBOL(get_options);