Orange: more relative path code cleanup. Introduced a new call in the

blenlib to correctly convert a relative path to a clean new path:

BLI_cleanup_dir(const char *relabase, char *name);

Only works for directories now.
This commit is contained in:
2005-12-14 13:21:32 +00:00
parent cb57d03e97
commit f88a0a6efd
7 changed files with 129 additions and 109 deletions

View File

@@ -111,6 +111,13 @@ int BLI_countlist(struct ListBase *listbase);
void BLI_freelinkN(ListBase *listbase, void *vlink);
void BLI_splitdirstring(char *di,char *fi);
/**
* dir can be any input, like from buttons, and this function
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
void BLI_cleanup_dir(const char *relabase, char *dir);
/**
* Blender's path code replacement function.
* Bases @a path strings leading with "//" by the
@@ -123,7 +130,7 @@ void BLI_splitdirstring(char *di,char *fi);
* @a framenum The framenumber to replace the frame code with.
* @retval Returns true if the path was relative (started with "//").
*/
int BLI_convertstringcode(char *path, char *basepath, int framenum);
int BLI_convertstringcode(char *path, const char *basepath, int framenum);
void BLI_makestringcode(const char *relfile, char *file);

View File

@@ -431,6 +431,96 @@ int BLI_strcaseeq(char *a, char *b) {
return (BLI_strcasecmp(a, b)==0);
}
/* ******************** string encoding ***************** */
/* This is quite an ugly function... its purpose is to
* take the dir name, make it absolute, and clean it up, replacing
* excess file entry stuff (like /tmp/../tmp/../)
* note that dir isn't protected for max string names...
*/
void BLI_cleanup_dir(const char *relabase, char *dir)
{
short a;
char *start, *eind;
BLI_convertstringcode(dir, relabase, 0);
#ifdef WIN32
if(dir[0]=='.') { /* happens for example in FILE_MAIN */
dir[0]= '\\';
dir[1]= 0;
return;
}
while ( (start = strstr(dir, "\\..\\")) ) {
eind = start + strlen("\\..\\") - 1;
a = start-dir-1;
while (a>0) {
if (dir[a] == '\\') break;
a--;
}
strcpy(dir+a,eind);
}
while ( (start = strstr(dir,"\\.\\")) ){
eind = start + strlen("\\.\\") - 1;
strcpy(start,eind);
}
while ( (start = strstr(dir,"\\\\" )) ){
eind = start + strlen("\\\\") - 1;
strcpy(start,eind);
}
if((a = strlen(dir))){ /* remove the '\\' at the end */
while(a>0 && dir[a-1] == '\\'){
a--;
dir[a] = 0;
}
}
strcat(dir, "\\");
#else
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
dir[0]= '/';
dir[1]= 0;
return;
}
while ( (start = strstr(dir, "/../")) ) {
eind = start + strlen("/../") - 1;
a = start-dir-1;
while (a>0) {
if (dir[a] == '/') break;
a--;
}
strcpy(dir+a,eind);
}
while ( (start = strstr(dir,"/./")) ){
eind = start + strlen("/./") - 1;
strcpy(start,eind);
}
while ( (start = strstr(dir,"//" )) ){
eind = start + strlen("//") - 1;
strcpy(start,eind);
}
if( (a = strlen(dir)) ){ /* remove all '/' at the end */
while(dir[a-1] == '/'){
a--;
dir[a] = 0;
if (a<=0) break;
}
}
strcat(dir, "/");
#endif
}
void BLI_makestringcode(const char *relfile, char *file)
{
char * p;
@@ -491,7 +581,7 @@ void BLI_makestringcode(const char *relfile, char *file)
}
strcat(res, q+1); /* don't copy the slash at the beginning */
#ifdef WIN32
BLI_char_switch(res+2, '/', '\\');
#endif
@@ -499,7 +589,7 @@ void BLI_makestringcode(const char *relfile, char *file)
}
}
int BLI_convertstringcode(char *path, char *basepath, int framenum)
int BLI_convertstringcode(char *path, const char *basepath, int framenum)
{
int len, wasrelative;
char tmp[FILE_MAXDIR+FILE_MAXFILE];

View File

@@ -469,6 +469,15 @@ void blo_split_main(ListBase *mainlist)
split_libdata(lbarray[i], mainl->next);
}
static void cleanup_path(const char *relabase, char *name)
{
char filename[FILE_MAXFILE];
BLI_splitdirstring(name, filename);
BLI_cleanup_dir(relabase, name);
strcat(name, filename);
}
static Main *blo_find_main(ListBase *mainlist, char *name)
{
Main *m;
@@ -477,24 +486,25 @@ static Main *blo_find_main(ListBase *mainlist, char *name)
char libname1[FILE_MAXDIR+FILE_MAXFILE];
// printf("G.sce %s\n", G.sce);
/* name in stringcode too */
/* everything in absolute paths now */
strcpy(name1, name);
BLI_makestringcode(G.sce, name1);
// printf("original %s\n", name);
// printf("converted %s\n", name1);
cleanup_path(G.sce, name1);
// printf("original in %s\n", name);
// printf("converted in %s\n", name1);
for (m= mainlist->first; m; m= m->next) {
char *libname= (m->curlib)?m->curlib->name:m->name;
// printf("libname %s\n", libname);
strcpy(libname1, libname);
BLI_makestringcode(G.sce, libname1);
cleanup_path(G.sce, libname1);
// printf("libname1 %s\n", libname1, name1);
if (BLI_streq(name1, libname1))
if (BLI_streq(name1, libname1)) {
printf("found library %s\n", libname);
return m;
}
}
m= MEM_callocN(sizeof(Main), "find_main");
@@ -504,7 +514,7 @@ static Main *blo_find_main(ListBase *mainlist, char *name)
strcpy(lib->name, name);
m->curlib= lib;
// printf("added new lib %s\n", name);
printf("added new lib %s\n", name);
return m;
}
@@ -5320,6 +5330,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
if(bheadlib) {
// BHEAD+DATA dependancy
Library *lib= (Library *)(bheadlib+1);
/* we read the lib->name directly from the bhead, potential danger (64 bits?) */
mainvar= blo_find_main(&fd->mainlist, lib->name);
id= is_yet_read(mainvar, bhead);

View File

@@ -42,7 +42,6 @@ struct BWinEvent;
void clear_global_filesel_vars(void);
void filesel_statistics(struct SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen);
void checkdir(char *dir);
void test_flags_file(struct SpaceFile *sfile);
void sort_filelist(struct SpaceFile *sfile);
void read_dir(struct SpaceFile *sfile);

View File

@@ -865,7 +865,7 @@ void drawimaselspace(ScrArea *sa, void *spacedata)
myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375);
if (simasel->fase == 0){
checkdir(simasel->dir);
BLI_cleanup_dir(G.sce, simasel->dir);
clear_ima_dir(simasel);
}

