예제 #1
0
void BLI_make_exist(char *dir)
{
	int a;

	BLI_char_switch(dir, ALTSEP, SEP);

	a = strlen(dir);

	while (BLI_is_dir(dir) == 0) {
		a--;
		while (dir[a] != SEP) {
			a--;
			if (a <= 0) break;
		}
		if (a >= 0) {
			dir[a + 1] = '\0';
		}
		else {
#ifdef WIN32
			get_default_root(dir);
#else
			strcpy(dir, "/");
#endif
			break;
		}
	}
}
예제 #2
0
static void file_expand_directory(bContext *C)
{
	SpaceFile *sfile= CTX_wm_space_file(C);
	
	if(sfile->params) {
		if ( sfile->params->dir[0] == '~' ) {
			char tmpstr[sizeof(sfile->params->dir)-1];
			BLI_strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr));
			BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr);
		}

#ifdef WIN32
		if (sfile->params->dir[0] == '\0') {
			get_default_root(sfile->params->dir);
		}
		/* change "C:" --> "C:\", [#28102] */
		else if (   (isalpha(sfile->params->dir[0]) &&
		            (sfile->params->dir[1] == ':')) &&
		            (sfile->params->dir[2] == '\0')

		) {
			sfile->params->dir[2]= '\\';
			sfile->params->dir[3]= '\0';
		}
#endif
	}
}
예제 #3
0
static void file_expand_directory(bContext *C)
{
	SpaceFile *sfile = CTX_wm_space_file(C);
	
	if (sfile->params) {
		/* TODO, what about // when relbase isn't valid? */
		if (G.relbase_valid && BLI_path_is_rel(sfile->params->dir)) {
			BLI_path_abs(sfile->params->dir, G.main->name);
		}
		else if (sfile->params->dir[0] == '~') {
			char tmpstr[sizeof(sfile->params->dir) - 1];
			BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr));
			BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr);
		}

		else if (sfile->params->dir[0] == '\0')
#ifndef WIN32
		{
			sfile->params->dir[0] = '/';
			sfile->params->dir[1] = '\0';
		}
#else
		{
			get_default_root(sfile->params->dir);
		}
		/* change "C:" --> "C:\", [#28102] */
		else if ((isalpha(sfile->params->dir[0]) &&
		          (sfile->params->dir[1] == ':')) &&
		         (sfile->params->dir[2] == '\0'))
		{
			sfile->params->dir[2] = '\\';
			sfile->params->dir[3] = '\0';
		}
#endif
	}
예제 #4
0
int BLI_path_abs(char *path, const char *basepath)
{
	int wasrelative = BLI_path_is_rel(path);
	char tmp[FILE_MAX];
	char base[FILE_MAX];
#ifdef WIN32
	char vol[3] = {'\0', '\0', '\0'};

	BLI_strncpy(vol, path, 3);
	/* we are checking here if we have an absolute path that is not in the current
	 * blend file as a lib main - we are basically checking for the case that a 
	 * UNIX root '/' is passed.
	 */
	if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) {
		char *p = path;
		get_default_root(tmp);
		// get rid of the slashes at the beginning of the path
		while (*p == '\\' || *p == '/') {
			p++;
		}
		strcat(tmp, p);
	}
	else {
		BLI_strncpy(tmp, path, FILE_MAX);
	}
#else
	BLI_strncpy(tmp, path, sizeof(tmp));
	
	/* Check for loading a windows path on a posix system
	 * in this case, there is no use in trying C:/ since it 
	 * will never exist on a unix os.
	 * 
	 * Add a / prefix and lowercase the driveletter, remove the :
	 * C:\foo.JPG -> /c/foo.JPG */
	
	if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/') ) {
		tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */
		tmp[0] = '/'; 
		/* '\' the slash will be converted later */
	}
	
