fputils.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Utilility routines used by the IDE
  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. unit FPUtils;
  12. {$H-}
  13. interface
  14. uses
  15. Sysutils,
  16. Objects;
  17. const
  18. dirsep = System.DirectorySeparator;
  19. {$ifdef Unix}
  20. listsep = [';',':'];
  21. exeext = '';
  22. pasext = '.pas';
  23. ppext = '.pp';
  24. {$else}
  25. {$ifdef HASAMIGA}
  26. listsep = [';'];
  27. exeext = '';
  28. pasext = '.pas';
  29. ppext = '.pp';
  30. {$else HASAMIGA}
  31. listsep = [';'];
  32. exeext = '.exe';
  33. pasext = '.pas';
  34. ppext = '.pp';
  35. {$endif HASAMIGA}
  36. {$endif}
  37. function SmartPath(Path: string): string;
  38. Function FixPath(s:string;allowdot:boolean):string;
  39. function FixFileName(const s:string):string;
  40. function MakeFileNameExt(const fn:string; const aExt: string):string;
  41. function MakeExeName(const fn:string):string;
  42. function Center(const S: string; Len: byte): string;
  43. function FitStr(const S: string; Len: byte): string;
  44. function KillTilde(S: string): string;
  45. function LowercaseStr(const S: string): string;
  46. {function DirOf(const S: string): string;
  47. function ExtOf(const S: string): string;
  48. function NameOf(const S: string): string;
  49. function NameAndExtOf(const S: string): string;}
  50. function StrToExtended(S: string): Extended;
  51. function Power(const A,B: double): double;
  52. function MatchesMask(What, Mask: string): boolean;
  53. function MatchesMaskList(What, MaskList: string): boolean;
  54. function MatchesFileList(What, FileList: string): boolean;
  55. function EatIO: integer;
  56. function RenameFile(const OldFileName,NewFileName: string): boolean;
  57. function LocateFile(FileList: string): string;
  58. function LocatePasFile(const FileName:string):string;
  59. function LocateExeFile(var FileName:string): boolean;
  60. function EraseFile(FileName: string): boolean;
  61. function GetStr(const P: PString): string;
  62. procedure ReplaceStr(var S: string; const What,NewS: string);
  63. procedure ReplaceStrI(var S: string; What: string; const NewS: string);
  64. const ListSeparator : AnsiChar = ';';
  65. implementation
  66. uses Dos,
  67. WUtils,
  68. FPVars,FPSwitch;
  69. function IntToStr(L: longint): string;
  70. var S: string;
  71. begin
  72. Str(L,S);
  73. IntToStr:=S;
  74. end;
  75. function IntToStrZ(L: longint; MinLen: byte): string;
  76. var S: string;
  77. begin
  78. S:=IntToStr(L);
  79. if length(S)<MinLen then S:=CharStr('0',MinLen-length(S))+S;
  80. IntToStrZ:=S;
  81. end;
  82. function IntToStrL(L: longint; MinLen: byte): string;
  83. var S: string;
  84. begin
  85. S:=IntToStr(L);
  86. if length(S)<MinLen then S:=CharStr(' ',MinLen-length(S))+S;
  87. IntToStrL:=S;
  88. end;
  89. function SmartPath(Path: string): string;
  90. var S: string;
  91. begin
  92. GetDir(0,S);
  93. {$ifdef HASAMIGA}
  94. if (copy(S,length(S),1)<>DirSep) and (copy(S,length(S),1)<>DriveSeparator) then S:=S+DirSep;
  95. {$else}
  96. if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
  97. {$endif}
  98. {$ifdef FSCaseInsensitive}
  99. if (LowerCaseStr(copy(Path,1,length(S)))=LowerCaseStr(S)) {and (Pos('\',copy(Path,length(S)+1,High(S)))=0)} then
  100. {$else}
  101. if (copy(Path,1,length(S))=S) {and (Pos('\',copy(Path,length(S)+1,High(S)))=0)} then
  102. {$endif}
  103. system.Delete(Path,1,length(S));
  104. SmartPath:=Path;
  105. end;
  106. Function FixPath(s:string;allowdot:boolean):string;
  107. var
  108. i : longint;
  109. begin
  110. for i:=1 to length(s) do
  111. if s[i] in ['/','\'] then
  112. s[i]:=DirSep;
  113. if (length(s)>0) and (s[length(s)]<>DirSep) and
  114. (s[length(s)]<>':') then
  115. s:=s+DirSep;
  116. if (not allowdot) and (s='.'+DirSep) then
  117. s:='';
  118. FixPath:=s;
  119. end;
  120. function FixFileName(const s:string):string;
  121. var
  122. i : longint;
  123. {$ifdef Unix}
  124. NoPath : boolean;
  125. {$endif}
  126. begin
  127. {$ifdef Unix}NoPath:=true;{$endif}
  128. for i:=length(s) downto 1 do
  129. begin
  130. case s[i] of
  131. {$ifdef Unix}
  132. '/','\' : begin
  133. FixFileName[i]:='/';
  134. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  135. end;
  136. 'A'..'Z' : if NoPath then
  137. FixFileName[i]:=AnsiChar(byte(s[i])+ord('a')-ord('A'))
  138. else
  139. FixFileName[i]:=s[i];
  140. {$else}
  141. {$ifndef hasamiga}
  142. '/' : FixFileName[i]:='\';
  143. 'A'..'Z' : FixFileName[i]:=AnsiChar(byte(s[i])+32);
  144. {$else}
  145. '\' : FixFileName[i]:='/';
  146. {$endif}
  147. {$endif}
  148. else
  149. FixFileName[i]:=s[i];
  150. end;
  151. end;
  152. FixFileName[0]:=s[0];
  153. end;
  154. function MakeFileNameExt(const fn:string; const aExt: string):string;
  155. var
  156. d : DirStr;
  157. n : NameStr;
  158. e : ExtStr;
  159. begin
  160. FSplit(fn,d,n,e);
  161. MakeFileNameExt:=d+n+aExt;
  162. end;
  163. function MakeExeName(const fn:string):string;
  164. var
  165. d : DirStr;
  166. n : NameStr;
  167. e : ExtStr;
  168. begin
  169. FSplit(fn,d,n,e);
  170. MakeExeName:=d+n+ExeExt;
  171. end;
  172. function Center(const S: string; Len: byte): string;
  173. begin
  174. Center:=LExpand(S+CharStr(' ',Max(0,(Len-length(S)) div 2)),Len);
  175. end;
  176. function FitStr(const S: string; Len: byte): string;
  177. begin
  178. FitStr:=RExpand(copy(S,1,Len),Len);
  179. end;
  180. function KillTilde(S: string): string;
  181. var P: longint;
  182. begin
  183. repeat
  184. P:=Pos('~',S);
  185. if P>0 then
  186. Delete(S,P,1);
  187. until P=0;
  188. KillTilde:=S;
  189. end;
  190. function LowerCaseStr(const S: string): string;
  191. var
  192. I: Longint;
  193. begin
  194. for I:=1 to length(S) do
  195. if S[I] in ['A'..'Z'] then
  196. LowerCaseStr[I]:=chr(ord(S[I])+32)
  197. else
  198. LowerCaseStr[I]:=S[I];
  199. LowercaseStr[0]:=S[0];
  200. end;
  201. {function DirOf(const S: string): string;
  202. var D: DirStr; E: ExtStr; N: NameStr;
  203. begin
  204. FSplit(S,D,N,E);
  205. if (D<>'') and (D[Length(D)]<>DirSep) then
  206. DirOf:=D+DirSep
  207. else
  208. DirOf:=D;
  209. end;
  210. function ExtOf(const S: string): string;
  211. var D: DirStr; E: ExtStr; N: NameStr;
  212. begin
  213. FSplit(S,D,N,E);
  214. ExtOf:=E;
  215. end;
  216. function NameOf(const S: string): string;
  217. var D: DirStr; E: ExtStr; N: NameStr;
  218. begin
  219. FSplit(S,D,N,E);
  220. NameOf:=N;
  221. end;
  222. function NameAndExtOf(const S: string): string;
  223. var D: DirStr; E: ExtStr; N: NameStr;
  224. begin
  225. FSplit(S,D,N,E);
  226. NameAndExtOf:=N+E;
  227. end; }
  228. function StrToExtended(S: string): Extended;
  229. var R : Extended;
  230. C : integer;
  231. begin
  232. Val(S,R,C);
  233. StrToExtended:=R;
  234. end;
  235. function Power(const A,B: double): double;
  236. begin
  237. if A=0 then Power:=0
  238. else Power:=exp(B*ln(A));
  239. end;
  240. function MatchesMask(What, Mask: string): boolean;
  241. function upper(const s : string) : string;
  242. var
  243. i : Sw_integer;
  244. begin
  245. for i:=1 to length(s) do
  246. if s[i] in ['a'..'z'] then
  247. upper[i]:=AnsiChar(byte(s[i])-32)
  248. else
  249. upper[i]:=s[i];
  250. upper[0]:=s[0];
  251. end;
  252. Function CmpStr(const hstr1,hstr2:string):boolean;
  253. var
  254. found : boolean;
  255. i1,i2 : Sw_integer;
  256. begin
  257. i1:=0;
  258. i2:=0;
  259. found:=true;
  260. while found and (i1<length(hstr1)) and (i2<=length(hstr2)) do
  261. begin
  262. if found then
  263. inc(i2);
  264. inc(i1);
  265. case hstr1[i1] of
  266. '?' :
  267. found:=true;
  268. '*' :
  269. begin
  270. found:=true;
  271. if (i1=length(hstr1)) then
  272. i2:=length(hstr2)
  273. else
  274. if (i1<length(hstr1)) and (hstr1[i1+1]<>hstr2[i2]) then
  275. begin
  276. if i2<length(hstr2) then
  277. dec(i1)
  278. end
  279. else
  280. if i2>1 then
  281. dec(i2);
  282. end;
  283. else
  284. found:=(hstr1[i1]=hstr2[i2]) or (hstr2[i2]='?');
  285. end;
  286. end;
  287. if found then
  288. found:=(i1>=length(hstr1)) and (i2>=length(hstr2));
  289. CmpStr:=found;
  290. end;
  291. var
  292. D1,D2 : DirStr;
  293. N1,N2 : NameStr;
  294. E1,E2 : Extstr;
  295. begin
  296. {$ifdef Unix}
  297. FSplit(What,D1,N1,E1);
  298. FSplit(Mask,D2,N2,E2);
  299. {$else}
  300. FSplit(Upper(What),D1,N1,E1);
  301. FSplit(Upper(Mask),D2,N2,E2);
  302. {$endif}
  303. MatchesMask:=CmpStr(N2,N1) and CmpStr(E2,E1);
  304. end;
  305. function MatchesMaskList(What, MaskList: string): boolean;
  306. var P: integer;
  307. Match: boolean;
  308. begin
  309. Match:=false;
  310. if What<>'' then
  311. repeat
  312. P:=Pos(ListSeparator, MaskList);
  313. if P=0 then
  314. P:=length(MaskList)+1;
  315. Match:=MatchesMask(What,copy(MaskList,1,P-1));
  316. Delete(MaskList,1,P);
  317. until Match or (MaskList='');
  318. MatchesMaskList:=Match;
  319. end;
  320. function MatchesFileList(What, FileList: string): boolean;
  321. var P: integer;
  322. Match: boolean;
  323. WD,FD : record D: DirStr; N: NameStr; E: ExtStr; end;
  324. F: string;
  325. begin
  326. Match:=false;
  327. FSplit(What,WD.D,WD.N,WD.E);
  328. if What<>'' then
  329. repeat
  330. P:=Pos(ListSeparator, FileList);
  331. if P=0 then P:=length(FileList)+1;
  332. F:=copy(FileList,1,P-1);
  333. FSplit(F,FD.D,FD.N,FD.E);
  334. Match:=MatchesMask(WD.D+WD.N,FD.D+FD.N) and
  335. MatchesMask(WD.E,FD.E);
  336. Delete(FileList,1,P);
  337. until Match or (FileList='');
  338. MatchesFileList:=Match;
  339. end;
  340. function EatIO: integer;
  341. begin
  342. EatIO:=IOResult;
  343. end;
  344. function RenameFile(const OldFileName,NewFileName: string): boolean;
  345. var f: file;
  346. begin
  347. Assign(f,OldFileName);
  348. Rename(f,NewFileName);
  349. RenameFile:=(EatIO=0);
  350. end;
  351. function LocateFile(FileList: string): string;
  352. var FilePath: string;
  353. function CheckFile(Path,Name: string): boolean;
  354. var OK: boolean;
  355. begin
  356. Path:=CompleteDir(Path);
  357. Path:=Path+Name;
  358. OK:=ExistsFile(Path);
  359. if OK then FilePath:=Path;
  360. CheckFile:=OK;
  361. end;
  362. function LocateSingleFile(FileName: string): boolean;
  363. var OK: boolean;
  364. begin
  365. OK:=CheckFile(FExpand('.'),FileName);
  366. if OK=false then OK:=CheckFile(StartupDir,FileName);
  367. if OK=false then OK:=CheckFile(IDEDir,FileName);
  368. LocateSingleFile:=OK;
  369. end;
  370. var P: integer;
  371. begin
  372. FilePath:='';
  373. if FileList<>'' then
  374. repeat
  375. P:=Pos(ListSeparator,FileList); if P=0 then P:=length(FileList)+1;
  376. LocateSingleFile(copy(FileList,1,P-1));
  377. Delete(FileList,1,P);
  378. until (FilePath<>'') or (FileList='');
  379. LocateFile:=FilePath;
  380. end;
  381. function LocatePasFile(const FileName:string):string;
  382. var
  383. s : string;
  384. begin
  385. LocatePasFile:=FileName;
  386. if ExistsFile(FileName) or (ExtOf(FileName)<>'') then
  387. exit;
  388. S:=FileName+PPExt;
  389. if ExistsFile(S) then
  390. begin
  391. LocatePasFile:=S;
  392. exit;
  393. end;
  394. S:=FileName+PasExt;
  395. if ExistsFile(S) then
  396. begin
  397. LocatePasFile:=S;
  398. exit;
  399. end;
  400. end;
  401. function LocateExeFile(var FileName:string): boolean;
  402. var
  403. dir : string;
  404. s : ansistring;
  405. i : longint;
  406. begin
  407. LocateExeFile:=False;
  408. if ExistsFile(FileName) then
  409. begin
  410. LocateExeFile:=true;
  411. Exit;
  412. end;
  413. S:=sysutils.GetEnvironmentVariable('PATH');
  414. While Length(S)>0 do
  415. begin
  416. i:=1;
  417. While (i<=Length(S)) and not (S[i] in ListSep) do
  418. Inc(i);
  419. Dir:=CompleteDir(Copy(S,1,i-1));
  420. if i<Length(S) then
  421. Delete(S,1,i)
  422. else
  423. S:='';
  424. if ExistsFile(Dir+FileName) then
  425. Begin
  426. FileName:=Dir+FileName;
  427. LocateExeFile:=true;
  428. Exit;
  429. End;
  430. end;
  431. end;
  432. function GetStr(const P: PString): string;
  433. begin
  434. if P=nil then GetStr:='' else GetStr:=P^;
  435. end;
  436. function EraseFile(FileName: string): boolean;
  437. var f: file;
  438. begin
  439. if FileName='' then Exit;
  440. {$I-}
  441. Assign(f,FileName);
  442. Erase(f);
  443. {$I+}
  444. EraseFile:=(EatIO=0);
  445. end;
  446. procedure ReplaceStr(var S: string; const What,NewS: string);
  447. var I : Sw_integer;
  448. begin
  449. repeat
  450. I:=Pos(What,S);
  451. if I>0 then
  452. begin
  453. Delete(S,I,length(What));
  454. Insert(NewS,S,I);
  455. end;
  456. until I=0;
  457. end;
  458. procedure ReplaceStrI(var S: string; What: string; const NewS: string);
  459. var I : integer;
  460. UpcaseS: string;
  461. begin
  462. UpcaseS:=UpcaseStr(S); What:=UpcaseStr(What);
  463. repeat
  464. I:=Pos(What,UpcaseS);
  465. if I>0 then
  466. begin
  467. Delete(S,I,length(What));
  468. Insert(NewS,S,I);
  469. Delete(UpcaseS,I,length(What));
  470. Insert(NewS,UpcaseS,I);
  471. end;
  472. until I=0;
  473. end;
  474. END.