fputils.pas 11 KB

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