cmdline.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * linux/lib/cmdline.c
  3. * Helper functions generally used for parsing kernel command line
  4. * and module options.
  5. *
  6. * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c.
  7. *
  8. * This source code is licensed under the GNU General Public License,
  9. * Version 2. See the file COPYING for more details.
  10. *
  11. * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs
  12. *
  13. */
  14. #include <linux/export.h>
  15. #include <linux/kernel.h>
  16. #include <linux/string.h>
  17. #include <linux/ctype.h>
  18. /*
  19. * If a hyphen was found in get_option, this will handle the
  20. * range of numbers, M-N. This will expand the range and insert
  21. * the values[M, M+1, ..., N] into the ints array in get_options.
  22. */
  23. static int get_range(char **str, int *pint, int n)
  24. {
  25. int x, inc_counter, upper_range;
  26. (*str)++;
  27. upper_range = simple_strtol((*str), NULL, 0);
  28. inc_counter = upper_range - *pint;
  29. for (x = *pint; n && x < upper_range; x++, n--)
  30. *pint++ = x;
  31. return inc_counter;
  32. }
  33. /**
  34. * get_option - Parse integer from an option string
  35. * @str: option string
  36. * @pint: (output) integer value parsed from @str
  37. *
  38. * Read an int from an option string; if available accept a subsequent
  39. * comma as well.
  40. *
  41. * Return values:
  42. * 0 - no int in string
  43. * 1 - int found, no subsequent comma
  44. * 2 - int found including a subsequent comma
  45. * 3 - hyphen found to denote a range
  46. */
  47. int get_option(char **str, int *pint)
  48. {
  49. char *cur = *str;
  50. if (!cur || !(*cur))
  51. return 0;
  52. *pint = simple_strtol(cur, str, 0);
  53. if (cur == *str)
  54. return 0;
  55. if (**str == ',') {
  56. (*str)++;
  57. return 2;
  58. }
  59. if (**str == '-')
  60. return 3;
  61. return 1;
  62. }
  63. EXPORT_SYMBOL(get_option);
  64. /**
  65. * get_options - Parse a string into a list of integers
  66. * @str: String to be parsed
  67. * @nints: size of integer array
  68. * @ints: integer array
  69. *
  70. * This function parses a string containing a comma-separated
  71. * list of integers, a hyphen-separated range of _positive_ integers,
  72. * or a combination of both. The parse halts when the array is
  73. * full, or when no more numbers can be retrieved from the
  74. * string.
  75. *
  76. * Return value is the character in the string which caused
  77. * the parse to end (typically a null terminator, if @str is
  78. * completely parseable).
  79. */
  80. char *get_options(const char *str, int nints, int *ints)
  81. {
  82. int res, i = 1;
  83. while (i < nints) {
  84. res = get_option((char **)&str, ints + i);
  85. if (res == 0)
  86. break;
  87. if (res == 3) {
  88. int range_nums;
  89. range_nums = get_range((char **)&str, ints + i, nints - i);
  90. if (range_nums < 0)
  91. break;
  92. /*
  93. * Decrement the result by one to leave out the
  94. * last number in the range. The next iteration
  95. * will handle the upper number in the range
  96. */
  97. i += (range_nums - 1);
  98. }
  99. i++;
  100. if (res == 1)
  101. break;
  102. }
  103. ints[0] = i - 1;
  104. return (char *)str;
  105. }
  106. EXPORT_SYMBOL(get_options);
  107. /**
  108. * memparse - parse a string with mem suffixes into a number
  109. * @ptr: Where parse begins
  110. * @retptr: (output) Optional pointer to next char after parse completes
  111. *
  112. * Parses a string into a number. The number stored at @ptr is
  113. * potentially suffixed with K, M, G, T, P, E.
  114. */
  115. unsigned long long memparse(const char *ptr, char **retptr)
  116. {
  117. char *endptr; /* local pointer to end of parsed string */
  118. unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
  119. switch (*endptr) {
  120. case 'E':
  121. case 'e':
  122. ret <<= 10;
  123. case 'P':
  124. case 'p':
  125. ret <<= 10;
  126. case 'T':
  127. case 't':
  128. ret <<= 10;
  129. case 'G':
  130. case 'g':
  131. ret <<= 10;
  132. case 'M':
  133. case 'm':
  134. ret <<= 10;
  135. case 'K':
  136. case 'k':
  137. ret <<= 10;
  138. endptr++;
  139. default:
  140. break;
  141. }
  142. if (retptr)
  143. *retptr = endptr;
  144. return ret;
  145. }
  146. EXPORT_SYMBOL(memparse);
  147. /**
  148. * parse_option_str - Parse a string and check an option is set or not
  149. * @str: String to be parsed
  150. * @option: option name
  151. *
  152. * This function parses a string containing a comma-separated list of
  153. * strings like a=b,c.
  154. *
  155. * Return true if there's such option in the string, or return false.
  156. */
  157. bool parse_option_str(const char *str, const char *option)
  158. {
  159. while (*str) {
  160. if (!strncmp(str, option, strlen(option))) {
  161. str += strlen(option);
  162. if (!*str || *str == ',')
  163. return true;
  164. }
  165. while (*str && *str != ',')
  166. str++;
  167. if (*str == ',')
  168. str++;
  169. }
  170. return false;
  171. }
  172. /*
  173. * Parse a string to get a param value pair.
  174. * You can use " around spaces, but can't escape ".
  175. * Hyphens and underscores equivalent in parameter names.
  176. */
  177. char *next_arg(char *args, char **param, char **val)
  178. {
  179. unsigned int i, equals = 0;
  180. int in_quote = 0, quoted = 0;
  181. char *next;
  182. if (*args == '"') {
  183. args++;
  184. in_quote = 1;
  185. quoted = 1;
  186. }
  187. for (i = 0; args[i]; i++) {
  188. if (isspace(args[i]) && !in_quote)
  189. break;
  190. if (equals == 0) {
  191. if (args[i] == '=')
  192. equals = i;
  193. }
  194. if (args[i] == '"')
  195. in_quote = !in_quote;
  196. }
  197. *param = args;
  198. if (!equals)
  199. *val = NULL;
  200. else {
  201. args[equals] = '\0';
  202. *val = args + equals + 1;
  203. /* Don't include quotes in value. */
  204. if (**val == '"') {
  205. (*val)++;
  206. if (args[i-1] == '"')
  207. args[i-1] = '\0';
  208. }
  209. }
  210. if (quoted && args[i-1] == '"')
  211. args[i-1] = '\0';
  212. if (args[i]) {
  213. args[i] = '\0';
  214. next = args + i + 1;
  215. } else
  216. next = args + i;
  217. /* Chew up trailing spaces. */
  218. return skip_spaces(next);
  219. }