Repair path names with ..: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
mNo edit summary
(better solution)
Line 1: Line 1:
Seeing as how this page didn't exist yet, but the topic did, hopefully somebody else can clean it up...
Seeing as how this page didn't exist yet, but the topic did, hopefully somebody else can clean it up...
:A better solution for this is using GetFullPathName.
:<highlight-nsis>GetFullPathName $R0 "C:\folder\subfolder\.\anotherfolder\..\someotherfolder\somefile.ext"</highlight-nsis>


Below is a very naive piece of code, which uses LogicLib a bit to keep things sane.  DON'T USE THIS CODE :D
Below is a very naive piece of code, which uses LogicLib a bit to keep things sane.  DON'T USE THIS CODE :D

Revision as of 08:24, 29 September 2006

Seeing as how this page didn't exist yet, but the topic did, hopefully somebody else can clean it up...

A better solution for this is using GetFullPathName.
GetFullPathName $R0 "C:\folder\subfolder\.\anotherfolder\..\someotherfolder\somefile.ext"

Below is a very naive piece of code, which uses LogicLib a bit to keep things sane. DON'T USE THIS CODE :D (not until somebody cleans it up anyway)

Section "Bladeebla"
    StrCpy $R0 "C:\folder\subfolder\.\anotherfolder\..\someotherfolder\somefile.ext"
    StrCpy $4 $R0 1 0
    StrLen $1 $R0
    StrCpy $2 0
    Push "RelAbs"
	_loop:
	    IntOp $2 $2 + 1
	    ${If} $2 > $1
	        goto _end
		${EndIf}
		StrCpy $0 $R0 3 $2
		${If} $0 == "..\"
		    Pop $4
		    Pop $4
		    IntOp $2 $2 + 2
		${ElseIf} $0 == "\.\"
			IntOp $2 $2 + 1
		${Else}
		    StrCpy $3 $R0 1 $2
		    StrCpy $4 "$4$3"
		    ${If} $3 == "\"
				Push $4
			${EndIf}
		${EndIf}
		goto _loop
	_end:
 
	_loop2:
		Pop $0
		${If} $0 == "RelAbs"
		    goto _end2
		${EndIf}
		goto _loop2
	_end2:
 
	MessageBox MB_OK "$R0$\r$\n$4"
SectionEnd

This will display a messagebox with: C:\folder\subfolder\.\anotherfolder\..\someotherfolder\somefile.ext C:\folder\subfolder\someotherfolder\somefile.ext

Note that instead of lots of string manipulations, this code is either lazy or smart, depending on how you look at it. Everytime a "\.\" is encountered, it ignores it. Everytime a "..\" is encountered, it also ignores it, and Pops the currently collected path off the stack, twice, to get back to what the collected path was before the parent folder was added. If a "\" is encountered not as part of the above two, the currently collected path is pushed to the stack, effectively pushing the path with each folder encountered to the stack. Then at the end the stack is cleaned up by popping off until "RelAbs" is the value popped.

Please note that this means you can't feed it paths like "..\whatever" because it doesn't know where to start in. It also doesn't deal with forward slashes "/". It doesn't bother cleaning up "\\", it fails when you've got "A\B\C\D\..\..\" (returning "A\") etc. So the above code really is quite naive, should be cleaned up, etc. but may be a good starting point as it doesn't do insane things with strings using a ton of variables.