pas2jsfileutilsunix.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. {%MainUnit pas2jsfileutils.pas}
  2. {
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 2018 Mattias Gaertner [email protected]
  5. Unix backend of pas2jsfileutils
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************
  12. }
  13. function FilenameIsAbsolute(const aFilename: string): boolean;
  14. begin
  15. Result:=FilenameIsUnixAbsolute(aFilename);
  16. end;
  17. function ExpandFileNamePJ(const FileName: string; BaseDir: string): string;
  18. var
  19. IsAbs: Boolean;
  20. HomeDir, Fn: String;
  21. begin
  22. Fn := FileName;
  23. ForcePathDelims(Fn);
  24. IsAbs := FileNameIsUnixAbsolute(Fn);
  25. if (not IsAbs) then
  26. begin
  27. if ((Length(Fn) > 1) and (Fn[1] = '~') and (Fn[2] = '/')) or (Fn = '~') then
  28. begin
  29. HomeDir := GetEnvironmentVariablePJ('HOME');
  30. if not FileNameIsUnixAbsolute(HomeDir) then
  31. HomeDir := ExpandFileNamePJ(HomeDir,'');
  32. Fn := HomeDir + Copy(Fn,2,length(Fn));
  33. IsAbs := True;
  34. end;
  35. end;
  36. if IsAbs then
  37. begin
  38. Result := ResolveDots(Fn);
  39. end
  40. else
  41. begin
  42. if (BaseDir = '') then
  43. Fn := IncludeTrailingPathDelimiter(GetCurrentDirPJ) + Fn
  44. else
  45. Fn := IncludeTrailingPathDelimiter(BaseDir) + Fn;
  46. Fn := ResolveDots(Fn);
  47. //if BaseDir is not absolute then this needs to be expanded as well
  48. if not FileNameIsUnixAbsolute(Fn) then
  49. Fn := ExpandFileNamePJ(Fn, '');
  50. Result := Fn;
  51. end;
  52. end;
  53. function GetCurrentDirPJ: String;
  54. begin
  55. Result:=GetCurrentDir;
  56. end;
  57. function GetPhysicalFilename(const Filename: string; ExceptionOnError: boolean
  58. ): string;
  59. var
  60. OldPath: String;
  61. NewPath: String;
  62. p: PChar;
  63. begin
  64. Result:=Filename;
  65. p:=PChar(Result);
  66. repeat
  67. while p^='/' do
  68. inc(p);
  69. if p^=#0 then exit;
  70. if p^<>'/' then
  71. begin
  72. repeat
  73. inc(p);
  74. until p^ in [#0,'/'];
  75. OldPath:=LeftStr(Result,p-PChar(Result));
  76. NewPath:=ResolveSymLinks(OldPath,ExceptionOnError);
  77. if NewPath='' then exit('');
  78. if OldPath<>NewPath then
  79. begin
  80. Result:=NewPath+copy(Result,length(OldPath)+1,length(Result));
  81. p:=PChar(Result)+length(NewPath);
  82. end;
  83. end;
  84. until false;
  85. end;
  86. function ResolveSymLinks(const Filename: string; ExceptionOnError: boolean
  87. ): string;
  88. var
  89. LinkFilename: string;
  90. AText: string;
  91. Depth: Integer;
  92. begin
  93. Result:=Filename;
  94. Depth:=0;
  95. while Depth<12 do begin
  96. inc(Depth);
  97. LinkFilename:=fpReadLink(Result);
  98. if LinkFilename='' then
  99. begin
  100. AText:='"'+Filename+'"';
  101. case fpGetErrno() of
  102. ESysEAcces:
  103. AText:='read access denied for '+AText;
  104. ESysENoEnt:
  105. AText:='a directory component in '+AText
  106. +' does not exist or is a dangling symlink';
  107. ESysENotDir:
  108. AText:='a directory component in '+AText+' is not a directory';
  109. ESysENoMem:
  110. AText:='insufficient memory';
  111. ESysELoop:
  112. AText:=AText+' has a circular symbolic link';
  113. else
  114. // not a symbolic link, just a regular file
  115. exit;
  116. end;
  117. if (not ExceptionOnError) then
  118. begin
  119. Result:='';
  120. exit;
  121. end;
  122. raise EFOpenError.Create(AText);
  123. end else begin
  124. if not FilenameIsAbsolute(LinkFilename) then
  125. Result:=ExtractFilePath(Result)+LinkFilename
  126. else
  127. Result:=LinkFilename;
  128. end;
  129. end;
  130. // probably an endless loop
  131. if ExceptionOnError then
  132. raise EFOpenError.Create('too many links, maybe an endless loop.')
  133. else
  134. Result:='';
  135. end;
  136. function IsUNCPath(const Path: String): Boolean;
  137. begin
  138. Result := false;
  139. end;
  140. function ExtractUNCVolume(const Path: String): String;
  141. begin
  142. Result := '';
  143. end;
  144. function FileIsWritable(const AFilename: string): boolean;
  145. begin
  146. Result := BaseUnix.FpAccess(AFilename, BaseUnix.W_OK) = 0;
  147. end;
  148. function FileIsExecutable(const AFilename: string): boolean;
  149. var
  150. Info : Stat;
  151. begin
  152. // first check AFilename is not a directory and then check if executable
  153. Result:= (FpStat(AFilename,info{%H-})<>-1) and FPS_ISREG(info.st_mode) and
  154. (BaseUnix.FpAccess(AFilename,BaseUnix.X_OK)=0);
  155. end;
  156. function GetEnvironmentVariableCountPJ: Integer;
  157. begin
  158. Result:=GetEnvironmentVariableCount;
  159. end;
  160. function GetEnvironmentStringPJ(Index: Integer): string;
  161. begin
  162. Result:=ConsoleToUTF8(GetEnvironmentString(Index));
  163. end;
  164. function GetEnvironmentVariablePJ(const EnvVar: string): String;
  165. begin
  166. Result:=ConsoleToUTF8(GetEnvironmentVariable(EnvVar));
  167. end;
  168. {$IFNDEF Darwin}
  169. function GetUnixEncoding: string;
  170. var
  171. i: integer;
  172. begin
  173. Result:=EncodingSystem;
  174. i:=pos('.',Lang);
  175. if (i>0) and (i<=length(Lang)) then
  176. Result:=copy(Lang,i+1,length(Lang)-i);
  177. end;
  178. {$ENDIF}
  179. function GetConsoleTextEncoding: string;
  180. begin
  181. Result:=GetDefaultTextEncoding;
  182. end;
  183. function UTF8ToSystemCP(const s: string): string;
  184. begin
  185. if NonUTF8System and not IsASCII(s) then
  186. begin
  187. Result:=UTF8ToAnsi(s);
  188. // prevent UTF8 codepage appear in the strings - we don't need codepage
  189. // conversion magic
  190. SetCodePage(RawByteString(Result), StringCodePage(s), False);
  191. end
  192. else
  193. Result:=s;
  194. end;
  195. function SystemCPToUTF8(const s: string): string;
  196. begin
  197. if NonUTF8System and not IsASCII(s) then
  198. begin
  199. Result:=AnsiToUTF8(s);
  200. // prevent UTF8 codepage appear in the strings - we don't need codepage
  201. // conversion magic
  202. SetCodePage(RawByteString(Result), StringCodePage(s), False);
  203. end
  204. else
  205. Result:=s;
  206. end;
  207. function ConsoleToUTF8(const s: string): string;
  208. begin
  209. Result:=SystemCPToUTF8(s);
  210. end;
  211. function UTF8ToConsole(const s: string): string;
  212. begin
  213. Result:=UTF8ToSystemCP(s);
  214. end;
  215. procedure InitPlatform;
  216. begin
  217. end;
  218. procedure FinalizePlatform;
  219. begin
  220. end;