fputils.pas 11 KB

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