1 /* 2 * This file is part of the Linux kernel, and is made available under 3 * the terms of the GNU General Public License version 2. 4 * 5 * Misc librarized functions for cmdline poking. 6 */ 7 #include <linux/kernel.h> 8 #include <linux/string.h> 9 #include <linux/ctype.h> 10 #include <asm/setup.h> 11 12 static inline int myisspace(u8 c) 13 { 14 return c <= ' '; /* Close enough approximation */ 15 } 16 17 /** 18 * Find a boolean option (like quiet,noapic,nosmp....) 19 * 20 * @cmdline: the cmdline string 21 * @option: option string to look for 22 * 23 * Returns the position of that @option (starts counting with 1) 24 * or 0 on not found. @option will only be found if it is found 25 * as an entire word in @cmdline. For instance, if @option="car" 26 * then a cmdline which contains "cart" will not match. 27 */ 28 static int 29 __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size, 30 const char *option) 31 { 32 char c; 33 int pos = 0, wstart = 0; 34 const char *opptr = NULL; 35 enum { 36 st_wordstart = 0, /* Start of word/after whitespace */ 37 st_wordcmp, /* Comparing this word */ 38 st_wordskip, /* Miscompare, skip */ 39 } state = st_wordstart; 40 41 if (!cmdline) 42 return -1; /* No command line */ 43 44 /* 45 * This 'pos' check ensures we do not overrun 46 * a non-NULL-terminated 'cmdline' 47 */ 48 while (pos < max_cmdline_size) { 49 c = *(char *)cmdline++; 50 pos++; 51 52 switch (state) { 53 case st_wordstart: 54 if (!c) 55 return 0; 56 else if (myisspace(c)) 57 break; 58 59 state = st_wordcmp; 60 opptr = option; 61 wstart = pos; 62 /* fall through */ 63 64 case st_wordcmp: 65 if (!*opptr) { 66 /* 67 * We matched all the way to the end of the 68 * option we were looking for. If the 69 * command-line has a space _or_ ends, then 70 * we matched! 71 */ 72 if (!c || myisspace(c)) 73 return wstart; 74 /* 75 * We hit the end of the option, but _not_ 76 * the end of a word on the cmdline. Not 77 * a match. 78 */ 79 } else if (!c) { 80 /* 81 * Hit the NULL terminator on the end of 82 * cmdline. 83 */ 84 return 0; 85 } else if (c == *opptr++) { 86 /* 87 * We are currently matching, so continue 88 * to the next character on the cmdline. 89 */ 90 break; 91 } 92 state = st_wordskip; 93 /* fall through */ 94 95 case st_wordskip: 96 if (!c) 97 return 0; 98 else if (myisspace(c)) 99 state = st_wordstart; 100 break; 101 } 102 } 103 104 return 0; /* Buffer overrun */ 105 } 106 107 int cmdline_find_option_bool(const char *cmdline, const char *option) 108 { 109 return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option); 110 } 111