13034Sdougm /*
23034Sdougm  * CDDL HEADER START
33034Sdougm  *
43034Sdougm  * The contents of this file are subject to the terms of the
53034Sdougm  * Common Development and Distribution License (the "License").
63034Sdougm  * You may not use this file except in compliance with the License.
73034Sdougm  *
83034Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93034Sdougm  * or http://www.opensolaris.org/os/licensing.
103034Sdougm  * See the License for the specific language governing permissions
113034Sdougm  * and limitations under the License.
123034Sdougm  *
133034Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
143034Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153034Sdougm  * If applicable, add the following below this CDDL HEADER, with the
163034Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
173034Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
183034Sdougm  *
193034Sdougm  * CDDL HEADER END
203034Sdougm  */
213034Sdougm 
223034Sdougm /*
23*8334SJose.Borrego@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
243034Sdougm  * Use is subject to license terms.
253034Sdougm  */
263034Sdougm 
273034Sdougm #include <stdio.h>
283034Sdougm #include <ctype.h>
293034Sdougm 
303034Sdougm #define	TK_INIT		0
313034Sdougm #define	TK_TOKEN	1
323034Sdougm #define	TK_SKIPWHITE	2
333034Sdougm #define	TK_QUOTED	3
343034Sdougm 
353034Sdougm /*
363034Sdougm  * assumes quoted strings are delimited by white space (i.e sp
373034Sdougm  * "string" sp). Backslash can be used to quote a quote mark.
383034Sdougm  * quoted strings will have the quotes stripped.
393034Sdougm  */
403034Sdougm 
413034Sdougm char *
42*8334SJose.Borrego@Sun.COM _sa_get_token(char *string)
433034Sdougm {
443034Sdougm 	static char *orig = NULL;
453034Sdougm 	static char *curp;
463034Sdougm 	char *ret;
473034Sdougm 	int state = TK_INIT;
483034Sdougm 	int c;
493034Sdougm 	int quotechar;
503034Sdougm 
513034Sdougm 	if (string != orig || string == NULL) {
523034Sdougm 		orig = string;
533034Sdougm 		curp = string;
543034Sdougm 		if (string == NULL) {
553034Sdougm 			return (NULL);
563034Sdougm 		}
573034Sdougm 	}
583034Sdougm 	ret = curp;
593034Sdougm 	while ((c = *curp) != '\0') {
603034Sdougm 		switch (state) {
613034Sdougm 		case TK_SKIPWHITE:
623034Sdougm 		case TK_INIT:
633034Sdougm 			if (isspace(c)) {
643034Sdougm 				while (*curp && isspace(*curp))
653034Sdougm 					curp++;
663034Sdougm 				ret = curp;
673034Sdougm 			}
683034Sdougm 			if (c == '"' || c == '\'') {
693034Sdougm 				state = TK_QUOTED;
703034Sdougm 				curp++;
713034Sdougm 				ret = curp;
723034Sdougm 				quotechar = c; /* want to match for close */
733034Sdougm 			} else {
743034Sdougm 				state = TK_TOKEN;
753034Sdougm 			}
763034Sdougm 			break;
773034Sdougm 		case TK_TOKEN:
783034Sdougm 			switch (c) {
793034Sdougm 			case '\\':
803034Sdougm 				curp++;
813034Sdougm 				if (*curp) {
823034Sdougm 					curp++;
833034Sdougm 					break;
843034Sdougm 				} else {
853034Sdougm 					return (ret);
863034Sdougm 				}
873034Sdougm 				break;
883034Sdougm 			default:
893034Sdougm 				if (*curp == '\0' || isspace(c)) {
903034Sdougm 					*curp++ = '\0';
913034Sdougm 					return (ret);
923034Sdougm 				}
933034Sdougm 				curp++;
943034Sdougm 				break;
953034Sdougm 			}
963034Sdougm 			break;
973034Sdougm 		case TK_QUOTED:
983034Sdougm 			switch (c) {
993034Sdougm 			case '\\':
1003034Sdougm 				curp++;
1013034Sdougm 				if (*curp) {
1023034Sdougm 					curp++;
1033034Sdougm 					break;
1043034Sdougm 				}
1053034Sdougm 				curp++;
1063034Sdougm 				break;
1073034Sdougm 			default:
1083034Sdougm 				if (c == '\0' || c == quotechar) {
1093034Sdougm 					*curp++ = '\0';
1103034Sdougm 					return (ret);
1113034Sdougm 				}
1123034Sdougm 				curp++;
1133034Sdougm 				break;
1143034Sdougm 			}
1153034Sdougm 			break;
1163034Sdougm 		}
1173034Sdougm 	}
1183034Sdougm 	return (NULL);
1193034Sdougm }
120