Relative Path !

Share your advanced PureBasic knowledge/code with the community.
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Relative Path !

Post by thyphoon »

Hello !

it'is my procedure to tranform an absolute path in relative path. (i hope you understand what i say....Excuse me for my poooor English)

Code: Select all


Procedure.s RelativePath(FromPath.s,Path.s)
  Protected l.w,c.w,NewPath.s
  Newpath.s=""
  c=0
  For l=Len(FromPath) To 1 Step -1 ; We stat at the end of the string
  
    If Mid(FromPath,l,1)="\" ; I count all new folder
       c+1
    
       If FindString(Path,Mid(FromPath,1,l),1) ; If we have the same path we break the loop
         Break
       EndIf 
  
    EndIf
  
  Next l
  
  For z=1 To c-1
    Newpath+"..\"
  Next
  Newpath+Right(Path,Len(Path)-l)
  ProcedureReturn NewPath
EndProcedure 
 
 File$=OpenFileRequester("Choose a File", FichierParDefaut$, Filtre$, Filtre)
While File$
       Debug "Absolute Path:"+File$
       Debug "Relative Path:"+RelativePath(GetCurrentDirectory(),File$)
File$ = NextSelectedFileName()
Wend
User avatar
bingo
Enthusiast
Enthusiast
Posts: 210
Joined: Fri Apr 02, 2004 12:21 pm
Location: germany/thueringen
Contact:

Post by bingo »

the same with win32 api ...

Code: Select all

Procedure.s RelativePath(FromPath.s,Path.s) 

NewPath.s = Space(#MAX_PATH)

PathRelativePathTo_(@NewPath,FromPath,0,Path,#FILE_ATTRIBUTE_DIRECTORY)

  ProcedureReturn NewPath 
EndProcedure 
  
 File$=OpenFileRequester("Choose a File", FichierParDefaut$, Filtre$, Filtre) 
While File$ 
       Debug "Absolute Path:"+File$ 
       Debug "Relative Path:"+RelativePath(GetCurrentDirectory(),File$) 
File$ = NextSelectedFileName() 
Wend
:wink:
["1:0>1"]
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Problem: What do you do, if the EXE and the file are on different drives?

typhoons code gives an acceptable path, but typhoons path is not beautiful:
Absolute Path:D:\and.ico
Relative Path:..\..\D:\and.ico
bingo's code doesn't procude anything:
Absolute Path:D:\and.ico
Relative Path:
Another problem with bingo's code: It adds a \backslash\ in front of the relative path. This might be strange when you connect it with string containing a backslash-terminated path:
Absolute Path:D:\and.ico
Relative Path:.\and.ico
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Post by thyphoon »

AND51 wrote:Problem: What do you do, if the EXE and the file are on different drives?
very good question ! I think juste add this

Code: Select all

if mid(Path,1,2)<>mid(FromPath,1,2)
 ProcedureReturn Path
Endif 
What do you think about this

Code: Select all

Procedure.s RelativePath(FromPath.s,Path.s)
  Protected l.w,c.w,NewPath.s
  Newpath.s=""
  c=0
;   Debug Path
;   Debug FromPath
;   Debug  Mid(Path,1,1)
;   Debug Mid(FromPath,1,1)
  If Mid(Path,1,1)<>Mid(FromPath,1,1)
    ProcedureReturn Path
  EndIf
  For l=Len(FromPath) To 1 Step -1 ; We stat at the end of the string
 
    If Mid(FromPath,l,1)="" ; I count all new folder
       c+1
   
       If FindString(Path,Mid(FromPath,1,l),1) ; If we have the same path we break the loop
         Break
       EndIf
 
    EndIf
 
  Next l
 
  For z=1 To c-1
    Newpath+".."
  Next
  Newpath+Right(Path,Len(Path)-l)
  ProcedureReturn NewPath
EndProcedure
 
 File$=OpenFileRequester("Choose a File", FichierParDefaut$, Filtre$, Filtre)
While File$
       Debug "Absolute Path:"+File$
       Debug "Relative Path:"+RelativePath(GetCurrentDirectory(),File$)
File$ = NextSelectedFileName()
Wend
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

> very good question !
Thanks. The simple solution is to make an absolute path from the other drive.

So if your EXE is on C:, your picture is on D:, you must return the absolute path from D:\, because you cannot build any other relative path beginning with C:\ !!
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Post by thyphoon »

AND51 wrote:> very good question !
Thanks. The simple solution is to make an absolute path from the other drive.

So if your EXE is on C:, your picture is on D:, you must return the absolute path from D:\, because you cannot build any other relative path beginning with C:\ !!
yes it' normaly what i do on my last code ! Thanks for this bug ;)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

No prob! :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Oh, I see something very bad:
if mid(Path,1,2)<>mid(FromPath,1,2)
ProcedureReturn Path
Endif
Why not

Code: Select all

If Left(Path, 1) <> Left(FromPath), 1)
     ProcedureReturn Path
EndIF
Moreover, there is anoter bug: you do work case-sensitive, but what, if I give you a lcase(path) ?? :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Post by thyphoon »

AND51 wrote:Oh, I see something very bad:
if mid(Path,1,2)<>mid(FromPath,1,2)
ProcedureReturn Path
Endif
Why not

Code: Select all

If Left(Path, 1) <> Left(FromPath), 1)
     ProcedureReturn Path
