fputils.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Utilility routines used by the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPUtils;
  13. interface
  14. uses Objects;
  15. const
  16. {$ifdef linux}
  17. dirsep = '/';
  18. listsep = [';',':'];
  19. exeext = '';
  20. pasext = '.pas';
  21. ppext = '.pp';
  22. {$else}
  23. dirsep = '\';
  24. listsep = [';'];
  25. exeext = '.exe';
  26. pasext = '.pas';
  27. ppext = '.pp';
  28. {$endif}
  29. function IntToStr(L: longint): string;
  30. function IntToStrZ(L: longint; MinLen: byte): string;
  31. function IntToStrL(L: longint; MinLen: byte): string;
  32. function StrToInt(const S: string): longint;
  33. function IntToHex(L: longint): string;
  34. function IntToHexL(L: longint; MinLen: byte): string;
  35. function HexToInt(S: string): longint;
  36. function CharStr(C: char; Count: byte): string;
  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 LExpand(S: string; MinLen: byte): string;
  42. function RExpand(S: string; MinLen: byte): string;
  43. function FitStr(const S: string; Len: byte): string;
  44. function LTrim(const S: string): string;
  45. function RTrim(const S: string): string;
  46. function Trim(const S: string): string;
  47. function KillTilde(S: string): string;
  48. function UpcaseStr(const S: string): string;
  49. function LowerCaseStr(const S: string): string;
  50. function Max(A,B: longint): longint;
  51. function Min(A,B: longint): longint;
  52. function DirOf(const S: string): string;
  53. function ExtOf(const S: string): string;
  54. function NameOf(const S: string): string;
  55. function NameAndExtOf(const S: string): string;
  56. function StrToExtended(S: string): Extended;
  57. function Power(const A,B: double): double;
  58. function GetCurDir: string;
  59. function MatchesMask(What, Mask: string): boolean;
  60. function MatchesMaskList(const What:string;MaskList: string): boolean;
  61. function MatchesFileList(What, FileList: string): boolean;
  62. function EatIO: integer;
  63. function ExistsFile(const FileName: string): boolean;
  64. function CompleteDir(const Path: string): string;
  65. function LocateFile(FileList: string): string;
  66. function LocatePasFile(const FileName:string):string;
  67. function LocateExeFile(var FileName:string): boolean;
  68. function GetStr(P: PString): string;
  69. procedure ReplaceStr(var S: string; const What,NewS: string);
  70. procedure ReplaceStrI(var S: string; What: string; const NewS: string);
  71. const LastStrToIntResult : integer = 0;
  72. LastHexToIntResult : integer = 0;
  73. ListSeparator : char = ';';
  74. implementation
  75. uses Dos,
  76. FPVars;
  77. function IntToStr(L: longint): string;
  78. var S: string;
  79. begin
  80. Str(L,S);
  81. IntToStr:=S;
  82. end;
  83. function StrToInt(const S: string): longint;
  84. var L: longint;
  85. C: integer;
  86. begin
  87. Val(S,L,C);
  88. if C<>0 then L:=-1;
  89. LastStrToIntResult:=C;
  90. StrToInt:=L;
  91. end;
  92. function CharStr(C: char; Count: byte): string;
  93. var S: string;
  94. begin
  95. S[0]:=chr(Count);
  96. FillChar(S[1],Count,C);
  97. CharStr:=S;
  98. end;
  99. function IntToStrZ(L: longint; MinLen: byte): string;
  100. var S: string;
  101. begin
  102. S:=IntToStr(L);
  103. if length(S)<MinLen then S:=CharStr('0',MinLen-length(S))+S;
  104. IntToStrZ:=S;
  105. end;
  106. function IntToStrL(L: longint; MinLen: byte): string;
  107. var S: string;
  108. begin
  109. S:=IntToStr(L);
  110. if length(S)<MinLen then S:=CharStr(' ',MinLen-length(S))+S;
  111. IntToStrL:=S;
  112. end;
  113. function SmartPath(Path: string): string;
  114. var S: string;
  115. begin
  116. GetDir(0,S); if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
  117. if (copy(Path,1,length(S))=S) {and (Pos('\',copy(Path,length(S)+1,255))=0)} then
  118. system.Delete(Path,1,length(S));
  119. SmartPath:=Path;
  120. end;
  121. Function FixPath(s:string;allowdot:boolean):string;
  122. var
  123. i : longint;
  124. begin
  125. for i:=1 to length(s) do
  126. if s[i] in ['/','\'] then
  127. s[i]:=DirSep;
  128. if (length(s)>0) and (s[length(s)]<>DirSep) and
  129. (s[length(s)]<>':') then
  130. s:=s+DirSep;
  131. if (not allowdot) and (s='.'+DirSep) then
  132. s:='';
  133. FixPath:=s;
  134. end;
  135. function FixFileName(const s:string):string;
  136. var
  137. i : longint;
  138. NoPath : boolean;
  139. begin
  140. NoPath:=true;
  141. for i:=length(s) downto 1 do
  142. begin
  143. case s[i] of
  144. {$ifdef Linux}
  145. '/','\' : begin
  146. FixFileName[i]:='/';
  147. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  148. end;
  149. 'A'..'Z' : if NoPath then
  150. FixFileName[i]:=char(byte(s[i])+32)
  151. else
  152. FixFileName[i]:=s[i];
  153. {$else}
  154. '/' : FixFileName[i]:='\';
  155. 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
  156. {$endif}
  157. else
  158. FixFileName[i]:=s[i];
  159. end;
  160. end;
  161. FixFileName[0]:=s[0];
  162. end;
  163. function MakeExeName(const fn:string):string;
  164. var
  165. d : DirStr;
  166. n : NameStr;
  167. e : ExtStr;
  168. begin
  169. FSplit(fn,d,n,e);
  170. MakeExeName:=d+n+ExeExt;
  171. end;
  172. function LExpand(S: string; MinLen: byte): string;
  173. begin
  174. if length(S)<MinLen then S:=CharStr(' ',MinLen-length(S))+S;
  175. LExpand:=S;
  176. end;
  177. function RExpand(S: string; MinLen: byte): string;
  178. begin
  179. if length(S)<MinLen then S:=S+CharStr(' ',MinLen-length(S));
  180. RExpand:=S;
  181. end;
  182. function FitStr(const S: string; Len: byte): string;
  183. begin
  184. FitStr:=RExpand(copy(S,1,Len),Len);
  185. end;
  186. function KillTilde(S: string): string;
  187. var P: longint;
  188. begin
  189. repeat
  190. P:=Pos('~',S);
  191. if P>0 then
  192. Delete(S,P,1);
  193. until P=0;
  194. KillTilde:=S;
  195. end;
  196. function UpcaseStr(const S: string): string;
  197. var
  198. i : Sw_word;
  199. begin
  200. for i:=1 to length(s) do
  201. if s[i] in ['a'..'z'] then
  202. UpcaseStr[i]:=char(byte(s[i])-32)
  203. else
  204. UpcaseStr[i]:=s[i];
  205. UpcaseStr[0]:=s[0];
  206. end;
  207. function LowercaseStr(const S: string): string;
  208. var
  209. i : Sw_word;
  210. begin
  211. for i:=1 to length(s) do
  212. if s[i] in ['A'..'Z'] then
  213. LowercaseStr[i]:=char(byte(s[i])+32)
  214. else
  215. LowercaseStr[i]:=s[i];
  216. LowercaseStr[0]:=s[0];
  217. end;
  218. function Max(A,B: longint): longint;
  219. begin
  220. if A>B then Max:=A else Max:=B;
  221. end;
  222. function Min(A,B: longint): longint;
  223. begin
  224. if A<B then Min:=A else Min:=B;
  225. end;
  226. function DirOf(const S: string): string;
  227. var D: DirStr; E: ExtStr; N: NameStr;
  228. begin
  229. FSplit(S,D,N,E);
  230. if (D<>'') and (D[Length(D)]<>DirSep) then
  231. DirOf:=D+DirSep
  232. else
  233. DirOf:=D;
  234. end;
  235. function ExtOf(const S: string): string;
  236. var D: DirStr; E: ExtStr; N: NameStr;
  237. begin
  238. FSplit(S,D,N,E);
  239. ExtOf:=E;
  240. end;
  241. function NameOf(const S: string): string;
  242. var D: DirStr; E: ExtStr; N: NameStr;
  243. begin
  244. FSplit(S,D,N,E);
  245. NameOf:=N;
  246. end;
  247. function NameAndExtOf(const S: string): string;
  248. var D: DirStr; E: ExtStr; N: NameStr;
  249. begin
  250. FSplit(S,D,N,E);
  251. NameAndExtOf:=N+E;
  252. end;
  253. function StrToExtended(S: string): Extended;
  254. var R : Extended;
  255. C : integer;
  256. begin
  257. Val(S,R,C);
  258. StrToExtended:=R;
  259. end;
  260. function Power(const A,B: double): double;
  261. begin
  262. if A=0 then Power:=0
  263. else Power:=exp(B*ln(A));
  264. end;
  265. function GetCurDir: string;
  266. var S: string;
  267. begin
  268. GetDir(0,S);
  269. if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
  270. GetCurDir:=S;
  271. end;
  272. function IntToHex(L: longint): string;
  273. const HexNums : string[16] = '0123456789ABCDEF';
  274. var S: string;
  275. R: real;
  276. function DivF(Mit,Mivel: real): longint;
  277. begin
  278. DivF:=trunc(Mit/Mivel);
  279. end;
  280. function ModF(Mit,Mivel: real): longint;
  281. begin
  282. ModF:=trunc(Mit-DivF(Mit,Mivel)*Mivel);
  283. end;
  284. begin
  285. S:='';
  286. R:=L; if R<0 then begin R:=R+2147483647+2147483647+2; end;
  287. repeat
  288. S:=HexNums[ModF(R,16)+1]+S;
  289. R:=DivF(R,16);
  290. until R=0;
  291. IntToHex:=S;
  292. end;
  293. function HexToInt(S: string): longint;
  294. var L,I: longint;
  295. C: char;
  296. const HexNums: string[16] = '0123456789ABCDEF';
  297. begin
  298. S:=Trim(S); L:=0; I:=1; LastHexToIntResult:=0;
  299. while (I<=length(S)) and (LastHexToIntResult=0) do
  300. begin
  301. C:=Upcase(S[I]);
  302. if C in['0'..'9','A'..'F'] then
  303. begin
  304. L:=L*16+(Pos(C,HexNums)-1);
  305. end else LastHexToIntResult:=I;
  306. Inc(I);
  307. end;
  308. HexToInt:=L;
  309. end;
  310. function IntToHexL(L: longint; MinLen: byte): string;
  311. var S: string;
  312. begin
  313. S:=IntToHex(L);
  314. while length(S)<MinLen do S:='0'+S;
  315. IntToHexL:=S;
  316. end;
  317. function LTrim(const S: string): string;
  318. var
  319. i : Sw_integer;
  320. begin
  321. i:=1;
  322. while (i<length(S)) and (S[i]=' ') do
  323. inc(i);
  324. LTrim:=Copy(S,i,255);
  325. end;
  326. Function RTrim(const S:string):string;
  327. var
  328. i : Sw_integer;
  329. begin
  330. i:=length(S);
  331. while (i>0) and (S[i]=' ') do
  332. dec(i);
  333. RTrim:=Copy(S,1,i);
  334. end;
  335. function Trim(const S: string): string;
  336. begin
  337. Trim:=RTrim(LTrim(S));
  338. end;
  339. function MatchesMask(What, Mask: string): boolean;
  340. var P: integer;
  341. Match: boolean;
  342. begin
  343. P:=Pos('*',Mask);
  344. if P>0 then
  345. begin
  346. Mask:=copy(Mask,1,P-1);
  347. What:=copy(What,1,P-1);
  348. end;
  349. Match:=length(Mask)=length(What); P:=1;
  350. if Match and (Mask<>'') then
  351. repeat
  352. Match:=Match and ((Mask[P]='?') or (Upcase(Mask[P])=Upcase(What[P])));
  353. Inc(P);
  354. until (Match=false) or (P>length(Mask));
  355. MatchesMask:=Match;
  356. end;
  357. function MatchesMaskList(const What:string;MaskList: string): boolean;
  358. var P: integer;
  359. Match: boolean;
  360. begin
  361. Match:=false;
  362. if What<>'' then
  363. repeat
  364. P:=Pos(ListSeparator, MaskList);
  365. if P=0 then P:=length(MaskList)+1;
  366. Match:=MatchesMask(What,copy(MaskList,1,P-1));
  367. Delete(MaskList,1,P);
  368. until Match or (MaskList='');
  369. MatchesMaskList:=Match;
  370. end;
  371. function MatchesFileList(What, FileList: string): boolean;
  372. var P: integer;
  373. Match: boolean;
  374. WD,FD : record D: DirStr; N: NameStr; E: ExtStr; end;
  375. F: string;
  376. begin
  377. Match:=false;
  378. FSplit(What,WD.D,WD.N,WD.E);
  379. if What<>'' then
  380. repeat
  381. P:=Pos(ListSeparator, FileList);
  382. if P=0 then P:=length(FileList)+1;
  383. F:=copy(FileList,1,P-1);
  384. FSplit(F,FD.D,FD.N,FD.E);
  385. Match:=MatchesMask(WD.D+WD.N,FD.D+FD.N) and
  386. MatchesMask(WD.E,FD.E);
  387. Delete(FileList,1,P);
  388. until Match or (FileList='');
  389. MatchesFileList:=Match;
  390. end;
  391. function EatIO: integer;
  392. begin
  393. EatIO:=IOResult;
  394. end;
  395. function ExistsFile(const FileName: string): boolean;
  396. var
  397. Dir : SearchRec;
  398. begin
  399. FindFirst(FileName,Archive+ReadOnly,Dir);
  400. ExistsFile:=(DosError=0);
  401. {$ifdef FPC}
  402. FindClose(Dir);
  403. {$endif def FPC}
  404. end;
  405. function CompleteDir(const Path: string): string;
  406. begin
  407. { keep c: untouched PM }
  408. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  409. (Path[Length(Path)]<>':') then
  410. CompleteDir:=Path+DirSep
  411. else
  412. CompleteDir:=Path;
  413. end;
  414. function LocateFile(FileList: string): string;
  415. var FilePath: string;
  416. function CheckFile(Path,Name: string): boolean;
  417. var OK: boolean;
  418. begin
  419. Path:=CompleteDir(Path);
  420. Path:=Path+Name;
  421. OK:=ExistsFile(Path);
  422. if OK then FilePath:=Path;
  423. CheckFile:=OK;
  424. end;
  425. function LocateSingleFile(FileName: string): boolean;
  426. var OK: boolean;
  427. begin
  428. OK:=CheckFile(FExpand('.'),FileName);
  429. if OK=false then OK:=CheckFile(StartupDir,FileName);
  430. if OK=false then OK:=CheckFile(DirOf(FExpand(ParamStr(0))),FileName);
  431. LocateSingleFile:=OK;
  432. end;
  433. var P: integer;
  434. begin
  435. FilePath:='';
  436. if FileList<>'' then
  437. repeat
  438. P:=Pos(ListSeparator,FileList); if P=0 then P:=length(FileList)+1;
  439. LocateSingleFile(copy(FileList,1,P-1));
  440. Delete(FileList,1,P);
  441. until (FilePath<>'') or (FileList='');
  442. LocateFile:=FilePath;
  443. end;
  444. function LocatePasFile(const FileName:string):string;
  445. var
  446. s : string;
  447. begin
  448. LocatePasFile:=FileName;
  449. if ExistsFile(FileName) or (ExtOf(FileName)<>'') then
  450. exit;
  451. S:=FileName+PPExt;
  452. if ExistsFile(S) then
  453. begin
  454. LocatePasFile:=S;
  455. exit;
  456. end;
  457. S:=FileName+PasExt;
  458. if ExistsFile(S) then
  459. begin
  460. LocatePasFile:=S;
  461. exit;
  462. end;
  463. end;
  464. function LocateExeFile(var FileName:string): boolean;
  465. var
  466. dir,s : string;
  467. i : longint;
  468. begin
  469. LocateExeFile:=False;
  470. if ExistsFile(FileName) then
  471. begin
  472. LocateExeFile:=true;
  473. Exit;
  474. end;
  475. S:=GetEnv('PATH');
  476. repeat
  477. i:=0;
  478. While (i<=Length(S)) and not (S[i] in ListSep) do
  479. Inc(i);
  480. Dir:=CompleteDir(Copy(S,1,i-1));
  481. Delete(S,1,i);
  482. if ExistsFile(Dir+FileName) then
  483. Begin
  484. FileName:=Dir+FileName;
  485. LocateExeFile:=true;
  486. Exit;
  487. End;
  488. until s='';
  489. end;
  490. function GetStr(P: PString): string;
  491. begin
  492. if P=nil then GetStr:='' else GetStr:=P^;
  493. end;
  494. procedure ReplaceStr(var S: string; const What,NewS: string);
  495. var I : Sw_integer;
  496. begin
  497. repeat
  498. I:=Pos(What,S);
  499. if I>0 then
  500. begin
  501. Delete(S,I,length(What));
  502. Insert(NewS,S,I);
  503. end;
  504. until I=0;
  505. end;
  506. procedure ReplaceStrI(var S: string; What: string; const NewS: string);
  507. var I : integer;
  508. UpcaseS: string;
  509. begin
  510. UpcaseS:=UpcaseStr(S); What:=UpcaseStr(What);
  511. repeat
  512. I:=Pos(What,UpcaseS);
  513. if I>0 then
  514. begin
  515. Delete(S,I,length(What));
  516. Insert(NewS,S,I);
  517. end;
  518. until I=0;
  519. end;
  520. END.
  521. {
  522. $Log$
  523. Revision 1.8 1999-02-22 02:15:20 peter
  524. + default extension for save in the editor
  525. + Separate Text to Find for the grep dialog
  526. * fixed redir crash with tp7
  527. Revision 1.7 1999/02/16 17:13:55 pierre
  528. + findclose added for FPC
  529. Revision 1.6 1999/02/05 12:12:01 pierre
  530. + SourceDir that stores directories for sources that the
  531. compiler should not know about
  532. Automatically asked for addition when a new file that
  533. needed filedialog to be found is in an unknown directory
  534. Stored and retrieved from INIFile
  535. + Breakpoints conditions added to INIFile
  536. * Breakpoints insterted and removed at debin and end of debug session
  537. Revision 1.5 1999/02/02 16:41:43 peter
  538. + automatic .pas/.pp adding by opening of file
  539. * better debuggerscreen changes
  540. Revision 1.4 1999/01/21 11:54:25 peter
  541. + tools menu
  542. + speedsearch in symbolbrowser
  543. * working run command
  544. Revision 1.3 1999/01/12 14:29:40 peter
  545. + Implemented still missing 'switch' entries in Options menu
  546. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  547. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  548. ASCII chars and inserted directly in the text.
  549. + Added symbol browser
  550. * splitted fp.pas to fpide.pas
  551. Revision 1.2 1998/12/28 15:47:53 peter
  552. + Added user screen support, display & window
  553. + Implemented Editor,Mouse Options dialog
  554. + Added location of .INI and .CFG file
  555. + Option (INI) file managment implemented (see bottom of Options Menu)
  556. + Switches updated
  557. + Run program
  558. Revision 1.31 1998/12/27 11:25:37 gabor
  559. + MatchesMask(), MatchesMaskList() and MatchesFileList() added
  560. + NameAndExtOf() added
  561. Revision 1.3 1998/12/22 10:39:52 peter
  562. + options are now written/read
  563. + find and replace routines
  564. }