pas2jsfileutilsunix.inc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. {%MainUnit pas2jsfileutils.pas}
  2. function FilenameIsAbsolute(const aFilename: string): boolean;
  3. begin
  4. Result:=FilenameIsUnixAbsolute(aFilename);
  5. end;
  6. function ExpandFileNameUTF8(const FileName: string; BaseDir: string): string;
  7. var
  8. IsAbs: Boolean;
  9. CurDir, HomeDir, Fn: String;
  10. begin
  11. Fn := FileName;
  12. ForcePathDelims(Fn);
  13. IsAbs := FileNameIsUnixAbsolute(Fn);
  14. if (not IsAbs) then
  15. begin
  16. CurDir := GetCurrentDirUtf8;
  17. if ((Length(Fn) > 1) and (Fn[1] = '~') and (Fn[2] = '/')) or (Fn = '~') then
  18. begin
  19. HomeDir := GetEnvironmentVariableUTF8('HOME');
  20. if not FileNameIsUnixAbsolute(HomeDir) then
  21. HomeDir := ExpandFileNameUtf8(HomeDir,'');
  22. Fn := HomeDir + Copy(Fn,2,length(Fn));
  23. IsAbs := True;
  24. end;
  25. end;
  26. if IsAbs then
  27. begin
  28. Result := ResolveDots(Fn);
  29. end
  30. else
  31. begin
  32. if (BaseDir = '') then
  33. Fn := IncludeTrailingPathDelimiter(CurDir) + Fn
  34. else
  35. Fn := IncludeTrailingPathDelimiter(BaseDir) + Fn;
  36. Fn := ResolveDots(Fn);
  37. //if BaseDir is not absolute then this needs to be expanded as well
  38. if not FileNameIsUnixAbsolute(Fn) then
  39. Fn := ExpandFileNameUtf8(Fn, '');
  40. Result := Fn;
  41. end;
  42. end;
  43. function GetCurrentDirUTF8: String;
  44. begin
  45. Result:=GetCurrentDir;
  46. end;
  47. function GetPhysicalFilename(const Filename: string; ExceptionOnError: boolean
  48. ): string;
  49. var
  50. OldPath: String;
  51. NewPath: String;
  52. p: PChar;
  53. begin
  54. Result:=Filename;
  55. p:=PChar(Result);
  56. repeat
  57. while p^='/' do
  58. inc(p);
  59. if p^=#0 then exit;
  60. if p^<>'/' then
  61. begin
  62. repeat
  63. inc(p);
  64. until p^ in [#0,'/'];
  65. OldPath:=LeftStr(Result,p-PChar(Result));
  66. NewPath:=ResolveSymLinks(OldPath,ExceptionOnError);
  67. if NewPath='' then exit('');
  68. if OldPath<>NewPath then
  69. begin
  70. Result:=NewPath+copy(Result,length(OldPath)+1,length(Result));
  71. p:=PChar(Result)+length(NewPath);
  72. end;
  73. end;
  74. until false;
  75. end;
  76. function ResolveSymLinks(const Filename: string; ExceptionOnError: boolean
  77. ): string;
  78. var
  79. LinkFilename: string;
  80. AText: string;
  81. Depth: Integer;
  82. begin
  83. Result:=Filename;
  84. Depth:=0;
  85. while Depth<12 do begin
  86. inc(Depth);
  87. LinkFilename:=fpReadLink(Result);
  88. if LinkFilename='' then begin
  89. AText:='"'+Filename+'"';
  90. case fpGetErrno() of
  91. ESysEAcces:
  92. AText:='read access denied for '+AText;
  93. ESysENoEnt:
  94. AText:='a directory component in '+AText
  95. +' does not exist or is a dangling symlink';
  96. ESysENotDir:
  97. AText:='a directory component in '+AText+' is not a directory';
  98. ESysENoMem:
  99. AText:='insufficient memory';
  100. ESysELoop:
  101. AText:=AText+' has a circular symbolic link';
  102. else
  103. // not a symbolic link, just a regular file
  104. exit;
  105. end;
  106. if (not ExceptionOnError) then begin
  107. Result:='';
  108. exit;
  109. end;
  110. raise EFOpenError.Create(AText);
  111. end else begin
  112. if not FilenameIsAbsolute(LinkFilename) then
  113. Result:=ExtractFilePath(Result)+LinkFilename
  114. else
  115. Result:=LinkFilename;
  116. end;
  117. end;
  118. // probably an endless loop
  119. if ExceptionOnError then
  120. raise EFOpenError.Create('too many links, maybe an endless loop.')
  121. else
  122. Result:='';
  123. end;
  124. function GetEnvironmentVariableCountUTF8: Integer;
  125. begin
  126. Result:=GetEnvironmentVariableCount;
  127. end;
  128. function GetEnvironmentStringUTF8(Index: Integer): string;
  129. begin
  130. Result:=ConsoleToUTF8(GetEnvironmentString(Index));
  131. end;
  132. function GetEnvironmentVariableUTF8(const EnvVar: string): String;
  133. begin
  134. Result:=ConsoleToUTF8(GetEnvironmentVariable(EnvVar));
  135. end;
  136. {$IFNDEF Darwin}
  137. function GetUnixEncoding: string;
  138. var
  139. i: integer;
  140. begin
  141. Result:=EncodingSystem;
  142. i:=pos('.',Lang);
  143. if (i>0) and (i<=length(Lang)) then
  144. Result:=copy(Lang,i+1,length(Lang)-i);
  145. end;
  146. {$ENDIF}
  147. function GetConsoleTextEncoding: string;
  148. begin
  149. Result:=GetDefaultTextEncoding;
  150. end;
  151. function UTF8ToSystemCP(const s: string): string;
  152. begin
  153. if NonUTF8System and not IsASCII(s) then
  154. begin
  155. Result:=UTF8ToAnsi(s);
  156. // prevent UTF8 codepage appear in the strings - we don't need codepage
  157. // conversion magic
  158. SetCodePage(RawByteString(Result), StringCodePage(s), False);
  159. end
  160. else
  161. Result:=s;
  162. end;
  163. function SystemCPToUTF8(const s: string): string;
  164. begin
  165. if NonUTF8System and not IsASCII(s) then
  166. begin
  167. Result:=AnsiToUTF8(s);
  168. // prevent UTF8 codepage appear in the strings - we don't need codepage
  169. // conversion magic
  170. SetCodePage(RawByteString(Result), StringCodePage(s), False);
  171. end
  172. else
  173. Result:=s;
  174. end;
  175. function ConsoleToUTF8(const s: string): string;
  176. begin
  177. Result:=SystemCPToUTF8(s);
  178. end;
  179. function UTF8ToConsole(const s: string): string;
  180. begin
  181. Result:=UTF8ToSystemCP(s);
  182. end;
  183. procedure InitPlatform;
  184. begin
  185. end;
  186. procedure FinalizePlatform;
  187. begin
  188. end;