2 * Copyright (c) 1997, 1998
3 * Nan Yang Computer Services Limited. All rights reserved.
5 * This software is distributed under the so-called ``Berkeley
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the Company nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * This software is provided ``as is'', and any express or implied
21 * warranties, including, but not limited to, the implied warranties of
22 * merchantability and fitness for a particular purpose are disclaimed.
23 * In no event shall the company or contributors be liable for any
24 * direct, indirect, incidental, special, exemplary, or consequential
25 * damages (including, but not limited to, procurement of substitute
26 * goods or services; loss of use, data, or profits; or business
27 * interruption) however caused and on any theory of liability, whether
28 * in contract, strict liability, or tort (including negligence or
29 * otherwise) arising in any way out of the use of this software, even if
30 * advised of the possibility of such damage.
32 * $Id: vinumparser.c,v 1.21 2000/12/20 03:44:13 grog Exp grog $
33 * $FreeBSD: src/sys/dev/vinum/vinumparser.c,v 1.20.2.5 2001/05/28 05:56:27 grog Exp $
34 * $DragonFly: src/sbin/vinum/vinumparser.c,v 1.8 2007/01/20 19:20:39 dillon Exp $
38 * This file contains the parser for the configuration routines. It's used
39 * both in the kernel and in the user interface program, thus the separate file.
43 * Go through a text and split up into text tokens. These are either non-blank
44 * sequences, or any sequence (except \0) enclosed in ' or ". Embedded ' or
45 * " characters may be escaped by \, which otherwise has no special meaning.
47 * Delimit by following with a \0, and return pointers to the starts at token [].
48 * Return the number of tokens found as the return value.
50 * This method has the restriction that a closing " or ' must be followed by
53 * Error conditions are end of line before end of quote, or no space after
54 * a closing quote. In this case, tokenize() returns -1.
57 #include <sys/param.h>
58 #include <dev/raid/vinum/vinumkw.h>
63 #define iswhite isspace /* use the ctype macro */
65 /* enum keyword is defined in vinumvar.h */
67 #define keypair(x) { #x, kw_##x } /* create pair "foo", kw_foo */
68 #define flagkeypair(x) { "-"#x, kw_##x } /* create pair "-foo", kw_foo */
69 #define KEYWORDSET(x) {sizeof (x) / sizeof (struct _keywords), x}
71 /* Normal keywords. These are all the words that vinum knows. */
72 struct _keywords keywords
[] =
84 keypair(writethrough
),
109 keypair(printconfig
),
128 keypair(resetconfig
),
141 keypair(checkparity
),
142 keypair(rebuildparity
),
146 struct keywordset keyword_set
= KEYWORDSET(keywords
);
148 struct _keywords flag_keywords
[] =
156 struct keywordset flag_set
= KEYWORDSET(flag_keywords
);
159 * Take a blank separated list of tokens and turn it into a list of
160 * individual nul-delimited strings. Build a list of pointers at
161 * token, which must have enough space for the tokens. Return the
162 * number of tokens, or -1 on error (typically a missing string
166 tokenize(char *cptr
, char *token
[])
168 char delim
; /* delimiter for searching for the partner */
169 int tokennr
; /* index of this token */
170 tokennr
= 0; /* none found yet */
173 while (iswhite(*cptr
))
174 cptr
++; /* skip initial white space */
175 if ((*cptr
== '\0') || (*cptr
== '\n') || (*cptr
== '#')) /* end of line */
176 return tokennr
; /* return number of tokens found */
178 token
[tokennr
] = cptr
; /* point to it */
179 tokennr
++; /* one more */
180 /* XXX this is broken. It leaves superfluous \\ characters in the text */
181 if ((delim
== '\'') || (delim
== '"')) { /* delimitered */
184 if ((*cptr
== delim
) && (cptr
[-1] != '\\')) { /* found the partner */
185 cptr
++; /* move on past */
186 if (!iswhite(*cptr
)) /* error, no space after closing quote */
188 *cptr
++ = '\0'; /* delimit */
189 } else if ((*cptr
== '\0') || (*cptr
== '\n')) /* end of line */
192 } else { /* not quoted */
193 while ((*cptr
!= '\0') && (!iswhite(*cptr
)) && (*cptr
!= '\n'))
195 if (*cptr
!= '\0') /* not end of the line, */
196 *cptr
++ = '\0'; /* delimit and move to the next */
201 /* Find a keyword and return an index */
203 get_keyword(char *name
, struct keywordset
*keywordset
)
206 struct _keywords
*keywords
= keywordset
->k
; /* point to the keywords */
207 if (name
!= NULL
) { /* parameter exists */
208 for (i
= 0; i
< keywordset
->size
; i
++)
209 if (!strcmp(name
, keywords
[i
].name
))
210 return (enum keyword
) keywords
[i
].keyword
;
212 return kw_invalid_keyword
;