1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Implementations of the functions described in vsnprintf(3C) and string(3C), 31*7c478bd9Sstevel@tonic-gate * for use by the kernel, the standalone, and kmdb. Unless otherwise specified, 32*7c478bd9Sstevel@tonic-gate * these functions match the section 3C manpages. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/varargs.h> 37*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) || defined(_KMDB) 38*7c478bd9Sstevel@tonic-gate #include <string.h> 39*7c478bd9Sstevel@tonic-gate #else 40*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 41*7c478bd9Sstevel@tonic-gate #endif 42*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 43*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 44*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * kmdb has its own *printf routines, and thus doesn't need these versions too. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate #if !defined(_KMDB) 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #define ADDCHAR(c) if (bufp++ - buf < buflen) bufp[-1] = (c) 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate /* 54*7c478bd9Sstevel@tonic-gate * Given a buffer 'buf' of size 'buflen', render as much of the string 55*7c478bd9Sstevel@tonic-gate * described by <fmt, args> as possible. The string will always be 56*7c478bd9Sstevel@tonic-gate * null-terminated, so the maximum string length is 'buflen - 1'. 57*7c478bd9Sstevel@tonic-gate * Returns the number of bytes that would be necessary to render the 58*7c478bd9Sstevel@tonic-gate * entire string, not including null terminator (just like vsnprintf(3S)). 59*7c478bd9Sstevel@tonic-gate * To determine buffer size in advance, use vsnprintf(NULL, 0, fmt, args) + 1. 60*7c478bd9Sstevel@tonic-gate * 61*7c478bd9Sstevel@tonic-gate * There is no support for floating point, and the C locale is assumed. 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate size_t 64*7c478bd9Sstevel@tonic-gate vsnprintf(char *buf, size_t buflen, const char *fmt, va_list aargs) 65*7c478bd9Sstevel@tonic-gate { 66*7c478bd9Sstevel@tonic-gate uint64_t ul, tmp; 67*7c478bd9Sstevel@tonic-gate char *bufp = buf; /* current buffer pointer */ 68*7c478bd9Sstevel@tonic-gate int pad, width, ells, base, sign, c; 69*7c478bd9Sstevel@tonic-gate char *digits, *sp, *bs; 70*7c478bd9Sstevel@tonic-gate char numbuf[65]; /* sufficient for a 64-bit binary value */ 71*7c478bd9Sstevel@tonic-gate va_list args; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Make a copy so that all our callers don't have to make a copy 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate va_copy(args, aargs); 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate if ((ssize_t)buflen < 0) 79*7c478bd9Sstevel@tonic-gate buflen = 0; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate while ((c = *fmt++) != '\0') { 82*7c478bd9Sstevel@tonic-gate if (c != '%') { 83*7c478bd9Sstevel@tonic-gate ADDCHAR(c); 84*7c478bd9Sstevel@tonic-gate continue; 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate if ((c = *fmt++) == '\0') 88*7c478bd9Sstevel@tonic-gate break; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate for (pad = ' '; c == '0'; c = *fmt++) 91*7c478bd9Sstevel@tonic-gate pad = '0'; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate for (width = 0; c >= '0' && c <= '9'; c = *fmt++) 94*7c478bd9Sstevel@tonic-gate width = width * 10 + c - '0'; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate for (ells = 0; c == 'l'; c = *fmt++) 97*7c478bd9Sstevel@tonic-gate ells++; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate digits = "0123456789abcdef"; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate if (c >= 'A' && c <= 'Z') { 102*7c478bd9Sstevel@tonic-gate c += 'a' - 'A'; 103*7c478bd9Sstevel@tonic-gate digits = "0123456789ABCDEF"; 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate base = sign = 0; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate switch (c) { 109*7c478bd9Sstevel@tonic-gate case 'd': 110*7c478bd9Sstevel@tonic-gate sign = 1; 111*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 112*7c478bd9Sstevel@tonic-gate case 'u': 113*7c478bd9Sstevel@tonic-gate base = 10; 114*7c478bd9Sstevel@tonic-gate break; 115*7c478bd9Sstevel@tonic-gate case 'p': 116*7c478bd9Sstevel@tonic-gate ells = 1; 117*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 118*7c478bd9Sstevel@tonic-gate case 'x': 119*7c478bd9Sstevel@tonic-gate base = 16; 120*7c478bd9Sstevel@tonic-gate break; 121*7c478bd9Sstevel@tonic-gate case 'o': 122*7c478bd9Sstevel@tonic-gate base = 8; 123*7c478bd9Sstevel@tonic-gate break; 124*7c478bd9Sstevel@tonic-gate case 'b': 125*7c478bd9Sstevel@tonic-gate ells = 0; 126*7c478bd9Sstevel@tonic-gate base = 1; 127*7c478bd9Sstevel@tonic-gate break; 128*7c478bd9Sstevel@tonic-gate case 'c': 129*7c478bd9Sstevel@tonic-gate ul = (int64_t)va_arg(args, int); 130*7c478bd9Sstevel@tonic-gate ADDCHAR((int)ul & 0xff); 131*7c478bd9Sstevel@tonic-gate break; 132*7c478bd9Sstevel@tonic-gate case 's': 133*7c478bd9Sstevel@tonic-gate sp = va_arg(args, char *); 134*7c478bd9Sstevel@tonic-gate if (sp == NULL) 135*7c478bd9Sstevel@tonic-gate sp = "<null string>"; 136*7c478bd9Sstevel@tonic-gate while ((c = *sp++) != 0) 137*7c478bd9Sstevel@tonic-gate ADDCHAR(c); 138*7c478bd9Sstevel@tonic-gate break; 139*7c478bd9Sstevel@tonic-gate case '%': 140*7c478bd9Sstevel@tonic-gate ADDCHAR('%'); 141*7c478bd9Sstevel@tonic-gate break; 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate if (base == 0) 145*7c478bd9Sstevel@tonic-gate continue; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate if (ells == 0) 148*7c478bd9Sstevel@tonic-gate ul = (int64_t)va_arg(args, int); 149*7c478bd9Sstevel@tonic-gate else if (ells == 1) 150*7c478bd9Sstevel@tonic-gate ul = (int64_t)va_arg(args, long); 151*7c478bd9Sstevel@tonic-gate else 152*7c478bd9Sstevel@tonic-gate ul = (int64_t)va_arg(args, int64_t); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate if (sign && (int64_t)ul < 0) 155*7c478bd9Sstevel@tonic-gate ul = -ul; 156*7c478bd9Sstevel@tonic-gate else 157*7c478bd9Sstevel@tonic-gate sign = 0; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate if (ells < 8 / sizeof (long)) 160*7c478bd9Sstevel@tonic-gate ul &= 0xffffffffU; 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if (c == 'b') { 163*7c478bd9Sstevel@tonic-gate bs = va_arg(args, char *); 164*7c478bd9Sstevel@tonic-gate base = *bs++; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate tmp = ul; 168*7c478bd9Sstevel@tonic-gate do { 169*7c478bd9Sstevel@tonic-gate width--; 170*7c478bd9Sstevel@tonic-gate } while ((tmp /= base) != 0); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (sign && pad == '0') 173*7c478bd9Sstevel@tonic-gate ADDCHAR('-'); 174*7c478bd9Sstevel@tonic-gate while (width-- > sign) 175*7c478bd9Sstevel@tonic-gate ADDCHAR(pad); 176*7c478bd9Sstevel@tonic-gate if (sign && pad == ' ') 177*7c478bd9Sstevel@tonic-gate ADDCHAR('-'); 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate sp = numbuf; 180*7c478bd9Sstevel@tonic-gate tmp = ul; 181*7c478bd9Sstevel@tonic-gate do { 182*7c478bd9Sstevel@tonic-gate *sp++ = digits[tmp % base]; 183*7c478bd9Sstevel@tonic-gate } while ((tmp /= base) != 0); 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate while (sp > numbuf) { 186*7c478bd9Sstevel@tonic-gate sp--; 187*7c478bd9Sstevel@tonic-gate ADDCHAR(*sp); 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate if (c == 'b' && ul != 0) { 191*7c478bd9Sstevel@tonic-gate int any = 0; 192*7c478bd9Sstevel@tonic-gate c = *bs++; 193*7c478bd9Sstevel@tonic-gate while (c != 0) { 194*7c478bd9Sstevel@tonic-gate if (ul & (1 << (c - 1))) { 195*7c478bd9Sstevel@tonic-gate if (any++ == 0) 196*7c478bd9Sstevel@tonic-gate ADDCHAR('<'); 197*7c478bd9Sstevel@tonic-gate while ((c = *bs++) >= 32) 198*7c478bd9Sstevel@tonic-gate ADDCHAR(c); 199*7c478bd9Sstevel@tonic-gate ADDCHAR(','); 200*7c478bd9Sstevel@tonic-gate } else { 201*7c478bd9Sstevel@tonic-gate while ((c = *bs++) >= 32) 202*7c478bd9Sstevel@tonic-gate continue; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate if (any) { 206*7c478bd9Sstevel@tonic-gate bufp--; 207*7c478bd9Sstevel@tonic-gate ADDCHAR('>'); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate if (bufp - buf < buflen) 212*7c478bd9Sstevel@tonic-gate bufp[0] = c; 213*7c478bd9Sstevel@tonic-gate else if (buflen != 0) 214*7c478bd9Sstevel@tonic-gate buf[buflen - 1] = c; 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate va_end(args); 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate return (bufp - buf); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 222*7c478bd9Sstevel@tonic-gate size_t 223*7c478bd9Sstevel@tonic-gate snprintf(char *buf, size_t buflen, const char *fmt, ...) 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate va_list args; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate va_start(args, fmt); 228*7c478bd9Sstevel@tonic-gate buflen = vsnprintf(buf, buflen, fmt, args); 229*7c478bd9Sstevel@tonic-gate va_end(args); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate return (buflen); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 235*7c478bd9Sstevel@tonic-gate /* 236*7c478bd9Sstevel@tonic-gate * The sprintf() and vsprintf() routines aren't shared with the kernel because 237*7c478bd9Sstevel@tonic-gate * the DDI mandates that they return the buffer rather than its length. 238*7c478bd9Sstevel@tonic-gate */ 239*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/ 240*7c478bd9Sstevel@tonic-gate int 241*7c478bd9Sstevel@tonic-gate sprintf(char *buf, const char *fmt, ...) 242*7c478bd9Sstevel@tonic-gate { 243*7c478bd9Sstevel@tonic-gate va_list args; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate va_start(args, fmt); 246*7c478bd9Sstevel@tonic-gate (void) vsnprintf(buf, INT_MAX, fmt, args); 247*7c478bd9Sstevel@tonic-gate va_end(args); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate return (strlen(buf)); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate int 253*7c478bd9Sstevel@tonic-gate vsprintf(char *buf, const char *fmt, va_list args) 254*7c478bd9Sstevel@tonic-gate { 255*7c478bd9Sstevel@tonic-gate (void) vsnprintf(buf, INT_MAX, fmt, args); 256*7c478bd9Sstevel@tonic-gate return (strlen(buf)); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate #endif 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate #endif /* !_KMDB */ 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate char * 263*7c478bd9Sstevel@tonic-gate strcat(char *s1, const char *s2) 264*7c478bd9Sstevel@tonic-gate { 265*7c478bd9Sstevel@tonic-gate char *os1 = s1; 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate while (*s1++ != '\0') 268*7c478bd9Sstevel@tonic-gate ; 269*7c478bd9Sstevel@tonic-gate s1--; 270*7c478bd9Sstevel@tonic-gate while ((*s1++ = *s2++) != '\0') 271*7c478bd9Sstevel@tonic-gate ; 272*7c478bd9Sstevel@tonic-gate return (os1); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate char * 276*7c478bd9Sstevel@tonic-gate strchr(const char *sp, int c) 277*7c478bd9Sstevel@tonic-gate { 278*7c478bd9Sstevel@tonic-gate do { 279*7c478bd9Sstevel@tonic-gate if (*sp == (char)c) 280*7c478bd9Sstevel@tonic-gate return ((char *)sp); 281*7c478bd9Sstevel@tonic-gate } while (*sp++); 282*7c478bd9Sstevel@tonic-gate return (NULL); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate int 286*7c478bd9Sstevel@tonic-gate strcmp(const char *s1, const char *s2) 287*7c478bd9Sstevel@tonic-gate { 288*7c478bd9Sstevel@tonic-gate while (*s1 == *s2++) 289*7c478bd9Sstevel@tonic-gate if (*s1++ == '\0') 290*7c478bd9Sstevel@tonic-gate return (0); 291*7c478bd9Sstevel@tonic-gate return (*(unsigned char *)s1 - *(unsigned char *)--s2); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate int 295*7c478bd9Sstevel@tonic-gate strncmp(const char *s1, const char *s2, size_t n) 296*7c478bd9Sstevel@tonic-gate { 297*7c478bd9Sstevel@tonic-gate if (s1 == s2) 298*7c478bd9Sstevel@tonic-gate return (0); 299*7c478bd9Sstevel@tonic-gate n++; 300*7c478bd9Sstevel@tonic-gate while (--n != 0 && *s1 == *s2++) 301*7c478bd9Sstevel@tonic-gate if (*s1++ == '\0') 302*7c478bd9Sstevel@tonic-gate return (0); 303*7c478bd9Sstevel@tonic-gate return ((n == 0) ? 0 : *(unsigned char *)s1 - *(unsigned char *)--s2); 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate static const char charmap[] = { 307*7c478bd9Sstevel@tonic-gate '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', 308*7c478bd9Sstevel@tonic-gate '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', 309*7c478bd9Sstevel@tonic-gate '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', 310*7c478bd9Sstevel@tonic-gate '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', 311*7c478bd9Sstevel@tonic-gate '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', 312*7c478bd9Sstevel@tonic-gate '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', 313*7c478bd9Sstevel@tonic-gate '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', 314*7c478bd9Sstevel@tonic-gate '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', 315*7c478bd9Sstevel@tonic-gate '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', 316*7c478bd9Sstevel@tonic-gate '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', 317*7c478bd9Sstevel@tonic-gate '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', 318*7c478bd9Sstevel@tonic-gate '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', 319*7c478bd9Sstevel@tonic-gate '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', 320*7c478bd9Sstevel@tonic-gate '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', 321*7c478bd9Sstevel@tonic-gate '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', 322*7c478bd9Sstevel@tonic-gate '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', 323*7c478bd9Sstevel@tonic-gate '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', 324*7c478bd9Sstevel@tonic-gate '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', 325*7c478bd9Sstevel@tonic-gate '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', 326*7c478bd9Sstevel@tonic-gate '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', 327*7c478bd9Sstevel@tonic-gate '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', 328*7c478bd9Sstevel@tonic-gate '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', 329*7c478bd9Sstevel@tonic-gate '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', 330*7c478bd9Sstevel@tonic-gate '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', 331*7c478bd9Sstevel@tonic-gate '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', 332*7c478bd9Sstevel@tonic-gate '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', 333*7c478bd9Sstevel@tonic-gate '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', 334*7c478bd9Sstevel@tonic-gate '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', 335*7c478bd9Sstevel@tonic-gate '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', 336*7c478bd9Sstevel@tonic-gate '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', 337*7c478bd9Sstevel@tonic-gate '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', 338*7c478bd9Sstevel@tonic-gate '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', 339*7c478bd9Sstevel@tonic-gate }; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate int 342*7c478bd9Sstevel@tonic-gate strcasecmp(const char *s1, const char *s2) 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate const unsigned char *cm = (const unsigned char *)charmap; 345*7c478bd9Sstevel@tonic-gate const unsigned char *us1 = (const unsigned char *)s1; 346*7c478bd9Sstevel@tonic-gate const unsigned char *us2 = (const unsigned char *)s2; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate while (cm[*us1] == cm[*us2++]) 349*7c478bd9Sstevel@tonic-gate if (*us1++ == '\0') 350*7c478bd9Sstevel@tonic-gate return (0); 351*7c478bd9Sstevel@tonic-gate return (cm[*us1] - cm[*(us2 - 1)]); 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate int 355*7c478bd9Sstevel@tonic-gate strncasecmp(const char *s1, const char *s2, size_t n) 356*7c478bd9Sstevel@tonic-gate { 357*7c478bd9Sstevel@tonic-gate const unsigned char *cm = (const unsigned char *)charmap; 358*7c478bd9Sstevel@tonic-gate const unsigned char *us1 = (const unsigned char *)s1; 359*7c478bd9Sstevel@tonic-gate const unsigned char *us2 = (const unsigned char *)s2; 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate while (n != 0 && cm[*us1] == cm[*us2++]) { 362*7c478bd9Sstevel@tonic-gate if (*us1++ == '\0') 363*7c478bd9Sstevel@tonic-gate return (0); 364*7c478bd9Sstevel@tonic-gate n--; 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate return (n == 0 ? 0 : cm[*us1] - cm[*(us2 - 1)]); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate char * 370*7c478bd9Sstevel@tonic-gate strcpy(char *s1, const char *s2) 371*7c478bd9Sstevel@tonic-gate { 372*7c478bd9Sstevel@tonic-gate char *os1 = s1; 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate while ((*s1++ = *s2++) != '\0') 375*7c478bd9Sstevel@tonic-gate ; 376*7c478bd9Sstevel@tonic-gate return (os1); 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate char * 380*7c478bd9Sstevel@tonic-gate strncpy(char *s1, const char *s2, size_t n) 381*7c478bd9Sstevel@tonic-gate { 382*7c478bd9Sstevel@tonic-gate char *os1 = s1; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate n++; 385*7c478bd9Sstevel@tonic-gate while (--n != 0 && (*s1++ = *s2++) != '\0') 386*7c478bd9Sstevel@tonic-gate ; 387*7c478bd9Sstevel@tonic-gate if (n != 0) 388*7c478bd9Sstevel@tonic-gate while (--n != 0) 389*7c478bd9Sstevel@tonic-gate *s1++ = '\0'; 390*7c478bd9Sstevel@tonic-gate return (os1); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate char * 394*7c478bd9Sstevel@tonic-gate strrchr(const char *sp, int c) 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate char *r = NULL; 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate do { 399*7c478bd9Sstevel@tonic-gate if (*sp == (char)c) 400*7c478bd9Sstevel@tonic-gate r = (char *)sp; 401*7c478bd9Sstevel@tonic-gate } while (*sp++); 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate return (r); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate char * 407*7c478bd9Sstevel@tonic-gate strstr(const char *as1, const char *as2) 408*7c478bd9Sstevel@tonic-gate { 409*7c478bd9Sstevel@tonic-gate const char *s1, *s2; 410*7c478bd9Sstevel@tonic-gate const char *tptr; 411*7c478bd9Sstevel@tonic-gate char c; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate s1 = as1; 414*7c478bd9Sstevel@tonic-gate s2 = as2; 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate if (s2 == NULL || *s2 == '\0') 417*7c478bd9Sstevel@tonic-gate return ((char *)s1); 418*7c478bd9Sstevel@tonic-gate c = *s2; 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate while (*s1) 421*7c478bd9Sstevel@tonic-gate if (*s1++ == c) { 422*7c478bd9Sstevel@tonic-gate tptr = s1; 423*7c478bd9Sstevel@tonic-gate while ((c = *++s2) == *s1++ && c) 424*7c478bd9Sstevel@tonic-gate ; 425*7c478bd9Sstevel@tonic-gate if (c == 0) 426*7c478bd9Sstevel@tonic-gate return ((char *)tptr - 1); 427*7c478bd9Sstevel@tonic-gate s1 = tptr; 428*7c478bd9Sstevel@tonic-gate s2 = as2; 429*7c478bd9Sstevel@tonic-gate c = *s2; 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate return (NULL); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate char * 436*7c478bd9Sstevel@tonic-gate strpbrk(const char *string, const char *brkset) 437*7c478bd9Sstevel@tonic-gate { 438*7c478bd9Sstevel@tonic-gate const char *p; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate do { 441*7c478bd9Sstevel@tonic-gate for (p = brkset; *p != '\0' && *p != *string; ++p) 442*7c478bd9Sstevel@tonic-gate ; 443*7c478bd9Sstevel@tonic-gate if (*p != '\0') 444*7c478bd9Sstevel@tonic-gate return ((char *)string); 445*7c478bd9Sstevel@tonic-gate } while (*string++); 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate return (NULL); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate char * 451*7c478bd9Sstevel@tonic-gate strncat(char *s1, const char *s2, size_t n) 452*7c478bd9Sstevel@tonic-gate { 453*7c478bd9Sstevel@tonic-gate char *os1 = s1; 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate n++; 456*7c478bd9Sstevel@tonic-gate while (*s1++ != '\0') 457*7c478bd9Sstevel@tonic-gate ; 458*7c478bd9Sstevel@tonic-gate --s1; 459*7c478bd9Sstevel@tonic-gate while ((*s1++ = *s2++) != '\0') { 460*7c478bd9Sstevel@tonic-gate if (--n == 0) { 461*7c478bd9Sstevel@tonic-gate s1[-1] = '\0'; 462*7c478bd9Sstevel@tonic-gate break; 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate return (os1); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) || defined(_KMDB) 469*7c478bd9Sstevel@tonic-gate #define bcopy(src, dst, n) (void) memcpy((dst), (src), (n)) 470*7c478bd9Sstevel@tonic-gate #endif 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate size_t 473*7c478bd9Sstevel@tonic-gate strlcat(char *dst, const char *src, size_t dstsize) 474*7c478bd9Sstevel@tonic-gate { 475*7c478bd9Sstevel@tonic-gate char *df = dst; 476*7c478bd9Sstevel@tonic-gate size_t left = dstsize; 477*7c478bd9Sstevel@tonic-gate size_t l1; 478*7c478bd9Sstevel@tonic-gate size_t l2 = strlen(src); 479*7c478bd9Sstevel@tonic-gate size_t copied; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate while (left-- != 0 && *df != '\0') 482*7c478bd9Sstevel@tonic-gate df++; 483*7c478bd9Sstevel@tonic-gate l1 = df - dst; 484*7c478bd9Sstevel@tonic-gate if (dstsize == l1) 485*7c478bd9Sstevel@tonic-gate return (l1 + l2); 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2; 488*7c478bd9Sstevel@tonic-gate bcopy(src, dst + l1, copied); 489*7c478bd9Sstevel@tonic-gate dst[l1+copied] = '\0'; 490*7c478bd9Sstevel@tonic-gate return (l1 + l2); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate size_t 494*7c478bd9Sstevel@tonic-gate strlcpy(char *dst, const char *src, size_t len) 495*7c478bd9Sstevel@tonic-gate { 496*7c478bd9Sstevel@tonic-gate size_t slen = strlen(src); 497*7c478bd9Sstevel@tonic-gate size_t copied; 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate if (len == 0) 500*7c478bd9Sstevel@tonic-gate return (slen); 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (slen >= len) 503*7c478bd9Sstevel@tonic-gate copied = len - 1; 504*7c478bd9Sstevel@tonic-gate else 505*7c478bd9Sstevel@tonic-gate copied = slen; 506*7c478bd9Sstevel@tonic-gate bcopy(src, dst, copied); 507*7c478bd9Sstevel@tonic-gate dst[copied] = '\0'; 508*7c478bd9Sstevel@tonic-gate return (slen); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate size_t 512*7c478bd9Sstevel@tonic-gate strspn(const char *string, const char *charset) 513*7c478bd9Sstevel@tonic-gate { 514*7c478bd9Sstevel@tonic-gate const char *p, *q; 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate for (q = string; *q != '\0'; ++q) { 517*7c478bd9Sstevel@tonic-gate for (p = charset; *p != '\0' && *p != *q; ++p) 518*7c478bd9Sstevel@tonic-gate ; 519*7c478bd9Sstevel@tonic-gate if (*p == '\0') 520*7c478bd9Sstevel@tonic-gate break; 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate return (q - string); 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate /* 527*7c478bd9Sstevel@tonic-gate * Unless mentioned otherwise, all of the routines below should be added to 528*7c478bd9Sstevel@tonic-gate * the Solaris DDI as necessary. For now, only provide them to standalone. 529*7c478bd9Sstevel@tonic-gate */ 530*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) || defined(_KMDB) 531*7c478bd9Sstevel@tonic-gate char * 532*7c478bd9Sstevel@tonic-gate strtok(char *string, const char *sepset) 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate char *p, *q, *r; 535*7c478bd9Sstevel@tonic-gate static char *savept; 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate /* 538*7c478bd9Sstevel@tonic-gate * Set `p' to our current location in the string. 539*7c478bd9Sstevel@tonic-gate */ 540*7c478bd9Sstevel@tonic-gate p = (string == NULL) ? savept : string; 541*7c478bd9Sstevel@tonic-gate if (p == NULL) 542*7c478bd9Sstevel@tonic-gate return (NULL); 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* 545*7c478bd9Sstevel@tonic-gate * Skip leading separators; bail if no tokens remain. 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate q = p + strspn(p, sepset); 548*7c478bd9Sstevel@tonic-gate if (*q == '\0') 549*7c478bd9Sstevel@tonic-gate return (NULL); 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate /* 552*7c478bd9Sstevel@tonic-gate * Mark the end of the token and set `savept' for the next iteration. 553*7c478bd9Sstevel@tonic-gate */ 554*7c478bd9Sstevel@tonic-gate if ((r = strpbrk(q, sepset)) == NULL) 555*7c478bd9Sstevel@tonic-gate savept = NULL; 556*7c478bd9Sstevel@tonic-gate else { 557*7c478bd9Sstevel@tonic-gate *r = '\0'; 558*7c478bd9Sstevel@tonic-gate savept = ++r; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate return (q); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate /* 565*7c478bd9Sstevel@tonic-gate * The strlen() routine isn't shared with the kernel because it has its own 566*7c478bd9Sstevel@tonic-gate * hand-tuned assembly version. 567*7c478bd9Sstevel@tonic-gate */ 568*7c478bd9Sstevel@tonic-gate size_t 569*7c478bd9Sstevel@tonic-gate strlen(const char *s) 570*7c478bd9Sstevel@tonic-gate { 571*7c478bd9Sstevel@tonic-gate size_t n = 0; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate while (*s++) 574*7c478bd9Sstevel@tonic-gate n++; 575*7c478bd9Sstevel@tonic-gate return (n); 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate #endif /* _BOOT || _KMDB */ 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * Check for a valid C identifier: 583*7c478bd9Sstevel@tonic-gate * a letter or underscore, followed by 584*7c478bd9Sstevel@tonic-gate * zero or more letters, digits and underscores. 585*7c478bd9Sstevel@tonic-gate */ 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate #define IS_ALPHA(c) \ 590*7c478bd9Sstevel@tonic-gate (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate int 593*7c478bd9Sstevel@tonic-gate strident_valid(const char *id) 594*7c478bd9Sstevel@tonic-gate { 595*7c478bd9Sstevel@tonic-gate int c = *id++; 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate if (!IS_ALPHA(c) && c != '_') 598*7c478bd9Sstevel@tonic-gate return (0); 599*7c478bd9Sstevel@tonic-gate while ((c = *id++) != 0) { 600*7c478bd9Sstevel@tonic-gate if (!IS_ALPHA(c) && !IS_DIGIT(c) && c != '_') 601*7c478bd9Sstevel@tonic-gate return (0); 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate return (1); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* 607*7c478bd9Sstevel@tonic-gate * Convert a string into a valid C identifier by replacing invalid 608*7c478bd9Sstevel@tonic-gate * characters with '_'. Also makes sure the string is nul-terminated 609*7c478bd9Sstevel@tonic-gate * and takes up at most n bytes. 610*7c478bd9Sstevel@tonic-gate */ 611*7c478bd9Sstevel@tonic-gate void 612*7c478bd9Sstevel@tonic-gate strident_canon(char *s, size_t n) 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate char c; 615*7c478bd9Sstevel@tonic-gate char *end = s + n - 1; 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate ASSERT(n > 0); 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate if ((c = *s) == 0) 620*7c478bd9Sstevel@tonic-gate return; 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate if (!IS_ALPHA(c) && c != '_') 623*7c478bd9Sstevel@tonic-gate *s = '_'; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate while (s < end && ((c = *(++s)) != 0)) { 626*7c478bd9Sstevel@tonic-gate if (!IS_ALPHA(c) && !IS_DIGIT(c) && c != '_') 627*7c478bd9Sstevel@tonic-gate *s = '_'; 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate *s = 0; 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 633