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 48extern "C" { 49#endif 50 51#ifdef _GNU_SOURCE 52 53#define util_strchrnul strchrnul 54 55#else 56 57static INLINE char * 58util_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 69int util_vsnprintf(char *, size_t, const char *, va_list); 70int util_snprintf(char *str, size_t size, const char *format, ...); 71 72static INLINE void 73util_vsprintf(char *str, const char *format, va_list ap) 74{ 75 util_vsnprintf(str, (size_t)-1, format, ap); 76} 77 78static INLINE void 79util_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 87static INLINE char * 88util_strchr(const char *s, char c) 89{ 90 char *p = util_strchrnul(s, c); 91 92 return *p ? p : NULL; 93} 94 95static INLINE char* 96util_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 109static INLINE int 110util_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 125static INLINE int 126util_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 141static INLINE char * 142util_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 155static INLINE void * 156util_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 */ 194struct util_strbuf 195{ 196 char *str; 197 char *ptr; 198 size_t left; 199}; 200 201 202static INLINE void 203util_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 212static INLINE void 213util_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