#endif

	BLI_strncpy(base, basepath, sizeof(base));

	/* file component is ignored, so don't bother with the trailing slash */
	BLI_cleanup_path(NULL, base);
	
	/* push slashes into unix mode - strings entering this part are
	 * potentially messed up: having both back- and forward slashes.
	 * Here we push into one conform direction, and at the end we
	 * push them into the system specific dir. This ensures uniformity
	 * of paths and solving some problems (and prevent potential future
	 * ones) -jesterKing. */
	BLI_char_switch(tmp, '\\', '/');
	BLI_char_switch(base, '\\', '/');

	/* Paths starting with // will get the blend file as their base,
	 * this isn't standard in any os but is used in blender all over the place */
	if (wasrelative) {
		char *lslash = BLI_last_slash(base);
		if (lslash) {
			int baselen = (int) (lslash - base) + 1;
			/* use path for temp storage here, we copy back over it right away */
			BLI_strncpy(path, tmp + 2, FILE_MAX);
			
			memcpy(tmp, base, baselen);
			BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen);
			BLI_strncpy(path, tmp, FILE_MAX);
		}
		else {
			BLI_strncpy(path, tmp + 2, FILE_MAX);
		}
	}
	else {
		BLI_strncpy(path, tmp, FILE_MAX);
	}

	BLI_cleanup_path(NULL, path);

#ifdef WIN32
	/* skip first two chars, which in case of
	 * absolute path will be drive:/blabla and
	 * in case of relpath //blabla/. So relpath
	 * // will be retained, rest will be nice and
	 * shiny win32 backward slashes :) -jesterKing
	 */
	BLI_char_switch(path + 2, '/', '\\');
#endif
	
	return wasrelative;
}
예제 #5
0
void BLI_path_rel(char *file, const char *relfile)
{
	char *lslash;
	char temp[FILE_MAX];
	char res[FILE_MAX];
	
	/* if file is already relative, bail out */
	if (BLI_path_is_rel(file)) {
		return;
	}
	
	/* also bail out if relative path is not set */
	if (relfile[0] == '\0') {
		return;
	}

#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 */
		get_default_root(temp);
		ptemp = &temp[2];
		if (relfile[0] != '\\' && relfile[0] != '/') {
			ptemp++;
		}
		BLI_strncpy(ptemp, relfile, FILE_MAX - 3);
	}
	else {
		BLI_strncpy(temp, relfile, FILE_MAX);
	}

	if (BLI_strnlen(file, 3) > 2) {
		if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0])
			return;
	}
#else
	BLI_strncpy(temp, relfile, FILE_MAX);
