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