filutil.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2012 by the Free Pascal development team
  4. File utility calls
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$ifndef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  12. Function FileOpen (Const FileName : unicodestring; Mode : Integer) : THandle;
  13. begin
  14. Result:=FileOpen(ToSingleByteFileSystemEncodedFileName(FileName),Mode);
  15. end;
  16. Function FileCreate (Const FileName : UnicodeString) : THandle;
  17. begin
  18. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName));
  19. end;
  20. Function FileCreate (Const FileName : UnicodeString; Rights : Integer) : THandle;
  21. begin
  22. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),Rights);
  23. end;
  24. Function FileCreate (Const FileName : UnicodeString; ShareMode : Integer; Rights : Integer) : THandle;
  25. begin
  26. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),ShareMode,Rights);
  27. end;
  28. Function FileAge (Const FileName : UnicodeString): Longint;
  29. begin
  30. Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName));
  31. end;
  32. Function FileExists (Const FileName : UnicodeString) : Boolean;
  33. begin
  34. Result:=FileExists(ToSingleByteFileSystemEncodedFileName(FileName));
  35. end;
  36. Function DirectoryExists (Const Directory : UnicodeString) : Boolean;
  37. begin
  38. Result:=DirectoryExists(ToSingleByteFileSystemEncodedFileName(Directory));
  39. end;
  40. Function FileGetAttr (Const FileName : UnicodeString) : Longint;
  41. begin
  42. Result:=FileGetAttr(ToSingleByteFileSystemEncodedFileName(FileName));
  43. end;
  44. Function FileSetAttr (Const Filename : UnicodeString; Attr: longint) : Longint;
  45. begin
  46. Result:=FileSetAttr(ToSingleByteFileSystemEncodedFileName(FileName),Attr);
  47. end;
  48. Function DeleteFile (Const FileName : UnicodeString) : Boolean;
  49. begin
  50. Result:=DeleteFile(ToSingleByteFileSystemEncodedFileName(FileName));
  51. end;
  52. Function RenameFile (Const OldName, NewName : UnicodeString) : Boolean;
  53. begin
  54. Result:=RenameFile(ToSingleByteFileSystemEncodedFileName(OldName),
  55. ToSingleByteFileSystemEncodedFileName(NewName));
  56. end;
  57. {$ifdef OS_FILEISREADONLY}
  58. Function FileIsReadOnly(const FileName: UnicodeString): Boolean;
  59. begin
  60. Result:=FileIsReadOnly(ToSingleByteFileSystemEncodedFileName(FileName));
  61. end;
  62. {$endif}
  63. {$ifdef OS_FILESETDATEBYNAME}
  64. Function FileSetDate (Const FileName : UnicodeString;Age : Longint) : Longint;
  65. begin
  66. Result:=FileSetDate(ToSingleByteFileSystemEncodedFileName(FileName),Age);
  67. end;
  68. {$endif}
  69. function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  70. Var
  71. Info : TRawByteSearchRec;
  72. A : Integer;
  73. begin
  74. for A:=1 to Length(FileName) do
  75. if CharInSet(FileName[A],['?','*']) then
  76. Exit(False);
  77. A:=0;
  78. if not FollowLink then
  79. A:=A or faSymLink;
  80. Result:=FindFirst(FileName,A,Info)=0;
  81. if Result then
  82. begin
  83. FileDateTime:=FileDatetoDateTime(Info.Time);
  84. FindClose(Info);
  85. end;
  86. end;
  87. Function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  88. begin
  89. Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTime,FollowLink);
  90. end;
  91. Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
  92. begin
  93. Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
  94. ToSingleByteFileSystemEncodedFileName(Dirlist),Options));
  95. end;
  96. Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
  97. begin
  98. Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
  99. ToSingleByteFileSystemEncodedFileName(DirList),ImplicitCurrentDir));
  100. end;
  101. Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
  102. begin
  103. Result:=UnicodeString(ExeSearch(ToSingleByteFileSystemEncodedFileName(Name),
  104. ToSingleByteFileSystemEncodedFileName(Dirlist)));
  105. end;
  106. Function FileSearch (Const Name, DirList : RawByteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
  107. Var
  108. I : longint;
  109. Temp : RawByteString;
  110. begin
  111. Result:=Name;
  112. temp:=SetDirSeparators(DirList);
  113. // Start with checking the file in the current directory
  114. If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
  115. exit;
  116. while True do begin
  117. If Temp = '' then
  118. Break; // No more directories to search - fail
  119. I:=pos(PathSeparator,Temp);
  120. If I<>0 then
  121. begin
  122. Result:=Copy (Temp,1,i-1);
  123. system.Delete(Temp,1,I);
  124. end
  125. else
  126. begin
  127. Result:=Temp;
  128. Temp:='';
  129. end;
  130. If Result<>'' then
  131. begin
  132. If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
  133. Result:=Copy(Result,2,Length(Result)-2);
  134. if (Result<>'') then
  135. Result:=IncludeTrailingPathDelimiter(Result)+name;
  136. end;
  137. If (Result <> '') and FileExists(Result) Then
  138. exit;
  139. end;
  140. Result:='';
  141. end;
  142. Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : Boolean) : RawByteString;
  143. begin
  144. if ImplicitCurrentDir then
  145. Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
  146. else
  147. Result:=FileSearch(Name,DirList,[]);
  148. end;
  149. Function ExeSearch (Const Name : RawByteString; Const DirList : RawByteString ='' ) : RawByteString;
  150. Var
  151. D : RawByteString;
  152. O : TFileSearchOptions;
  153. begin
  154. D:=DirList;
  155. if (D='') then
  156. D:=GetEnvironmentVariable('PATH');
  157. {$ifdef unix}
  158. O:=[];
  159. {$else unix}
  160. O:=[sfoImplicitCurrentDir,sfoStripQuotes];
  161. {$endif unix}
  162. Result := FileSearch(Name, D, O);
  163. end;
  164. {$endif}
  165. {$ifndef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  166. Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : THandle;
  167. begin
  168. Result:=FileOpen(UnicodeString(FileName),Mode);
  169. end;
  170. Function FileCreate (Const FileName : RawByteString) : THandle;
  171. begin
  172. Result:=FileCreate(UnicodeString(FileName));
  173. end;
  174. Function FileCreate (Const FileName : RawByteString; Rights : Integer) : THandle;
  175. begin
  176. Result:=FileCreate(UnicodeString(FileName),Rights);
  177. end;
  178. Function FileCreate (Const FileName : RawByteString; ShareMode : Integer; Rights : Integer) : THandle;
  179. begin
  180. Result:=FileCreate(UnicodeString(FileName),ShareMode,Rights);
  181. end;
  182. Function FileAge (Const FileName : RawByteString): Longint;
  183. begin
  184. Result:=FileAge(UnicodeString(FileName));
  185. end;
  186. Function FileExists (Const FileName : RawByteString) : Boolean;
  187. begin
  188. Result:=FileExists(UnicodeString(FileName));
  189. end;
  190. Function DirectoryExists (Const Directory : RawByteString) : Boolean;
  191. begin
  192. Result:=DirectoryExists(UnicodeString(Directory));
  193. end;
  194. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  195. begin
  196. Result:=FileGetAttr(unicodestring(FileName));
  197. end;
  198. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  199. begin
  200. Result:=FileSetAttr(unicodestring(FileName),Attr);
  201. end;
  202. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  203. begin
  204. Result:=DeleteFile(UnicodeString(FileName));
  205. end;
  206. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  207. begin
  208. Result:=RenameFile(UnicodeString(OldName),UnicodeString(NewName));
  209. end;
  210. {$ifdef OS_FILEISREADONLY}
  211. Function FileIsReadOnly(const FileName: RawByteString): Boolean;
  212. begin
  213. Result:=FileIsReadOnly(UnicodeString(FileName));
  214. end;
  215. {$endif}
  216. {$ifdef OS_FILESETDATEBYNAME}
  217. Function FileSetDate (Const FileName : RawByteString;Age : Longint) : Longint;
  218. begin
  219. Result:=FileSetDate(UnicodeString(FileName),Age);
  220. end;
  221. {$endif}
  222. function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  223. Var
  224. Info : TUnicodeSearchRec;
  225. A : Integer;
  226. begin
  227. for A:=1 to Length(FileName) do
  228. if CharInSet(FileName[A],['?','*']) then
  229. Exit(False);
  230. A:=0;
  231. if not FollowLink then
  232. A:=A or faSymLink;
  233. Result:=FindFirst(FileName,A,Info)=0;
  234. if Result then
  235. begin
  236. FileDateTime:=FileDatetoDateTime(Info.Time);
  237. FindClose(Info);
  238. end;
  239. end;
  240. Function FileAge(const FileName: RawbyteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  241. begin
  242. Result:=FileAge(UnicodeString(FileName),FileDateTime,FollowLink);
  243. end;
  244. Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
  245. Var
  246. I : longint;
  247. Temp : UnicodeString;
  248. begin
  249. Result:=Name;
  250. temp:=SetDirSeparators(DirList);
  251. // Start with checking the file in the current directory
  252. If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
  253. exit;
  254. while True do begin
  255. If Temp = '' then
  256. Break; // No more directories to search - fail
  257. I:=pos(PathSeparator,Temp);
  258. If I<>0 then
  259. begin
  260. Result:=Copy (Temp,1,i-1);
  261. system.Delete(Temp,1,I);
  262. end
  263. else
  264. begin
  265. Result:=Temp;
  266. Temp:='';
  267. end;
  268. If Result<>'' then
  269. begin
  270. If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
  271. Result:=Copy(Result,2,Length(Result)-2);
  272. if (Result<>'') then
  273. Result:=IncludeTrailingPathDelimiter(Result)+name;
  274. end;
  275. If (Result <> '') and FileExists(Result) Then
  276. exit;
  277. end;
  278. Result:='';
  279. end;
  280. Function FileSearch (Const Name, DirList : RawbyteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
  281. begin
  282. Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(unicodestring(name),unicodestring(dirlist),options));
  283. end;
  284. Function FileSearch (Const Name, DirList : RawbyteString; ImplicitCurrentDir : Boolean) : RawByteString;
  285. begin
  286. Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(unicodestring(name),unicodestring(dirlist),ImplicitCurrentDir));
  287. end;
  288. Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
  289. begin
  290. if ImplicitCurrentDir then
  291. Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
  292. else
  293. Result:=FileSearch(Name,DirList,[]);
  294. end;
  295. Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
  296. Var
  297. D : UnicodeString;
  298. O : TFileSearchOptions;
  299. begin
  300. D:=DirList;
  301. if (D='') then
  302. D:=UnicodeString(GetEnvironmentVariable('PATH'));
  303. {$ifdef unix}
  304. O:=[];
  305. {$else unix}
  306. O:=[sfoImplicitCurrentDir,sfoStripQuotes];
  307. {$endif unix}
  308. Result := FileSearch(Name, D, O);
  309. end;
  310. Function ExeSearch (Const Name : RawbyteString; Const DirList : RawbyteString ='' ) : RawByteString;
  311. begin
  312. Result:=ToSingleByteFileSystemEncodedFileName(ExeSearch(unicodestring(name),unicodestring(dirlist)));
  313. end;
  314. {$endif}
  315. Function GetFileHandle(var f : File):THandle;
  316. begin
  317. Result:=filerec(f).handle;
  318. end;
  319. Function GetFileHandle(var f : Text):THandle;
  320. begin
  321. Result:=textrec(f).handle;
  322. end;
  323. { FindFirst/FindNext. In order to avoid having to duplicate most code in th
  324. OS-specific implementations, we let those implementations fill in all
  325. fields of TRawbyte/UnicodeSearchRec, except for the name. That field is
  326. filled in by the OS-indepedent wrappers, which also takes care of setting
  327. the appropriate code page if applicable.
  328. }
  329. type
  330. TAbstractSearchRec = Record
  331. Time : Longint;
  332. Size : Int64;
  333. Attr : Longint;
  334. { this will be assigned by the generic code; it is actually either a
  335. rawbytestring or unicodestring; keep it a reference-counted type
  336. so that -gt doesn't overwrite it, the field name should be
  337. indication enough that you should not touch it }
  338. Name_do_not_touch : RawByteString;
  339. ExcludeAttr : Longint;
  340. FindHandle : {$ifdef FINDHANDLE_IS_POINTER}Pointer{$else}THandle{$endif};
  341. {$ifdef unix}
  342. Mode : TMode;
  343. {$endif unix}
  344. {$ifdef USEFINDDATA}
  345. FindData : TFindData;
  346. {$endif}
  347. end;
  348. {$ifdef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  349. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint; forward;
  350. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint; forward;
  351. {$endif SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  352. {$ifdef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  353. Function InternalFindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: UnicodeString) : Longint; forward;
  354. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : UnicodeString) : Longint; forward;
  355. {$endif SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  356. procedure InternalFindClose(var Handle: {$ifdef FINDHANDLE_IS_POINTER}Pointer{$else}THandle{$endif}{$ifdef USEFINDDATA};var FindData: TFindData{$endif}); forward;
  357. {$ifndef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  358. Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
  359. var
  360. Name: UnicodeString;
  361. begin
  362. Result:=InternalFindFirst(UnicodeString(Path),Attr,TAbstractSearchRec(Rslt),Name);
  363. if Result=0 then
  364. widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Name),Rslt.Name,DefaultRTLFileSystemCodePage,length(Name));
  365. end;
  366. Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
  367. var
  368. Name: UnicodeString;
  369. begin
  370. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Name);
  371. if Result=0 then
  372. widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Name),Rslt.Name,DefaultRTLFileSystemCodePage,length(Name));
  373. end;
  374. {$else not SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  375. Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
  376. begin
  377. Result:=InternalFindFirst(Path,Attr,TAbstractSearchRec(Rslt),Rslt.Name);
  378. if Result=0 then
  379. SetCodePage(Rslt.Name,DefaultRTLFileSystemCodePage);
  380. end;
  381. Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
  382. begin
  383. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Rslt.Name);
  384. if Result=0 then
  385. SetCodePage(Rslt.Name,DefaultRTLFileSystemCodePage);
  386. end;
  387. {$endif not SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  388. {$ifndef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  389. Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
  390. var
  391. Name: RawByteString;
  392. begin
  393. Result:=InternalFindFirst(ToSingleByteFileSystemEncodedFileName(Path),Attr,TAbstractSearchRec(Rslt),Name);
  394. if Result=0 then
  395. Rslt.Name:=UnicodeString(Name);
  396. end;
  397. Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
  398. var
  399. Name: RawByteString;
  400. begin
  401. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Name);
  402. if Result=0 then
  403. Rslt.Name:=UnicodeString(Name);
  404. end;
  405. {$else not SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  406. Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
  407. begin
  408. Result:=InternalFindFirst(Path,Attr,TAbstractSearchRec(Rslt),Rslt.Name);
  409. end;
  410. Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
  411. begin
  412. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Rslt.Name);
  413. end;
  414. {$endif not SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  415. Procedure FindClose(Var f: TRawByteSearchRec);
  416. begin
  417. InternalFindClose(f.FindHandle{$ifdef USEFINDDATA},f.FindData{$endif});
  418. end;
  419. Procedure FindClose(Var f: TUnicodeSearchRec);
  420. begin
  421. InternalFindClose(f.FindHandle{$ifdef USEFINDDATA},f.FindData{$endif});
  422. end;