xref: /openbmc/linux/arch/x86/lib/cmdline.c (revision 02afeaae)
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 int cmdline_find_option_bool(const char *cmdline, const char *option)
29 {
30 	char c;
31 	int pos = 0, wstart = 0;
32 	const char *opptr = NULL;
33 	enum {
34 		st_wordstart = 0,	/* Start of word/after whitespace */
35 		st_wordcmp,	/* Comparing this word */
36 		st_wordskip,	/* Miscompare, skip */
37 	} state = st_wordstart;
38 
39 	if (!cmdline)
40 		return -1;      /* No command line */
41 
42 	if (!strlen(cmdline))
43 		return 0;
44 
45 	/*
46 	 * This 'pos' check ensures we do not overrun
47 	 * a non-NULL-terminated 'cmdline'
48 	 */
49 	while (pos < COMMAND_LINE_SIZE) {
50 		c = *(char *)cmdline++;
51 		pos++;
52 
53 		switch (state) {
54 		case st_wordstart:
55 			if (!c)
56 				return 0;
57 			else if (myisspace(c))
58 				break;
59 
60 			state = st_wordcmp;
61 			opptr = option;
62 			wstart = pos;
63 			/* fall through */
64 
65 		case st_wordcmp:
66 			if (!*opptr) {
67 				/*
68 				 * We matched all the way to the end of the
69 				 * option we were looking for.  If the
70 				 * command-line has a space _or_ ends, then
71 				 * we matched!
72 				 */
73 				if (!c || myisspace(c))
74 					return wstart;
75 				else
76 					state = st_wordskip;
77 			} else if (!c) {
78 				/*
79 				 * Hit the NULL terminator on the end of
80 				 * cmdline.
81 				 */
82 				return 0;
83 			} else if (c != *opptr++) {
84 				state = st_wordskip;
85 			}
86 			break;
87 
88 		case st_wordskip:
89 			if (!c)
90 				return 0;
91 			else if (myisspace(c))
92 				state = st_wordstart;
93 			break;
94 		}
95 	}
96 
97 	return 0;	/* Buffer overrun */
98 }
99