1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/cmn_err.h>
28 #include <sys/systm.h>
29 #include <sys/varargs.h>
30
31 /*
32 * SunOS-specific extensions to libc's standard set of string routines.
33 *
34 * NOTE: The standard libc string routines are in $SRC/common/util/string.c,
35 * to facilitate sharing with standalone.
36 */
37
38 /*
39 * Historical entry point: remove in Solaris 2.8.
40 */
41 char *
vsprintf_len(size_t buflen,char * buf,const char * fmt,va_list args)42 vsprintf_len(size_t buflen, char *buf, const char *fmt, va_list args)
43 {
44 (void) vsnprintf(buf, buflen, fmt, args);
45 return (buf);
46 }
47
48 /*
49 * Historical entry point: remove in Solaris 2.8.
50 */
51 /*PRINTFLIKE3*/
52 char *
sprintf_len(size_t buflen,char * buf,const char * fmt,...)53 sprintf_len(size_t buflen, char *buf, const char *fmt, ...)
54 {
55 va_list args;
56
57 va_start(args, fmt);
58 (void) vsnprintf(buf, buflen, fmt, args);
59 va_end(args);
60
61 return (buf);
62 }
63
64 /*
65 * Simple-minded conversion of a long into a null-terminated character
66 * string. Caller must ensure there's enough space to hold the result.
67 */
68 void
numtos(unsigned long num,char * s)69 numtos(unsigned long num, char *s)
70 {
71 char prbuf[40];
72
73 char *cp = prbuf;
74
75 do {
76 *cp++ = "0123456789"[num % 10];
77 num /= 10;
78 } while (num);
79
80 do {
81 *s++ = *--cp;
82 } while (cp > prbuf);
83 *s = '\0';
84 }
85
86 /*
87 * Returns the integer value of the string of decimal numeric
88 * chars beginning at **str. Does no overflow checking.
89 * Note: updates *str to point at the last character examined.
90 */
91 int
stoi(char ** str)92 stoi(char **str)
93 {
94 char *p = *str;
95 int n;
96 int c;
97
98 for (n = 0; (c = *p) >= '0' && c <= '9'; p++) {
99 n = n * 10 + c - '0';
100 }
101 *str = p;
102 return (n);
103 }
104
105 /*
106 * Like strrchr(), except
107 * (a) it takes a maximum length for the string to be searched, and
108 * (b) if the string ends with a null, it is not considered part of the string.
109 */
110 char *
strnrchr(const char * sp,int c,size_t n)111 strnrchr(const char *sp, int c, size_t n)
112 {
113 const char *r = 0;
114
115 while (n-- > 0 && *sp) {
116 if (*sp == c)
117 r = sp;
118 sp++;
119 }
120
121 return ((char *)r);
122 }
123
124 /*
125 * NOTE: These routines aren't shared with standalone because the DDI mandates
126 * that they return the buffer rather than its length.
127 */
128 /*PRINTFLIKE2*/
129 char *
sprintf(char * buf,const char * fmt,...)130 sprintf(char *buf, const char *fmt, ...)
131 {
132 va_list args;
133
134 va_start(args, fmt);
135 (void) vsnprintf(buf, INT_MAX, fmt, args);
136 va_end(args);
137
138 return (buf);
139 }
140
141 char *
vsprintf(char * buf,const char * fmt,va_list args)142 vsprintf(char *buf, const char *fmt, va_list args)
143 {
144 (void) vsnprintf(buf, INT_MAX, fmt, args);
145 return (buf);
146 }
147
148 /*
149 * Do not change the length of the returned string; it must be freed
150 * with strfree().
151 */
152 char *
kmem_asprintf(const char * fmt,...)153 kmem_asprintf(const char *fmt, ...)
154 {
155 int size;
156 va_list adx;
157 char *buf;
158
159 va_start(adx, fmt);
160 size = vsnprintf(NULL, 0, fmt, adx) + 1;
161 va_end(adx);
162
163 buf = kmem_alloc(size, KM_SLEEP);
164
165 va_start(adx, fmt);
166 size = vsnprintf(buf, size, fmt, adx);
167 va_end(adx);
168
169 return (buf);
170 }
171