1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright (c) 1999, by Sun Microsystems, Inc.
28*0Sstevel@tonic-gate  * All rights reserved.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*0Sstevel@tonic-gate /*LINTLIBRARY*/
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #include "synonyms.h"
35*0Sstevel@tonic-gate #include <sys/types.h>
36*0Sstevel@tonic-gate #include <stdio.h>
37*0Sstevel@tonic-gate #include <ctype.h>
38*0Sstevel@tonic-gate #include "s_string.h"
39*0Sstevel@tonic-gate #include <stdlib.h>
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate /* global to this file */
42*0Sstevel@tonic-gate #define	STRLEN 128UL
43*0Sstevel@tonic-gate #define	STRALLOC 128UL
44*0Sstevel@tonic-gate #define	MAXINCR 250000UL
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate /* buffer pool for allocating string structures */
47*0Sstevel@tonic-gate typedef struct {
48*0Sstevel@tonic-gate 	string s[STRALLOC];
49*0Sstevel@tonic-gate 	size_t o;
50*0Sstevel@tonic-gate } stralloc;
51*0Sstevel@tonic-gate static stralloc *freep = NULL;
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate /* pool of freed strings */
54*0Sstevel@tonic-gate static string *freed = NULL;
55*0Sstevel@tonic-gate static string *s_alloc(void);
56*0Sstevel@tonic-gate static void s_simplegrow(string *, size_t);
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate void
59*0Sstevel@tonic-gate s_free(string *sp)
60*0Sstevel@tonic-gate {
61*0Sstevel@tonic-gate 	if (sp != NULL) {
62*0Sstevel@tonic-gate 		sp->ptr = (char *)freed;
63*0Sstevel@tonic-gate 		freed = sp;
64*0Sstevel@tonic-gate 	}
65*0Sstevel@tonic-gate }
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate /* allocate a string head */
68*0Sstevel@tonic-gate static string *
69*0Sstevel@tonic-gate s_alloc(void)
70*0Sstevel@tonic-gate {
71*0Sstevel@tonic-gate 	if (freep == NULL || freep->o >= STRALLOC) {
72*0Sstevel@tonic-gate 		freep = (stralloc *)malloc(sizeof (stralloc));
73*0Sstevel@tonic-gate 		if (freep == NULL) {
74*0Sstevel@tonic-gate 			perror("allocating string");
75*0Sstevel@tonic-gate 			exit(1);
76*0Sstevel@tonic-gate 		}
77*0Sstevel@tonic-gate 		freep->o = (size_t)0;
78*0Sstevel@tonic-gate 	}
79*0Sstevel@tonic-gate 	return (&(freep->s[freep->o++]));
80*0Sstevel@tonic-gate }
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate /* create a new `short' string */
83*0Sstevel@tonic-gate string *
84*0Sstevel@tonic-gate s_new(void)
85*0Sstevel@tonic-gate {
86*0Sstevel@tonic-gate 	string *sp;
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	if (freed != NULL) {
89*0Sstevel@tonic-gate 		sp = freed;
90*0Sstevel@tonic-gate 		/*LINTED*/
91*0Sstevel@tonic-gate 		freed = (string *)(freed->ptr);
92*0Sstevel@tonic-gate 		sp->ptr = sp->base;
93*0Sstevel@tonic-gate 		return (sp);
94*0Sstevel@tonic-gate 	}
95*0Sstevel@tonic-gate 	sp = s_alloc();
96*0Sstevel@tonic-gate 	sp->base = sp->ptr = malloc(STRLEN);
97*0Sstevel@tonic-gate 	if (sp->base == NULL) {
98*0Sstevel@tonic-gate 		perror("allocating string");
99*0Sstevel@tonic-gate 		exit(1);
100*0Sstevel@tonic-gate 	}
101*0Sstevel@tonic-gate 	sp->end = sp->base + STRLEN;
102*0Sstevel@tonic-gate 	s_terminate(sp);
103*0Sstevel@tonic-gate 	return (sp);
104*0Sstevel@tonic-gate }
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate /* grow a string's allocation by at least `incr' bytes */
107*0Sstevel@tonic-gate static void
108*0Sstevel@tonic-gate s_simplegrow(string *sp, size_t incr)
109*0Sstevel@tonic-gate {
110*0Sstevel@tonic-gate 	char *cp;
111*0Sstevel@tonic-gate 	size_t size;
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 	/*
114*0Sstevel@tonic-gate 	 *  take a larger increment to avoid mallocing too often
115*0Sstevel@tonic-gate 	 */
116*0Sstevel@tonic-gate 	if (((sp->end - sp->base) < incr) && (MAXINCR < incr))
117*0Sstevel@tonic-gate 		size = (sp->end - sp->base) + incr;
118*0Sstevel@tonic-gate 	else if ((sp->end - sp->base) > MAXINCR)
119*0Sstevel@tonic-gate 		size = (sp->end - sp->base) + MAXINCR;
120*0Sstevel@tonic-gate 	else
121*0Sstevel@tonic-gate 		size = (size_t)2 * (sp->end - sp->base);
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	cp = realloc(sp->base, size);
124*0Sstevel@tonic-gate 	if (cp == NULL) {
125*0Sstevel@tonic-gate 		perror("string:");
126*0Sstevel@tonic-gate 		exit(1);
127*0Sstevel@tonic-gate 	}
128*0Sstevel@tonic-gate 	sp->ptr = (sp->ptr - sp->base) + cp;
129*0Sstevel@tonic-gate 	sp->end = cp + size;
130*0Sstevel@tonic-gate 	sp->base = cp;
131*0Sstevel@tonic-gate }
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate /* grow a string's allocation */
134*0Sstevel@tonic-gate int
135*0Sstevel@tonic-gate s_grow(string *sp, int c)
136*0Sstevel@tonic-gate {
137*0Sstevel@tonic-gate 	s_simplegrow(sp, (size_t)2);
138*0Sstevel@tonic-gate 	s_putc(sp, c);
139*0Sstevel@tonic-gate 	return (c);
140*0Sstevel@tonic-gate }
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate /* return a string containing a character array (this had better not grow) */
143*0Sstevel@tonic-gate string *
144*0Sstevel@tonic-gate s_array(char *cp, size_t len)
145*0Sstevel@tonic-gate {
146*0Sstevel@tonic-gate 	string *sp = s_alloc();
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	sp->base = sp->ptr = cp;
149*0Sstevel@tonic-gate 	sp->end = sp->base + len;
150*0Sstevel@tonic-gate 	return (sp);
151*0Sstevel@tonic-gate }
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate /* return a string containing a copy of the passed char array */
154*0Sstevel@tonic-gate string*
155*0Sstevel@tonic-gate s_copy(char *cp)
156*0Sstevel@tonic-gate {
157*0Sstevel@tonic-gate 	string *sp;
158*0Sstevel@tonic-gate 	size_t len;
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	sp = s_alloc();
161*0Sstevel@tonic-gate 	len = strlen(cp)+1;
162*0Sstevel@tonic-gate 	sp->base = malloc(len);
163*0Sstevel@tonic-gate 	if (sp->base == NULL) {
164*0Sstevel@tonic-gate 		perror("string:");
165*0Sstevel@tonic-gate 		exit(1);
166*0Sstevel@tonic-gate 	}
167*0Sstevel@tonic-gate 	sp->end = sp->base + len;	/* point past end of allocation */
168*0Sstevel@tonic-gate 	(void) strcpy(sp->base, cp);
169*0Sstevel@tonic-gate 	sp->ptr = sp->end - (size_t)1;	/* point to NULL terminator */
170*0Sstevel@tonic-gate 	return (sp);
171*0Sstevel@tonic-gate }
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate /* convert string to lower case */
174*0Sstevel@tonic-gate void
175*0Sstevel@tonic-gate s_tolower(string *sp)
176*0Sstevel@tonic-gate {
177*0Sstevel@tonic-gate 	char *cp;
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 	for (cp = sp->ptr; *cp; cp++)
180*0Sstevel@tonic-gate 		*cp = tolower(*cp);
181*0Sstevel@tonic-gate }
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate void
184*0Sstevel@tonic-gate s_skipwhite(string *sp)
185*0Sstevel@tonic-gate {
186*0Sstevel@tonic-gate 	while (isspace(*sp->ptr))
187*0Sstevel@tonic-gate 		s_skipc(sp);
188*0Sstevel@tonic-gate }
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate /* append a char array to a string */
191*0Sstevel@tonic-gate string *
192*0Sstevel@tonic-gate s_append(string *to, char *from)
193*0Sstevel@tonic-gate {
194*0Sstevel@tonic-gate 	if (to == NULL)
195*0Sstevel@tonic-gate 		to = s_new();
196*0Sstevel@tonic-gate 	if (from == NULL)
197*0Sstevel@tonic-gate 		return (to);
198*0Sstevel@tonic-gate 	for (; *from; from++)
199*0Sstevel@tonic-gate 		s_putc(to, (int)(unsigned int)*from);
200*0Sstevel@tonic-gate 	s_terminate(to);
201*0Sstevel@tonic-gate 	return (to);
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate /*
205*0Sstevel@tonic-gate  * Append a logical input sequence into a string.  Ignore blank and
206*0Sstevel@tonic-gate  * comment lines.  Backslash preceding newline indicates continuation.
207*0Sstevel@tonic-gate  * The `lineortoken' variable indicates whether the sequence to beinput
208*0Sstevel@tonic-gate  * is a whitespace delimited token or a whole line.
209*0Sstevel@tonic-gate  *
210*0Sstevel@tonic-gate  *	FILE *fp;		stream to read from
211*0Sstevel@tonic-gate  *	string *to;		where to put token
212*0Sstevel@tonic-gate  *	int lineortoken;	how the sequence terminates
213*0Sstevel@tonic-gate  *
214*0Sstevel@tonic-gate  * Returns a pointer to the string or NULL. Trailing newline is stripped off.
215*0Sstevel@tonic-gate  */
216*0Sstevel@tonic-gate string *
217*0Sstevel@tonic-gate s_seq_read(FILE *fp, string *to, int lineortoken)
218*0Sstevel@tonic-gate {
219*0Sstevel@tonic-gate 	int c;
220*0Sstevel@tonic-gate 	int done = 0;
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate 	if (feof(fp))
223*0Sstevel@tonic-gate 		return (NULL);
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	/* get rid of leading goo */
226*0Sstevel@tonic-gate 	do {
227*0Sstevel@tonic-gate 		c = getc(fp);
228*0Sstevel@tonic-gate 		switch (c) {
229*0Sstevel@tonic-gate 		case EOF:
230*0Sstevel@tonic-gate 			if (to != NULL)
231*0Sstevel@tonic-gate 				s_terminate(to);
232*0Sstevel@tonic-gate 			return (NULL);
233*0Sstevel@tonic-gate 		case '#':
234*0Sstevel@tonic-gate 			/*LINTED*/
235*0Sstevel@tonic-gate 			while ((c = getc(fp)) != '\n' && c != EOF);
236*0Sstevel@tonic-gate 			break;
237*0Sstevel@tonic-gate 		case ' ':
238*0Sstevel@tonic-gate 		case '\t':
239*0Sstevel@tonic-gate 		case '\n':
240*0Sstevel@tonic-gate 		case '\r':
241*0Sstevel@tonic-gate 		case '\f':
242*0Sstevel@tonic-gate 			break;
243*0Sstevel@tonic-gate 		default:
244*0Sstevel@tonic-gate 			done = 1;
245*0Sstevel@tonic-gate 			break;
246*0Sstevel@tonic-gate 		}
247*0Sstevel@tonic-gate 	} while (!done);
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	if (to == NULL)
250*0Sstevel@tonic-gate 		to = s_new();
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	/* gather up a sequence */
253*0Sstevel@tonic-gate 	for (;;) {
254*0Sstevel@tonic-gate 		switch (c) {
255*0Sstevel@tonic-gate 		case '\\':
256*0Sstevel@tonic-gate 			c = getc(fp);
257*0Sstevel@tonic-gate 			if (c != '\n') {
258*0Sstevel@tonic-gate 				s_putc(to, (int)(unsigned int)'\\');
259*0Sstevel@tonic-gate 				s_putc(to, c);
260*0Sstevel@tonic-gate 			}
261*0Sstevel@tonic-gate 			break;
262*0Sstevel@tonic-gate 		case EOF:
263*0Sstevel@tonic-gate 		case '\r':
264*0Sstevel@tonic-gate 		case '\f':
265*0Sstevel@tonic-gate 		case '\n':
266*0Sstevel@tonic-gate 			s_terminate(to);
267*0Sstevel@tonic-gate 			return (to);
268*0Sstevel@tonic-gate 		case ' ':
269*0Sstevel@tonic-gate 		case '\t':
270*0Sstevel@tonic-gate 			if (lineortoken == TOKEN) {
271*0Sstevel@tonic-gate 				s_terminate(to);
272*0Sstevel@tonic-gate 				return (to);
273*0Sstevel@tonic-gate 			}
274*0Sstevel@tonic-gate 			/* fall through */
275*0Sstevel@tonic-gate 		default:
276*0Sstevel@tonic-gate 			s_putc(to, c);
277*0Sstevel@tonic-gate 			break;
278*0Sstevel@tonic-gate 		}
279*0Sstevel@tonic-gate 		c = getc(fp);
280*0Sstevel@tonic-gate 	}
281*0Sstevel@tonic-gate }
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate string *
284*0Sstevel@tonic-gate s_tok(string *from, char *split)
285*0Sstevel@tonic-gate {
286*0Sstevel@tonic-gate 	char *splitend = strpbrk(from->ptr, split);
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate 	if (splitend) {
289*0Sstevel@tonic-gate 		string *to = s_new();
290*0Sstevel@tonic-gate 		for (; from->ptr < splitend; ) {
291*0Sstevel@tonic-gate 			s_putc(to, (int)(unsigned int)*from->ptr);
292*0Sstevel@tonic-gate 			from->ptr++;
293*0Sstevel@tonic-gate 		}
294*0Sstevel@tonic-gate 		s_terminate(to);
295*0Sstevel@tonic-gate 		s_restart(to);
296*0Sstevel@tonic-gate 		/* LINT: warning due to lint bug */
297*0Sstevel@tonic-gate 		from->ptr += strspn(from->ptr, split);
298*0Sstevel@tonic-gate 		return (to);
299*0Sstevel@tonic-gate 	}
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 	else if (from->ptr[0]) {
302*0Sstevel@tonic-gate 		string *to = s_clone(from);
303*0Sstevel@tonic-gate 		while (*from->ptr)
304*0Sstevel@tonic-gate 			from->ptr++;
305*0Sstevel@tonic-gate 		return (to);
306*0Sstevel@tonic-gate 	}
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate 	else
309*0Sstevel@tonic-gate 		return (NULL);
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate /*
313*0Sstevel@tonic-gate  * Append an input line to a string.
314*0Sstevel@tonic-gate  *
315*0Sstevel@tonic-gate  * Returns a pointer to the string (or NULL).
316*0Sstevel@tonic-gate  * Trailing newline is left on.
317*0Sstevel@tonic-gate  */
318*0Sstevel@tonic-gate char *
319*0Sstevel@tonic-gate s_read_line(FILE *fp, string *to)
320*0Sstevel@tonic-gate {
321*0Sstevel@tonic-gate 	int c;
322*0Sstevel@tonic-gate 	size_t len = 0;
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate 	s_terminate(to);
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate 	/* end of input */
327*0Sstevel@tonic-gate 	if (feof(fp) || (c = getc(fp)) == EOF)
328*0Sstevel@tonic-gate 		return (NULL);
329*0Sstevel@tonic-gate 
330*0Sstevel@tonic-gate 	/* gather up a line */
331*0Sstevel@tonic-gate 	for (; ; ) {
332*0Sstevel@tonic-gate 		len++;
333*0Sstevel@tonic-gate 		switch (c) {
334*0Sstevel@tonic-gate 		case EOF:
335*0Sstevel@tonic-gate 			s_terminate(to);
336*0Sstevel@tonic-gate 			return (to->ptr - len);
337*0Sstevel@tonic-gate 		case '\n':
338*0Sstevel@tonic-gate 			s_putc(to, (int)(unsigned int)'\n');
339*0Sstevel@tonic-gate 			s_terminate(to);
340*0Sstevel@tonic-gate 			return (to->ptr - len);
341*0Sstevel@tonic-gate 		default:
342*0Sstevel@tonic-gate 			s_putc(to, c);
343*0Sstevel@tonic-gate 			break;
344*0Sstevel@tonic-gate 		}
345*0Sstevel@tonic-gate 		c = getc(fp);
346*0Sstevel@tonic-gate 	}
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate 
349*0Sstevel@tonic-gate /*
350*0Sstevel@tonic-gate  * Read till eof
351*0Sstevel@tonic-gate  */
352*0Sstevel@tonic-gate size_t
353*0Sstevel@tonic-gate s_read_to_eof(FILE *fp, string *to)
354*0Sstevel@tonic-gate {
355*0Sstevel@tonic-gate 	size_t got;
356*0Sstevel@tonic-gate 	size_t have;
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 	s_terminate(to);
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 	for (; ; ) {
361*0Sstevel@tonic-gate 		if (feof(fp))
362*0Sstevel@tonic-gate 			break;
363*0Sstevel@tonic-gate 		/* allocate room for a full buffer */
364*0Sstevel@tonic-gate 		have = to->end - to->ptr;
365*0Sstevel@tonic-gate 		if (have < 4096UL)
366*0Sstevel@tonic-gate 			s_simplegrow(to, (size_t)4096);
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 		/* get a buffers worth */
369*0Sstevel@tonic-gate 		have = to->end - to->ptr;
370*0Sstevel@tonic-gate 		got = fread(to->ptr, (size_t)1, have, fp);
371*0Sstevel@tonic-gate 		if (got == (size_t)0)
372*0Sstevel@tonic-gate 			break;
373*0Sstevel@tonic-gate 		/* LINT: warning due to lint bug */
374*0Sstevel@tonic-gate 		to->ptr += got;
375*0Sstevel@tonic-gate 	}
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate 	/* null terminate the line */
378*0Sstevel@tonic-gate 	s_terminate(to);
379*0Sstevel@tonic-gate 	return (to->ptr - to->base);
380*0Sstevel@tonic-gate }
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate /*
383*0Sstevel@tonic-gate  * Get the next field from a string.  The field is delimited by white space,
384*0Sstevel@tonic-gate  * single or double quotes.
385*0Sstevel@tonic-gate  *
386*0Sstevel@tonic-gate  *	string *from;	string to parse
387*0Sstevel@tonic-gate  *	string *to;	where to put parsed token
388*0Sstevel@tonic-gate  */
389*0Sstevel@tonic-gate string *
390*0Sstevel@tonic-gate s_parse(string *from, string *to)
391*0Sstevel@tonic-gate {
392*0Sstevel@tonic-gate 	while (isspace(*from->ptr))
393*0Sstevel@tonic-gate 		from->ptr++;
394*0Sstevel@tonic-gate 	if (*from->ptr == '\0')
395*0Sstevel@tonic-gate 		return (NULL);
396*0Sstevel@tonic-gate 	if (to == NULL)
397*0Sstevel@tonic-gate 		to = s_new();
398*0Sstevel@tonic-gate 	if (*from->ptr == '\'') {
399*0Sstevel@tonic-gate 		from->ptr++;
400*0Sstevel@tonic-gate 		for (; *from->ptr != '\'' && *from->ptr != '\0'; from->ptr++)
401*0Sstevel@tonic-gate 			s_putc(to, (int)(unsigned int)*from->ptr);
402*0Sstevel@tonic-gate 		if (*from->ptr == '\'')
403*0Sstevel@tonic-gate 			from->ptr++;
404*0Sstevel@tonic-gate 	} else if (*from->ptr == '"') {
405*0Sstevel@tonic-gate 		from->ptr++;
406*0Sstevel@tonic-gate 		for (; *from->ptr != '"' && *from->ptr != '\0'; from->ptr++)
407*0Sstevel@tonic-gate 			s_putc(to, (int)(unsigned int)*from->ptr);
408*0Sstevel@tonic-gate 		if (*from->ptr == '"')
409*0Sstevel@tonic-gate 			from->ptr++;
410*0Sstevel@tonic-gate 	} else {
411*0Sstevel@tonic-gate 		for (; !isspace(*from->ptr) && *from->ptr != '\0'; from->ptr++)
412*0Sstevel@tonic-gate 			s_putc(to, (int)(unsigned int)*from->ptr);
413*0Sstevel@tonic-gate 	}
414*0Sstevel@tonic-gate 	s_terminate(to);
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate 	return (to);
417*0Sstevel@tonic-gate }
418