View File

@@ -179,7 +179,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
queredraw = 1;
case 1: /* dir entry */
checkdir(simasel->dir);
BLI_cleanup_dir(G.sce, simasel->dir);
clear_ima_dir(simasel);
queredraw = 1;
break;
@@ -188,7 +188,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
selname= fsmenu_get_entry(simasel->fileselmenuitem-1);
if (selname) {
strcpy(simasel->dir, selname);
checkdir(simasel->dir);
BLI_cleanup_dir(G.sce, simasel->dir);
clear_ima_dir(simasel);
queredraw = 1;
}
@@ -349,7 +349,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
if (G.qual == 0){
imadir_parent(simasel);
checkdir(simasel->dir);
BLI_cleanup_dir(G.sce, simasel->dir);
clear_ima_dir(simasel);
queredraw = 1;
}

View File

@@ -456,93 +456,6 @@ void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *tot
/* *************** HELP FUNCTIONS ******************* */
/* This is a really ugly function... its purpose is to
* take the space file name and clean it up, replacing
* excess file entry stuff (like /tmp/../tmp/../)
*/
void checkdir(char *dir)
{
short a;
char *start, *eind;
char tmp[FILE_MAXDIR+FILE_MAXFILE];
BLI_make_file_string(G.sce, tmp, dir, "");
strcpy(dir, tmp);
#ifdef WIN32
if(dir[0]=='.') { /* happens for example in FILE_MAIN */
dir[0]= '\\';
dir[1]= 0;
return;
}
while ( (start = strstr(dir, "\\..\\")) ) {
eind = start + strlen("\\..\\") - 1;
a = start-dir-1;
while (a>0) {
if (dir[a] == '\\') break;
a--;
}
strcpy(dir+a,eind);
}
while ( (start = strstr(dir,"\\.\\")) ){
eind = start + strlen("\\.\\") - 1;
strcpy(start,eind);
}
while ( (start = strstr(dir,"\\\\" )) ){
eind = start + strlen("\\\\") - 1;
strcpy(start,eind);
}
if((a = strlen(dir))){ /* remove the '\\' at the end */
while(a>0 && dir[a-1] == '\\'){
a--;
dir[a] = 0;
}
}
strcat(dir, "\\");
#else
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
dir[0]= '/';
dir[1]= 0;
return;
}
while ( (start = strstr(dir, "/../")) ) {
eind = start + strlen("/../") - 1;
a = start-dir-1;
while (a>0) {
if (dir[a] == '/') break;
a--;
}
strcpy(dir+a,eind);
}
while ( (start = strstr(dir,"/./")) ){
eind = start + strlen("/./") - 1;
strcpy(start,eind);
}
while ( (start = strstr(dir,"//" )) ){
eind = start + strlen("//") - 1;
strcpy(start,eind);
}
if( (a = strlen(dir)) ){ /* remove all '/' at the end */
while(dir[a-1] == '/'){
a--;
dir[a] = 0;
if (a<=0) break;
}
}
strcat(dir, "/");
#endif
}
/* not called when browsing .blend itself */
void test_flags_file(SpaceFile *sfile)
@@ -1353,7 +1266,7 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *)
}
else { /* FILE_BLENDER */
split_sfile(sfile, name); /* test filelist too */
checkdir(sfile->dir);
BLI_cleanup_dir(G.sce, sfile->dir);
/* free: filelist and libfiledata became incorrect */
if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata);
@@ -1387,7 +1300,7 @@ void activate_imageselect(int type, char *title, char *file, void (*func)(char *
else simasel->mode &= ~IMS_STRINGCODE;
BLI_split_dirfile(name, dir, simasel->file);
checkdir(simasel->dir);
BLI_cleanup_dir(G.sce, simasel->dir);
if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0;
strcpy(simasel->dir, dir);
@@ -1616,7 +1529,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile)
}
else if(event== 2) {
/* reuse the butname variable */
checkdir(sfile->dir);
BLI_cleanup_dir(G.sce, sfile->dir);
BLI_make_file_string(G.sce, butname, sfile->dir, "");
/* strip the trailing slash if its a real dir */
@@ -1642,7 +1555,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile)
if (selected) {
strcpy(sfile->dir, selected);
BLI_make_exist(sfile->dir);
checkdir(sfile->dir);
BLI_cleanup_dir(G.sce, sfile->dir);
freefilelist(sfile);
sfile->ofs= 0;
scrarea_queue_winredraw(curarea);
@@ -1921,7 +1834,7 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(S_ISDIR(sfile->filelist[act].type)) {
strcat(sfile->dir, sfile->filelist[act].relname);
strcat(sfile->dir,"/");
checkdir(sfile->dir);
BLI_cleanup_dir(G.sce, sfile->dir);
freefilelist(sfile);
sfile->ofs= 0;
do_draw= 1;