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; } } }
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 } }
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 }
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; }
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); } }
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 }
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); }