xref: /titanic_52/usr/src/lib/libshare/common/parser.c (revision 6185db853e024a486ff8837e6784dd290d866112)
1*6185db85Sdougm /*
2*6185db85Sdougm  * CDDL HEADER START
3*6185db85Sdougm  *
4*6185db85Sdougm  * The contents of this file are subject to the terms of the
5*6185db85Sdougm  * Common Development and Distribution License (the "License").
6*6185db85Sdougm  * You may not use this file except in compliance with the License.
7*6185db85Sdougm  *
8*6185db85Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6185db85Sdougm  * or http://www.opensolaris.org/os/licensing.
10*6185db85Sdougm  * See the License for the specific language governing permissions
11*6185db85Sdougm  * and limitations under the License.
12*6185db85Sdougm  *
13*6185db85Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
14*6185db85Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6185db85Sdougm  * If applicable, add the following below this CDDL HEADER, with the
16*6185db85Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
17*6185db85Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6185db85Sdougm  *
19*6185db85Sdougm  * CDDL HEADER END
20*6185db85Sdougm  */
21*6185db85Sdougm 
22*6185db85Sdougm /*
23*6185db85Sdougm  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*6185db85Sdougm  * Use is subject to license terms.
25*6185db85Sdougm  */
26*6185db85Sdougm 
27*6185db85Sdougm #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*6185db85Sdougm 
29*6185db85Sdougm #include <stdio.h>
30*6185db85Sdougm #include <ctype.h>
31*6185db85Sdougm 
32*6185db85Sdougm #define	TK_INIT		0
33*6185db85Sdougm #define	TK_TOKEN	1
34*6185db85Sdougm #define	TK_SKIPWHITE	2
35*6185db85Sdougm #define	TK_QUOTED	3
36*6185db85Sdougm 
37*6185db85Sdougm /*
38*6185db85Sdougm  * assumes quoted strings are delimited by white space (i.e sp
39*6185db85Sdougm  * "string" sp). Backslash can be used to quote a quote mark.
40*6185db85Sdougm  * quoted strings will have the quotes stripped.
41*6185db85Sdougm  */
42*6185db85Sdougm 
43*6185db85Sdougm char *
44*6185db85Sdougm get_token(char *string)
45*6185db85Sdougm {
46*6185db85Sdougm 	static char *orig = NULL;
47*6185db85Sdougm 	static char *curp;
48*6185db85Sdougm 	char *ret;
49*6185db85Sdougm 	int state = TK_INIT;
50*6185db85Sdougm 	int c;
51*6185db85Sdougm 	int quotechar;
52*6185db85Sdougm 
53*6185db85Sdougm 	if (string != orig || string == NULL) {
54*6185db85Sdougm 		orig = string;
55*6185db85Sdougm 		curp = string;
56*6185db85Sdougm 		if (string == NULL) {
57*6185db85Sdougm 			return (NULL);
58*6185db85Sdougm 		}
59*6185db85Sdougm 	}
60*6185db85Sdougm 	ret = curp;
61*6185db85Sdougm 	while ((c = *curp) != '\0') {
62*6185db85Sdougm 		switch (state) {
63*6185db85Sdougm 		case TK_SKIPWHITE:
64*6185db85Sdougm 		case TK_INIT:
65*6185db85Sdougm 			if (isspace(c)) {
66*6185db85Sdougm 				while (*curp && isspace(*curp))
67*6185db85Sdougm 					curp++;
68*6185db85Sdougm 				ret = curp;
69*6185db85Sdougm 			}
70*6185db85Sdougm 			if (c == '"' || c == '\'') {
71*6185db85Sdougm 				state = TK_QUOTED;
72*6185db85Sdougm 				curp++;
73*6185db85Sdougm 				ret = curp;
74*6185db85Sdougm 				quotechar = c; /* want to match for close */
75*6185db85Sdougm 			} else {
76*6185db85Sdougm 				state = TK_TOKEN;
77*6185db85Sdougm 			}
78*6185db85Sdougm 			break;
79*6185db85Sdougm 		case TK_TOKEN:
80*6185db85Sdougm 			switch (c) {
81*6185db85Sdougm 			case '\\':
82*6185db85Sdougm 				curp++;
83*6185db85Sdougm 				if (*curp) {
84*6185db85Sdougm 					curp++;
85*6185db85Sdougm 					break;
86*6185db85Sdougm 				} else {
87*6185db85Sdougm 					return (ret);
88*6185db85Sdougm 				}
89*6185db85Sdougm 				break;
90*6185db85Sdougm 			default:
91*6185db85Sdougm 				if (*curp == '\0' || isspace(c)) {
92*6185db85Sdougm 					*curp++ = '\0';
93*6185db85Sdougm 					return (ret);
94*6185db85Sdougm 				}
95*6185db85Sdougm 				curp++;
96*6185db85Sdougm 				break;
97*6185db85Sdougm 			}
98*6185db85Sdougm 			break;
99*6185db85Sdougm 		case TK_QUOTED:
100*6185db85Sdougm 			switch (c) {
101*6185db85Sdougm 			case '\\':
102*6185db85Sdougm 				curp++;
103*6185db85Sdougm 				if (*curp) {
104*6185db85Sdougm 					curp++;
105*6185db85Sdougm 					break;
106*6185db85Sdougm 				}
107*6185db85Sdougm 				curp++;
108*6185db85Sdougm 				break;
109*6185db85Sdougm 			default:
110*6185db85Sdougm 				if (c == '\0' || c == quotechar) {
111*6185db85Sdougm 					*curp++ = '\0';
112*6185db85Sdougm 					return (ret);
113*6185db85Sdougm 				}
114*6185db85Sdougm 				curp++;
115*6185db85Sdougm 				break;
116*6185db85Sdougm 			}
117*6185db85Sdougm 			break;
118*6185db85Sdougm 		}
119*6185db85Sdougm 	}
120*6185db85Sdougm 	return (NULL);
121*6185db85Sdougm }
122