15b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca/**************************************************************************
25b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca *
35b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
45b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * All Rights Reserved.
55b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca *
65b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
75b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * copy of this software and associated documentation files (the
85b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * "Software"), to deal in the Software without restriction, including
95b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish,
105b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to
115b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to
125b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * the following conditions:
135b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca *
145b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * The above copyright notice and this permission notice (including the
155b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * next paragraph) shall be included in all copies or substantial portions
165b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * of the Software.
175b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca *
185b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
195b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
225b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca *
265b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca **************************************************************************/
275b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
285b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca/**
295b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * @file
305b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * Platform independent functions for string manipulation.
313b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonseca *
325b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
335b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca */
345b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
355b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#ifndef U_STRING_H_
365b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#define U_STRING_H_
375b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
383b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonseca#if !defined(WIN32) && !defined(XF86_LIBC_H)
395b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#include <stdio.h>
405b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#endif
415b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#include <stddef.h>
425b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#include <stdarg.h>
435b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
44131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#include "pipe/p_compiler.h"
45131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
465b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
475b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#ifdef __cplusplus
485b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonsecaextern "C" {
495b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#endif
505b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
510a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez#ifdef _GNU_SOURCE
520a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
530a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez#define util_strchrnul strchrnul
540a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
550a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez#else
560a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
570a62af3bcc530a6d09130368055c64263ba48848Francisco Jerezstatic INLINE char *
580a62af3bcc530a6d09130368055c64263ba48848Francisco Jerezutil_strchrnul(const char *s, char c)
590a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez{
600a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez   for (; *s && *s != c; ++s);
610a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
620a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez   return (char *)s;
630a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez}
640a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
650a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez#endif
663b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonseca
675b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#ifdef WIN32
683b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonseca
695b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonsecaint util_vsnprintf(char *, size_t, const char *, va_list);
705b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonsecaint util_snprintf(char *str, size_t size, const char *format, ...);
71131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
723b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonsecastatic INLINE void
7354777e124c38812e5e80319048b6c71009bcf9ddJosé Fonsecautil_vsprintf(char *str, const char *format, va_list ap)
7454777e124c38812e5e80319048b6c71009bcf9ddJosé Fonseca{
7554777e124c38812e5e80319048b6c71009bcf9ddJosé Fonseca   util_vsnprintf(str, (size_t)-1, format, ap);
7654777e124c38812e5e80319048b6c71009bcf9ddJosé Fonseca}
7754777e124c38812e5e80319048b6c71009bcf9ddJosé Fonseca
783b5ee3d6de2c08faf69c701bf05d8f33ccd01502José Fonsecastatic INLINE void
79131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_sprintf(char *str, const char *format, ...)
80131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
81131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   va_list ap;
82131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   va_start(ap, format);
83131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   util_vsnprintf(str, (size_t)-1, format, ap);
84131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   va_end(ap);
85131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
86131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
87131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE char *
88131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_strchr(const char *s, char c)
89131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
900a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez   char *p = util_strchrnul(s, c);
910a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez
920a62af3bcc530a6d09130368055c64263ba48848Francisco Jerez   return *p ? p : NULL;
93131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
94131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
95131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE char*
96131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_strncat(char *dst, const char *src, size_t n)
97131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
98131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   char *p = dst + strlen(dst);
99131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   const char *q = src;
100131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   size_t i;
101131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
102131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   for (i = 0; i < n && *q != '\0'; ++i)
103131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca       *p++ = *q++;
104131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   *p = '\0';
105131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
106131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   return dst;
107131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
108131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
109131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE int
110131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_strcmp(const char *s1, const char *s2)
111131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
112131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   unsigned char u1, u2;
113131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
114131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   while (1) {
115131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      u1 = (unsigned char) *s1++;
116131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      u2 = (unsigned char) *s2++;
117131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      if (u1 != u2)
118131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 return u1 - u2;
119131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      if (u1 == '\0')
120131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 return 0;
121131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   }
122131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   return 0;
123131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
124131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
125131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE int
126131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_strncmp(const char *s1, const char *s2, size_t n)
127131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
128131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   unsigned char u1, u2;
129131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
130131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   while (n-- > 0) {
131131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      u1 = (unsigned char) *s1++;
132131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      u2 = (unsigned char) *s2++;
133131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      if (u1 != u2)
134131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 return u1 - u2;
135131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      if (u1 == '\0')
136131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 return 0;
137131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   }
138131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   return 0;
139131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
140131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
141131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE char *
142131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_strstr(const char *haystack, const char *needle)
143131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
144131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   const char *p = haystack;
1459fb46fb4c30fe01c9cb485f909aca502691aaa3bJosé Fonseca   size_t len = strlen(needle);
146131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
147131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   for (; (p = util_strchr(p, *needle)) != 0; p++) {
148131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      if (util_strncmp(p, needle, len) == 0) {
149131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 return (char *)p;
150131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      }
151131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   }
152131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   return NULL;
153131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
154131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
155131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecastatic INLINE void *
156131a1fbc91725c11e4822b82e58b94ec3a711476José Fonsecautil_memmove(void *dest, const void *src, size_t n)
157131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca{
158131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   char *p = (char *)dest;
159131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   const char *q = (const char *)src;
160131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   if (dest < src) {
161131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      while (n--)
162131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 *p++ = *q++;
163131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   }
164131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   else
165131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   {
166131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      p += n;
167131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      q += n;
168131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca      while (n--)
169131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca	 *--p = *--q;
170131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   }
171131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca   return dest;
172131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca}
173131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
174131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
1755b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#else
176131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
1775b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#define util_vsnprintf vsnprintf
1785b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#define util_snprintf snprintf
17954777e124c38812e5e80319048b6c71009bcf9ddJosé Fonseca#define util_vsprintf vsprintf
1804c6c073f993e13da0b68f897a4221e6bb7875fbeMichel Dänzer#define util_sprintf sprintf
181131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_strchr strchr
182131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_strcmp strcmp
183131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_strncmp strncmp
184131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_strncat strncat
185131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_strstr strstr
186131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca#define util_memmove memmove
187131a1fbc91725c11e4822b82e58b94ec3a711476José Fonseca
1885b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#endif
1895b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
1905b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
1913e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca/**
1923e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca * Printable string buffer
1933e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca */
1943e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonsecastruct util_strbuf
1953e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca{
1963e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   char *str;
1973e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   char *ptr;
1983e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   size_t left;
1993e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca};
2003e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2013e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2023e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonsecastatic INLINE void
2033e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonsecautil_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size)
2043e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca{
2053e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   sbuf->str = str;
2063e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   sbuf->str[0] = 0;
2073e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   sbuf->ptr = sbuf->str;
2083e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   sbuf->left = size;
2093e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca}
2103e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2113e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2123e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonsecastatic INLINE void
2133e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonsecautil_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...)
2143e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca{
2153e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   if(sbuf->left > 1) {
2163e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      size_t written;
2173e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      va_list ap;
2183e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      va_start(ap, format);
2193e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap);
2203e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      va_end(ap);
2213e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      sbuf->ptr += written;
2223e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca      sbuf->left -= written;
2233e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca   }
2243e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca}
2253e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2263e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2273e1974f94ef8796a5ac9e750d47ccb63c677a85bJosé Fonseca
2285b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#ifdef __cplusplus
2295b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca}
2305b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#endif
2315b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca
2325b8fa518476868530d748ce6d03674e9cca3d89fJosé Fonseca#endif /* U_STRING_H_ */
233