1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Platform independent functions for string manipulation.
31 *
32 * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
33 */
34
35 #ifndef U_STRING_H_
36 #define U_STRING_H_
37
38 #if !defined(WIN32) && !defined(XF86_LIBC_H)
39 #include <stdio.h>
40 #endif
41 #include <stddef.h>
42 #include <stdarg.h>
43
44 #include "pipe/p_compiler.h"
45
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 #ifdef _GNU_SOURCE
52
53 #define util_strchrnul strchrnul
54
55 #else
56
57 static INLINE char *
58 util_strchrnul(const char *s, char c)
59 {
60 for (; *s && *s != c; ++s);
61
62 return (char *)s;
63 }
64
65 #endif
66
67 #ifdef WIN32
68
69 int util_vsnprintf(char *, size_t, const char *, va_list);
70 int util_snprintf(char *str, size_t size, const char *format, ...);
71
72 static INLINE void
util_vsprintf(char * str,const char * format,va_list ap)73 util_vsprintf(char *str, const char *format, va_list ap)
74 {
75 util_vsnprintf(str, (size_t)-1, format, ap);
76 }
77
78 static INLINE void
util_sprintf(char * str,const char * format,...)79 util_sprintf(char *str, const char *format, ...)
80 {
81 va_list ap;
82 va_start(ap, format);
83 util_vsnprintf(str, (size_t)-1, format, ap);
84 va_end(ap);
85 }
86
87 static INLINE char *
util_strchr(const char * s,char c)88 util_strchr(const char *s, char c)
89 {
90 char *p = util_strchrnul(s, c);
91
92 return *p ? p : NULL;
93 }
94
95 static INLINE char*
util_strncat(char * dst,const char * src,size_t n)96 util_strncat(char *dst, const char *src, size_t n)
97 {
98 char *p = dst + strlen(dst);
99 const char *q = src;
100 size_t i;
101
102 for (i = 0; i < n && *q != '\0'; ++i)
103 *p++ = *q++;
104 *p = '\0';
105
106 return dst;
107 }
108
109 static INLINE int
util_strcmp(const char * s1,const char * s2)110 util_strcmp(const char *s1, const char *s2)
111 {
112 unsigned char u1, u2;
113
114 while (1) {
115 u1 = (unsigned char) *s1++;
116 u2 = (unsigned char) *s2++;
117 if (u1 != u2)
118 return u1 - u2;
119 if (u1 == '\0')
120 return 0;
121 }
122 return 0;
123 }
124
125 static INLINE int
util_strncmp(const char * s1,const char * s2,size_t n)126 util_strncmp(const char *s1, const char *s2, size_t n)
127 {
128 unsigned char u1, u2;
129
130 while (n-- > 0) {
131 u1 = (unsigned char) *s1++;
132 u2 = (unsigned char) *s2++;
133 if (u1 != u2)
134 return u1 - u2;
135 if (u1 == '\0')
136 return 0;
137 }
138 return 0;
139 }
140
141 static INLINE char *
util_strstr(const char * haystack,const char * needle)142 util_strstr(const char *haystack, const char *needle)
143 {
144 const char *p = haystack;
145 size_t len = strlen(needle);
146
147 for (; (p = util_strchr(p, *needle)) != 0; p++) {
148 if (util_strncmp(p, needle, len) == 0) {
149 return (char *)p;
150 }
151 }
152 return NULL;
153 }
154
155 static INLINE void *
util_memmove(void * dest,const void * src,size_t n)156 util_memmove(void *dest, const void *src, size_t n)
157 {
158 char *p = (char *)dest;
159 const char *q = (const char *)src;
160 if (dest < src) {
161 while (n--)
162 *p++ = *q++;
163 }
164 else
165 {
166 p += n;
167 q += n;
168 while (n--)
169 *--p = *--q;
170 }
171 return dest;
172 }
173
174
175 #else
176
177 #define util_vsnprintf vsnprintf
178 #define util_snprintf snprintf
179 #define util_vsprintf vsprintf
180 #define util_sprintf sprintf
181 #define util_strchr strchr
182 #define util_strcmp strcmp
183 #define util_strncmp strncmp
184 #define util_strncat strncat
185 #define util_strstr strstr
186 #define util_memmove memmove
187
188 #endif
189
190
191 /**
192 * Printable string buffer
193 */
194 struct util_strbuf
195 {
196 char *str;
197 char *ptr;
198 size_t left;
199 };
200
201
202 static INLINE void
util_strbuf_init(struct util_strbuf * sbuf,char * str,size_t size)203 util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size)
204 {
205 sbuf->str = str;
206 sbuf->str[0] = 0;
207 sbuf->ptr = sbuf->str;
208 sbuf->left = size;
209 }
210
211
212 static INLINE void
util_strbuf_printf(struct util_strbuf * sbuf,const char * format,...)213 util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...)
214 {
215 if(sbuf->left > 1) {
216 size_t written;
217 va_list ap;
218 va_start(ap, format);
219 written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap);
220 va_end(ap);
221 sbuf->ptr += written;
222 sbuf->left -= written;
223 }
224 }
225
226
227
228 #ifdef __cplusplus
229 }
230 #endif
231
232 #endif /* U_STRING_H_ */
233