; --------------------------------------------------------------------------------------------; Copyright (c) Fantaisie Software. All rights reserved.; Dual licensed under the GPL and Fantaisie Software licenses.; See LICENSE and LICENSE-FANTAISIE in the project root for license information.; --------------------------------------------------------------------------------------------; --------------------------------------------------------------;; Functions for easier working with filenames on all platforms.;; Note: This file is standalone and does not need anything from; the IDE sources, so it can be used in any other project as well.;; This file is unicode ready.;; Used by: IDE, Debugger, PureUnit;; --------------------------------------------------------------; redefine these from the IDE source if not present;CompilerIf Defined(Separator, #PB_Constant) = 0CompilerIf #PB_Compiler_OS = #PB_OS_Windows#Separator = "\"CompilerElse#Separator = "/"CompilerEndIfCompilerEndIf; Creates a unique representation of a filename, by doing this:; - replaces any "../directory" parts to get a direct path; - removes multiple redundant "//" in the path; - cutting any "./" in the path; - on Windows, replaces all "/" by "\" as both are allowed.;; The resulting path can be compared for equalness by only taking; care or the case sensitivity of the filesystem.;; Returns "" if the path contains more "../" than directories!;Procedure.s UniqueFilename(FileName$); Got a 0-pointer here on Linux once.If FileName$ = ""ProcedureReturn ""EndIf; On Windows, we need to replace all "/" with "\" to have a unique path,; as both can be mixed as separator characters!;; We also do the conversion in the other direction so we can easily share; Project files and compiler settings between Windows and Linux.;CompilerIf #PB_Compiler_OS = #PB_OS_WindowsFileName$ = ReplaceString(FileName,ドル "/", "\")CompilerElseFileName$ = ReplaceString(FileName,ドル "\", "/")CompilerEndIf*Cursor.Character = @FileName$While *Cursor\cIf *Cursor\c = Asc(#Separator)If PeekS(*Cursor, 4) = #Separator + ".." + #Separator; remove the previous directory name*BackCursor.Character = *Cursor - SizeOf(Character)While *BackCursor >= @FileName$If *BackCursor\c = Asc(#Separator)BreakEndIf*BackCursor - SizeOf(Character)WendIf *BackCursor < @FileName$; oops, more ".." in the string than directories!ProcedureReturn ""EndIf; poking in the string is ok, since it can only get shorter by thisPokeS(*BackCursor, PeekS(*Cursor + 3*SizeOf(Character))); Make sure the cursor stays inside the string.; Otherwise, if removing a large dir towards the string end, *Cursor might; end up outside of the valid string and create an endless loop*Cursor = *BackCursorElseIf PeekS(*Cursor, 3) = #Separator + "." + #Separator; simply remove this reference to the own directoryPokeS(*Cursor, PeekS(*Cursor + 2*SizeOf(Character)))ElseIf PeekS(*Cursor, 2) = #Separator + #Separator; Redundant "\\" or "//". Remove one of them; Special case: On Windows a path starting with \\ is a UNC network oathCompilerIf #PB_Compiler_OS = #PB_OS_WindowsIf *Cursor = @FileName$*Cursor + (SizeOf(Character) * 2)ContinueEndIfCompilerEndIfPokeS(*Cursor, PeekS(*Cursor + SizeOf(Character))); Do not skip the remaining "/" yet to reprocess it in the next loop so do not increase *Cursor hereElse*Cursor + SizeOf(Character)EndIfElse*Cursor + SizeOf(Character)EndIfWendProcedureReturn Filename$EndProcedure; Returns true if the two (full) filenames are representing; the same file. This function calls UniqueFilename().;Procedure IsEqualFile(File1,ドル File2$)File1$ = UniqueFilename(File1$)File2$ = UniqueFilename(File2$); The UniqueFilename() returns "" if the filename has too many "../";If File1$ <> "" And File2$ <> ""CompilerIf #PB_Compiler_OS = #PB_OS_LinuxIf File1$ = File2$ProcedureReturn #TrueEndIfCompilerElseIf UCase(File1$) = UCase(File2$)ProcedureReturn #TrueEndIfCompilerEndIfEndIfProcedureReturn #FalseEndProcedure; Creates a relative path representation of the (full) FileName$; relative to the (full) BasePath$. Note that the full FileName$ is returned; if no relative path can be created (different drives), or if there; would be too many "../../" involved.;Procedure.s CreateRelativePath(BasePath,ドル FileName$)If FileName$ = "" ; otherwise this gives an ugly "../../"ProcedureReturn ""EndIf; make sure both have no "../" or "/", "\" mixupsFileName$ = UniqueFilename(FileName$)BasePath$ = UniqueFilename(BasePath$); check if both are really full paths:;CompilerIf #PB_Compiler_OS = #PB_OS_WindowsIf Mid(BasePath,ドル 2, 1) = ":" And Mid(FileName,ドル 2, 1) = ":"; Both have drive letters.. check the drive matchIf UCase(Left(BasePath,ドル 1)) <> UCase(Left(FileName,ドル 1))ProcedureReturn FileName$EndIfElseIf Left(BasePath,ドル 2) = "\\" And Left(FileName,ドル 2) = "\\"; Both are network paths, check if the computer name matchesIf UCase(StringField(BasePath,ドル 3, "\")) <> UCase(StringField(FileName,ドル 3, "\"))ProcedureReturn FileName$EndIfElse; Either a mix of Network/non-network paths, or not full paths at allProcedureReturn FileName$EndIfCompilerElseIf Left(BasePath,ドル 1) <> "/" Or Left(FileName,ドル 1) <> "/"ProcedureReturn FileName$EndIfCompilerEndIfIf Right(BasePath,ドル 1) <> #SeparatorBasePath$ + #SeparatorEndIfFullFileName$ = FileName$ ; make backup for later; process the part that is identical;For x = Len(BasePath$) To 1 Step -1If Mid(BasePath,ドル x, 1) = #SeparatorProtected CaseModeCompilerIf #PB_Compiler_OS = #PB_OS_LinuxCaseMode = #PB_String_CaseSensitiveCompilerElseCaseMode = #PB_String_NoCaseCompilerEndIfIf CompareMemoryString(@BasePath,ドル @FileName,ドル CaseMode, x) = 0BasePath$ = Right(BasePath,ドル Len(BasePath$)-x)FileName$ = Right(FileName,ドル Len(FileName$)-x)BreakEndIfEndIfNext x; now add ".." for each directory left in the BasePath$;count = CountString(BasePath,ドル #Separator)If count <= 3 ; do not go too many levels back.. it looks uglyFor i = 1 To countFileName$ = ".." + #Separator + FileName$Next iElseFileName$ = FullFileName$ ; use the full name hereEndIfProcedureReturn FileName$EndProcedure; Tries to resolve a (relative or full) FileName$ relative to the; (full) BasePath$. The returned filename is made unique with; UniqueFilename();Procedure.s ResolveRelativePath(BasePath,ドル FileName$); do the cutting of "../" even if basepath is actually emptyIf BasePath$ <> ""BasePath$ = UniqueFilename(BasePath$)If Right(BasePath,ドル 1) <> #SeparatorBasePath$ + #SeparatorEndIfIf FindString(FileName,ドル #Separator, 1) = 0FileName$ = BasePath$ + FileName$CompilerIf #PB_Compiler_OS = #PB_OS_WindowsElseIf Left(FileName,ドル 2) = "\\" ; Network file path, Windows only (like: \192円.168.0.1\Test.pb); FileName$ remains untouched here (it contains a drive letter)CompilerEndIfElseIf Left(FileName,ドル 1) = #SeparatorCompilerIf #PB_Compiler_OS = #PB_OS_WindowsFileName$ = Left(BasePath,ドル 2) + FileName$CompilerEndIf; On linux/mac. FileName is a full path, so no changeCompilerIf #PB_Compiler_OS = #PB_OS_WindowsElseIf Mid(FileName,ドル 2, 1) = ":"; FileName$ remains untouched here (it contains a drive letter)CompilerEndIfElseFileName$ = BasePath$ + FileName$EndIfEndIf; the UniqueFilename() cuts all the "../" in the combined path; Do this even if FileName$ was a full path to get a unique name as; the debugger reports full filenames containing "../" for example.;ProcedureReturn UniqueFilename(FileName$)EndProcedure
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。