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 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 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 * 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 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 * 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 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 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 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