xref: /titanic_44/usr/src/lib/libinstzones/common/zones_str.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland /*
22*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*5c51f124SMoriah Waterland  * Use is subject to license terms.
24*5c51f124SMoriah Waterland  */
25*5c51f124SMoriah Waterland 
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland /*
29*5c51f124SMoriah Waterland  * Module:	zones_str.c
30*5c51f124SMoriah Waterland  * Group:	libinstzones
31*5c51f124SMoriah Waterland  * Description:	Private functions used by zones library functions to manipulate
32*5c51f124SMoriah Waterland  *		strings
33*5c51f124SMoriah Waterland  *
34*5c51f124SMoriah Waterland  * Public Methods:
35*5c51f124SMoriah Waterland  *
36*5c51f124SMoriah Waterland  * _z_strAddToken - Add a token to a string
37*5c51f124SMoriah Waterland  * _z_strContainsToken - Does a given string contain a specified substring
38*5c51f124SMoriah Waterland  * _z_strGetToken - Get a separator delimited token from a string
39*5c51f124SMoriah Waterland  * _z_strGetToken_r - Get separator delimited token from string to fixed buffer
40*5c51f124SMoriah Waterland  * _z_strPrintf - Create string from printf style format and arguments
41*5c51f124SMoriah Waterland  * _z_strPrintf_r - Create string from printf style format and arguments
42*5c51f124SMoriah Waterland  * _z_strRemoveLeadingWhitespace - Remove leading whitespace from string
43*5c51f124SMoriah Waterland  * _z_strRemoveToken - Remove a token from a string
44*5c51f124SMoriah Waterland  */
45*5c51f124SMoriah Waterland 
46*5c51f124SMoriah Waterland /*
47*5c51f124SMoriah Waterland  * System includes
48*5c51f124SMoriah Waterland  */
49*5c51f124SMoriah Waterland 
50*5c51f124SMoriah Waterland #include <stdio.h>
51*5c51f124SMoriah Waterland #include <stdlib.h>
52*5c51f124SMoriah Waterland #include <unistd.h>
53*5c51f124SMoriah Waterland #include <ctype.h>
54*5c51f124SMoriah Waterland #include <sys/types.h>
55*5c51f124SMoriah Waterland #include <sys/param.h>
56*5c51f124SMoriah Waterland #include <string.h>
57*5c51f124SMoriah Waterland #include <strings.h>
58*5c51f124SMoriah Waterland #include <stdarg.h>
59*5c51f124SMoriah Waterland #include <limits.h>
60*5c51f124SMoriah Waterland #include <stropts.h>
61*5c51f124SMoriah Waterland #include <libintl.h>
62*5c51f124SMoriah Waterland #include <locale.h>
63*5c51f124SMoriah Waterland #include <assert.h>
64*5c51f124SMoriah Waterland 
65*5c51f124SMoriah Waterland /*
66*5c51f124SMoriah Waterland  * local includes
67*5c51f124SMoriah Waterland  */
68*5c51f124SMoriah Waterland 
69*5c51f124SMoriah Waterland #include "instzones_lib.h"
70*5c51f124SMoriah Waterland #include "zones_strings.h"
71*5c51f124SMoriah Waterland 
72*5c51f124SMoriah Waterland /*
73*5c51f124SMoriah Waterland  * Private structures
74*5c51f124SMoriah Waterland  */
75*5c51f124SMoriah Waterland 
76*5c51f124SMoriah Waterland /*
77*5c51f124SMoriah Waterland  * Library Function Prototypes
78*5c51f124SMoriah Waterland  */
79*5c51f124SMoriah Waterland 
80*5c51f124SMoriah Waterland /*
81*5c51f124SMoriah Waterland  * Local Function Prototypes
82*5c51f124SMoriah Waterland  */
83*5c51f124SMoriah Waterland 
84*5c51f124SMoriah Waterland /*
85*5c51f124SMoriah Waterland  * Global internal (private) declarations
86*5c51f124SMoriah Waterland  */
87*5c51f124SMoriah Waterland 
88*5c51f124SMoriah Waterland /*
89*5c51f124SMoriah Waterland  * *****************************************************************************
90*5c51f124SMoriah Waterland  * global external (public) functions
91*5c51f124SMoriah Waterland  * *****************************************************************************
92*5c51f124SMoriah Waterland  */
93*5c51f124SMoriah Waterland 
94*5c51f124SMoriah Waterland /*
95*5c51f124SMoriah Waterland  * Name:	_z_strAddToken
96*5c51f124SMoriah Waterland  * Synopsis:	Add a token to a string
97*5c51f124SMoriah Waterland  * Description:	Append a token (sequence of one or more characters) to a
98*5c51f124SMoriah Waterland  *		string that is in allocated space - create new string if
99*5c51f124SMoriah Waterland  *		no string to append to exists
100*5c51f124SMoriah Waterland  * Arguments:	a_old - [RO, *RW] - (char **)
101*5c51f124SMoriah Waterland  *			- Pointer to handle to string to append token to
102*5c51f124SMoriah Waterland  *			  == NULL - new string is created
103*5c51f124SMoriah Waterland  *		a_new - [RO, *RO] - (char *)
104*5c51f124SMoriah Waterland  *			- Pointer to string representing token to append
105*5c51f124SMoriah Waterland  *			  to the end of the "a_old" string
106*5c51f124SMoriah Waterland  *			  == NULL - no action is performed
107*5c51f124SMoriah Waterland  *			  a_new[0] == '\0' - no action is performed
108*5c51f124SMoriah Waterland  *		a_separator - [RO, *RO] - (char)
109*5c51f124SMoriah Waterland  *			- One character placed between the old (existing)
110*5c51f124SMoriah Waterland  *			  string and the new token to be added IF the old
111*5c51f124SMoriah Waterland  *			  string exists and is not empty (zero length)
112*5c51f124SMoriah Waterland  * Returns:	void
113*5c51f124SMoriah Waterland  * CAUTION:	The old (existing) string must be allocated space (via lu_mem*
114*5c51f124SMoriah Waterland  *		or _z_str* methods) - it must not be a static or inline
115*5c51f124SMoriah Waterland  *		character string
116*5c51f124SMoriah Waterland  * NOTE:	The old (existing) string may be freed with 'free'
117*5c51f124SMoriah Waterland  *		if a token is appended to it
118*5c51f124SMoriah Waterland  * NOTE:    	Any string returned in 'a_old' is placed in new storage for the
119*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
120*5c51f124SMoriah Waterland  *		of the storage once the token string is no longer needed.
121*5c51f124SMoriah Waterland  */
122*5c51f124SMoriah Waterland 
123*5c51f124SMoriah Waterland void
_z_strAddToken(char ** a_old,char * a_new,char a_separator)124*5c51f124SMoriah Waterland _z_strAddToken(char **a_old, char *a_new, char a_separator)
125*5c51f124SMoriah Waterland {
126*5c51f124SMoriah Waterland 	/* entry assertions */
127*5c51f124SMoriah Waterland 
128*5c51f124SMoriah Waterland 	assert(a_old != NULL);
129*5c51f124SMoriah Waterland 	assert(a_separator != '\0');
130*5c51f124SMoriah Waterland 
131*5c51f124SMoriah Waterland 	/* if token to add is null or token is zero length, just return */
132*5c51f124SMoriah Waterland 
133*5c51f124SMoriah Waterland 	if (a_new == NULL || *a_new == '\0') {
134*5c51f124SMoriah Waterland 		return;
135*5c51f124SMoriah Waterland 	}
136*5c51f124SMoriah Waterland 
137*5c51f124SMoriah Waterland 	/* make sure that new token does not contain the separator */
138*5c51f124SMoriah Waterland 
139*5c51f124SMoriah Waterland 	assert(strchr(a_new, (int)a_separator) == NULL);
140*5c51f124SMoriah Waterland 
141*5c51f124SMoriah Waterland 	/* if old string is empty (zero length), deallocate */
142*5c51f124SMoriah Waterland 
143*5c51f124SMoriah Waterland 	if ((*a_old != NULL) && ((*a_old)[0] == '\0')) {
144*5c51f124SMoriah Waterland 		/* *a_old is set to NULL by free */
145*5c51f124SMoriah Waterland 		free(*a_old);
146*5c51f124SMoriah Waterland 		*a_old = NULL;
147*5c51f124SMoriah Waterland 	}
148*5c51f124SMoriah Waterland 
149*5c51f124SMoriah Waterland 	/* if old string exists, append separator and token */
150*5c51f124SMoriah Waterland 
151*5c51f124SMoriah Waterland 	if (*a_old != NULL) {
152*5c51f124SMoriah Waterland 		char *p;
153*5c51f124SMoriah Waterland 		p = _z_strPrintf("%s%c%s", *a_old, a_separator, a_new);
154*5c51f124SMoriah Waterland 		free(*a_old);
155*5c51f124SMoriah Waterland 		*a_old = p;
156*5c51f124SMoriah Waterland 		return;
157*5c51f124SMoriah Waterland 	}
158*5c51f124SMoriah Waterland 
159*5c51f124SMoriah Waterland 	/* old string does not exist - return duplicate of token */
160*5c51f124SMoriah Waterland 
161*5c51f124SMoriah Waterland 	assert(*a_old == NULL);
162*5c51f124SMoriah Waterland 	*a_old = _z_strdup(a_new);
163*5c51f124SMoriah Waterland }
164*5c51f124SMoriah Waterland 
165*5c51f124SMoriah Waterland /*
166*5c51f124SMoriah Waterland  * Name:	_z_strContainsToken
167*5c51f124SMoriah Waterland  * Synopsis:	Does a given string contain a specified substring
168*5c51f124SMoriah Waterland  * Description:	Determine if a given substring exists in a larger string
169*5c51f124SMoriah Waterland  * Arguments:	a_string - [RO, *RO] - (char *)
170*5c51f124SMoriah Waterland  *			Pointer to string to look for substring in
171*5c51f124SMoriah Waterland  *		a_token - [RO, *RO] - (char *)
172*5c51f124SMoriah Waterland  *			Pointer to substring to look for in larger string
173*5c51f124SMoriah Waterland  * Results:	boolean_t
174*5c51f124SMoriah Waterland  *			B_TRUE - substring exists in larger string
175*5c51f124SMoriah Waterland  *			B_FALSE - substring does NOT exist in larger string
176*5c51f124SMoriah Waterland  * NOTE:	The substring must match on a "token" basis; that is, the
177*5c51f124SMoriah Waterland  *		substring must exist in the larger string delineated with
178*5c51f124SMoriah Waterland  *		either spaces or tabs to match.
179*5c51f124SMoriah Waterland  */
180*5c51f124SMoriah Waterland 
181*5c51f124SMoriah Waterland boolean_t
_z_strContainsToken(char * a_string,char * a_token,char * a_separators)182*5c51f124SMoriah Waterland _z_strContainsToken(char *a_string, char *a_token, char *a_separators)
183*5c51f124SMoriah Waterland {
184*5c51f124SMoriah Waterland 	char	*lasts;
185*5c51f124SMoriah Waterland 	char	*current;
186*5c51f124SMoriah Waterland 	char	*p;
187*5c51f124SMoriah Waterland 
188*5c51f124SMoriah Waterland 	/* entry assertions */
189*5c51f124SMoriah Waterland 
190*5c51f124SMoriah Waterland 	assert(a_separators != NULL);
191*5c51f124SMoriah Waterland 	assert(*a_separators != '\0');
192*5c51f124SMoriah Waterland 
193*5c51f124SMoriah Waterland 	/*
194*5c51f124SMoriah Waterland 	 * if token is not supplied, no string provided,
195*5c51f124SMoriah Waterland 	 * or the string is an empty string, return false
196*5c51f124SMoriah Waterland 	 */
197*5c51f124SMoriah Waterland 
198*5c51f124SMoriah Waterland 	if (a_token == NULL || a_string == NULL || *a_string == '\0') {
199*5c51f124SMoriah Waterland 		return (B_FALSE);
200*5c51f124SMoriah Waterland 	}
201*5c51f124SMoriah Waterland 
202*5c51f124SMoriah Waterland 	/* if no string provided, return false */
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 	/* if string empty (zero length), return false */
205*5c51f124SMoriah Waterland 
206*5c51f124SMoriah Waterland 	/* duplicate larger string because strtok_r changes it */
207*5c51f124SMoriah Waterland 
208*5c51f124SMoriah Waterland 	p = _z_strdup(a_string);
209*5c51f124SMoriah Waterland 
210*5c51f124SMoriah Waterland 	lasts = p;
211*5c51f124SMoriah Waterland 
212*5c51f124SMoriah Waterland 	/* scan each token looking for a match */
213*5c51f124SMoriah Waterland 
214*5c51f124SMoriah Waterland 	while ((current = strtok_r(NULL, a_separators, &lasts)) !=
215*5c51f124SMoriah Waterland 	    NULL) {
216*5c51f124SMoriah Waterland 		if (strcmp(current, a_token) == 0) {
217*5c51f124SMoriah Waterland 			free(p);
218*5c51f124SMoriah Waterland 			return (B_TRUE);
219*5c51f124SMoriah Waterland 		}
220*5c51f124SMoriah Waterland 	}
221*5c51f124SMoriah Waterland 
222*5c51f124SMoriah Waterland 	/* free up temporary storage */
223*5c51f124SMoriah Waterland 
224*5c51f124SMoriah Waterland 	free(p);
225*5c51f124SMoriah Waterland 
226*5c51f124SMoriah Waterland 	/* not found */
227*5c51f124SMoriah Waterland 
228*5c51f124SMoriah Waterland 	return (B_FALSE);
229*5c51f124SMoriah Waterland }
230*5c51f124SMoriah Waterland 
231*5c51f124SMoriah Waterland /*
232*5c51f124SMoriah Waterland  * Name:	_z_strGetToken
233*5c51f124SMoriah Waterland  * Synopsis:	Get a separator delimited token from a string
234*5c51f124SMoriah Waterland  * Description:	Given a string and a list of one or more separators,
235*5c51f124SMoriah Waterland  *		return the position specified token (sequence of one or
236*5c51f124SMoriah Waterland  *		more characters that do not include any of the separators)
237*5c51f124SMoriah Waterland  * Arguments:	r_sep - [*RW] - (char *)
238*5c51f124SMoriah Waterland  *			- separator that ended the token returned
239*5c51f124SMoriah Waterland  *			- NOTE: this is a pointer to a "char", e.g.:
240*5c51f124SMoriah Waterland  *				- char a;
241*5c51f124SMoriah Waterland  *				- _z_strGetToken(&a, ...)
242*5c51f124SMoriah Waterland  *		a_string - [RO, *RO] - (char *)
243*5c51f124SMoriah Waterland  *			- pointer to string to extract token from
244*5c51f124SMoriah Waterland  *		a_index - [RO, *RO] - (int)
245*5c51f124SMoriah Waterland  *			- Index of token to return; '0' is first matching
246*5c51f124SMoriah Waterland  *			  token, '1' is second matching token, etc.
247*5c51f124SMoriah Waterland  *		a_separators - [RO, *RO] - (char *)
248*5c51f124SMoriah Waterland  *			- String containing one or more characters that
249*5c51f124SMoriah Waterland  *			  can separate one "token" from another
250*5c51f124SMoriah Waterland  * Returns:	char *
251*5c51f124SMoriah Waterland  *			== NULL - no token matching criteria found
252*5c51f124SMoriah Waterland  *			!= NULL - token matching criteria
253*5c51f124SMoriah Waterland  * NOTE:    	Any token string returned is placed in new storage for the
254*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
255*5c51f124SMoriah Waterland  *		of the storage once the token string is no longer needed.
256*5c51f124SMoriah Waterland  */
257*5c51f124SMoriah Waterland 
258*5c51f124SMoriah Waterland char *
_z_strGetToken(char * r_sep,char * a_string,int a_index,char * a_separators)259*5c51f124SMoriah Waterland _z_strGetToken(char *r_sep, char *a_string, int a_index, char *a_separators)
260*5c51f124SMoriah Waterland {
261*5c51f124SMoriah Waterland 	char	*p;
262*5c51f124SMoriah Waterland 	char	*q;
263*5c51f124SMoriah Waterland 	char	*lasts;
264*5c51f124SMoriah Waterland 
265*5c51f124SMoriah Waterland 	/* entry assertions */
266*5c51f124SMoriah Waterland 
267*5c51f124SMoriah Waterland 	assert(a_string != NULL);
268*5c51f124SMoriah Waterland 	assert(a_index >= 0);
269*5c51f124SMoriah Waterland 	assert(a_separators != NULL);
270*5c51f124SMoriah Waterland 	assert(*a_separators != '\0');
271*5c51f124SMoriah Waterland 
272*5c51f124SMoriah Waterland 	/* if returned separator requested, reset to null until token found */
273*5c51f124SMoriah Waterland 
274*5c51f124SMoriah Waterland 	if (r_sep != NULL) {
275*5c51f124SMoriah Waterland 		*r_sep = '\0';
276*5c51f124SMoriah Waterland 	}
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland 	/* duplicate original string before breaking down into tokens */
279*5c51f124SMoriah Waterland 
280*5c51f124SMoriah Waterland 	p = _z_strdup(a_string);
281*5c51f124SMoriah Waterland 
282*5c51f124SMoriah Waterland 	lasts = p;
283*5c51f124SMoriah Waterland 
284*5c51f124SMoriah Waterland 	/* scan for separators and return 'index'th token found */
285*5c51f124SMoriah Waterland 
286*5c51f124SMoriah Waterland 	while (q = strtok_r(NULL, a_separators, &lasts)) {
287*5c51f124SMoriah Waterland 		/* retrieve separator if requested */
288*5c51f124SMoriah Waterland 
289*5c51f124SMoriah Waterland 		if (r_sep != NULL) {
290*5c51f124SMoriah Waterland 			char	*x;
291*5c51f124SMoriah Waterland 
292*5c51f124SMoriah Waterland 			x = strpbrk(a_string, a_separators);
293*5c51f124SMoriah Waterland 			if (x != NULL) {
294*5c51f124SMoriah Waterland 				*r_sep = *x;
295*5c51f124SMoriah Waterland 			}
296*5c51f124SMoriah Waterland 		}
297*5c51f124SMoriah Waterland 
298*5c51f124SMoriah Waterland 		/* if this is the 'index'th token requested return it */
299*5c51f124SMoriah Waterland 
300*5c51f124SMoriah Waterland 		if (a_index-- == 0) {
301*5c51f124SMoriah Waterland 			char	*tmp;
302*5c51f124SMoriah Waterland 
303*5c51f124SMoriah Waterland 			/* duplicate token into its own storage */
304*5c51f124SMoriah Waterland 
305*5c51f124SMoriah Waterland 			tmp = _z_strdup(q);
306*5c51f124SMoriah Waterland 
307*5c51f124SMoriah Waterland 			/* free up copy of original input string */
308*5c51f124SMoriah Waterland 
309*5c51f124SMoriah Waterland 			free(p);
310*5c51f124SMoriah Waterland 
311*5c51f124SMoriah Waterland 			/* return token found */
312*5c51f124SMoriah Waterland 
313*5c51f124SMoriah Waterland 			return (tmp);
314*5c51f124SMoriah Waterland 		}
315*5c51f124SMoriah Waterland 	}
316*5c51f124SMoriah Waterland 
317*5c51f124SMoriah Waterland 	/*
318*5c51f124SMoriah Waterland 	 * token not found
319*5c51f124SMoriah Waterland 	 */
320*5c51f124SMoriah Waterland 
321*5c51f124SMoriah Waterland 	/* free up copy of original input string */
322*5c51f124SMoriah Waterland 
323*5c51f124SMoriah Waterland 	free(p);
324*5c51f124SMoriah Waterland 
325*5c51f124SMoriah Waterland 	/* return NULL pointer (token not found) */
326*5c51f124SMoriah Waterland 
327*5c51f124SMoriah Waterland 	return (NULL);
328*5c51f124SMoriah Waterland }
329*5c51f124SMoriah Waterland 
330*5c51f124SMoriah Waterland /*
331*5c51f124SMoriah Waterland  * Name:	_z_strGetToken_r
332*5c51f124SMoriah Waterland  * Synopsis:	Get separator delimited token from a string into a fixed buffer
333*5c51f124SMoriah Waterland  * Description:	Given a string and a list of one or more separators,
334*5c51f124SMoriah Waterland  *		return the position specified token (sequence of one or
335*5c51f124SMoriah Waterland  *		more characters that do not include any of the separators)
336*5c51f124SMoriah Waterland  *		into a specified buffer of a fixed maximum size
337*5c51f124SMoriah Waterland  * Arguments:	r_sep - [*RW] - (char *)
338*5c51f124SMoriah Waterland  *			- separator that ended the token returned
339*5c51f124SMoriah Waterland  *			- NOTE: this is a pointer to a "char", e.g.:
340*5c51f124SMoriah Waterland  *				- char a;
341*5c51f124SMoriah Waterland  *				- _z_strGetToken(&a, ...)
342*5c51f124SMoriah Waterland  *		a_string - [RO, *RO] - (char *)
343*5c51f124SMoriah Waterland  *			- pointer to string to extract token from
344*5c51f124SMoriah Waterland  *		a_index - [RO, *RO] - (int)
345*5c51f124SMoriah Waterland  *			- Index of token to return; '0' is first matching
346*5c51f124SMoriah Waterland  *			  token, '1' is second matching token, etc.
347*5c51f124SMoriah Waterland  *		a_separators - [RO, *RO] - (char *)
348*5c51f124SMoriah Waterland  *			- String containing one or more characters that
349*5c51f124SMoriah Waterland  *			  can separate one "token" from another
350*5c51f124SMoriah Waterland  *		a_buf - [RO, *RW] - (char *)
351*5c51f124SMoriah Waterland  *			- Pointer to buffer used as storage space for the
352*5c51f124SMoriah Waterland  *			  returned token - the returned token is always
353*5c51f124SMoriah Waterland  *			  null terminated
354*5c51f124SMoriah Waterland  *			  a_buf[0] == '\0' - no token meeting criteria found
355*5c51f124SMoriah Waterland  *			  a_buf[0] != '\0' - token meeting criteria returned
356*5c51f124SMoriah Waterland  *		a_bufLen - [RO, *RO] - (int)
357*5c51f124SMoriah Waterland  *			- Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1'
358*5c51f124SMoriah Waterland  *			  bytes will be placed in 'a_buf' - the returned
359*5c51f124SMoriah Waterland  *			  token is always null terminated
360*5c51f124SMoriah Waterland  * Returns:	void
361*5c51f124SMoriah Waterland  */
362*5c51f124SMoriah Waterland 
363*5c51f124SMoriah Waterland void
_z_strGetToken_r(char * r_sep,char * a_string,int a_index,char * a_separators,char * a_buf,int a_bufLen)364*5c51f124SMoriah Waterland _z_strGetToken_r(char *r_sep, char *a_string, int a_index,
365*5c51f124SMoriah Waterland     char *a_separators, char *a_buf, int a_bufLen)
366*5c51f124SMoriah Waterland {
367*5c51f124SMoriah Waterland 	char	*p;
368*5c51f124SMoriah Waterland 	char	*q;
369*5c51f124SMoriah Waterland 	char	*lasts;
370*5c51f124SMoriah Waterland 
371*5c51f124SMoriah Waterland 	/* entry assertions */
372*5c51f124SMoriah Waterland 
373*5c51f124SMoriah Waterland 	assert(a_string != NULL);
374*5c51f124SMoriah Waterland 	assert(a_index >= 0);
375*5c51f124SMoriah Waterland 	assert(a_separators != NULL);
376*5c51f124SMoriah Waterland 	assert(*a_separators != '\0');
377*5c51f124SMoriah Waterland 	assert(a_buf != NULL);
378*5c51f124SMoriah Waterland 	assert(a_bufLen > 0);
379*5c51f124SMoriah Waterland 
380*5c51f124SMoriah Waterland 	/* reset returned separator */
381*5c51f124SMoriah Waterland 
382*5c51f124SMoriah Waterland 	if (r_sep != NULL) {
383*5c51f124SMoriah Waterland 		*r_sep = '\0';
384*5c51f124SMoriah Waterland 	}
385*5c51f124SMoriah Waterland 
386*5c51f124SMoriah Waterland 	/* zero out contents of return buffer */
387*5c51f124SMoriah Waterland 
388*5c51f124SMoriah Waterland 	bzero(a_buf, a_bufLen);
389*5c51f124SMoriah Waterland 
390*5c51f124SMoriah Waterland 	/* duplicate original string before breaking down into tokens */
391*5c51f124SMoriah Waterland 
392*5c51f124SMoriah Waterland 	p = _z_strdup(a_string);
393*5c51f124SMoriah Waterland 
394*5c51f124SMoriah Waterland 	lasts = p;
395*5c51f124SMoriah Waterland 
396*5c51f124SMoriah Waterland 	/* scan for separators and return 'index'th token found */
397*5c51f124SMoriah Waterland 
398*5c51f124SMoriah Waterland 	while (q = strtok_r(NULL, a_separators, &lasts)) {
399*5c51f124SMoriah Waterland 		/* retrieve separator if requested */
400*5c51f124SMoriah Waterland 
401*5c51f124SMoriah Waterland 		if (r_sep != NULL) {
402*5c51f124SMoriah Waterland 			char	*x;
403*5c51f124SMoriah Waterland 			x = strpbrk(a_string, a_separators);
404*5c51f124SMoriah Waterland 			if (x != NULL) {
405*5c51f124SMoriah Waterland 				*r_sep = *x;
406*5c51f124SMoriah Waterland 			}
407*5c51f124SMoriah Waterland 		}
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland 		/* if this is the 'index'th token requested return it */
410*5c51f124SMoriah Waterland 
411*5c51f124SMoriah Waterland 		if (a_index-- == 0) {
412*5c51f124SMoriah Waterland 			/* copy as many characters as possible to return buf */
413*5c51f124SMoriah Waterland 
414*5c51f124SMoriah Waterland 			(void) strncpy(a_buf, q, a_bufLen-1);
415*5c51f124SMoriah Waterland 			break;
416*5c51f124SMoriah Waterland 		}
417*5c51f124SMoriah Waterland 	}
418*5c51f124SMoriah Waterland 
419*5c51f124SMoriah Waterland 	/* free up copy of original input string */
420*5c51f124SMoriah Waterland 
421*5c51f124SMoriah Waterland 	free(p);
422*5c51f124SMoriah Waterland }
423*5c51f124SMoriah Waterland 
424*5c51f124SMoriah Waterland /*
425*5c51f124SMoriah Waterland  * Name:	_z_strPrintf
426*5c51f124SMoriah Waterland  * Synopsis:	Create string from printf style format and arguments
427*5c51f124SMoriah Waterland  * Description:	Call to convert a printf style format and arguments into a
428*5c51f124SMoriah Waterland  *		string of characters placed in allocated storage
429*5c51f124SMoriah Waterland  * Arguments:	format - [RO, RO*] (char *)
430*5c51f124SMoriah Waterland  *			printf-style format for string to be formatted
431*5c51f124SMoriah Waterland  *		VARG_LIST - [RO] (?)
432*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
433*5c51f124SMoriah Waterland  * Returns:	char *
434*5c51f124SMoriah Waterland  *			A string representing the printf conversion results
435*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
436*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
437*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
438*5c51f124SMoriah Waterland  * Errors:	If the string cannot be created, the process exits
439*5c51f124SMoriah Waterland  */
440*5c51f124SMoriah Waterland 
441*5c51f124SMoriah Waterland /*PRINTFLIKE1*/
442*5c51f124SMoriah Waterland char *
_z_strPrintf(char * a_format,...)443*5c51f124SMoriah Waterland _z_strPrintf(char *a_format, ...)
444*5c51f124SMoriah Waterland {
445*5c51f124SMoriah Waterland 	va_list		ap;
446*5c51f124SMoriah Waterland 	size_t		vres = 0;
447*5c51f124SMoriah Waterland 	char		bfr[1];
448*5c51f124SMoriah Waterland 	char		*rstr = NULL;
449*5c51f124SMoriah Waterland 
450*5c51f124SMoriah Waterland 	/* entry assertions */
451*5c51f124SMoriah Waterland 
452*5c51f124SMoriah Waterland 	assert(a_format != NULL);
453*5c51f124SMoriah Waterland 	assert(*a_format != '\0');
454*5c51f124SMoriah Waterland 
455*5c51f124SMoriah Waterland 	/* determine size of the message in bytes */
456*5c51f124SMoriah Waterland 
457*5c51f124SMoriah Waterland 	va_start(ap, a_format);
458*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
459*5c51f124SMoriah Waterland 	va_end(ap);
460*5c51f124SMoriah Waterland 
461*5c51f124SMoriah Waterland 	assert(vres > 0);
462*5c51f124SMoriah Waterland 	assert(vres < LINE_MAX);
463*5c51f124SMoriah Waterland 
464*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
465*5c51f124SMoriah Waterland 
466*5c51f124SMoriah Waterland 	rstr = (char *)_z_calloc(vres+2);
467*5c51f124SMoriah Waterland 
468*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
469*5c51f124SMoriah Waterland 
470*5c51f124SMoriah Waterland 	va_start(ap, a_format);
471*5c51f124SMoriah Waterland 	vres = vsnprintf(rstr, vres+1, a_format, ap);
472*5c51f124SMoriah Waterland 	va_end(ap);
473*5c51f124SMoriah Waterland 
474*5c51f124SMoriah Waterland 	assert(vres > 0);
475*5c51f124SMoriah Waterland 	assert(vres < LINE_MAX);
476*5c51f124SMoriah Waterland 	assert(*rstr != '\0');
477*5c51f124SMoriah Waterland 
478*5c51f124SMoriah Waterland 	/* return the results */
479*5c51f124SMoriah Waterland 
480*5c51f124SMoriah Waterland 	return (rstr);
481*5c51f124SMoriah Waterland }
482*5c51f124SMoriah Waterland 
483*5c51f124SMoriah Waterland /*
484*5c51f124SMoriah Waterland  * Name:	_z_strPrintf_r
485*5c51f124SMoriah Waterland  * Synopsis:	Create string from printf style format and arguments
486*5c51f124SMoriah Waterland  * Description:	Call to convert a printf style format and arguments into a
487*5c51f124SMoriah Waterland  *		string of characters placed in allocated storage
488*5c51f124SMoriah Waterland  * Arguments:	a_buf - [RO, *RW] - (char *)
489*5c51f124SMoriah Waterland  *			- Pointer to buffer used as storage space for the
490*5c51f124SMoriah Waterland  *			  returned string created
491*5c51f124SMoriah Waterland  *		a_bufLen - [RO, *RO] - (int)
492*5c51f124SMoriah Waterland  *			- Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1'
493*5c51f124SMoriah Waterland  *			  bytes will be placed in 'a_buf' - the returned
494*5c51f124SMoriah Waterland  *			  string is always null terminated
495*5c51f124SMoriah Waterland  *		a_format - [RO, RO*] (char *)
496*5c51f124SMoriah Waterland  *			printf-style format for string to be formatted
497*5c51f124SMoriah Waterland  *		VARG_LIST - [RO] (?)
498*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
499*5c51f124SMoriah Waterland  * Returns:	void
500*5c51f124SMoriah Waterland  */
501*5c51f124SMoriah Waterland 
502*5c51f124SMoriah Waterland /*PRINTFLIKE3*/
503*5c51f124SMoriah Waterland void
_z_strPrintf_r(char * a_buf,int a_bufLen,char * a_format,...)504*5c51f124SMoriah Waterland _z_strPrintf_r(char *a_buf, int a_bufLen, char *a_format, ...)
505*5c51f124SMoriah Waterland {
506*5c51f124SMoriah Waterland 	va_list		ap;
507*5c51f124SMoriah Waterland 	size_t		vres = 0;
508*5c51f124SMoriah Waterland 
509*5c51f124SMoriah Waterland 	/* entry assertions */
510*5c51f124SMoriah Waterland 
511*5c51f124SMoriah Waterland 	assert(a_format != NULL);
512*5c51f124SMoriah Waterland 	assert(*a_format != '\0');
513*5c51f124SMoriah Waterland 	assert(a_buf != NULL);
514*5c51f124SMoriah Waterland 	assert(a_bufLen > 1);
515*5c51f124SMoriah Waterland 
516*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
517*5c51f124SMoriah Waterland 
518*5c51f124SMoriah Waterland 	va_start(ap, a_format);
519*5c51f124SMoriah Waterland 	vres = vsnprintf(a_buf, a_bufLen-1, a_format, ap);
520*5c51f124SMoriah Waterland 	va_end(ap);
521*5c51f124SMoriah Waterland 
522*5c51f124SMoriah Waterland 	assert(vres > 0);
523*5c51f124SMoriah Waterland 	assert(vres < a_bufLen);
524*5c51f124SMoriah Waterland 
525*5c51f124SMoriah Waterland 	a_buf[a_bufLen-1] = '\0';
526*5c51f124SMoriah Waterland }
527*5c51f124SMoriah Waterland 
528*5c51f124SMoriah Waterland /*
529*5c51f124SMoriah Waterland  * Name:	_z_strRemoveLeadingWhitespace
530*5c51f124SMoriah Waterland  * Synopsis:	Remove leading whitespace from string
531*5c51f124SMoriah Waterland  * Description:	Remove all leading whitespace characters from a string
532*5c51f124SMoriah Waterland  * Arguments:	a_str - [RO, *RW] - (char **)
533*5c51f124SMoriah Waterland  *			Pointer to handle to string (in allocated storage) to
534*5c51f124SMoriah Waterland  *			remove all leading whitespace from
535*5c51f124SMoriah Waterland  * Returns:	void
536*5c51f124SMoriah Waterland  *			The input string is modified as follows:
537*5c51f124SMoriah Waterland  *			== NULL:
538*5c51f124SMoriah Waterland  *				- input string was NULL
539*5c51f124SMoriah Waterland  *				- input string is all whitespace
540*5c51f124SMoriah Waterland  *			!= NULL:
541*5c51f124SMoriah Waterland  *				- copy of input string with leading
542*5c51f124SMoriah Waterland  *				  whitespace removed
543*5c51f124SMoriah Waterland  * CAUTION:	The input string must be allocated space (via mem* or
544*5c51f124SMoriah Waterland  *		_z_str* methods) - it must not be a static or inline
545*5c51f124SMoriah Waterland  *		character string
546*5c51f124SMoriah Waterland  * NOTE:	The input string a_str will be freed with 'free'
547*5c51f124SMoriah Waterland  *		if it is all whitespace, or if it contains any leading
548*5c51f124SMoriah Waterland  *		whitespace characters
549*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
550*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
551*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
552*5c51f124SMoriah Waterland  * Errors:	If the string cannot be created, the process exits
553*5c51f124SMoriah Waterland  */
554*5c51f124SMoriah Waterland 
555*5c51f124SMoriah Waterland void
_z_strRemoveLeadingWhitespace(char ** a_str)556*5c51f124SMoriah Waterland _z_strRemoveLeadingWhitespace(char **a_str)
557*5c51f124SMoriah Waterland {
558*5c51f124SMoriah Waterland 	char	*o_str;
559*5c51f124SMoriah Waterland 
560*5c51f124SMoriah Waterland 	/* entry assertions */
561*5c51f124SMoriah Waterland 
562*5c51f124SMoriah Waterland 	assert(a_str != NULL);
563*5c51f124SMoriah Waterland 
564*5c51f124SMoriah Waterland 	/* if string is null, just return */
565*5c51f124SMoriah Waterland 
566*5c51f124SMoriah Waterland 	if (*a_str == NULL) {
567*5c51f124SMoriah Waterland 		return;
568*5c51f124SMoriah Waterland 	}
569*5c51f124SMoriah Waterland 	o_str = *a_str;
570*5c51f124SMoriah Waterland 
571*5c51f124SMoriah Waterland 	/* if string is empty, deallocate and return NULL */
572*5c51f124SMoriah Waterland 
573*5c51f124SMoriah Waterland 	if (*o_str == '\0') {
574*5c51f124SMoriah Waterland 		/* free string - handle is not reset to NULL by free */
575*5c51f124SMoriah Waterland 		free(*a_str);
576*5c51f124SMoriah Waterland 		*a_str = NULL;
577*5c51f124SMoriah Waterland 		return;
578*5c51f124SMoriah Waterland 	}
579*5c51f124SMoriah Waterland 
580*5c51f124SMoriah Waterland 	/* if first character is not a space, just return */
581*5c51f124SMoriah Waterland 
582*5c51f124SMoriah Waterland 	if (!isspace(*o_str)) {
583*5c51f124SMoriah Waterland 		return;
584*5c51f124SMoriah Waterland 	}
585*5c51f124SMoriah Waterland 
586*5c51f124SMoriah Waterland 	/* advance past all space characters */
587*5c51f124SMoriah Waterland 
588*5c51f124SMoriah Waterland 	while ((*o_str != '\0') && (isspace(*o_str))) {
589*5c51f124SMoriah Waterland 		o_str++;
590*5c51f124SMoriah Waterland 	}
591*5c51f124SMoriah Waterland 
592*5c51f124SMoriah Waterland 	/* if string was all space characters, deallocate and return NULL */
593*5c51f124SMoriah Waterland 
594*5c51f124SMoriah Waterland 	if (*o_str == '\0') {
595*5c51f124SMoriah Waterland 		/* free string - *a_str is not reset to NULL by free */
596*5c51f124SMoriah Waterland 		free(*a_str);
597*5c51f124SMoriah Waterland 		*a_str = NULL;
598*5c51f124SMoriah Waterland 		return;
599*5c51f124SMoriah Waterland 	}
600*5c51f124SMoriah Waterland 
601*5c51f124SMoriah Waterland 	/* have non-space/null byte, return dup, deallocate original */
602*5c51f124SMoriah Waterland 
603*5c51f124SMoriah Waterland 	free(*a_str);
604*5c51f124SMoriah Waterland 	*a_str = _z_strdup(o_str);
605*5c51f124SMoriah Waterland }
606*5c51f124SMoriah Waterland 
607*5c51f124SMoriah Waterland /*
608*5c51f124SMoriah Waterland  * Name:	_z_strRemoveToken
609*5c51f124SMoriah Waterland  * Synopsis:	Remove a token from a string
610*5c51f124SMoriah Waterland  * Description:	Remove a token (sequence of one or more characters) from a
611*5c51f124SMoriah Waterland  *		string that is in allocated space
612*5c51f124SMoriah Waterland  * Arguments:	r_string - [RO, *RW] - (char **)
613*5c51f124SMoriah Waterland  *			- Pointer to handle to string to remove token from
614*5c51f124SMoriah Waterland  *		a_token - [RO, *RO] - (char *)
615*5c51f124SMoriah Waterland  *			Pointer to token (substring) to look for and remove
616*5c51f124SMoriah Waterland  *			from r_string provided
617*5c51f124SMoriah Waterland  *		a_separators - [RO, *RO] - (char *)
618*5c51f124SMoriah Waterland  *			- String containing one or more characters that
619*5c51f124SMoriah Waterland  *			  separate one "token" from another in r_string
620*5c51f124SMoriah Waterland  *		a_index - [RO, *RO] - (int)
621*5c51f124SMoriah Waterland  *			- Index of token to remove; '0' is first matching
622*5c51f124SMoriah Waterland  *			  token, '1' is second matching token, etc.
623*5c51f124SMoriah Waterland  * Returns:	void
624*5c51f124SMoriah Waterland  * CAUTION:	The input string must be allocated space (via lu_mem* or
625*5c51f124SMoriah Waterland  *		_z_str* methods) - it must not be a static or inline
626*5c51f124SMoriah Waterland  *		character string
627*5c51f124SMoriah Waterland  * NOTE:	The input string r_string will be freed with 'free'
628*5c51f124SMoriah Waterland  *		if the token to be removed is found
629*5c51f124SMoriah Waterland  * NOTE:    	Any token string returned is placed in new storage for the
630*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
631*5c51f124SMoriah Waterland  *		of the storage once the token string is no longer needed.
632*5c51f124SMoriah Waterland  * Errors:	If the new token string cannot be created, the process exits
633*5c51f124SMoriah Waterland  */
634*5c51f124SMoriah Waterland 
635*5c51f124SMoriah Waterland void
_z_strRemoveToken(char ** r_string,char * a_token,char * a_separators,int a_index)636*5c51f124SMoriah Waterland _z_strRemoveToken(char **r_string, char *a_token, char *a_separators,
637*5c51f124SMoriah Waterland 	int a_index)
638*5c51f124SMoriah Waterland {
639*5c51f124SMoriah Waterland 	char	*a_string;
640*5c51f124SMoriah Waterland 	char	*copyString;
641*5c51f124SMoriah Waterland 	char	sep = 0;
642*5c51f124SMoriah Waterland 	int	copyLength;
643*5c51f124SMoriah Waterland 	int	i;
644*5c51f124SMoriah Waterland 
645*5c51f124SMoriah Waterland 	/* entry assertions */
646*5c51f124SMoriah Waterland 
647*5c51f124SMoriah Waterland 	assert(r_string != NULL);
648*5c51f124SMoriah Waterland 	assert(a_token != NULL);
649*5c51f124SMoriah Waterland 	assert(*a_token != '\0');
650*5c51f124SMoriah Waterland 	assert(a_separators != NULL);
651*5c51f124SMoriah Waterland 	assert(*a_separators != '\0');
652*5c51f124SMoriah Waterland 
653*5c51f124SMoriah Waterland 	/* simple case: input string is null; return empty string */
654*5c51f124SMoriah Waterland 
655*5c51f124SMoriah Waterland 	a_string = *r_string;
656*5c51f124SMoriah Waterland 	if (*a_string == '\0') {
657*5c51f124SMoriah Waterland 		return;
658*5c51f124SMoriah Waterland 	}
659*5c51f124SMoriah Waterland 
660*5c51f124SMoriah Waterland 	/* simple case: token == input string; return empty string */
661*5c51f124SMoriah Waterland 
662*5c51f124SMoriah Waterland 	if (strcmp(a_string, a_token) == 0) {
663*5c51f124SMoriah Waterland 		/*
664*5c51f124SMoriah Waterland 		 * deallocate input string; free doesn't
665*5c51f124SMoriah Waterland 		 * set *r_string to NULL
666*5c51f124SMoriah Waterland 		 */
667*5c51f124SMoriah Waterland 		free(*r_string);
668*5c51f124SMoriah Waterland 		*r_string = NULL;
669*5c51f124SMoriah Waterland 		return;
670*5c51f124SMoriah Waterland 	}
671*5c51f124SMoriah Waterland 
672*5c51f124SMoriah Waterland 	/* simple case: token not in input string: return */
673*5c51f124SMoriah Waterland 
674*5c51f124SMoriah Waterland 	if (!_z_strContainsToken(a_string, a_token, a_separators)) {
675*5c51f124SMoriah Waterland 		return;
676*5c51f124SMoriah Waterland 	}
677*5c51f124SMoriah Waterland 
678*5c51f124SMoriah Waterland 	/*
679*5c51f124SMoriah Waterland 	 * Pick apart the old string building the new one as we go along
680*5c51f124SMoriah Waterland 	 * removing the first occurance of the token provided
681*5c51f124SMoriah Waterland 	 */
682*5c51f124SMoriah Waterland 
683*5c51f124SMoriah Waterland 	copyLength = (strlen(a_string)-strlen(a_token))+2;
684*5c51f124SMoriah Waterland 	copyString = (char *)_z_calloc(copyLength);
685*5c51f124SMoriah Waterland 
686*5c51f124SMoriah Waterland 	for (i = 0; ; i++) {
687*5c51f124SMoriah Waterland 		char	*p;
688*5c51f124SMoriah Waterland 
689*5c51f124SMoriah Waterland 		p = _z_strGetToken(&sep, a_string, i, a_separators);
690*5c51f124SMoriah Waterland 		if (p == NULL) {
691*5c51f124SMoriah Waterland 			break;
692*5c51f124SMoriah Waterland 		}
693*5c51f124SMoriah Waterland 
694*5c51f124SMoriah Waterland 		if ((strcmp(p, a_token) == 0) && (a_index-- == 0)) {
695*5c51f124SMoriah Waterland 			free(p);
696*5c51f124SMoriah Waterland 			continue;
697*5c51f124SMoriah Waterland 		}
698*5c51f124SMoriah Waterland 
699*5c51f124SMoriah Waterland 		if (*copyString) {
700*5c51f124SMoriah Waterland 			assert(sep != '\0');
701*5c51f124SMoriah Waterland 			(void) strncat(copyString, &sep, 1);
702*5c51f124SMoriah Waterland 		}
703*5c51f124SMoriah Waterland 
704*5c51f124SMoriah Waterland 		(void) strcat(copyString, p);
705*5c51f124SMoriah Waterland 		free(p);
706*5c51f124SMoriah Waterland 	}
707*5c51f124SMoriah Waterland 
708*5c51f124SMoriah Waterland 	free(*r_string);
709*5c51f124SMoriah Waterland 	assert(*copyString);
710*5c51f124SMoriah Waterland 	*r_string = copyString;
711*5c51f124SMoriah Waterland }
712