2
0

fputils.pas 11 KB

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