#endif

	BLI_char_switch(temp, '\\', '/');
	BLI_char_switch(file, '\\', '/');
	
	/* remove /./ which confuse the following slash counting... */
	BLI_cleanup_path(NULL, file);
	BLI_cleanup_path(NULL, temp);
	
	/* the last slash in the file indicates where the path part ends */
	lslash = BLI_last_slash(temp);

	if (lslash) {
		/* find the prefix of the filename that is equal for both filenames.
		 * This is replaced by the two slashes at the beginning */
		char *p = temp;
		char *q = file;

#ifdef WIN32
		while (tolower(*p) == tolower(*q))
#else
		while (*p == *q)
#endif
		{
			p++;
			q++;

			/* don't search beyond the end of the string
			 * in the rare case they match */
			if ((*p == '\0') || (*q == '\0')) {
				break;
			}
		}

		/* we might have passed the slash when the beginning of a dir matches 
		 * so we rewind. Only check on the actual filename
		 */
		if (*q != '/') {
			while ( (q >= file) && (*q != '/') ) { --q; --p; }
		}
		else if (*p != '/') {
			while ( (p >= temp) && (*p != '/') ) { --p; --q; }
		}
		
		strcpy(res, "//");

		/* p now points to the slash that is at the beginning of the part
		 * where the path is different from the relative path. 
		 * We count the number of directories we need to go up in the
		 * hierarchy to arrive at the common 'prefix' of the path
		 */
		while (p && p < lslash) {
			if (*p == '/') 
				strcat(res, "../");
			p++;
		}

		strcat(res, q + 1); /* don't copy the slash at the beginning */
		
#ifdef  WIN32
		BLI_char_switch(res + 2, '/', '\\');
#endif
		strcpy(file, res);
	}
}
예제 #6
0
void BLI_cleanup_path(const char *relabase, char *dir)
{
	ptrdiff_t a;
	char *start, *eind;
	if (relabase) {
		BLI_path_abs(dir, relabase);
	}
	else {
		if (dir[0] == '/' && dir[1] == '/') {
			if (dir[2] == '\0') {
				return; /* path is "//" - cant clean it */
			}
			dir = dir + 2; /* skip the first // */
		}
	}
	
	/* Note
	 *   memmove(start, eind, strlen(eind) + 1);
	 * is the same as
	 *   strcpy( start, eind ); 
	 * except strcpy should not be used because there is overlap,
	 * so use memmove's slightly more obscure syntax - Campbell
	 */
	
#ifdef WIN32
	
	/* Note, this should really be moved to the file selector,
	 * since this function is used in many areas */
	if (strcmp(dir, ".") == 0) {  /* happens for example in FILE_MAIN */
		get_default_root(dir);
		return;
	}

	while ( (start = strstr(dir, "\\..\\")) ) {
		eind = start + strlen("\\..\\") - 1;
		a = start - dir - 1;
		while (a > 0) {
			if (dir[a] == '\\') break;
			a--;
		}
		if (a < 0) {
			break;
		}
		else {
			memmove(dir + a, eind, strlen(eind) + 1);
		}
	}

	while ( (start = strstr(dir, "\\.\\")) ) {
		eind = start + strlen("\\.\\") - 1;
		memmove(start, eind, strlen(eind) + 1);
	}

	while ( (start = strstr(dir, "\\\\")) ) {
		eind = start + strlen("\\\\") - 1;
		memmove(start, eind, strlen(eind) + 1);
	}
#else
	if (dir[0] == '.') {  /* happens, for example in FILE_MAIN */
		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 usual way below
	 * simply strip this prefix then evaluate the path as usual. 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 + (4 - 1) /* strlen("/../") - 1 */;
		a = start - dir - 1;
		while (a > 0) {
			if (dir[a] == '/') break;
			a--;
		}
		if (a < 0) {
			break;
		}
		else {
			memmove(dir + a, eind, strlen(eind) + 1);
		}
	}

	while ( (start = strstr(dir, "/./")) ) {
		eind = start + (3 - 1) /* strlen("/./") - 1 */;
		memmove(start, eind, strlen(eind) + 1);
	}

	while ( (start = strstr(dir, "//")) ) {
		eind = start + (2 - 1) /* strlen("//") - 1 */;
		memmove(start, eind, strlen(eind) + 1);
	}
#endif
}
예제 #7
0
void BLI_make_file_string(const char *relabase, char *string,  const char *dir, const char *file)
{
	int sl;

	if (string) {
		/* ensure this is always set even if dir/file are NULL */
		string[0] = '\0';

		if (ELEM(NULL, dir, file)) {
			return; /* We don't want any NULLs */
		}
	}
	else {
		return; /* string is NULL, probably shouldnt happen but return anyway */
	}


	/* we first push all slashes into unix mode, just to make sure we don't get
	 * any mess with slashes later on. -jesterKing */
	/* constant strings can be passed for those parameters - don't change them - elubie */
#if 0
	BLI_char_switch(relabase, '\\', '/');
	BLI_char_switch(dir, '\\', '/');
	BLI_char_switch(file, '\\', '/');
#endif

	/* Resolve relative references */
	if (relabase && dir[0] == '/' && dir[1] == '/') {
		char *lslash;
		
		/* Get the file name, chop everything past the last slash (ie. the filename) */
		strcpy(string, relabase);
		
		lslash = BLI_last_slash(string);
		if (lslash) *(lslash + 1) = 0;

		dir += 2; /* Skip over the relative reference */
	}
#ifdef WIN32
	else {
		if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':') {
			BLI_strncpy(string, dir, 3);
			dir += 2;
		}
		else { /* no drive specified */
			   /* first option: get the drive from the relabase if it has one */
			if (relabase && strlen(relabase) >= 2 && relabase[1] == ':') {
				BLI_strncpy(string, relabase, 3);
				string[2] = '\\';
				string[3] = '\0';
			}
			else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
				get_default_root(string);
			}
			
			/* ignore leading slashes */
			while (*dir == '/' || *dir == '\\') dir++;
		}
	}
#endif

	strcat(string, dir);

	/* Make sure string ends in one (and only one) slash */
	/* first trim all slashes from the end of the string */
	sl = strlen(string);
	while (sl > 0 && (string[sl - 1] == '/' || string[sl - 1] == '\\') ) {
		string[sl - 1] = '\0';
		sl--;
	}
	/* since we've now removed all slashes, put back one slash at the end. */
	strcat(string, "/");
	
	while (*file && (*file == '/' || *file == '\\')) /* Trim slashes from the front of file */
		file++;
		
	strcat(string, file);
	
	/* Push all slashes to the system preferred direction */
	BLI_clean(string);
}