Code cleanup: remove BLI_exist, now there is only BLI_exists. One function just
[blender.git] / source / blender / blenlib / intern / path_util.c
1 /*
2  *  $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * various string, file, list operations.
30  */
31
32 /** \file blender/blenlib/intern/path_util.c
33  *  \ingroup bli
34  */
35
36
37 #include <ctype.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <assert.h>
41
42 #include "MEM_guardedalloc.h"
43
44 #include "DNA_listBase.h"
45
46 #include "BLI_fileops.h"
47 #include "BLI_path_util.h"
48 #include "BLI_string.h"
49 #include "BLI_storage.h"
50 #include "BLI_storage_types.h"
51 #include "BLI_utildefines.h"
52
53 #include "BKE_utildefines.h"
54 #include "BKE_blender.h"        // BLENDER_VERSION
55
56 #include "GHOST_Path-api.h"
57
58 #if defined WIN32 && !defined _LIBC
59 # include "BLI_fnmatch.h" /* use fnmatch included in blenlib */
60 #else
61 #  ifndef _GNU_SOURCE
62 #    define _GNU_SOURCE
63 #  endif
64 #  include <fnmatch.h>
65 #endif
66
67 #ifdef WIN32
68 #include <io.h>
69
70 #ifdef _WIN32_IE
71 #undef _WIN32_IE
72 #endif
73 #define _WIN32_IE 0x0501
74 #include <windows.h>
75 #include <shlobj.h>
76
77 #include "BLI_winstuff.h"
78
79 #else /* non windows */
80
81 #ifdef WITH_BINRELOC
82 #include "binreloc.h"
83 #endif
84
85 #endif /* WIN32 */
86
87 /* standard paths */
88 #ifdef WIN32
89 #define BLENDER_USER_FORMAT             "%s\\Blender Foundation\\Blender\\%s"
90 #define BLENDER_SYSTEM_FORMAT           "%s\\Blender Foundation\\Blender\\%s"
91 #elif defined(__APPLE__)
92 #define BLENDER_USER_FORMAT                     "%s/Blender/%s"
93 #define BLENDER_SYSTEM_FORMAT                   "%s/Blender/%s"
94 #else
95 #define BLENDER_USER_FORMAT                     "%s/.blender/%s"
96 #define BLENDER_SYSTEM_FORMAT                   "%s/blender/%s"
97 #endif
98
99 /* local */
100 #define UNIQUE_NAME_MAX 128
101
102 static char bprogname[FILE_MAX];        /* path to program executable */
103 static char bprogdir[FILE_MAX];         /* path in which executable is located */
104 static char btempdir[FILE_MAX];         /* temporary directory */
105
106 static int add_win32_extension(char *name);
107 static char *blender_version_decimal(const int ver);
108
109 /* implementation */
110
111 int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
112 {
113         unsigned short len, len2, lenlslash = 0, nums = 0, nume = 0;
114         short i, found = 0;
115         char *lslash = BLI_last_slash(string);
116         len2 = len = strlen(string);
117         if(lslash)
118                 lenlslash= (int)(lslash - string);
119
120         while(len > lenlslash && string[--len] != '.') {};
121         if(len == lenlslash && string[len] != '.') len = len2;
122
123         for (i = len - 1; i >= lenlslash; i--) {
124                 if (isdigit(string[i])) {
125                         if (found){
126                                 nums = i;
127                         }
128                         else{
129                                 nume = i;
130                                 nums = i;
131                                 found = 1;
132                         }
133                 }
134                 else {
135                         if (found) break;
136                 }
137         }
138         if (found) {
139                 if (tail) strcpy(tail, &string[nume+1]);
140                 if (head) {
141                         strcpy(head,string);
142                         head[nums]=0;
143                 }
144                 if (numlen) *numlen = nume-nums+1;
145                 return ((int)atoi(&(string[nums])));
146         }
147         if (tail) strcpy(tail, string + len);
148         if (head) {
149                 strncpy(head, string, len);
150                 head[len] = '\0';
151         }
152         if (numlen) *numlen=0;
153         return 0;
154 }
155
156
157 void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
158 {
159         char fmtstr[16]="";
160         if(pic < 0) pic= 0;
161         sprintf(fmtstr, "%%s%%.%dd%%s", numlen);
162         sprintf(string, fmtstr, head, pic, tail);
163 }
164
165 /* Foo.001 -> "Foo", 1
166  * Returns the length of "Foo" */
167 int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
168 {
169         int a;
170
171         *nr= 0;
172         a= strlen(name);
173         memcpy(left, name, (a + 1) * sizeof(char));
174
175         if(a>1 && name[a-1]==delim) return a;
176         
177         while(a--) {
178                 if( name[a]==delim ) {
179                         left[a]= 0;
180                         *nr= atol(name+a+1);
181                         /* casting down to an int, can overflow for large numbers */
182                         if(*nr < 0)
183                                 *nr= 0;
184                         return a;
185                 }
186                 if( isdigit(name[a])==0 ) break;
187                 
188                 left[a]= 0;
189         }
190
191         for(a= 0; name[a]; a++)
192                 left[a]= name[a];
193
194         return a;
195 }
196
197 void BLI_newname(char *name, int add)
198 {
199         char head[UNIQUE_NAME_MAX], tail[UNIQUE_NAME_MAX];
200         int pic;
201         unsigned short digits;
202         
203         pic = BLI_stringdec(name, head, tail, &digits);
204         
205         /* are we going from 100 -> 99 or from 10 -> 9 */
206         if (add < 0 && digits < 4 && digits > 0) {
207                 int i, exp;
208                 exp = 1;
209                 for (i = digits; i > 1; i--) exp *= 10;
210                 if (pic >= exp && (pic + add) < exp) digits--;
211         }
212         
213         pic += add;
214         
215         if (digits==4 && pic<0) pic= 0;
216         BLI_stringenc(name, head, tail, digits, pic);
217 }
218
219
220
221 int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len)
222 {
223         if(name[0] == '\0') {
224                 BLI_strncpy(name, defname, name_len);
225         }
226
227         if(unique_check(arg, name)) {
228                 char    tempname[UNIQUE_NAME_MAX];
229                 char    left[UNIQUE_NAME_MAX];
230                 int             number;
231                 int             len= BLI_split_name_num(left, &number, name, delim);
232                 do {
233                         int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, ++number);
234                         if(newlen >= name_len) {
235                                 len -= ((newlen + 1) - name_len);
236                                 if(len < 0) len= number= 0;
237                                 left[len]= '\0';
238                         }
239                 } while(unique_check(arg, tempname));
240
241                 BLI_strncpy(name, tempname, name_len);
242                 
243                 return 1;
244         }
245         
246         return 0;
247 }
248
249 /* little helper macro for BLI_uniquename */
250 #ifndef GIVE_STRADDR
251         #define GIVE_STRADDR(data, offset) ( ((char *)data) + offset )
252 #endif
253
254 /* Generic function to set a unique name. It is only designed to be used in situations
255  * where the name is part of the struct, and also that the name is at most UNIQUE_NAME_MAX chars long.
256  * 
257  * For places where this is used, see constraint.c for example...
258  *
259  *      name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h
260  *      len: maximum length of string (to prevent overflows, etc.)
261  *      defname: the name that should be used by default if none is specified already
262  *      delim: the character which acts as a delimeter between parts of the name
263  */
264 static int uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
265 {
266         Link *link;
267
268         for (link = list->first; link; link= link->next) {
269                 if (link != vlink) {
270                         if (!strcmp(GIVE_STRADDR(link, name_offs), name)) {
271                                 return 1;
272                         }
273                 }
274         }
275
276         return 0;
277 }
278
279 static int uniquename_unique_check(void *arg, const char *name)
280 {
281         struct {ListBase *lb; void *vlink; short name_offs;} *data= arg;
282         return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
283 }
284
285 void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short name_len)
286 {
287         struct {ListBase *lb; void *vlink; short name_offs;} data;
288         data.lb= list;
289         data.vlink= vlink;
290         data.name_offs= name_offs;
291
292         assert((name_len > 1) && (name_len <= UNIQUE_NAME_MAX));
293
294         /* See if we are given an empty string */
295         if (ELEM(NULL, vlink, defname))
296                 return;
297
298         BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
299 }
300
301
302
303 /* ******************** string encoding ***************** */
304
305 /* This is quite an ugly function... its purpose is to
306  * take the dir name, make it absolute, and clean it up, replacing
307  * excess file entry stuff (like /tmp/../tmp/../)
308  * note that dir isn't protected for max string names... 
309  * 
310  * If relbase is NULL then its ignored
311  */
312
313 void BLI_cleanup_path(const char *relabase, char *dir)
314 {
315         short a;
316         char *start, *eind;
317         if (relabase) {
318                 BLI_path_abs(dir, relabase);
319         } else {
320                 if (dir[0]=='/' && dir[1]=='/') {
321                         if (dir[2]== '\0') {
322                                 return; /* path is "//" - cant clean it */
323                         }
324                         dir = dir+2; /* skip the first // */
325                 }
326         }
327         
328         /* Note
329          *   memmove( start, eind, strlen(eind)+1 );
330          * is the same as
331          *   strcpy( start, eind ); 
332          * except strcpy should not be used because there is overlap,
333           * so use memmove's slightly more obscure syntax - Campbell
334          */
335         
336 #ifdef WIN32
337         
338         /* Note, this should really be moved to the file selector,
339          * since this function is used in many areas */
340         if(strcmp(dir, ".")==0) {       /* happens for example in FILE_MAIN */
341                 get_default_root(dir);
342                 return;
343         }       
344
345         while ( (start = strstr(dir, "\\..\\")) ) {
346                 eind = start + strlen("\\..\\") - 1;
347                 a = start-dir-1;
348                 while (a>0) {
349                         if (dir[a] == '\\') break;
350                         a--;
351                 }
352                 if (a<0) {
353                         break;
354                 } else {
355                         memmove( dir+a, eind, strlen(eind)+1 );
356                 }
357         }
358
359         while ( (start = strstr(dir,"\\.\\")) ){
360                 eind = start + strlen("\\.\\") - 1;
361                 memmove( start, eind, strlen(eind)+1 );
362         }
363
364         while ( (start = strstr(dir,"\\\\" )) ){
365                 eind = start + strlen("\\\\") - 1;
366                 memmove( start, eind, strlen(eind)+1 );
367         }
368 #else
369         if(dir[0]=='.') {       /* happens, for example in FILE_MAIN */
370                 dir[0]= '/';
371                 dir[1]= 0;
372                 return;
373         }
374
375         /* support for odd paths: eg /../home/me --> /home/me
376          * this is a valid path in blender but we cant handle this the useual way below
377          * simply strip this prefix then evaluate the path as useual. pythons os.path.normpath() does this */
378         while((strncmp(dir, "/../", 4)==0)) {
379                 memmove( dir, dir + 4, strlen(dir + 4) + 1 );
380         }
381
382         while ( (start = strstr(dir, "/../")) ) {
383                 eind = start + (4 - 1) /* strlen("/../") - 1 */;
384                 a = start-dir-1;
385                 while (a>0) {
386                         if (dir[a] == '/') break;
387                         a--;
388                 }
389                 if (a<0) {
390                         break;
391                 } else {
392                         memmove( dir+a, eind, strlen(eind)+1 );
393                 }
394         }
395
396         while ( (start = strstr(dir,"/./")) ){
397                 eind = start + (3 - 1) /* strlen("/./") - 1 */;
398                 memmove( start, eind, strlen(eind)+1 );
399         }
400
401         while ( (start = strstr(dir,"//" )) ){
402                 eind = start + (2 - 1) /* strlen("//") - 1 */;
403                 memmove( start, eind, strlen(eind)+1 );
404         }
405 #endif
406 }
407
408 void BLI_cleanup_dir(const char *relabase, char *dir)
409 {
410         BLI_cleanup_path(relabase, dir);
411         BLI_add_slash(dir);
412
413 }
414
415 void BLI_cleanup_file(const char *relabase, char *dir)
416 {
417         BLI_cleanup_path(relabase, dir);
418         BLI_del_slash(dir);
419 }
420
421 void BLI_path_rel(char *file, const char *relfile)
422 {
423         char * lslash;
424         char temp[FILE_MAXDIR+FILE_MAXFILE];
425         char res[FILE_MAXDIR+FILE_MAXFILE];
426         
427         /* if file is already relative, bail out */
428         if(file[0]=='/' && file[1]=='/') return;
429         
430         /* also bail out if relative path is not set */
431         if (relfile[0] == 0) return;
432
433 #ifdef WIN32
434         if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') {
435                 char* ptemp;
436                 /* fix missing volume name in relative base,
437                    can happen with old recent-files.txt files */
438                 get_default_root(temp);
439                 ptemp = &temp[2];
440                 if (relfile[0] != '\\' && relfile[0] != '/') {
441                         ptemp++;
442                 }
443                 BLI_strncpy(ptemp, relfile, FILE_MAXDIR + FILE_MAXFILE-3);
444         } else {
445                 BLI_strncpy(temp, relfile, FILE_MAXDIR + FILE_MAXFILE);
446         }
447
448         if (BLI_strnlen(file, 3) > 2) {
449                 if ( temp[1] == ':' && file[1] == ':' && temp[0] != file[0] )
450                         return;
451         }
452 #else
453         BLI_strncpy(temp, relfile, FILE_MAX);
454 #endif
455
456         BLI_char_switch(temp, '\\', '/');
457         BLI_char_switch(file, '\\', '/');
458         
459         /* remove /./ which confuse the following slash counting... */
460         BLI_cleanup_path(NULL, file);
461         BLI_cleanup_path(NULL, temp);
462         
463         /* the last slash in the file indicates where the path part ends */
464         lslash = BLI_last_slash(temp);
465
466         if (lslash) 
467         {       
468                 /* find the prefix of the filename that is equal for both filenames.
469                    This is replaced by the two slashes at the beginning */
470                 char *p= temp;
471                 char *q= file;
472
473 #ifdef WIN32
474                 while (tolower(*p) == tolower(*q))
475 #else
476                 while (*p == *q)
477 #endif
478                 {
479                         ++p; ++q;
480                         /* dont search beyond the end of the string
481                          * in the rare case they match */
482                         if ((*p=='\0') || (*q=='\0')) {
483                                 break;
484                         }
485                 }
486
487                 /* we might have passed the slash when the beginning of a dir matches 
488                    so we rewind. Only check on the actual filename
489                 */
490                 if (*q != '/') {
491                         while ( (q >= file) && (*q != '/') ) { --q; --p; }
492                 } 
493                 else if (*p != '/') {
494                         while ( (p >= temp) && (*p != '/') ) { --p; --q; }
495                 }
496                 
497                 strcpy(res,     "//");
498
499                 /* p now points to the slash that is at the beginning of the part
500                    where the path is different from the relative path. 
501                    We count the number of directories we need to go up in the
502                    hierarchy to arrive at the common 'prefix' of the path
503                 */                      
504                 while (p && p < lslash) {
505                         if (*p == '/') 
506                                 strcat(res,     "../");
507                         ++p;
508                 }
509
510                 strcat(res, q+1); /* don't copy the slash at the beginning */
511                 
512 #ifdef  WIN32
513                 BLI_char_switch(res+2, '/', '\\');
514 #endif
515                 strcpy(file, res);
516         }
517 }
518
519 int BLI_has_parent(char *path)
520 {
521         int len;
522         int slashes = 0;
523         BLI_clean(path);
524         len = BLI_add_slash(path) - 1;
525
526         while (len>=0) {
527                 if ((path[len] == '\\') || (path[len] == '/'))
528                         slashes++;
529                 len--;
530         }
531         return slashes > 1;
532 }
533
534 int BLI_parent_dir(char *path)
535 {
536         static char parent_dir[]= {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
537         char tmp[FILE_MAXDIR+FILE_MAXFILE+4];
538         BLI_strncpy(tmp, path, sizeof(tmp)-4);
539         BLI_add_slash(tmp);
540         strcat(tmp, parent_dir);
541         BLI_cleanup_dir(NULL, tmp);
542
543         if (!BLI_testextensie(tmp, parent_dir)) {
544                 BLI_strncpy(path, tmp, sizeof(tmp));    
545                 return 1;
546         } else {
547                 return 0;
548         }
549 }
550
551 static int stringframe_chars(char *path, int *char_start, int *char_end)
552 {
553         int ch_sta, ch_end, i;
554         /* Insert current frame: file### -> file001 */
555         ch_sta = ch_end = 0;
556         for (i = 0; path[i] != '\0'; i++) {
557                 if (path[i] == '\\' || path[i] == '/') {
558                         ch_end = 0; /* this is a directory name, dont use any hashes we found */
559                 } else if (path[i] == '#') {
560                         ch_sta = i;
561                         ch_end = ch_sta+1;
562                         while (path[ch_end] == '#') {
563                                 ch_end++;
564                         }
565                         i = ch_end-1; /* keep searching */
566                         
567                         /* dont break, there may be a slash after this that invalidates the previous #'s */
568                 }
569         }
570
571         if(ch_end) {
572                 *char_start= ch_sta;
573                 *char_end= ch_end;
574                 return 1;
575         }
576         else {
577                 *char_start= -1;
578                 *char_end= -1;
579                 return 0;
580         }
581 }
582
583 static void ensure_digits(char *path, int digits)
584 {
585         char *file= BLI_last_slash(path);
586
587         if(file==NULL)
588                 file= path;
589
590         if(strrchr(file, '#') == NULL) {
591                 int len= strlen(file);
592
593                 while(digits--) {
594                         file[len++]= '#';
595                 }
596                 file[len]= '\0';
597         }
598 }
599
600 int BLI_path_frame(char *path, int frame, int digits)
601 {
602         int ch_sta, ch_end;
603
604         if(digits)
605                 ensure_digits(path, digits);
606
607         if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
608                 char tmp[FILE_MAX];
609                 sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end-ch_sta, frame, path+ch_end);
610                 strcpy(path, tmp);
611                 return 1;
612         }
613         return 0;
614 }
615
616 int BLI_path_frame_range(char *path, int sta, int end, int digits)
617 {
618         int ch_sta, ch_end;
619
620         if(digits)
621                 ensure_digits(path, digits);
622
623         if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
624                 char tmp[FILE_MAX];
625                 sprintf(tmp, "%.*s%.*d-%.*d%s", ch_sta, path, ch_end-ch_sta, sta, ch_end-ch_sta, end, path+ch_end);
626                 strcpy(path, tmp);
627                 return 1;
628         }
629         return 0;
630 }
631
632 int BLI_path_abs(char *path, const char *basepath)
633 {
634         int wasrelative = (strncmp(path, "//", 2)==0);
635         char tmp[FILE_MAX];
636         char base[FILE_MAX];
637 #ifdef WIN32
638         char vol[3] = {'\0', '\0', '\0'};
639
640         BLI_strncpy(vol, path, 3);
641         /* we are checking here if we have an absolute path that is not in the current
642            blend file as a lib main - we are basically checking for the case that a 
643            UNIX root '/' is passed.
644         */
645         if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) {
646                 char *p = path;
647                 get_default_root(tmp);
648                 // get rid of the slashes at the beginning of the path
649                 while (*p == '\\' || *p == '/') {
650                         p++;
651                 }
652                 strcat(tmp, p);
653         }
654         else {
655                 BLI_strncpy(tmp, path, FILE_MAX);
656         }
657 #else
658         BLI_strncpy(tmp, path, sizeof(tmp));
659         
660         /* Check for loading a windows path on a posix system
661          * in this case, there is no use in trying C:/ since it 
662          * will never exist on a unix os.
663          * 
664          * Add a / prefix and lowercase the driveletter, remove the :
665          * C:\foo.JPG -> /c/foo.JPG */
666         
667         if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2]=='\\' || tmp[2]=='/') ) {
668                 tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */
669                 tmp[0] = '/'; 
670                 /* '\' the slash will be converted later */
671         }
672         
673 #endif
674
675         BLI_strncpy(base, basepath, sizeof(base));
676
677         /* file component is ignored, so dont bother with the trailing slash */
678         BLI_cleanup_path(NULL, base);
679         
680         /* push slashes into unix mode - strings entering this part are
681            potentially messed up: having both back- and forward slashes.
682            Here we push into one conform direction, and at the end we
683            push them into the system specific dir. This ensures uniformity
684            of paths and solving some problems (and prevent potential future
685            ones) -jesterKing. */
686         BLI_char_switch(tmp, '\\', '/');
687         BLI_char_switch(base, '\\', '/');       
688
689         /* Paths starting with // will get the blend file as their base,
690          * this isnt standard in any os but is uesed in blender all over the place */
691         if (wasrelative) {
692                 char *lslash= BLI_last_slash(base);
693                 if (lslash) {
694                         int baselen= (int) (lslash-base) + 1;
695                         /* use path for temp storage here, we copy back over it right away */
696                         BLI_strncpy(path, tmp+2, FILE_MAX);
697                         
698                         memcpy(tmp, base, baselen);
699                         BLI_strncpy(tmp+baselen, path, sizeof(tmp)-baselen);
700                         BLI_strncpy(path, tmp, FILE_MAX);
701                 } else {
702                         BLI_strncpy(path, tmp+2, FILE_MAX);
703                 }
704         } else {
705                 BLI_strncpy(path, tmp, FILE_MAX);
706         }
707
708         BLI_cleanup_path(NULL, path);
709
710 #ifdef WIN32
711         /* skip first two chars, which in case of
712            absolute path will be drive:/blabla and
713            in case of relpath //blabla/. So relpath
714            // will be retained, rest will be nice and
715            shiny win32 backward slashes :) -jesterKing
716         */
717         BLI_char_switch(path+2, '/', '\\');
718 #endif
719         
720         return wasrelative;
721 }
722
723
724 /*
725  * Should only be done with command line paths.
726  * this is NOT somthing blenders internal paths support like the // prefix
727  */
728 int BLI_path_cwd(char *path)
729 {
730         int wasrelative = 1;
731         int filelen = strlen(path);
732         
733 #ifdef WIN32
734         if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
735                 wasrelative = 0;
736 #else
737         if (filelen >= 2 && path[0] == '/')
738                 wasrelative = 0;
739 #endif
740         
741         if (wasrelative==1) {
742                 char cwd[FILE_MAXDIR + FILE_MAXFILE]= "";
743                 BLI_getwdN(cwd, sizeof(cwd)); /* incase the full path to the blend isnt used */
744                 
745                 if (cwd[0] == '\0') {
746                         printf( "Could not get the current working directory - $PWD for an unknown reason.");
747                 } else {
748                         /* uses the blend path relative to cwd important for loading relative linked files.
749                         *
750                         * cwd should contain c:\ etc on win32 so the relbase can be NULL
751                         * relbase being NULL also prevents // being misunderstood as relative to the current
752                         * blend file which isnt a feature we want to use in this case since were dealing
753                         * with a path from the command line, rather than from inside Blender */
754                         
755                         char origpath[FILE_MAXDIR + FILE_MAXFILE];
756                         BLI_strncpy(origpath, path, FILE_MAXDIR + FILE_MAXFILE);
757                         
758                         BLI_make_file_string(NULL, path, cwd, origpath); 
759                 }
760         }
761         
762         return wasrelative;
763 }
764
765
766 /* 'di's filename component is moved into 'fi', di is made a dir path */
767 void BLI_splitdirstring(char *di, char *fi)
768 {
769         char *lslash= BLI_last_slash(di);
770
771         if (lslash) {
772                 BLI_strncpy(fi, lslash+1, FILE_MAXFILE);
773                 *(lslash+1)=0;
774         } else {
775                 BLI_strncpy(fi, di, FILE_MAXFILE);
776                 di[0]= 0;
777         }
778 }
779
780 void BLI_getlastdir(const char* dir, char *last, const size_t maxlen)
781 {
782         const char *s = dir;
783         const char *lslash = NULL;
784         const char *prevslash = NULL;
785         while (*s) {
786                 if ((*s == '\\') || (*s == '/')) {
787                         prevslash = lslash;
788                         lslash = s;
789                 }
790                 s++;
791         }
792         if (prevslash) {
793                 BLI_strncpy(last, prevslash+1, maxlen);
794         } else {
795                 BLI_strncpy(last, dir, maxlen);
796         }
797 }
798
799 /* This is now only used to really get the user's default document folder */
800 /* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
801    as default location to save documents */
802 const char *BLI_getDefaultDocumentFolder(void)
803 {
804         #if !defined(WIN32)
805                 return getenv("HOME");
806
807         #else /* Windows */
808                 const char * ret;
809                 static char documentfolder[MAXPATHLEN];
810                 HRESULT hResult;
811
812                 /* Check for %HOME% env var */
813
814                 ret = getenv("HOME");
815                 if(ret) {
816                         if (BLI_is_dir(ret)) return ret;
817                 }
818                                 
819                 /* add user profile support for WIN 2K / NT.
820                  * This is %APPDATA%, which translates to either
821                  * %USERPROFILE%\Application Data or since Vista
822                  * to %USERPROFILE%\AppData\Roaming
823                  */
824                 hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
825                 
826                 if (hResult == S_OK)
827                 {
828                         if (BLI_is_dir(documentfolder)) return documentfolder;
829                 }
830                 
831                 return NULL;
832         #endif
833 }
834
835 /* NEW stuff, to be cleaned up when fully migrated */
836 /* ************************************************************* */
837 /* ************************************************************* */
838
839 // #define PATH_DEBUG2
840
841 static char *blender_version_decimal(const int ver)
842 {
843         static char version_str[5];
844         sprintf(version_str, "%d.%02d", ver/100, ver%100);
845         return version_str;
846 }
847
848 static int test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
849 {
850         char tmppath[FILE_MAX];
851         
852         if(path_sep)    BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep);
853         else                    BLI_strncpy(tmppath, path_base, sizeof(tmppath));
854
855         /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */
856         if(folder_name)
857                 BLI_make_file_string("/", targetpath, tmppath, folder_name);
858         else
859                 BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
860
861         if (BLI_is_dir(targetpath)) {
862 #ifdef PATH_DEBUG2
863                 printf("\tpath found: %s\n", targetpath);
864 #endif
865                 return 1;
866         }
867         else {
868 #ifdef PATH_DEBUG2
869                 printf("\tpath missing: %s\n", targetpath);
870 #endif
871                 //targetpath[0] = '\0';
872                 return 0;
873         }
874 }
875
876 static int test_env_path(char *path, const char *envvar)
877 {
878         const char *env = envvar?getenv(envvar):NULL;
879         if (!env) return 0;
880         
881         if (BLI_is_dir(env)) {
882                 BLI_strncpy(path, env, FILE_MAX);
883                 return 1;
884         } else {
885                 path[0] = '\0';
886                 return 0;
887         }
888 }
889
890 static int get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
891 {
892         char relfolder[FILE_MAX];
893         
894 #ifdef PATH_DEBUG2
895         printf("get_path_local...\n");
896 #endif
897
898         if(folder_name) {
899                 if (subfolder_name) {
900                         BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
901                 } else {
902                         BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
903                 }
904         }
905         else {
906                 relfolder[0]= '\0';
907         }
908
909         /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
910         if(test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder))
911                 return 1;
912
913         return 0;
914 }
915
916 static int is_portable_install(void)
917 {
918         /* detect portable install by the existance of config folder */
919         const int ver= BLENDER_VERSION;
920         char path[FILE_MAX];
921
922         return get_path_local(path, "config", NULL, ver);
923 }
924
925 static int get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
926 {
927         char user_path[FILE_MAX];
928         const char *user_base_path;
929
930         /* for portable install, user path is always local */
931         if (is_portable_install())
932                 return get_path_local(targetpath, folder_name, subfolder_name, ver);
933         
934         user_path[0] = '\0';
935
936         if (test_env_path(user_path, envvar)) {
937                 if (subfolder_name) {
938                         return test_path(targetpath, user_path, NULL, subfolder_name);
939                 } else {
940                         BLI_strncpy(targetpath, user_path, FILE_MAX);
941                         return 1;
942                 }
943         }
944
945         user_base_path = (const char *)GHOST_getUserDir();
946         if (user_base_path) {
947                 BLI_snprintf(user_path, FILE_MAX, BLENDER_USER_FORMAT, user_base_path, blender_version_decimal(ver));
948         }
949
950         if(!user_path[0])
951                 return 0;
952         
953 #ifdef PATH_DEBUG2
954         printf("get_path_user: %s\n", user_path);
955 #endif
956         
957         if (subfolder_name) {
958                 /* try $HOME/folder_name/subfolder_name */
959                 return test_path(targetpath, user_path, folder_name, subfolder_name);
960         } else {
961                 /* try $HOME/folder_name */
962                 return test_path(targetpath, user_path, NULL, folder_name);
963         }
964 }
965
966 static int get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
967 {
968         char system_path[FILE_MAX];
969         const char *system_base_path;
970
971
972         /* first allow developer only overrides to the system path
973          * these are only used when running blender from source */
974         char cwd[FILE_MAX];
975         char relfolder[FILE_MAX];
976
977         if(folder_name) {
978                 if (subfolder_name) {
979                         BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
980                 } else {
981                         BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
982                 }
983         }
984         else {
985                 relfolder[0]= '\0';
986         }
987
988         /* try CWD/release/folder_name */
989         if(BLI_getwdN(cwd, sizeof(cwd))) {
990                 if(test_path(targetpath, cwd, "release", relfolder)) {
991                         return 1;
992                 }
993         }
994
995         /* try EXECUTABLE_DIR/release/folder_name */
996         if(test_path(targetpath, bprogdir, "release", relfolder))
997                 return 1;
998         /* end developer overrides */
999
1000
1001
1002         system_path[0] = '\0';
1003
1004         if (test_env_path(system_path, envvar)) {
1005                 if (subfolder_name) {
1006                         return test_path(targetpath, system_path, NULL, subfolder_name);
1007                 } else {
1008                         BLI_strncpy(targetpath, system_path, FILE_MAX);
1009                         return 1;
1010                 }
1011         }
1012
1013         system_base_path = (const char *)GHOST_getSystemDir();
1014         if (system_base_path) {
1015                 BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path, blender_version_decimal(ver));
1016         }
1017         
1018         if(!system_path[0])
1019                 return 0;
1020         
1021 #ifdef PATH_DEBUG2
1022         printf("get_path_system: %s\n", system_path);
1023 #endif
1024         
1025         if (subfolder_name) {
1026                 /* try $BLENDERPATH/folder_name/subfolder_name */
1027                 return test_path(targetpath, system_path, folder_name, subfolder_name);
1028         } else {
1029                 /* try $BLENDERPATH/folder_name */
1030                 return test_path(targetpath, system_path, NULL, folder_name);
1031         }
1032 }
1033
1034 /* get a folder out of the 'folder_id' presets for paths */
1035 /* returns the path if found, NULL string if not */
1036 char *BLI_get_folder(int folder_id, const char *subfolder)
1037 {
1038         const int ver= BLENDER_VERSION;
1039         static char path[FILE_MAX] = "";
1040         
1041         switch (folder_id) {
1042                 case BLENDER_DATAFILES:         /* general case */
1043                         if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
1044                         if (get_path_local(path, "datafiles", subfolder, ver)) break;
1045                         if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
1046                         return NULL;
1047                         
1048                 case BLENDER_USER_DATAFILES:
1049                         if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
1050                         return NULL;
1051                         
1052                 case BLENDER_SYSTEM_DATAFILES:
1053                         if (get_path_local(path, "datafiles", subfolder, ver)) break;
1054                         if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver))     break;
1055                         return NULL;
1056                         
1057                 case BLENDER_USER_AUTOSAVE:
1058                         if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver))  break;
1059                         return NULL;
1060
1061                 case BLENDER_USER_CONFIG:
1062                         if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break;
1063                         return NULL;
1064                         
1065                 case BLENDER_USER_SCRIPTS:
1066                         if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break;
1067                         return NULL;
1068                         
1069                 case BLENDER_SYSTEM_SCRIPTS:
1070                         if (get_path_local(path, "scripts", subfolder, ver)) break;
1071                         if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break;
1072                         return NULL;
1073                         
1074                 case BLENDER_SYSTEM_PYTHON:
1075                         if (get_path_local(path, "python", subfolder, ver)) break;
1076                         if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break;
1077                         return NULL;
1078         }
1079         
1080         return path;
1081 }
1082
1083 char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
1084 {
1085         const int ver= BLENDER_VERSION;
1086         static char path[FILE_MAX] = "";
1087
1088         switch (folder_id) {
1089                 case BLENDER_USER_DATAFILES:
1090                         get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver);
1091                         break;
1092                 case BLENDER_USER_CONFIG:
1093                         get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver);
1094                         break;
1095                 case BLENDER_USER_AUTOSAVE:
1096                         get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver);
1097                         break;
1098                 case BLENDER_USER_SCRIPTS:
1099                         get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver);
1100                         break;
1101         }
1102         if ('\0' == path[0]) {
1103                 return NULL;
1104         }
1105         return path;
1106 }
1107
1108 char *BLI_get_folder_create(int folder_id, const char *subfolder)
1109 {
1110         char *path;
1111
1112         /* only for user folders */
1113         if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
1114                 return NULL;
1115         
1116         path = BLI_get_folder(folder_id, subfolder);
1117         
1118         if (!path) {
1119                 path = BLI_get_user_folder_notest(folder_id, subfolder);
1120                 if (path) BLI_recurdir_fileops(path);
1121         }
1122         
1123         return path;
1124 }
1125
1126 char *BLI_get_folder_version(const int id, const int ver, const int do_check)
1127 {
1128         static char path[FILE_MAX] = "";
1129         int ok;
1130         switch(id) {
1131         case BLENDER_RESOURCE_PATH_USER:
1132                 ok= get_path_user(path, NULL, NULL, NULL, ver);
1133                 break;
1134         case BLENDER_RESOURCE_PATH_LOCAL:
1135                 ok= get_path_local(path, NULL, NULL, ver);
1136                 break;
1137         case BLENDER_RESOURCE_PATH_SYSTEM:
1138                 ok= get_path_system(path, NULL, NULL, NULL, ver);
1139                 break;
1140         default:
1141                 path[0]= '\0'; /* incase do_check is false */
1142                 ok= FALSE;
1143                 BLI_assert(!"incorrect ID");
1144         }
1145
1146         if((ok == FALSE) && do_check) {
1147                 return NULL;
1148         }
1149
1150         return path;
1151 }
1152
1153 /* End new stuff */
1154 /* ************************************************************* */
1155 /* ************************************************************* */
1156
1157
1158
1159 #ifdef PATH_DEBUG
1160 #undef PATH_DEBUG
1161 #endif
1162
1163 void BLI_setenv(const char *env, const char*val)
1164 {
1165         /* free windows */
1166 #if (defined(WIN32) || defined(WIN64)) && defined(FREE_WINDOWS)
1167         char *envstr= MEM_mallocN(sizeof(char) * (strlen(env) + strlen(val) + 2), "envstr"); /* one for = another for \0 */
1168
1169         sprintf(envstr, "%s=%s", env, val);
1170         putenv(envstr);
1171         MEM_freeN(envstr);
1172
1173         /* non-free windows */
1174 #elif (defined(WIN32) || defined(WIN64)) /* not free windows */
1175         _putenv_s(env, val);
1176 #else
1177         /* linux/osx/bsd */
1178         setenv(env, val, 1);
1179 #endif
1180 }
1181
1182
1183 /**
1184  Only set an env var if already not there.
1185  Like Unix setenv(env, val, 0);
1186  */
1187 void BLI_setenv_if_new(const char *env, const char* val)
1188 {
1189         if(getenv(env) == NULL)
1190                 BLI_setenv(env, val);
1191 }
1192
1193
1194 void BLI_clean(char *path)
1195 {
1196         if(path==NULL) return;
1197
1198 #ifdef WIN32
1199         if(path && BLI_strnlen(path, 3) > 2) {
1200                 BLI_char_switch(path+2, '/', '\\');
1201         }
1202 #else
1203         BLI_char_switch(path, '\\', '/');
1204 #endif
1205 }
1206
1207 void BLI_char_switch(char *string, char from, char to) 
1208 {
1209         if(string==NULL) return;
1210         while (*string != 0) {
1211                 if (*string == from) *string = to;
1212                 string++;
1213         }
1214 }
1215
1216 void BLI_make_exist(char *dir)
1217 {
1218         int a;
1219
1220         BLI_char_switch(dir, ALTSEP, SEP);
1221
1222         a = strlen(dir);
1223
1224         while(BLI_is_dir(dir) == 0){
1225                 a --;
1226                 while(dir[a] != SEP){
1227                         a--;
1228                         if (a <= 0) break;
1229                 }
1230                 if (a >= 0) {
1231                         dir[a+1] = '\0';
1232                 }
1233                 else {
1234 #ifdef WIN32
1235                         get_default_root(dir);
1236 #else
1237                         strcpy(dir,"/");
1238 #endif
1239                         break;
1240                 }
1241         }
1242 }
1243
1244 void BLI_make_existing_file(const char *name)
1245 {
1246         char di[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
1247
1248         BLI_strncpy(di, name, sizeof(di));
1249         BLI_splitdirstring(di, fi);
1250         
1251         /* test exist */
1252         if (BLI_exists(di) == 0) {
1253                 BLI_recurdir_fileops(di);
1254         }
1255 }
1256
1257
1258 void BLI_make_file_string(const char *relabase, char *string,  const char *dir, const char *file)
1259 {
1260         int sl;
1261
1262         if (!string || !dir || !file) return; /* We don't want any NULLs */
1263         
1264         string[0]= 0; /* ton */
1265
1266         /* we first push all slashes into unix mode, just to make sure we don't get
1267            any mess with slashes later on. -jesterKing */
1268         /* constant strings can be passed for those parameters - don't change them - elubie */
1269         /*
1270         BLI_char_switch(relabase, '\\', '/');
1271         BLI_char_switch(dir, '\\', '/');
1272         BLI_char_switch(file, '\\', '/');
1273         */
1274
1275         /* Resolve relative references */       
1276         if (relabase && dir[0] == '/' && dir[1] == '/') {
1277                 char *lslash;
1278                 
1279                 /* Get the file name, chop everything past the last slash (ie. the filename) */
1280                 strcpy(string, relabase);
1281                 
1282                 lslash= BLI_last_slash(string);
1283                 if(lslash) *(lslash+1)= 0;
1284
1285                 dir+=2; /* Skip over the relative reference */
1286         }
1287 #ifdef WIN32
1288         else {
1289                 if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':' ) {
1290                         BLI_strncpy(string, dir, 3);
1291                         dir += 2;
1292                 }
1293                 else { /* no drive specified */
1294                         /* first option: get the drive from the relabase if it has one */
1295                         if (relabase && strlen(relabase) >= 2 && relabase[1] == ':' ) {
1296                                 BLI_strncpy(string, relabase, 3);       
1297                                 string[2] = '\\';
1298                                 string[3] = '\0';
1299                         }
1300                         else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
1301                                 get_default_root(string);
1302                         }
1303                         
1304                         /* ignore leading slashes */
1305                         while (*dir == '/' || *dir == '\\') dir++;
1306                 }
1307         }
1308 #endif
1309
1310         strcat(string, dir);
1311
1312         /* Make sure string ends in one (and only one) slash */ 
1313         /* first trim all slashes from the end of the string */
1314         sl = strlen(string);
1315         while (sl>0 && ( string[sl-1] == '/' || string[sl-1] == '\\') ) {
1316                 string[sl-1] = '\0';
1317                 sl--;
1318         }
1319         /* since we've now removed all slashes, put back one slash at the end. */
1320         strcat(string, "/");
1321         
1322         while (*file && (*file == '/' || *file == '\\')) /* Trim slashes from the front of file */
1323                 file++;
1324                 
1325         strcat (string, file);
1326         
1327         /* Push all slashes to the system preferred direction */
1328         BLI_clean(string);
1329 }
1330
1331 int BLI_testextensie(const char *str, const char *ext)
1332 {
1333         short a, b;
1334         int retval;
1335         
1336         a= strlen(str);
1337         b= strlen(ext);
1338         
1339         if(a==0 || b==0 || b>=a) {
1340                 retval = 0;
1341         } else if (BLI_strcasecmp(ext, str + a - b)) {
1342                 retval = 0;     
1343         } else {
1344                 retval = 1;
1345         }
1346         
1347         return (retval);
1348 }
1349
1350 int BLI_testextensie_array(const char *str, const char **ext_array)
1351 {
1352         int i=0;
1353         while(ext_array[i]) {
1354                 if(BLI_testextensie(str, ext_array[i])) {
1355                         return 1;
1356                 }
1357
1358                 i++;
1359         }
1360         return 0;
1361 }
1362
1363 /* semicolon separated wildcards, eg:
1364  *  '*.zip;*.py;*.exe' */
1365 int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
1366 {
1367         const char *ext_step= ext_fnmatch;
1368         char pattern[16];
1369
1370         while(ext_step[0]) {
1371                 char *ext_next;
1372                 int len_ext;
1373
1374                 if((ext_next=strchr(ext_step, ';'))) {
1375                         len_ext= (int)(ext_next - ext_step) + 1;
1376                 }
1377                 else {
1378                         len_ext= sizeof(pattern);
1379                 }
1380
1381                 BLI_strncpy(pattern, ext_step, len_ext);
1382
1383                 if(fnmatch(pattern, str, FNM_CASEFOLD)==0) {
1384                         return 1;
1385                 }
1386                 ext_step += len_ext;
1387         }
1388
1389         return 0;
1390 }
1391
1392
1393 int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
1394 {
1395         size_t a;
1396
1397         for(a=strlen(path); a>0; a--) {
1398                 if(path[a-1] == '.' || path[a-1] == '/' || path[a-1] == '\\') {
1399                         a--;
1400                         break;
1401                 }
1402         }
1403         
1404         if(path[a] != '.')
1405                 a= strlen(path);
1406
1407         if(a + strlen(ext) >= maxlen)
1408                 return 0;
1409
1410         strcpy(path+a, ext);
1411         return 1;
1412 }
1413
1414 /* Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
1415  * - wont change 'string'
1416  * - wont create any directories
1417  * - dosnt use CWD, or deal with relative paths.
1418  * - Only fill's in *dir and *file when they are non NULL
1419  * */
1420 void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
1421 {
1422         char *lslash_str = BLI_last_slash(string);
1423         size_t lslash= lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
1424
1425         if (dir) {
1426                 if (lslash) {
1427                         BLI_strncpy( dir, string, MIN2(dirlen, lslash + 1)); /* +1 to include the slash and the last char */
1428                 }
1429                 else {
1430                         dir[0] = '\0';
1431                 }
1432         }
1433         
1434         if (file) {
1435                 BLI_strncpy(file, string+lslash, filelen);
1436         }
1437 }
1438
1439 void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
1440 {
1441         BLI_split_dirfile(string, dir, NULL, dirlen, 0);
1442 }
1443
1444 void BLI_split_file_part(const char *string, char *file, const size_t filelen)
1445 {
1446         BLI_split_dirfile(string, NULL, file, 0, filelen);
1447 }
1448
1449 /* simple appending of filename to dir, does not check for valid path! */
1450 void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const char *file)
1451 {
1452         size_t dirlen= BLI_strnlen(dir, maxlen);
1453
1454         if (dst != dir) {
1455                 if(dirlen  == maxlen) {
1456                         memcpy(dst, dir, dirlen);
1457                         dst[dirlen - 1]= '\0';
1458                         return; /* dir fills the path */
1459                 }
1460                 else {
1461                         memcpy(dst, dir, dirlen + 1);
1462                 }
1463         }
1464
1465         if (dirlen + 1 >= maxlen) {
1466                 return; /* fills the path */
1467         }
1468
1469         /* inline BLI_add_slash */
1470         if (dst[dirlen - 1] != SEP) {
1471                 dst[dirlen++]= SEP;
1472                 dst[dirlen  ]= '\0';
1473         }
1474
1475         if (dirlen >= maxlen) {
1476                 return; /* fills the path */
1477         }
1478
1479         if (file == NULL) {
1480                 return;
1481         }
1482
1483         BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
1484 }
1485
1486 /* like pythons os.path.basename( ) */
1487 char *BLI_path_basename(char *path)
1488 {
1489         char *filename= BLI_last_slash(path);
1490         return filename ? filename + 1 : path;
1491 }
1492
1493 /*
1494   Produce image export path.
1495
1496   Fails returning 0 if image filename is empty or if destination path
1497   matches image path (i.e. both are the same file).
1498
1499   Trailing slash in dest_dir is optional.
1500
1501   Logic:
1502
1503   - if an image is "below" current .blend file directory, rebuild the
1504         same dir structure in dest_dir
1505
1506   For example //textures/foo/bar.png becomes
1507   [dest_dir]/textures/foo/bar.png.
1508
1509   - if an image is not "below" current .blend file directory,
1510   disregard it's path and copy it in the same directory where 3D file
1511   goes.
1512
1513   For example //../foo/bar.png becomes [dest_dir]/bar.png.
1514
1515   This logic will help ensure that all image paths are relative and
1516   that a user gets his images in one place. It'll also provide
1517   consistent behaviour across exporters.
1518  */
1519 int BKE_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir)
1520 {
1521         char path[FILE_MAX];
1522         char dir[FILE_MAX];
1523         char base[FILE_MAX];
1524         char blend_dir[FILE_MAX];       /* directory, where current .blend file resides */
1525         char dest_path[FILE_MAX];
1526         char rel_dir[FILE_MAX];
1527         int len;
1528
1529         if (abs)
1530                 abs[0]= 0;
1531
1532         if (rel)
1533                 rel[0]= 0;
1534
1535         BLI_split_dir_part(base_dir, blend_dir, sizeof(blend_dir));
1536
1537         if (src_dir[0]=='\0')
1538                 return 0;
1539
1540         BLI_strncpy(path, src_dir, sizeof(path));
1541
1542         /* expand "//" in filename and get absolute path */
1543         BLI_path_abs(path, base_dir);
1544
1545         /* get the directory part */
1546         BLI_split_dirfile(path, dir, base, sizeof(dir), sizeof(base));
1547
1548         len= strlen(blend_dir);
1549
1550         rel_dir[0] = 0;
1551
1552         /* if image is "below" current .blend file directory */
1553         if (!strncmp(path, blend_dir, len)) {
1554
1555                 /* if image is _in_ current .blend file directory */
1556                 if (BLI_path_cmp(dir, blend_dir) == 0) {
1557                         BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
1558                 }
1559                 /* "below" */
1560                 else {
1561                         /* rel = image_path_dir - blend_dir */
1562                         BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
1563
1564                         BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
1565                         BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
1566                 }
1567
1568         }
1569         /* image is out of current directory */
1570         else {
1571                 BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
1572         }
1573
1574         if (abs)
1575                 BLI_strncpy(abs, dest_path, abs_len);
1576
1577         if (rel) {
1578                 strncat(rel, rel_dir, rel_len);
1579                 strncat(rel, base, rel_len);
1580         }
1581
1582         /* return 2 if src=dest */
1583         if (BLI_path_cmp(path, dest_path) == 0) {
1584                 // if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
1585                 return 2;
1586         }
1587
1588         return 1;
1589 }
1590
1591 char *BLI_first_slash(char *string)
1592 {
1593         char *ffslash, *fbslash;
1594         
1595         ffslash= strchr(string, '/');   
1596         fbslash= strchr(string, '\\');
1597         
1598         if (!ffslash) return fbslash;
1599         else if (!fbslash) return ffslash;
1600         
1601         if ((intptr_t)ffslash < (intptr_t)fbslash) return ffslash;
1602         else return fbslash;
1603 }
1604
1605 char *BLI_last_slash(const char *string)
1606 {
1607         char *lfslash, *lbslash;
1608         
1609         lfslash= strrchr(string, '/');  
1610         lbslash= strrchr(string, '\\');
1611
1612         if (!lfslash) return lbslash; 
1613         else if (!lbslash) return lfslash;
1614         
1615         if ((intptr_t)lfslash < (intptr_t)lbslash) return lbslash;
1616         else return lfslash;
1617 }
1618
1619 /* adds a slash if there isnt one there already */
1620 int BLI_add_slash(char *string)
1621 {
1622         int len = strlen(string);
1623         if (len==0 || string[len-1] != SEP) {
1624                 string[len] = SEP;
1625                 string[len+1] = '\0';
1626                 return len+1;
1627         }
1628         return len;
1629 }
1630
1631 /* removes a slash if there is one */
1632 void BLI_del_slash(char *string)
1633 {
1634         int len = strlen(string);
1635         while (len) {
1636                 if (string[len-1] == SEP) {
1637                         string[len-1] = '\0';
1638                         len--;
1639                 } else {
1640                         break;
1641                 }
1642         }
1643 }
1644
1645 static int add_win32_extension(char *name)
1646 {
1647         int retval = 0;
1648         int type;
1649
1650         type = BLI_exists(name);
1651         if ((type == 0) || S_ISDIR(type)) {
1652 #ifdef _WIN32
1653                 char filename[FILE_MAXDIR+FILE_MAXFILE];
1654                 char ext[FILE_MAXDIR+FILE_MAXFILE];
1655                 const char *extensions = getenv("PATHEXT");
1656                 if (extensions) {
1657                         char *temp;
1658                         do {
1659                                 strcpy(filename, name);
1660                                 temp = strstr(extensions, ";");
1661                                 if (temp) {
1662                                         strncpy(ext, extensions, temp - extensions);
1663                                         ext[temp - extensions] = 0;
1664                                         extensions = temp + 1;
1665                                         strcat(filename, ext);
1666                                 } else {
1667                                         strcat(filename, extensions);
1668                                 }
1669
1670                                 type = BLI_exists(filename);
1671                                 if (type && (! S_ISDIR(type))) {
1672                                         retval = 1;
1673                                         strcpy(name, filename);
1674                                         break;
1675                                 }
1676                         } while (temp);
1677                 }
1678 #endif
1679         } else {
1680                 retval = 1;
1681         }
1682
1683         return (retval);
1684 }
1685
1686 /*
1687 * Checks if name is a fully qualified filename to an executable.
1688 * If not it searches $PATH for the file. On Windows it also
1689 * adds the correct extension (.com .exe etc) from
1690 * $PATHEXT if necessary. Also on Windows it translates
1691 * the name to its 8.3 version to prevent problems with
1692 * spaces and stuff. Final result is returned in fullname.
1693 *
1694 * @param fullname The full path and full name of the executable
1695 * (must be FILE_MAX minimum)
1696 * @param name The name of the executable (usually argv[0]) to be checked
1697 */
1698 static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
1699 {
1700         char filename[FILE_MAXDIR+FILE_MAXFILE];
1701         const char *path = NULL, *temp;
1702
1703 #ifdef _WIN32
1704         const char *separator = ";";
1705 #else
1706         const char *separator = ":";
1707 #endif
1708
1709         
1710 #ifdef WITH_BINRELOC
1711         /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */
1712         path = br_find_exe( NULL );
1713         if (path) {
1714                 BLI_strncpy(fullname, path, maxlen);
1715                 free((void *)path);
1716                 return;
1717         }
1718 #endif
1719
1720 #ifdef _WIN32
1721         if(GetModuleFileName(0, fullname, maxlen)) {
1722                 if(!BLI_exists(fullname)) {
1723                         printf("path can't be found: \"%.*s\"\n", maxlen, fullname);
1724                         MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK);
1725                 }
1726                 return;
1727         }
1728 #endif
1729
1730         /* unix and non linux */
1731         if (name && name[0]) {
1732                 BLI_strncpy(fullname, name, maxlen);
1733                 if (name[0] == '.') {
1734                         char wdir[FILE_MAX]= "";
1735                         BLI_getwdN(wdir, sizeof(wdir));  /* backup cwd to restore after */
1736
1737                         // not needed but avoids annoying /./ in name
1738                         if(name[1]==SEP)
1739                                 BLI_join_dirfile(fullname, maxlen, wdir, name+2);
1740                         else
1741                                 BLI_join_dirfile(fullname, maxlen, wdir, name);
1742
1743                         add_win32_extension(fullname); /* XXX, doesnt respect length */
1744                 }
1745                 else if (BLI_last_slash(name)) {
1746                         // full path
1747                         BLI_strncpy(fullname, name, maxlen);
1748                         add_win32_extension(fullname);
1749                 } else {
1750                         // search for binary in $PATH
1751                         path = getenv("PATH");
1752                         if (path) {
1753                                 do {
1754                                         temp = strstr(path, separator);
1755                                         if (temp) {
1756                                                 strncpy(filename, path, temp - path);
1757                                                 filename[temp - path] = 0;
1758                                                 path = temp + 1;
1759                                         } else {
1760                                                 strncpy(filename, path, sizeof(filename));
1761                                         }
1762                                         BLI_join_dirfile(fullname, maxlen, fullname, name);
1763                                         if (add_win32_extension(filename)) {
1764                                                 BLI_strncpy(fullname, filename, maxlen);
1765                                                 break;
1766                                         }
1767                                 } while (temp);
1768                         }
1769                 }
1770 #if defined(DEBUG)
1771                 if (strcmp(name, fullname)) {
1772                         printf("guessing '%s' == '%s'\n", name, fullname);
1773                 }
1774 #endif
1775         }
1776 }
1777
1778 void BLI_init_program_path(const char *argv0)
1779 {
1780         bli_where_am_i(bprogname, sizeof(bprogname), argv0);
1781         BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir));
1782 }
1783
1784 const char *BLI_program_path(void)
1785 {
1786         return bprogname;
1787 }
1788
1789 const char *BLI_program_dir(void)
1790 {
1791         return bprogdir;
1792 }
1793
1794 /**
1795 * Gets the temp directory when blender first runs.
1796 * If the default path is not found, use try $TEMP
1797
1798 * Also make sure the temp dir has a trailing slash
1799 *
1800 * @param fullname The full path to the temp directory
1801 * @param userdir Directory specified in user preferences 
1802 */
1803 void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir)
1804 {
1805         fullname[0] = '\0';
1806         
1807         if (userdir && BLI_is_dir(userdir)) {
1808                 BLI_strncpy(fullname, userdir, maxlen);
1809         }
1810         
1811         
1812 #ifdef WIN32
1813         if (fullname[0] == '\0') {
1814                 const char *tmp = getenv("TEMP"); /* Windows */
1815                 if (tmp && BLI_is_dir(tmp)) {
1816                         BLI_strncpy(fullname, tmp, maxlen);
1817                 }
1818         }
1819 #else
1820         /* Other OS's - Try TMP and TMPDIR */
1821         if (fullname[0] == '\0') {
1822                 const char *tmp = getenv("TMP");
1823                 if (tmp && BLI_is_dir(tmp)) {
1824                         BLI_strncpy(fullname, tmp, maxlen);
1825                 }
1826         }
1827         
1828         if (fullname[0] == '\0') {
1829                 const char *tmp = getenv("TMPDIR");
1830                 if (tmp && BLI_is_dir(tmp)) {
1831                         BLI_strncpy(fullname, tmp, maxlen);
1832                 }
1833         }
1834 #endif  
1835         
1836         if (fullname[0] == '\0') {
1837                 BLI_strncpy(fullname, "/tmp/", maxlen);
1838         } else {
1839                 /* add a trailing slash if needed */
1840                 BLI_add_slash(fullname);
1841 #ifdef WIN32
1842                 if(userdir != fullname) {
1843                         BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
1844                 }
1845 #endif
1846         }
1847 }
1848
1849 void BLI_init_temporary_dir(char *userdir)
1850 {
1851         BLI_where_is_temp(btempdir, FILE_MAX, userdir);
1852 }
1853
1854 const char *BLI_temporary_dir(void)
1855 {
1856         return btempdir;
1857 }
1858
1859 void BLI_system_temporary_dir(char *dir)
1860 {
1861         BLI_where_is_temp(dir, FILE_MAX, NULL);
1862 }
1863
1864 #ifdef WITH_ICONV
1865
1866 void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
1867 {
1868         size_t inbytesleft=strlen(original);
1869         size_t outbytesleft=512;
1870         size_t rv=0;
1871         iconv_t cd;
1872         
1873         if (NULL == code) {
1874                 code = locale_charset();
1875         }
1876         cd=iconv_open("UTF-8", code);
1877
1878         if (cd == (iconv_t)(-1)) {
1879                 printf("iconv_open Error");
1880                 *utf_8='\0';
1881                 return ;
1882         }
1883         rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
1884         if (rv == (size_t) -1) {
1885                 printf("iconv Error\n");
1886                 return ;
1887         }
1888         *utf_8 = '\0';
1889         iconv_close(cd);
1890 }
1891 #endif // WITH_ICONV
1892
1893