Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/path_util.c')
-rw-r--r--source/blender/blenlib/intern/path_util.c523
1 files changed, 345 insertions, 178 deletions
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index cf773d575e5..2359a858d51 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1,4 +1,4 @@
-/**
+/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -32,6 +32,7 @@
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#include "MEM_guardedalloc.h"
@@ -42,12 +43,19 @@
#include "BLI_string.h"
#include "BLI_storage.h"
#include "BLI_storage_types.h"
+#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_blender.h" // BLENDER_VERSION
#include "GHOST_Path-api.h"
+#if defined WIN32 && !defined _LIBC
+# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */
+#else
+# define _GNU_SOURCE
+# include <fnmatch.h>
+#endif
#ifdef WIN32
#include <io.h>
@@ -63,13 +71,16 @@
#else /* non windows */
-#ifdef __linux__
+#ifdef WITH_BINRELOC
#include "binreloc.h"
#endif
#endif /* WIN32 */
/* local */
+#define UNIQUE_NAME_MAX 128
+
+extern char bprogname[];
static int add_win32_extension(char *name);
static char *blender_version_decimal(void);
@@ -130,10 +141,41 @@ void BLI_stringenc(char *string, const char *head, const char *tail, unsigned sh
sprintf(string, fmtstr, head, pic, tail);
}
+/* Foo.001 -> "Foo", 1
+ * Returns the length of "Foo" */
+int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
+{
+ int a;
+
+ *nr= 0;
+ a= strlen(name);
+ memcpy(left, name, (a + 1) * sizeof(char));
+
+ if(a>1 && name[a-1]==delim) return a;
+
+ while(a--) {
+ if( name[a]==delim ) {
+ left[a]= 0;
+ *nr= atol(name+a+1);
+ /* casting down to an int, can overflow for large numbers */
+ if(*nr < 0)
+ *nr= 0;
+ return a;
+ }
+ if( isdigit(name[a])==0 ) break;
+
+ left[a]= 0;
+ }
+
+ for(a= 0; name[a]; a++)
+ left[a]= name[a];
+
+ return a;
+}
void BLI_newname(char *name, int add)
{
- char head[128], tail[128];
+ char head[UNIQUE_NAME_MAX], tail[UNIQUE_NAME_MAX];
int pic;
unsigned short digits;
@@ -153,13 +195,43 @@ void BLI_newname(char *name, int add)
BLI_stringenc(name, head, tail, digits, pic);
}
+
+
+int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len)
+{
+ if(name == '\0') {
+ BLI_strncpy(name, defname, name_len);
+ }
+
+ if(unique_check(arg, name)) {
+ char tempname[UNIQUE_NAME_MAX];
+ char left[UNIQUE_NAME_MAX];
+ int number;
+ int len= BLI_split_name_num(left, &number, name, delim);
+ do {
+ int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, number);
+ if(newlen >= name_len) {
+ len -= ((newlen + 1) - name_len);
+ if(len < 0) len= number= 0;
+ left[len]= '\0';
+ }
+ } while(number++, unique_check(arg, tempname));
+
+ BLI_strncpy(name, tempname, name_len);
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* little helper macro for BLI_uniquename */
#ifndef GIVE_STRADDR
#define GIVE_STRADDR(data, offset) ( ((char *)data) + offset )
#endif
/* Generic function to set a unique name. It is only designed to be used in situations
- * where the name is part of the struct, and also that the name is at most 128 chars long.
+ * where the name is part of the struct, and also that the name is at most UNIQUE_NAME_MAX chars long.
*
* For places where this is used, see constraint.c for example...
*
@@ -168,65 +240,45 @@ void BLI_newname(char *name, int add)
* defname: the name that should be used by default if none is specified already
* delim: the character which acts as a delimeter between parts of the name
*/
-void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len)
+static int uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
{
Link *link;
- char tempname[128];
- int number = 1, exists = 0;
- char *dot;
-
- /* Make sure length can be handled */
- if ((len < 0) || (len > 128))
- return;
-
- /* See if we are given an empty string */
- if (ELEM(NULL, vlink, defname))
- return;
-
- if (GIVE_STRADDR(vlink, name_offs) == '\0') {
- /* give it default name first */
- BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len);
- }
-
- /* See if we even need to do this */
- if (list == NULL)
- return;
-
+
for (link = list->first; link; link= link->next) {
if (link != vlink) {
- if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) {
- exists = 1;
- break;
+ if (!strcmp(GIVE_STRADDR(link, name_offs), name)) {
+ return 1;
}
}
}
- if (exists == 0)
+
+ return 0;
+}
+
+static int uniquename_unique_check(void *arg, const char *name)
+{
+ struct {ListBase *lb; void *vlink; short name_offs;} *data= arg;
+ return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
+}
+
+void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short name_len)
+{
+ struct {ListBase *lb; void *vlink; short name_offs;} data;
+ data.lb= list;
+ data.vlink= vlink;
+ data.name_offs= name_offs;
+
+ assert((name_len > 1) && (name_len <= UNIQUE_NAME_MAX));
+
+ /* See if we are given an empty string */
+ if (ELEM(NULL, vlink, defname))
return;
- /* Strip off the suffix */
- dot = strrchr(GIVE_STRADDR(vlink, name_offs), delim);
- if (dot)
- *dot=0;
-
- for (number = 1; number <= 999; number++) {
- BLI_snprintf(tempname, sizeof(tempname), "%s%c%03d", GIVE_STRADDR(vlink, name_offs), delim, number);
-
- exists = 0;
- for (link= list->first; link; link= link->next) {
- if (vlink != link) {
- if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) {
- exists = 1;
- break;
- }
- }
- }
- if (exists == 0) {
- BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len);
- return;
- }
- }
+ BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
}
+
+
/* ******************** string encoding ***************** */
/* This is quite an ugly function... its purpose is to
@@ -311,10 +363,17 @@ void BLI_cleanup_file(const char *relabase, char *dir)
dir[0]= '/';
dir[1]= 0;
return;
- }
+ }
+
+ /* support for odd paths: eg /../home/me --> /home/me
+ * this is a valid path in blender but we cant handle this the useual way below
+ * simply strip this prefix then evaluate the path as useual. pythons os.path.normpath() does this */
+ while((strncmp(dir, "/../", 4)==0)) {
+ memmove( dir, dir + 4, strlen(dir + 4) + 1 );
+ }
while ( (start = strstr(dir, "/../")) ) {
- eind = start + strlen("/../") - 1;
+ eind = start + (4 - 1) /* strlen("/../") - 1 */;
a = start-dir-1;
while (a>0) {
if (dir[a] == '/') break;
@@ -328,12 +387,12 @@ void BLI_cleanup_file(const char *relabase, char *dir)
}
while ( (start = strstr(dir,"/./")) ){
- eind = start + strlen("/./") - 1;
+ eind = start + (3 - 1) /* strlen("/./") - 1 */;
memmove( start, eind, strlen(eind)+1 );
}
while ( (start = strstr(dir,"//" )) ){
- eind = start + strlen("//") - 1;
+ eind = start + (2 - 1) /* strlen("//") - 1 */;
memmove( start, eind, strlen(eind)+1 );
}
@@ -360,8 +419,8 @@ void BLI_path_rel(char *file, const char *relfile)
/* also bail out if relative path is not set */
if (relfile[0] == 0) return;
-#ifdef WIN32
- if (strlen(relfile) > 2 && relfile[1] != ':') {
+#ifdef WIN32
+ if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') {
char* ptemp;
/* fix missing volume name in relative base,
can happen with old recent-files.txt files */
@@ -375,7 +434,7 @@ void BLI_path_rel(char *file, const char *relfile)
BLI_strncpy(temp, relfile, FILE_MAXDIR + FILE_MAXFILE);
}
- if (strlen(file) > 2) {
+ if (BLI_strnlen(file, 3) > 2) {
if ( temp[1] == ':' && file[1] == ':' && temp[0] != file[0] )
return;
}
@@ -400,7 +459,7 @@ void BLI_path_rel(char *file, const char *relfile)
char *p= temp;
char *q= file;
- while ((*p == *q)) {
+ while (*p == *q) {
++p; ++q;
/* dont search beyond the end of the string
* in the rare case they match */
@@ -458,13 +517,9 @@ int BLI_has_parent(char *path)
int BLI_parent_dir(char *path)
{
-#ifdef WIN32
- static char *parent_dir="..\\";
-#else
- static char *parent_dir="../";
-#endif
+ static char parent_dir[]= {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
char tmp[FILE_MAXDIR+FILE_MAXFILE+4];
- BLI_strncpy(tmp, path, sizeof(tmp));
+ BLI_strncpy(tmp, path, sizeof(tmp)-4);
BLI_add_slash(tmp);
strcat(tmp, parent_dir);
BLI_cleanup_dir(NULL, tmp);
@@ -534,9 +589,20 @@ int BLI_path_frame(char *path, int frame, int digits)
ensure_digits(path, digits);
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
- char tmp[FILE_MAX], format[64];
+ char tmp[FILE_MAX];
+#if 0 // neat but breaks on non ascii strings.
+ char format[64];
sprintf(format, "%%.%ds%%.%dd%%s", ch_sta, ch_end-ch_sta); /* example result: "%.12s%.5d%s" */
sprintf(tmp, format, path, frame, path+ch_end);
+#else
+ char format[8];
+ char *p;
+ sprintf(format, "%%.%dd", ch_end-ch_sta); /* example result: "%.5d" */
+ memcpy(tmp, path, sizeof(char) * ch_sta);
+ p= tmp + ch_sta;
+ p += sprintf(p, format, frame);
+ memcpy(p, path + ch_end, strlen(path + ch_end));
+#endif
strcpy(path, tmp);
return 1;
}
@@ -552,9 +618,18 @@ int BLI_path_frame_range(char *path, int sta, int end, int digits)
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
char tmp[FILE_MAX], format[64];
+#if 0 // neat but breaks on non ascii strings.
sprintf(format, "%%.%ds%%.%dd_%%.%dd%%s", ch_sta, ch_end-ch_sta, ch_end-ch_sta); /* example result: "%.12s%.5d-%.5d%s" */
sprintf(tmp, format, path, sta, end, path+ch_end);
strcpy(path, tmp);
+#else
+ char *tmp_pt;
+ BLI_snprintf(format, sizeof(format), "%%.%dd-%%.%dd%%s", digits, digits);
+ memcpy(tmp, path, ch_sta * sizeof(char));
+ tmp_pt = &tmp[ch_sta];
+ tmp_pt += BLI_snprintf(tmp_pt, sizeof(tmp)-ch_sta, format, sta, end, &path[ch_end]);
+ memcpy(path, tmp, (int)(tmp_pt - tmp) + 1);
+#endif
return 1;
}
return 0;
@@ -677,8 +752,8 @@ int BLI_path_cwd(char *path)
#endif
if (wasrelative==1) {
- char cwd[FILE_MAXDIR + FILE_MAXFILE];
- BLI_getwdN(cwd); /* incase the full path to the blend isnt used */
+ char cwd[FILE_MAXDIR + FILE_MAXFILE]= "";
+ BLI_getwdN(cwd, sizeof(cwd)); /* incase the full path to the blend isnt used */
if (cwd[0] == '\0') {
printf( "Could not get the current working directory - $PWD for an unknown reason.");
@@ -782,11 +857,11 @@ static char *blender_version_decimal(void)
return version_str;
}
-static int test_path(char *targetpath, char *path_base, char *path_sep, char *folder_name)
+static int test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
{
char tmppath[FILE_MAX];
- if(path_sep) BLI_join_dirfile(tmppath, path_base, path_sep);
+ if(path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep);
else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
BLI_make_file_string("/", targetpath, tmppath, folder_name);
@@ -806,7 +881,7 @@ static int test_path(char *targetpath, char *path_base, char *path_sep, char *fo
}
}
-static int test_env_path(char *path, char *envvar)
+static int test_env_path(char *path, const char *envvar)
{
char *env = envvar?getenv(envvar):NULL;
if (!env) return 0;
@@ -820,54 +895,32 @@ static int test_env_path(char *path, char *envvar)
}
}
-static int get_path_local(char *targetpath, char *folder_name, char *subfolder_name)
+static int get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name)
{
- extern char bprogname[]; /* argv[0] from creator.c */
char bprogdir[FILE_MAX];
char relfolder[FILE_MAX];
- char cwd[FILE_MAX];
- char *s;
- int i;
#ifdef PATH_DEBUG2
printf("get_path_local...\n");
#endif
if (subfolder_name) {
- BLI_join_dirfile(relfolder, folder_name, subfolder_name);
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
} else {
- BLI_strncpy(relfolder, folder_name, FILE_MAX);
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
}
/* use argv[0] (bprogname) to get the path to the executable */
- s = BLI_last_slash(bprogname);
- i = s - bprogname + 1;
- BLI_strncpy(bprogdir, bprogname, i);
-
- /* try EXECUTABLE_DIR/folder_name */
- if(test_path(targetpath, bprogdir, "", relfolder))
- return 1;
-
- /* try CWD/release/folder_name */
- if(test_path(targetpath, BLI_getwdN(cwd), "release", relfolder))
- return 1;
+ BLI_split_dirfile(bprogname, bprogdir, NULL);
- /* try EXECUTABLE_DIR/release/folder_name */
- if(test_path(targetpath, bprogdir, "release", relfolder))
- return 1;
-
- /* try EXECUTABLE_DIR/2.5/folder_name - new default directory for local blender installed files */
+ /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
if(test_path(targetpath, bprogdir, blender_version_decimal(), relfolder))
return 1;
- /* try ./.blender/folder_name -- DEPRECATED, need to update build systems */
- if(test_path(targetpath, bprogdir, ".blender", relfolder))
- return 1;
-
return 0;
}
-static int get_path_user(char *targetpath, char *folder_name, char *subfolder_name, char *envvar)
+static int get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar)
{
char user_path[FILE_MAX];
const char *user_base_path;
@@ -904,11 +957,41 @@ static int get_path_user(char *targetpath, char *folder_name, char *subfolder_na
}
}
-static int get_path_system(char *targetpath, char *folder_name, char *subfolder_name, char *envvar)
+static int get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar)
{
char system_path[FILE_MAX];
const char *system_base_path;
+
+ /* first allow developer only overrides to the system path
+ * these are only used when running blender from source */
+ char cwd[FILE_MAX];
+ char relfolder[FILE_MAX];
+ char bprogdir[FILE_MAX];
+
+ /* use argv[0] (bprogname) to get the path to the executable */
+ BLI_split_dirfile(bprogname, bprogdir, NULL);
+
+ if (subfolder_name) {
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
+ } else {
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
+ }
+
+ /* try CWD/release/folder_name */
+ if(BLI_getwdN(cwd, sizeof(cwd))) {
+ if(test_path(targetpath, cwd, "release", relfolder)) {
+ return 1;
+ }
+ }
+
+ /* try EXECUTABLE_DIR/release/folder_name */
+ if(test_path(targetpath, bprogdir, "release", relfolder))
+ return 1;
+ /* end developer overrides */
+
+
+
system_path[0] = '\0';
if (test_env_path(system_path, envvar)) {
@@ -943,7 +1026,7 @@ static int get_path_system(char *targetpath, char *folder_name, char *subfolder_
/* get a folder out of the 'folder_id' presets for paths */
/* returns the path if found, NULL string if not */
-char *BLI_get_folder(int folder_id, char *subfolder)
+char *BLI_get_folder(int folder_id, const char *subfolder)
{
static char path[FILE_MAX] = "";
@@ -1015,7 +1098,7 @@ char *BLI_get_folder(int folder_id, char *subfolder)
return path;
}
-static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
+char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
{
static char path[FILE_MAX] = "";
@@ -1029,6 +1112,9 @@ static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
case BLENDER_USER_AUTOSAVE:
get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE");
break;
+ case BLENDER_USER_SCRIPTS:
+ get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS");
+ break;
}
if ('\0' == path[0]) {
return NULL;
@@ -1036,12 +1122,12 @@ static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
return path;
}
-char *BLI_get_folder_create(int folder_id, char *subfolder)
+char *BLI_get_folder_create(int folder_id, const char *subfolder)
{
char *path;
/* only for user folders */
- if (!ELEM3(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_AUTOSAVE))
+ if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
return NULL;
path = BLI_get_folder(folder_id, subfolder);
@@ -1099,8 +1185,9 @@ void BLI_setenv_if_new(const char *env, const char* val)
void BLI_clean(char *path)
{
if(path==0) return;
+
#ifdef WIN32
- if(path && strlen(path)>2) {
+ if(path && BLI_strnlen(path, 3) > 2) {
BLI_char_switch(path+2, '/', '\\');
}
#else
@@ -1120,45 +1207,31 @@ void BLI_char_switch(char *string, char from, char to)
void BLI_make_exist(char *dir) {
int a;
- #ifdef WIN32
- BLI_char_switch(dir, '/', '\\');
- #else
- BLI_char_switch(dir, '\\', '/');
- #endif
-
+ BLI_char_switch(dir, ALTSEP, SEP);
+
a = strlen(dir);
-
-#ifdef WIN32
+
while(BLI_is_dir(dir) == 0){
a --;
- while(dir[a] != '\\'){
+ while(dir[a] != SEP){
a--;
if (a <= 0) break;
}
- if (a >= 0) dir[a+1] = 0;
+ if (a >= 0) {
+ dir[a+1] = '\0';
+ }
else {
- /* defaulting to drive (usually 'C:') of Windows installation */
+#ifdef WIN32
get_default_root(dir);
- break;
- }
- }
#else
- while(BLI_is_dir(dir) == 0){
- a --;
- while(dir[a] != '/'){
- a--;
- if (a <= 0) break;
- }
- if (a >= 0) dir[a+1] = 0;
- else {
strcpy(dir,"/");
+#endif
break;
}
}
-#endif
}
-void BLI_make_existing_file(char *name)
+void BLI_make_existing_file(const char *name)
{
char di[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
@@ -1196,15 +1269,14 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
/* Get the file name, chop everything past the last slash (ie. the filename) */
strcpy(string, relabase);
- lslash= (strrchr(string, '/')>strrchr(string, '\\'))?strrchr(string, '/'):strrchr(string, '\\');
-
+ lslash= BLI_last_slash(string);
if(lslash) *(lslash+1)= 0;
dir+=2; /* Skip over the relative reference */
}
#ifdef WIN32
else {
- if (strlen(dir) >= 2 && dir[1] == ':' ) {
+ if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':' ) {
BLI_strncpy(string, dir, 3);
dir += 2;
}
@@ -1250,10 +1322,10 @@ int BLI_testextensie(const char *str, const char *ext)
{
short a, b;
int retval;
-
+
a= strlen(str);
b= strlen(ext);
-
+
if(a==0 || b==0 || b>=a) {
retval = 0;
} else if (BLI_strcasecmp(ext, str + a - b)) {
@@ -1261,7 +1333,7 @@ int BLI_testextensie(const char *str, const char *ext)
} else {
retval = 1;
}
-
+
return (retval);
}
@@ -1278,9 +1350,39 @@ int BLI_testextensie_array(const char *str, const char **ext_array)
return 0;
}
+/* semicolon separated wildcards, eg:
+ * '*.zip;*.py;*.exe' */
+int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
+{
+ const char *ext_step= ext_fnmatch;
+ char pattern[16];
+
+ while(ext_step[0]) {
+ char *ext_next;
+ int len_ext;
+
+ if((ext_next=strchr(ext_step, ';'))) {
+ len_ext= (int)(ext_next - ext_step) + 1;
+ }
+ else {
+ len_ext= sizeof(pattern);
+ }
+
+ BLI_strncpy(pattern, ext_step, len_ext);
+
+ if(fnmatch(pattern, str, FNM_CASEFOLD)==0) {
+ return 1;
+ }
+ ext_step += len_ext;
+ }
+
+ return 0;
+}
+
+
int BLI_replace_extension(char *path, int maxlen, const char *ext)
{
- int a;
+ unsigned int a;
for(a=strlen(path)-1; a>=0; a--)
if(path[a] == '.' || path[a] == '/' || path[a] == '\\')
@@ -1321,12 +1423,12 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
}
/* simple appending of filename to dir, does not check for valid path! */
-void BLI_join_dirfile(char *string, const char *dir, const char *file)
+void BLI_join_dirfile(char *string, const int maxlen, const char *dir, const char *file)
{
int sl_dir;
if(string != dir) /* compare pointers */
- BLI_strncpy(string, dir, FILE_MAX);
+ BLI_strncpy(string, dir, maxlen);
if (!file)
return;
@@ -1334,7 +1436,7 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
sl_dir= BLI_add_slash(string);
if (sl_dir <FILE_MAX) {
- BLI_strncpy(string + sl_dir, file, FILE_MAX-sl_dir);
+ BLI_strncpy(string + sl_dir, file, maxlen - sl_dir);
}
}
@@ -1409,21 +1511,21 @@ int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char
/* if image is _in_ current .blend file directory */
if (!strcmp(dir, blend_dir)) {
- BLI_join_dirfile(dest_path, dest_dir, base);
+ BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
/* "below" */
else {
/* rel = image_path_dir - blend_dir */
BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
- BLI_join_dirfile(dest_path, dest_dir, rel_dir);
- BLI_join_dirfile(dest_path, dest_path, base);
+ BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
+ BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
}
}
/* image is out of current directory */
else {
- BLI_join_dirfile(dest_path, dest_dir, base);
+ BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
if (abs)
@@ -1443,6 +1545,67 @@ int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char
return 1;
}
+char *BLI_first_slash(char *string) {
+ char *ffslash, *fbslash;
+
+ ffslash= strchr(string, '/');
+ fbslash= strchr(string, '\\');
+
+ if (!ffslash) return fbslash;
+ else if (!fbslash) return ffslash;
+
+ if ((intptr_t)ffslash < (intptr_t)fbslash) return ffslash;
+ else return fbslash;
+}
+
+char *BLI_last_slash(const char *string) {
+ char *lfslash, *lbslash;
+
+ lfslash= strrchr(string, '/');
+ lbslash= strrchr(string, '\\');
+
+ if (!lfslash) return lbslash;
+ else if (!lbslash) return lfslash;
+
+ if ((intptr_t)lfslash < (intptr_t)lbslash) return lbslash;
+ else return lfslash;
+}
+
+/* adds a slash if there isnt one there already */
+int BLI_add_slash(char *string) {
+ int len = strlen(string);
+#ifdef WIN32
+ if (len==0 || string[len-1]!='\\') {
+ string[len] = '\\';
+ string[len+1] = '\0';
+ return len+1;
+ }
+#else
+ if (len==0 || string[len-1]!='/') {
+ string[len] = '/';
+ string[len+1] = '\0';
+ return len+1;
+ }
+#endif
+ return len;
+}
+
+/* removes a slash if there is one */
+void BLI_del_slash(char *string) {
+ int len = strlen(string);
+ while (len) {
+#ifdef WIN32
+ if (string[len-1]=='\\') {
+#else
+ if (string[len-1]=='/') {
+#endif
+ string[len-1] = '\0';
+ len--;
+ } else {
+ break;
+ }
+ }
+}
static int add_win32_extension(char *name)
{
@@ -1485,54 +1648,54 @@ static int add_win32_extension(char *name)
return (retval);
}
-void BLI_where_am_i(char *fullname, const char *name)
+/* filename must be FILE_MAX length minimum */
+void BLI_where_am_i(char *fullname, const int maxlen, const char *name)
{
char filename[FILE_MAXDIR+FILE_MAXFILE];
char *path = NULL, *temp;
-
+
#ifdef _WIN32
- char *separator = ";";
- char slash = '\\';
+ const char *separator = ";";
#else
- char *separator = ":";
- char slash = '/';
+ const char *separator = ":";
#endif
-#ifdef __linux__
+#ifdef WITH_BINRELOC
/* linux uses binreloc since argv[0] is not relyable, call br_init( NULL ) first */
path = br_find_exe( NULL );
if (path) {
- BLI_strncpy(fullname, path, FILE_MAXDIR+FILE_MAXFILE);
+ BLI_strncpy(fullname, path, maxlen);
free(path);
return;
}
#endif
#ifdef _WIN32
- if(GetModuleFileName(0, fullname, FILE_MAXDIR+FILE_MAXFILE)) {
- GetShortPathName(fullname, fullname, FILE_MAXDIR+FILE_MAXFILE);
+ if(GetModuleFileName(0, fullname, maxlen)) {
+ GetShortPathName(fullname, fullname, maxlen);
return;
}
#endif
/* unix and non linux */
- if (name && fullname && strlen(name)) {
- strcpy(fullname, name);
+ if (name && name[0]) {
+ BLI_strncpy(fullname, name, maxlen);
if (name[0] == '.') {
- // relative path, prepend cwd
- BLI_getwdN(fullname);
-
+ char wdir[FILE_MAX]= "";
+ BLI_getwdN(wdir, sizeof(wdir)); /* backup cwd to restore after */
+
// not needed but avoids annoying /./ in name
- if(name && name[0]=='.' && name[1]==slash)
- BLI_join_dirfile(fullname, fullname, name+2);
+ if(name[1]==SEP)
+ BLI_join_dirfile(fullname, maxlen, wdir, name+2);
else
- BLI_join_dirfile(fullname, fullname, name);
-
- add_win32_extension(fullname);
- } else if (BLI_last_slash(name)) {
+ BLI_join_dirfile(fullname, maxlen, wdir, name);
+
+ add_win32_extension(fullname); /* XXX, doesnt respect length */
+ }
+ else if (BLI_last_slash(name)) {
// full path
- strcpy(fullname, name);
+ BLI_strncpy(fullname, name, maxlen);
add_win32_extension(fullname);
} else {
// search for binary in $PATH
@@ -1547,15 +1710,15 @@ void BLI_where_am_i(char *fullname, const char *name)
} else {
strncpy(filename, path, sizeof(filename));
}
- BLI_join_dirfile(fullname, fullname, name);
+ BLI_join_dirfile(fullname, maxlen, fullname, name);
if (add_win32_extension(filename)) {
- strcpy(fullname, filename);
+ BLI_strncpy(fullname, filename, maxlen);
break;
}
} while (temp);
}
}
-#ifndef NDEBUG
+#if defined(DEBUG)
if (strcmp(name, fullname)) {
printf("guessing '%s' == '%s'\n", name, fullname);
}
@@ -1567,20 +1730,20 @@ void BLI_where_am_i(char *fullname, const char *name)
// spaces and double-quotes. There's another solution to this
// with spawnv(P_WAIT, bprogname, argv) instead of system() but
// that's even uglier
- GetShortPathName(fullname, fullname, FILE_MAXDIR+FILE_MAXFILE);
-#ifndef NDEBUG
+ GetShortPathName(fullname, fullname, maxlen);
+#if defined(DEBUG)
printf("Shortname = '%s'\n", fullname);
#endif
#endif
}
}
-void BLI_where_is_temp(char *fullname, int usertemp)
+void BLI_where_is_temp(char *fullname, const int maxlen, int usertemp)
{
fullname[0] = '\0';
if (usertemp && BLI_is_dir(U.tempdir)) {
- strcpy(fullname, U.tempdir);
+ BLI_strncpy(fullname, U.tempdir, maxlen);
}
@@ -1588,7 +1751,7 @@ void BLI_where_is_temp(char *fullname, int usertemp)
if (fullname[0] == '\0') {
char *tmp = getenv("TEMP"); /* Windows */
if (tmp && BLI_is_dir(tmp)) {
- strcpy(fullname, tmp);
+ BLI_strncpy(fullname, tmp, maxlen);
}
}
#else
@@ -1596,28 +1759,32 @@ void BLI_where_is_temp(char *fullname, int usertemp)
if (fullname[0] == '\0') {
char *tmp = getenv("TMP");
if (tmp && BLI_is_dir(tmp)) {
- strcpy(fullname, tmp);
+ BLI_strncpy(fullname, tmp, maxlen);
}
}
if (fullname[0] == '\0') {
char *tmp = getenv("TMPDIR");
if (tmp && BLI_is_dir(tmp)) {
- strcpy(fullname, tmp);
+ BLI_strncpy(fullname, tmp, maxlen);
}
}
#endif
if (fullname[0] == '\0') {
- strcpy(fullname, "/tmp/");
+ BLI_strncpy(fullname, "/tmp/", maxlen);
} else {
/* add a trailing slash if needed */
BLI_add_slash(fullname);
+#ifdef WIN32
+ if(U.tempdir != fullname) {
+ BLI_strncpy(U.tempdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
+ }
+#endif
}
}
char *get_install_dir(void) {
- extern char bprogname[];
char *tmpname = BLI_strdup(bprogname);
char *cut;