fputils.pas 13 KB

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