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 (at) 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 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 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 * 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* 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 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 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 * 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 * 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 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 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