VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/string.c@ 33988

Last change on this file since 33988 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_mem.h"
8#include "cr_string.h"
9
10#include <string.h>
11#include <stdio.h>
12#include <stdlib.h>
13
14int crStrlen( const char *str )
15{
16 const char *temp;
17 if (!str) return 0;
18 for (temp = str ; *temp ; temp++);
19 return temp-str;
20}
21
22char *crStrdup( const char *str )
23{
24 int len;
25 char *ret;
26
27 /* Allow strdup'ing of NULL strings -- this makes the __fillin functions
28 * much cleaner. */
29
30 if (str == NULL) return NULL;
31
32 len = crStrlen(str);
33 ret = (char*)crAlloc( len+1 );
34 crMemcpy( ret, str, len );
35 ret[len] = '\0';
36 return ret;
37}
38
39char *crStrndup( const char *str, unsigned int len )
40{
41 char *ret = (char*)crAlloc( len+1 );
42 crMemcpy( ret, str, len );
43 ret[len] = '\0';
44 return ret;
45}
46
47int crStrcmp( const char *str1, const char *str2 )
48{
49 while (*str1 && *str2)
50 {
51 if (*str1 != *str2)
52 {
53 break;
54 }
55 str1++; str2++;
56 }
57 return (*str1 - *str2);
58}
59
60int crStrncmp( const char *str1, const char *str2, int n )
61{
62 int i = 0;
63 while (*str1 && *str2 && i < n)
64 {
65 if (*str1 != *str2)
66 {
67 break;
68 }
69 str1++; str2++; i++;
70 }
71 if (i == n) return 0;
72 return (*str1 - *str2);
73}
74
75static char lowercase[256] = {
76 '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
77 '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
78 '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
79 '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
80 '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
81 '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
82 '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
83 '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
84 '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
85 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
86 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
87 '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
88 '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
89 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
90 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
91 '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
92 '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
93 '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
94 '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
95 '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
96 '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
97 '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
98 '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
99 '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
100 '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
101 '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
102 '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
103 '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
104 '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
105 '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
106 '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
107 '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
108};
109
110int crStrcasecmp( const char *str1, const char *str2 )
111{
112 while (*str1 && *str2)
113 {
114 if (lowercase[(int) *str1] != lowercase[(int) *str2])
115 {
116 break;
117 }
118 str1++; str2++;
119 }
120 return (lowercase[(int) *str1] - lowercase[(int) *str2]);
121}
122
123void crStrcpy( char *dest, const char *src )
124{
125 while ((*dest++ = *src++))
126 ;
127}
128
129void crStrncpy( char *dest, const char *src, unsigned int len )
130{
131 const unsigned int str_len = crStrlen(src);
132 if (str_len > len - 1) {
133 crMemcpy( dest, src, len ); /* NOTE: not null-terminated! */
134 }
135 else {
136 crMemcpy( dest, src, str_len + 1 ); /* includes null terminator */
137 }
138}
139
140void crStrcat( char *dest, const char *src )
141{
142 crStrcpy( dest + crStrlen(dest), src );
143}
144
145char *crStrjoin( const char *str1, const char *str2 )
146{
147 const int len1 = crStrlen(str1), len2 = crStrlen(str2);
148 char *s = crAlloc(len1 + len2 + 1);
149 if (s)
150 {
151 crMemcpy( s, str1, len1 );
152 crMemcpy( s + len1, str2, len2 );
153 s[len1 + len2] = '\0';
154 }
155 return s;
156}
157
158char *crStrjoin3( const char *str1, const char *str2, const char *str3 )
159{
160 const int len1 = crStrlen(str1), len2 = crStrlen(str2), len3 = crStrlen(str3);
161 char *s = crAlloc(len1 + len2 + len3 + 1);
162 if (s)
163 {
164 crMemcpy( s, str1, len1 );
165 crMemcpy( s + len1, str2, len2 );
166 crMemcpy( s + len1 + len2, str3, len3 );
167 s[len1 + len2 + len3] = '\0';
168 }
169 return s;
170}
171
172char *crStrstr( const char *str, const char *pat )
173{
174 int pat_len = crStrlen( pat );
175 const char *end = str + crStrlen(str) - pat_len;
176 char first_char = *pat;
177 if (!str) return NULL;
178 for (; str <= end ; str++)
179 {
180 if (*str == first_char && !crMemcmp( str, pat, pat_len ))
181 return (char *) str;
182 }
183 return NULL;
184}
185
186char *crStrchr( const char *str, char c )
187{
188 for ( ; *str ; str++ )
189 {
190 if (*str == c)
191 return (char *) str;
192 }
193 return NULL;
194}
195
196char *crStrrchr( const char *str, char c )
197{
198 const char *temp = str + crStrlen( str );
199 for ( ; temp >= str ; temp-- )
200 {
201 if (*temp == c)
202 return (char *) temp;
203 }
204 return NULL;
205}
206
207/* These functions are from the old wiregl net.c -- hexdumps? Not sure quite yet. */
208
209void crBytesToString( char *string, int nstring, void *data, int ndata )
210{
211 int i, offset;
212 unsigned char *udata;
213
214 offset = 0;
215 udata = (unsigned char *) data;
216 for ( i = 0; i < ndata && ( offset + 4 <= nstring ); i++ )
217 {
218 offset += sprintf( string + offset, "%02x ", udata[i] );
219 }
220
221 if ( i == ndata && offset > 0 )
222 string[offset-1] = '\0';
223 else
224 crStrcpy( string + offset - 3, "..." );
225}
226
227void crWordsToString( char *string, int nstring, void *data, int ndata )
228{
229 int i, offset, ellipsis;
230 unsigned int *udata;
231
232 /* turn byte count into word count */
233 ndata /= 4;
234
235 /* we need an ellipsis if all the words won't fit in the string */
236 ellipsis = ( ndata * 9 > nstring );
237 if ( ellipsis )
238 {
239 ndata = nstring / 9;
240
241 /* if the ellipsis won't fit then print one less word */
242 if ( ndata * 9 + 3 > nstring )
243 ndata--;
244 }
245
246 offset = 0;
247 udata = (unsigned int *) data;
248 for ( i = 0; i < ndata; i++ )
249 {
250 offset += sprintf( string + offset, "%08x ", udata[i] );
251 }
252
253 if ( ellipsis )
254 crStrcpy( string + offset, "..." );
255 else if ( offset > 0 )
256 string[offset-1] = 0;
257}
258
259int crStrToInt( const char *str )
260{
261 if (!str) return 0;
262
263 return atoi(str);
264}
265
266float crStrToFloat( const char *str )
267{
268 if (!str) return 0.0f;
269
270 return (float) atof(str);
271}
272
273static int __numOccurrences( const char *str, const char *substr )
274{
275 int ret = 0;
276 char *temp = (char *) str;
277 while ((temp = crStrstr( temp, substr )) != NULL )
278 {
279 temp += crStrlen(substr);
280 ret++;
281 }
282 return ret;
283}
284
285/**
286 * Split str into a NULL-terminated array of strings, using splitstr as
287 * the separator.
288 * It's the same as the Python call string.split(str, splitstr).
289 * Note: crStrSplit("a b c", " ") returns ["a", "b", "", "c", NULL] though!!!
290 */
291char **crStrSplit( const char *str, const char *splitstr )
292{
293 char *temp = (char *) str;
294 int num_args = __numOccurrences( str, splitstr ) + 1;
295 char **faked_argv = (char **) crAlloc( (num_args + 1)*sizeof( *faked_argv ) );
296 int i;
297
298 for (i = 0 ; i < num_args ; i++)
299 {
300 char *end;
301 end = crStrstr( temp, splitstr );
302 if (!end)
303 end = temp + crStrlen( temp );
304 faked_argv[i] = crStrndup( temp, end-temp );
305 temp = end + crStrlen(splitstr);
306 }
307 faked_argv[num_args] = NULL;
308 return faked_argv;
309}
310
311char **crStrSplitn( const char *str, const char *splitstr, int n )
312{
313 char **faked_argv;
314 int i;
315 char *temp = (char *) str;
316 int num_args = __numOccurrences( str, splitstr );
317
318 if (num_args > n)
319 num_args = n;
320 num_args++;
321
322 faked_argv = (char **) crAlloc( (num_args + 1) * sizeof( *faked_argv ) );
323 for (i = 0 ; i < num_args ; i++)
324 {
325 char *end;
326 end = crStrstr( temp, splitstr );
327 if (!end || i == num_args - 1 )
328 end = temp + crStrlen( temp );
329 faked_argv[i] = crStrndup( temp, end-temp );
330 temp = end + crStrlen(splitstr);
331 }
332 faked_argv[num_args] = NULL;
333 return faked_argv;
334}
335
336/* Free an array of strings, as returned by crStrSplit() and crStrSplitn(). */
337void crFreeStrings( char **strings )
338{
339 int i;
340 for (i = 0; strings[i]; i++) {
341 crFree(strings[i]);
342 }
343 crFree(strings);
344}
345
346
347/* Intersect two strings on a word-by-word basis (separated by spaces).
348 * We typically use this to intersect OpenGL extension strings.
349 * Example: if s1 = "apple banana plum pear"
350 * and s2 = "plum banana orange"
351 * then return "banana plum" (or "plum banana").
352 */
353char *crStrIntersect( const char *s1, const char *s2 )
354{
355 int len1, len2;
356 int resultLen;
357 char *result;
358 char **exten1, **exten2;
359 int i, j;
360
361 if (!s1 || !s2) {
362 /* null strings, no intersection */
363 return NULL;
364 }
365
366 len1 = crStrlen(s1);
367 len2 = crStrlen(s2);
368
369 /* allocate storage for result (a conservative estimate) */
370 resultLen = ((len1 > len2) ? len1 : len2) + 2;
371 result = (char *) crAlloc(resultLen);
372 if (!result)
373 {
374 return NULL;
375 }
376 result[0] = 0;
377
378 /* split s1 and s2 at space chars */
379 exten1 = crStrSplit(s1, " ");
380 exten2 = crStrSplit(s2, " ");
381
382 for (i = 0; exten1[i]; i++)
383 {
384 for (j = 0; exten2[j]; j++)
385 {
386 if (crStrcmp(exten1[i], exten2[j]) == 0)
387 {
388 /* found an intersection, append to result */
389 crStrcat(result, exten1[i]);
390 crStrcat(result, " ");
391 break;
392 }
393 }
394 }
395
396 /* free split strings */
397 crFreeStrings( exten1 );
398 crFreeStrings( exten2 );
399
400 /*CRASSERT(crStrlen(result) < resultLen);*/
401
402 /* all done! */
403 return result;
404}
405
406
407int crIsDigit(char c)
408{
409 return c >= '0' && c <= '9';
410}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette