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 */
41char *
42vsprintf_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*/
52char *
53sprintf_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 */
68void
69numtos(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 */
91int
92stoi(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 */
110char *
111strnrchr(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*/
129char *
130sprintf(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
141char *
142vsprintf(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 */
152char *
153kmem_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