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