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