fputils.pas 11 KB

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