EndIF
Moreover, there is anoter bug: you do work case-sensitive, but what, if I give you a lcase(path) ?? :wink:
lolllllllll yes you say true !! your code is better lolllllllll
It's end of week i am tired :wink:
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Even more better + faster: Use Peeks() instead of Left() :wink:

> It's end of week i am tired
Hey, stay in this forum, pls! Im now working on MY relative path procedure :wink:

Let's turn this task into a competition !! :D
PB 4.30

Code: Select all

onErrorGoto(?Fred)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Well, SetCurrentDirectory() should be enough... If you call it with an absolute Path, all future relative path will work relatively to the given absolute path from SetCurrentDirectory()...

Or am I wrong?
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Post by thyphoon »

AND51 wrote:Even more better + faster: Use Peeks() instead of Left() :wink:

> It's end of week i am tired
Hey, stay in this forum, pls! Im now working on MY relative path procedure :wink:

Let's turn this task into a competition !! :D
I think use pointer is faster than Peeks()
AND51 wrote:Well, SetCurrentDirectory() should be enough... If you call it with an absolute Path, all future relative path will work relatively to the given absolute path from SetCurrentDirectory()...

Or am I wrong?
I don't know it's a good question ! test it ! For me it time to go to bed :P
Have a good night :D
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

I've not tested this code, but it should work and I explain it:

Code: Select all

Debug GetCurrentDirectory() ; Debug current dir, lets say it is C:\PureBasic\Compilers

LoadImage(0, "flower.bmp") ; This RELATIVE PATH would try to load C:\PureBasic\Compilers\flower.bmp then


; Now lets change our working dir!

SetCurrentDirectory("C:\Windows\system32\") ; Now all RELATIVE PATHs will orientate on this path, that means:

LoadImage(1, "flower.jpg") ; Now, the JPG will be tried to load from C:\Windows\system32\flower.jpg
As you can see: in fact it's unnessecary to create an own procedure! We've got SetCUrrentDirectory()...
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 356
Joined: Sat Dec 25, 2004 2:37 pm

Post by thyphoon »

AND51 wrote:I've not tested this code, but it should work and I explain it:

Code: Select all

Debug GetCurrentDirectory() ; Debug current dir, lets say it is C:\PureBasic\Compilers

LoadImage(0, "flower.bmp") ; This RELATIVE PATH would try to load C:\PureBasic\Compilers\flower.bmp then


; Now lets change our working dir!

SetCurrentDirectory("C:\Windows\system32") ; Now all RELATIVE PATHs will orientate on this path, that means:

LoadImage(1, "flower.jpg") ; Now, the JPG will be tried to load from C:\Windows\system32\flower.jpg
As you can see: in fact it's unnessecary to create an own procedure! We've got SetCUrrentDirectory()...
I understand your idea..but theire is a problem.
An exemple.
I make a game.
MyGame/Game.exe
MyGame/Gfx/image.bmp
MyGame/Map/map.map
MyGame/Editor/Editor.exe

i can put MyGame Folder
anywhere on my harddrive or anywhere on other computer. But I want the editor load always file like Gfx with no problem.

to put SetCurrentDirectory() you must know the path and this path change at anytime you move My Game Folder. is more easy to write the path information with my procedure...

Lollllllll my english is poor ! I hope you understand what i Say.

I use it for a Big Front-End for my arcade Cabinet.... I can configure all with my standard computer, and transfert it on my cabinet..No probleme path because it's a Relative Path
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

> can put MyGame Folder anywhere on my harddrive or anywhere on other computer. But I want the editor load always file like Gfx with no problem.
Then, you also don't need a procedure:

Imagine you have:
MyGame\Game.exe
MyGame\Map\Map.map
MyGame\Gfx\image.bmp

You can move your folder "MyGame" everywhere: Desktop, C:, Recycle bin, if you only write in your EXE loadimage(0, "Gfx\image.bmp"), then the image will be loaded correctly. This is because the Image is 1 folder lower (sorry bad expression).
PB 4.30

Code: Select all

onErrorGoto(?Fred)
Post Reply