svn merge -r 21041:21301 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[blender.git] / source / blender / blenlib / intern / string.c
1 /* util.c
2  *
3  * various string, file, list operations.
4  *
5  *
6  * $Id$
7  *
8  * ***** BEGIN GPL LICENSE BLOCK *****
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
25  * All rights reserved.
26  *
27  * The Original Code is: all of this file.
28  *
29  * Contributor(s): none yet.
30  *
31  * ***** END GPL LICENSE BLOCK *****
32  * 
33  */
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <ctype.h>
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_dynstr.h"
44 #include "BLI_string.h"
45
46 char *BLI_strdupn(const char *str, int len) {
47         char *n= MEM_mallocN(len+1, "strdup");
48         memcpy(n, str, len);
49         n[len]= '\0';
50         
51         return n;
52 }
53 char *BLI_strdup(const char *str) {
54         return BLI_strdupn(str, strlen(str));
55 }
56
57 char *BLI_strncpy(char *dst, const char *src, int maxncpy) {
58         int srclen= strlen(src);
59         int cpylen= (srclen>(maxncpy-1))?(maxncpy-1):srclen;
60         
61         memcpy(dst, src, cpylen);
62         dst[cpylen]= '\0';
63         
64         return dst;
65 }
66
67 int BLI_snprintf(char *buffer, size_t count, const char *format, ...)
68 {
69         int n;
70         va_list arg;
71
72         va_start(arg, format);
73         n = vsnprintf(buffer, count, format, arg);
74         
75         if (n != -1 && n < count) {
76                 buffer[n] = '\0';
77         } else {
78                 buffer[count-1] = '\0';
79         }
80         
81         va_end(arg);
82         return n;
83 }
84
85 char *BLI_sprintfN(const char *format, ...)
86 {
87         DynStr *ds;
88         va_list arg;
89         char *n;
90
91         va_start(arg, format);
92
93         ds= BLI_dynstr_new();
94         BLI_dynstr_vappendf(ds, format, arg);
95         n= BLI_dynstr_get_cstring(ds);
96         BLI_dynstr_free(ds);
97
98         va_end(arg);
99
100         return n;
101 }
102
103 int BLI_streq(const char *a, const char *b) 
104 {
105         return (strcmp(a, b)==0);
106 }
107
108 int BLI_strcaseeq(const char *a, const char *b) 
109 {
110         return (BLI_strcasecmp(a, b)==0);
111 }
112
113 /* strcasestr not available in MSVC */
114 char *BLI_strcasestr(const char *s, const char *find)
115 {
116     register char c, sc;
117     register size_t len;
118         
119     if ((c = *find++) != 0) {
120                 c= tolower(c);
121                 len = strlen(find);
122                 do {
123                         do {
124                                 if ((sc = *s++) == 0)
125                                         return (NULL);
126                                 sc= tolower(sc);
127                         } while (sc != c);
128                 } while (BLI_strncasecmp(s, find, len) != 0);
129                 s--;
130     }
131     return ((char *) s);
132 }
133
134
135 int BLI_strcasecmp(const char *s1, const char *s2) {
136         int i;
137
138         for (i=0; ; i++) {
139                 char c1 = tolower(s1[i]);
140                 char c2 = tolower(s2[i]);
141
142                 if (c1<c2) {
143                         return -1;
144                 } else if (c1>c2) {
145                         return 1;
146                 } else if (c1==0) {
147                         break;
148                 }
149         }
150
151         return 0;
152 }
153
154 int BLI_strncasecmp(const char *s1, const char *s2, int n) {
155         int i;
156
157         for (i=0; i<n; i++) {
158                 char c1 = tolower(s1[i]);
159                 char c2 = tolower(s2[i]);
160
161                 if (c1<c2) {
162                         return -1;
163                 } else if (c1>c2) {
164                         return 1;
165                 } else if (c1==0) {
166                         break;
167                 }
168         }
169
170         return 0;
171 }
172
173 /* natural string compare, keeping numbers in order */
174 int BLI_natstrcmp(const char *s1, const char *s2)
175 {
176         int d1= 0, d2= 0;
177         
178         /* if both chars are numeric, to a strtol().
179            then increase string deltas as long they are 
180            numeric, else do a tolower and char compare */
181         
182         while(1) {
183                 char c1 = tolower(s1[d1]);
184                 char c2 = tolower(s2[d2]);
185                 
186                 if( isdigit(c1) && isdigit(c2) ) {
187                         int val1, val2;
188                         
189                         val1= (int)strtol(s1+d1, (char **)NULL, 10);
190                         val2= (int)strtol(s2+d2, (char **)NULL, 10);
191                         
192                         if (val1<val2) {
193                                 return -1;
194                         } else if (val1>val2) {
195                                 return 1;
196                         }
197                         d1++;
198                         while( isdigit(s1[d1]) )
199                                 d1++;
200                         d2++;
201                         while( isdigit(s2[d2]) )
202                                 d2++;
203                         
204                         c1 = tolower(s1[d1]);
205                         c2 = tolower(s2[d2]);
206                 }
207                 
208                 if (c1<c2) {
209                         return -1;
210                 } else if (c1>c2) {
211                         return 1;
212                 } else if (c1==0) {
213                         break;
214                 }
215                 d1++;
216                 d2++;
217         }
218         return 0;
219 }
220
221 void BLI_timestr(double _time, char *str)
222 {
223         /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
224         int  hr= ( (int)  _time) / (60*60);
225         int min= (((int)  _time) / 60 ) % 60;
226         int sec= ( (int) (_time)) % 60;
227         int hun= ( (int) (_time   * 100.0)) % 100;
228         
229         if (hr) {
230                 sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun);
231         } else {
232                 sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun);
233         }
234         
235         str[11]=0;
236 }