wutils.pas 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  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 WUtils;
  12. interface
  13. {$ifndef FPC}
  14. {$define TPUNIXLF}
  15. {$endif}
  16. uses
  17. Dos,Objects;
  18. type
  19. PByteArray = ^TByteArray;
  20. TByteArray = array[0..MaxBytes] of byte;
  21. PNoDisposeCollection = ^TNoDisposeCollection;
  22. TNoDisposeCollection = object(TCollection)
  23. procedure FreeItem(Item: Pointer); virtual;
  24. end;
  25. PUnsortedStringCollection = ^TUnsortedStringCollection;
  26. TUnsortedStringCollection = object(TCollection)
  27. constructor CreateFrom(ALines: PUnsortedStringCollection);
  28. procedure Assign(ALines: PUnsortedStringCollection);
  29. function At(Index: Integer): PString;
  30. procedure FreeItem(Item: Pointer); virtual;
  31. function GetItem(var S: TStream): Pointer; virtual;
  32. procedure PutItem(var S: TStream; Item: Pointer); virtual;
  33. procedure InsertStr(const S: string);
  34. end;
  35. PNulStream = ^TNulStream;
  36. TNulStream = object(TStream)
  37. constructor Init;
  38. function GetPos: Longint; virtual;
  39. function GetSize: Longint; virtual;
  40. procedure Read(var Buf; Count: Word); virtual;
  41. procedure Seek(Pos: Longint); virtual;
  42. procedure Write(var Buf; Count: Word); virtual;
  43. end;
  44. PSubStream = ^TSubStream;
  45. TSubStream = object(TStream)
  46. constructor Init(AStream: PStream; AStartPos, ASize: longint);
  47. function GetPos: Longint; virtual;
  48. function GetSize: Longint; virtual;
  49. procedure Read(var Buf; Count: Word); virtual;
  50. procedure Seek(Pos: Longint); virtual;
  51. procedure Write(var Buf; Count: Word); virtual;
  52. private
  53. StartPos: longint;
  54. S : PStream;
  55. end;
  56. PTextCollection = ^TTextCollection;
  57. TTextCollection = object(TStringCollection)
  58. function LookUp(const S: string; var Idx: sw_integer): string;
  59. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  60. end;
  61. {$ifdef TPUNIXLF}
  62. procedure readln(var t:text;var s:string);
  63. {$endif}
  64. procedure ReadlnFromStream(Stream: PStream; var s:string;var linecomplete : boolean);
  65. function eofstream(s: pstream): boolean;
  66. function Min(A,B: longint): longint;
  67. function Max(A,B: longint): longint;
  68. function CharStr(C: char; Count: integer): string;
  69. function UpcaseStr(const S: string): string;
  70. function LowCase(C: char): char;
  71. function LowcaseStr(S: string): string;
  72. function RExpand(const S: string; MinLen: byte): string;
  73. function LExpand(const S: string; MinLen: byte): string;
  74. function LTrim(const S: string): string;
  75. function RTrim(const S: string): string;
  76. function Trim(const S: string): string;
  77. function IntToStr(L: longint): string;
  78. function IntToStrL(L: longint; MinLen: sw_integer): string;
  79. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  80. function StrToInt(const S: string): longint;
  81. function IntToHex(L: longint): string;
  82. function GetStr(P: PString): string;
  83. function GetPChar(P: PChar): string;
  84. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  85. function DirOf(const S: string): string;
  86. function ExtOf(const S: string): string;
  87. function NameOf(const S: string): string;
  88. function NameAndExtOf(const S: string): string;
  89. function DirAndNameOf(const S: string): string;
  90. { return Dos GetFTime value or -1 if the file does not exist }
  91. function GetFileTime(const FileName: string): longint;
  92. { copied from compiler global unit }
  93. function GetShortName(const n:string):string;
  94. function GetLongName(const n:string):string;
  95. function TrimEndSlash(const Path: string): string;
  96. function OptimizePath(Path: string; MaxLen: integer): string;
  97. function CompareText(S1, S2: string): integer;
  98. function FormatPath(Path: string): string;
  99. function CompletePath(const Base, InComplete: string): string;
  100. function CompleteURL(const Base, URLRef: string): string;
  101. function DeleteFile(const FileName: string): integer;
  102. function EatIO: integer;
  103. function Now: longint;
  104. function FormatDateTimeL(L: longint; const Format: string): string;
  105. function FormatDateTime(const D: DateTime; const Format: string): string;
  106. {$ifdef TP}
  107. function StrPas(C: PChar): string;
  108. {$endif}
  109. function MemToStr(var B; Count: byte): string;
  110. procedure StrToMem(S: string; var B);
  111. procedure GiveUpTimeSlice;
  112. const LastStrToIntResult : integer = 0;
  113. DirSep : char = {$ifdef Linux}'/'{$else}'\'{$endif};
  114. procedure RegisterWUtils;
  115. implementation
  116. uses
  117. {$ifdef win32}
  118. windows,
  119. {$endif win32}
  120. Strings;
  121. {$ifndef NOOBJREG}
  122. const
  123. RUnsortedStringCollection: TStreamRec = (
  124. ObjType: 22500;
  125. VmtLink: Ofs(TypeOf(TUnsortedStringCollection)^);
  126. Load: @TUnsortedStringCollection.Load;
  127. Store: @TUnsortedStringCollection.Store
  128. );
  129. {$endif}
  130. {$ifdef TPUNIXLF}
  131. procedure readln(var t:text;var s:string);
  132. var
  133. c : char;
  134. i : longint;
  135. begin
  136. if TextRec(t).UserData[1]=2 then
  137. system.readln(t,s)
  138. else
  139. begin
  140. c:=#0;
  141. i:=0;
  142. while (not eof(t)) and (c<>#10) and (i<High(S)) do
  143. begin
  144. read(t,c);
  145. if c<>#10 then
  146. begin
  147. inc(i);
  148. s[i]:=c;
  149. end;
  150. end;
  151. if (i>0) and (s[i]=#13) then
  152. begin
  153. dec(i);
  154. TextRec(t).UserData[1]:=2;
  155. end;
  156. s[0]:=chr(i);
  157. end;
  158. end;
  159. {$endif}
  160. function eofstream(s: pstream): boolean;
  161. begin
  162. eofstream:=(s^.getpos>=s^.getsize);
  163. end;
  164. procedure ReadlnFromStream(Stream: PStream; var S:string;var linecomplete : boolean);
  165. var
  166. c : char;
  167. i,pos : longint;
  168. begin
  169. linecomplete:=false;
  170. c:=#0;
  171. i:=0;
  172. { this created problems for lines longer than 255 characters
  173. now those lines are cutted into pieces without warning PM }
  174. { changed implicit 255 to High(S), so it will be automatically extended
  175. when longstrings eventually become default - Gabor }
  176. while (not eofstream(stream)) and (c<>#10) and (i<High(S)) do
  177. begin
  178. stream^.read(c,sizeof(c));
  179. if c<>#10 then
  180. begin
  181. inc(i);
  182. s[i]:=c;
  183. end;
  184. end;
  185. { if there was a CR LF then remove the CR Dos newline style }
  186. if (i>0) and (s[i]=#13) then
  187. begin
  188. dec(i);
  189. end;
  190. if (c=#13) and (not eofstream(stream)) then
  191. stream^.read(c,sizeof(c));
  192. if (i=High(S)) and not eofstream(stream) then
  193. begin
  194. pos:=stream^.getpos;
  195. stream^.read(c,sizeof(c));
  196. if (c=#13) and not eofstream(stream) then
  197. stream^.read(c,sizeof(c));
  198. if c<>#10 then
  199. stream^.seek(pos);
  200. end;
  201. if (c=#10) or eofstream(stream) then
  202. linecomplete:=true;
  203. s[0]:=chr(i);
  204. end;
  205. {$ifdef TP}
  206. { TP's own StrPas() is buggy, because it causes GPF with strings longer than
  207. 255 chars }
  208. function StrPas(C: PChar): string;
  209. var S: string;
  210. I: longint;
  211. begin
  212. if Assigned(C)=false then
  213. S:=''
  214. else
  215. begin
  216. I:=StrLen(C); if I>255 then I:=255;
  217. S[0]:=chr(I); Move(C^,S[1],I);
  218. end;
  219. StrPas:=S;
  220. end;
  221. {$endif}
  222. function MemToStr(var B; Count: byte): string;
  223. var S: string;
  224. begin
  225. S[0]:=chr(Count);
  226. if Count>0 then Move(B,S[1],Count);
  227. MemToStr:=S;
  228. end;
  229. procedure StrToMem(S: string; var B);
  230. begin
  231. if length(S)>0 then Move(S[1],B,length(S));
  232. end;
  233. function Max(A,B: longint): longint;
  234. begin
  235. if A>B then Max:=A else Max:=B;
  236. end;
  237. function Min(A,B: longint): longint;
  238. begin
  239. if A<B then Min:=A else Min:=B;
  240. end;
  241. function CharStr(C: char; Count: integer): string;
  242. {$ifndef FPC}
  243. var S: string;
  244. {$endif}
  245. begin
  246. {$ifdef FPC}
  247. CharStr[0]:=chr(Count);
  248. FillChar(CharStr[1],Count,C);
  249. {$else}
  250. S[0]:=chr(Count);
  251. FillChar(S[1],Count,C);
  252. CharStr:=S;
  253. {$endif}
  254. end;
  255. function UpcaseStr(const S: string): string;
  256. var
  257. I: Longint;
  258. begin
  259. for I:=1 to length(S) do
  260. if S[I] in ['a'..'z'] then
  261. UpCaseStr[I]:=chr(ord(S[I])-32)
  262. else
  263. UpCaseStr[I]:=S[I];
  264. UpcaseStr[0]:=S[0];
  265. end;
  266. function RExpand(const S: string; MinLen: byte): string;
  267. begin
  268. if length(S)<MinLen then
  269. RExpand:=S+CharStr(' ',MinLen-length(S))
  270. else
  271. RExpand:=S;
  272. end;
  273. function LExpand(const S: string; MinLen: byte): string;
  274. begin
  275. if length(S)<MinLen then
  276. LExpand:=CharStr(' ',MinLen-length(S))+S
  277. else
  278. LExpand:=S;
  279. end;
  280. function LTrim(const S: string): string;
  281. var
  282. i : longint;
  283. begin
  284. i:=1;
  285. while (i<length(s)) and (s[i]=' ') do
  286. inc(i);
  287. LTrim:=Copy(s,i,High(S));
  288. end;
  289. function RTrim(const S: string): string;
  290. var
  291. i : longint;
  292. begin
  293. i:=length(s);
  294. while (i>0) and (s[i]=' ') do
  295. dec(i);
  296. RTrim:=Copy(s,1,i);
  297. end;
  298. function Trim(const S: string): string;
  299. begin
  300. Trim:=RTrim(LTrim(S));
  301. end;
  302. function IntToStr(L: longint): string;
  303. var S: string;
  304. begin
  305. Str(L,S);
  306. IntToStr:=S;
  307. end;
  308. function IntToStrL(L: longint; MinLen: sw_integer): string;
  309. begin
  310. IntToStrL:=LExpand(IntToStr(L),MinLen);
  311. end;
  312. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  313. var S: string;
  314. begin
  315. S:=IntToStr(L);
  316. if length(S)<MinLen then
  317. S:=CharStr('0',MinLen-length(S))+S;
  318. IntToStrZ:=S;
  319. end;
  320. function StrToInt(const S: string): longint;
  321. var L: longint;
  322. C: integer;
  323. begin
  324. Val(S,L,C); if C<>0 then L:=-1;
  325. LastStrToIntResult:=C;
  326. StrToInt:=L;
  327. end;
  328. function IntToHex(L: longint): string;
  329. const HexNums : string[16] = '0123456789ABCDEF';
  330. var S: string;
  331. R: real;
  332. function DivF(Mit,Mivel: real): longint;
  333. begin
  334. DivF:=trunc(Mit/Mivel);
  335. end;
  336. function ModF(Mit,Mivel: real): longint;
  337. begin
  338. ModF:=trunc(Mit-DivF(Mit,Mivel)*Mivel);
  339. end;
  340. begin
  341. S:='';
  342. R:=L; if R<0 then begin R:=R+2147483647+2147483647+2; end;
  343. repeat
  344. S:=HexNums[ModF(R,16)+1]+S;
  345. R:=DivF(R,16);
  346. until R=0;
  347. IntToHex:=S;
  348. end;
  349. function GetStr(P: PString): string;
  350. begin
  351. if P=nil then GetStr:='' else GetStr:=P^;
  352. end;
  353. function GetPChar(P: PChar): string;
  354. begin
  355. if P=nil then GetPChar:='' else GetPChar:=StrPas(P);
  356. end;
  357. function DirOf(const S: string): string;
  358. var D: DirStr; E: ExtStr; N: NameStr;
  359. begin
  360. FSplit(S,D,N,E);
  361. if (D<>'') and (D[Length(D)]<>DirSep) then
  362. DirOf:=D+DirSep
  363. else
  364. DirOf:=D;
  365. end;
  366. function ExtOf(const S: string): string;
  367. var D: DirStr; E: ExtStr; N: NameStr;
  368. begin
  369. FSplit(S,D,N,E);
  370. ExtOf:=E;
  371. end;
  372. function NameOf(const S: string): string;
  373. var D: DirStr; E: ExtStr; N: NameStr;
  374. begin
  375. FSplit(S,D,N,E);
  376. NameOf:=N;
  377. end;
  378. function NameAndExtOf(const S: string): string;
  379. var D: DirStr; E: ExtStr; N: NameStr;
  380. begin
  381. FSplit(S,D,N,E);
  382. NameAndExtOf:=N+E;
  383. end;
  384. function DirAndNameOf(const S: string): string;
  385. var D: DirStr; E: ExtStr; N: NameStr;
  386. begin
  387. FSplit(S,D,N,E);
  388. DirAndNameOf:=D+N;
  389. end;
  390. { return Dos GetFTime value or -1 if the file does not exist }
  391. function GetFileTime(const FileName: string): longint;
  392. var T: longint;
  393. f: file;
  394. FM: integer;
  395. begin
  396. if FileName='' then
  397. T:=-1
  398. else
  399. begin
  400. FM:=FileMode; FileMode:=0;
  401. EatIO; DosError:=0;
  402. Assign(f,FileName);
  403. {$I-}
  404. Reset(f);
  405. if InOutRes=0 then
  406. begin
  407. GetFTime(f,T);
  408. Close(f);
  409. end;
  410. {$I+}
  411. if (EatIO<>0) or (DosError<>0) then T:=-1;
  412. FileMode:=FM;
  413. end;
  414. GetFileTime:=T;
  415. end;
  416. function GetShortName(const n:string):string;
  417. {$ifdef win32}
  418. var
  419. hs,hs2 : string;
  420. i : longint;
  421. {$endif}
  422. {$ifdef go32v2}
  423. var
  424. hs : string;
  425. {$endif}
  426. begin
  427. GetShortName:=n;
  428. {$ifdef win32}
  429. hs:=n+#0;
  430. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  431. if (i>0) and (i<=high(hs2)) then
  432. begin
  433. hs2[0]:=chr(strlen(@hs2[1]));
  434. GetShortName:=hs2;
  435. end;
  436. {$endif}
  437. {$ifdef go32v2}
  438. hs:=n;
  439. if Dos.GetShortName(hs) then
  440. GetShortName:=hs;
  441. {$endif}
  442. end;
  443. function GetLongName(const n:string):string;
  444. {$ifdef win32}
  445. var
  446. hs : string;
  447. hs2 : Array [0..255] of char;
  448. i : longint;
  449. j : pchar;
  450. {$endif}
  451. {$ifdef go32v2}
  452. var
  453. hs : string;
  454. {$endif}
  455. begin
  456. GetLongName:=n;
  457. {$ifdef win32}
  458. hs:=n+#0;
  459. i:=Windows.GetFullPathName(@hs[1],256,hs2,j);
  460. if (i>0) and (i<=high(hs)) then
  461. begin
  462. hs:=strpas(hs2);
  463. GetLongName:=hs;
  464. end;
  465. {$endif}
  466. {$ifdef go32v2}
  467. hs:=n;
  468. if Dos.GetLongName(hs) then
  469. GetLongName:=hs;
  470. {$endif}
  471. end;
  472. function EatIO: integer;
  473. begin
  474. EatIO:=IOResult;
  475. end;
  476. function LowCase(C: char): char;
  477. begin
  478. if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
  479. LowCase:=C;
  480. end;
  481. function LowcaseStr(S: string): string;
  482. var I: Longint;
  483. begin
  484. for I:=1 to length(S) do
  485. S[I]:=Lowcase(S[I]);
  486. LowcaseStr:=S;
  487. end;
  488. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  489. begin
  490. if B then BoolToStr:=TrueS else BoolToStr:=FalseS;
  491. end;
  492. procedure TNoDisposeCollection.FreeItem(Item: Pointer);
  493. begin
  494. { don't do anything here }
  495. end;
  496. constructor TUnsortedStringCollection.CreateFrom(ALines: PUnsortedStringCollection);
  497. begin
  498. if Assigned(ALines)=false then Fail;
  499. inherited Init(ALines^.Count,ALines^.Count div 10);
  500. Assign(ALines);
  501. end;
  502. procedure TUnsortedStringCollection.Assign(ALines: PUnsortedStringCollection);
  503. procedure AddIt(P: PString); {$ifndef FPC}far;{$endif}
  504. begin
  505. Insert(NewStr(GetStr(P)));
  506. end;
  507. begin
  508. FreeAll;
  509. if Assigned(ALines) then
  510. ALines^.ForEach(@AddIt);
  511. end;
  512. procedure TUnsortedStringCollection.InsertStr(const S: string);
  513. begin
  514. Insert(NewStr(S));
  515. end;
  516. function TUnsortedStringCollection.At(Index: Integer): PString;
  517. begin
  518. At:=inherited At(Index);
  519. end;
  520. procedure TUnsortedStringCollection.FreeItem(Item: Pointer);
  521. begin
  522. if Item<>nil then DisposeStr(Item);
  523. end;
  524. function TUnsortedStringCollection.GetItem(var S: TStream): Pointer;
  525. begin
  526. GetItem:=S.ReadStr;
  527. end;
  528. procedure TUnsortedStringCollection.PutItem(var S: TStream; Item: Pointer);
  529. begin
  530. S.WriteStr(Item);
  531. end;
  532. constructor TNulStream.Init;
  533. begin
  534. inherited Init;
  535. Position:=0;
  536. end;
  537. function TNulStream.GetPos: Longint;
  538. begin
  539. GetPos:=Position;
  540. end;
  541. function TNulStream.GetSize: Longint;
  542. begin
  543. GetSize:=Position;
  544. end;
  545. procedure TNulStream.Read(var Buf; Count: Word);
  546. begin
  547. Error(stReadError,0);
  548. end;
  549. procedure TNulStream.Seek(Pos: Longint);
  550. begin
  551. if Pos<=Position then
  552. Position:=Pos;
  553. end;
  554. procedure TNulStream.Write(var Buf; Count: Word);
  555. begin
  556. Inc(Position,Count);
  557. end;
  558. constructor TSubStream.Init(AStream: PStream; AStartPos, ASize: longint);
  559. begin
  560. inherited Init;
  561. if Assigned(AStream)=false then Fail;
  562. S:=AStream; StartPos:=AStartPos; StreamSize:=ASize;
  563. Seek(0);
  564. end;
  565. function TSubStream.GetPos: Longint;
  566. var Pos: longint;
  567. begin
  568. Pos:=S^.GetPos; Dec(Pos,StartPos);
  569. GetPos:=Pos;
  570. end;
  571. function TSubStream.GetSize: Longint;
  572. begin
  573. GetSize:=StreamSize;
  574. end;
  575. procedure TSubStream.Read(var Buf; Count: Word);
  576. var Pos: longint;
  577. RCount: word;
  578. begin
  579. Pos:=GetPos;
  580. if Pos+Count>StreamSize then RCount:=StreamSize-Pos else RCount:=Count;
  581. S^.Read(Buf,RCount);
  582. if RCount<Count then
  583. Error(stReadError,0);
  584. end;
  585. procedure TSubStream.Seek(Pos: Longint);
  586. var RPos: longint;
  587. begin
  588. if (Pos<=StreamSize) then RPos:=Pos else RPos:=StreamSize;
  589. S^.Seek(StartPos+RPos);
  590. end;
  591. procedure TSubStream.Write(var Buf; Count: Word);
  592. begin
  593. S^.Write(Buf,Count);
  594. end;
  595. function TTextCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  596. var K1: PString absolute Key1;
  597. K2: PString absolute Key2;
  598. R: Sw_integer;
  599. S1,S2: string;
  600. begin
  601. S1:=UpCaseStr(K1^);
  602. S2:=UpCaseStr(K2^);
  603. if S1<S2 then R:=-1 else
  604. if S1>S2 then R:=1 else
  605. R:=0;
  606. Compare:=R;
  607. end;
  608. function TTextCollection.LookUp(const S: string; var Idx: sw_integer): string;
  609. var OLI,ORI,Left,Right,Mid: integer;
  610. {LeftP,RightP,}MidP: PString;
  611. {LeftS,}MidS{,RightS}: string;
  612. FoundS: string;
  613. UpS : string;
  614. begin
  615. Idx:=-1; FoundS:='';
  616. Left:=0; Right:=Count-1;
  617. UpS:=UpCaseStr(S);
  618. if Left<Right then
  619. begin
  620. while (Left<Right) do
  621. begin
  622. OLI:=Left; ORI:=Right;
  623. Mid:=Left+(Right-Left) div 2;
  624. { LeftP:=At(Left); RightP:=At(Right); }MidP:=At(Mid);
  625. { LeftS:=UpCaseStr(LeftP^); }MidS:=UpCaseStr(MidP^);
  626. { RightS:=UpCaseStr(RightP^);}
  627. if copy(MidS,1,length(UpS))=UpS then
  628. begin
  629. Idx:=Mid; FoundS:=GetStr(MidP);
  630. end;
  631. { else}
  632. if UpS<MidS then
  633. Right:=Mid
  634. else
  635. Left:=Mid;
  636. if (OLI=Left) and (ORI=Right) then
  637. Break;
  638. end;
  639. end;
  640. LookUp:=FoundS;
  641. end;
  642. function TrimEndSlash(const Path: string): string;
  643. var S: string;
  644. begin
  645. S:=Path;
  646. if (length(S)>0) and (S<>DirSep) and (copy(S,length(S),1)=DirSep) and
  647. (S[length(S)-1]<>':') then
  648. S:=copy(S,1,length(S)-1);
  649. TrimEndSlash:=S;
  650. end;
  651. function CompareText(S1, S2: string): integer;
  652. var R: integer;
  653. begin
  654. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  655. if S1<S2 then R:=-1 else
  656. if S1>S2 then R:= 1 else
  657. R:=0;
  658. CompareText:=R;
  659. end;
  660. function FormatPath(Path: string): string;
  661. var P: sw_integer;
  662. SC: char;
  663. begin
  664. if ord(DirSep)=ord('/') then
  665. SC:='\'
  666. else
  667. SC:='/';
  668. repeat
  669. P:=Pos(SC,Path);
  670. if P>0 then Path[P]:=DirSep;
  671. until P=0;
  672. FormatPath:=Path;
  673. end;
  674. function CompletePath(const Base, InComplete: string): string;
  675. var Drv,BDrv: string[40]; D,BD: DirStr; N,BN: NameStr; E,BE: ExtStr;
  676. P: sw_integer;
  677. Complete: string;
  678. begin
  679. Complete:=FormatPath(InComplete);
  680. FSplit(FormatPath(InComplete),D,N,E);
  681. P:=Pos(':',D); if P=0 then Drv:='' else begin Drv:=copy(D,1,P); Delete(D,1,P); end;
  682. FSplit(FormatPath(Base),BD,BN,BE);
  683. P:=Pos(':',BD); if P=0 then BDrv:='' else begin BDrv:=copy(BD,1,P); Delete(BD,1,P); end;
  684. if copy(D,1,1)<>DirSep then
  685. Complete:=BD+D+N+E;
  686. if Drv='' then
  687. Complete:=BDrv+Complete;
  688. Complete:=FExpand(Complete);
  689. CompletePath:=Complete;
  690. end;
  691. function CompleteURL(const Base, URLRef: string): string;
  692. var P: integer;
  693. Drive: string[20];
  694. IsComplete: boolean;
  695. S: string;
  696. Ref: string;
  697. Bookmark: string;
  698. begin
  699. IsComplete:=false; Ref:=URLRef;
  700. P:=Pos(':',Ref);
  701. if P=0 then Drive:='' else Drive:=UpcaseStr(copy(Ref,1,P-1));
  702. if Drive<>'' then
  703. if (Drive='MAILTO') or (Drive='FTP') or (Drive='HTTP') or
  704. (Drive='GOPHER') or (Drive='FILE') then
  705. IsComplete:=true;
  706. if IsComplete then S:=Ref else
  707. begin
  708. P:=Pos('#',Ref);
  709. if P=0 then
  710. Bookmark:=''
  711. else
  712. begin
  713. Bookmark:=copy(Ref,P+1,length(Ref));
  714. Ref:=copy(Ref,1,P-1);
  715. end;
  716. S:=CompletePath(Base,Ref);
  717. if Bookmark<>'' then
  718. S:=S+'#'+Bookmark;
  719. end;
  720. CompleteURL:=S;
  721. end;
  722. function OptimizePath(Path: string; MaxLen: integer): string;
  723. var i : integer;
  724. BackSlashs : array[1..20] of integer;
  725. BSCount : integer;
  726. Jobbra : boolean;
  727. Jobb, Bal : byte;
  728. Hiba : boolean;
  729. begin
  730. if length(Path)>MaxLen then
  731. begin
  732. BSCount:=0; Jobbra:=true;
  733. for i:=1 to length(Path) do if Path[i]=DirSep then
  734. begin
  735. Inc(BSCount);
  736. BackSlashs[BSCount]:=i;
  737. end;
  738. i:=BSCount div 2;
  739. Hiba:=false;
  740. Bal:=i; Jobb:=i+1;
  741. case i of 0 : ;
  742. 1 : Path:=copy(Path, 1, BackSlashs[1])+'..'+
  743. copy(Path, BackSlashs[2], length(Path));
  744. else begin
  745. while (BackSlashs[Bal]+(length(Path)-BackSlashs[Jobb]) >=
  746. MaxLen) and not Hiba do
  747. begin
  748. if Jobbra then begin
  749. if Jobb<BSCount then inc(Jobb)
  750. else Hiba:=true;
  751. Jobbra:=false;
  752. end
  753. else begin
  754. if Bal>1 then dec(Bal)
  755. else Hiba:=true;
  756. Jobbra:=true;
  757. end;
  758. end;
  759. Path:=copy(Path, 1, BackSlashs[Bal])+'..'+
  760. copy(Path, BackSlashs[Jobb], length(Path));
  761. end;
  762. end;
  763. end;
  764. if length(Path)>MaxLen then
  765. begin
  766. i:=Pos('\..\',Path);
  767. if i>0 then Path:=copy(Path,1,i-1)+'..'+copy(Path,i+length('\..\'),length(Path));
  768. end;
  769. OptimizePath:=Path;
  770. end;
  771. function Now: longint;
  772. var D: DateTime;
  773. W: word;
  774. L: longint;
  775. begin
  776. FillChar(D,sizeof(D),0);
  777. GetDate(D.Year,D.Month,D.Day,W);
  778. GetTime(D.Hour,D.Min,D.Sec,W);
  779. PackTime(D,L);
  780. Now:=L;
  781. end;
  782. function FormatDateTimeL(L: longint; const Format: string): string;
  783. var D: DateTime;
  784. begin
  785. UnpackTime(L,D);
  786. FormatDateTimeL:=FormatDateTime(D,Format);
  787. end;
  788. function FormatDateTime(const D: DateTime; const Format: string): string;
  789. var I: sw_integer;
  790. CurCharStart: sw_integer;
  791. CurChar: char;
  792. CurCharCount: integer;
  793. DateS: string;
  794. C: char;
  795. procedure FlushChars;
  796. var S: string;
  797. I: sw_integer;
  798. begin
  799. S:='';
  800. for I:=1 to CurCharCount do
  801. S:=S+CurChar;
  802. case CurChar of
  803. 'y' : S:=IntToStrL(D.Year,length(S));
  804. 'm' : S:=IntToStrZ(D.Month,length(S));
  805. 'd' : S:=IntToStrZ(D.Day,length(S));
  806. 'h' : S:=IntToStrZ(D.Hour,length(S));
  807. 'n' : S:=IntToStrZ(D.Min,length(S));
  808. 's' : S:=IntToStrZ(D.Sec,length(S));
  809. end;
  810. DateS:=DateS+S;
  811. end;
  812. begin
  813. DateS:='';
  814. CurCharStart:=-1; CurCharCount:=0; CurChar:=#0;
  815. for I:=1 to length(Format) do
  816. begin
  817. C:=Format[I];
  818. if (C<>CurChar) or (CurCharStart=-1) then
  819. begin
  820. if CurCharStart<>-1 then FlushChars;
  821. CurCharCount:=1; CurCharStart:=I;
  822. end
  823. else
  824. Inc(CurCharCount);
  825. CurChar:=C;
  826. end;
  827. FlushChars;
  828. FormatDateTime:=DateS;
  829. end;
  830. function DeleteFile(const FileName: string): integer;
  831. var f: file;
  832. begin
  833. {$I-}
  834. Assign(f,FileName);
  835. Erase(f);
  836. DeleteFile:=EatIO;
  837. {$I+}
  838. end;
  839. procedure GiveUpTimeSlice;
  840. {$ifdef GO32V2}{$define DOS}{$endif}
  841. {$ifdef TP}{$define DOS}{$endif}
  842. {$ifdef DOS}
  843. var r: registers;
  844. begin
  845. r.ax:=$1680;
  846. intr($2f,r);
  847. end;
  848. {$endif}
  849. {$ifdef Linux}
  850. begin
  851. end;
  852. {$endif}
  853. {$ifdef Win32}
  854. begin
  855. end;
  856. {$endif}
  857. {$undef DOS}
  858. procedure RegisterWUtils;
  859. begin
  860. {$ifndef NOOBJREG}
  861. RegisterType(RUnsortedStringCollection);
  862. {$endif}
  863. end;
  864. END.
  865. {
  866. $Log$
  867. Revision 1.25 2000-06-22 09:07:15 pierre
  868. * Gabor changes: see fixes.txt
  869. Revision 1.24 2000/06/16 21:16:41 pierre
  870. * allow to read until 255 chars per line
  871. Revision 1.23 2000/06/16 08:50:45 pierre
  872. + new bunch of Gabor's changes
  873. Revision 1.22 2000/05/29 11:09:14 pierre
  874. + New bunch of Gabor's changes: see fixes.txt
  875. Revision 1.21 2000/05/02 08:42:29 pierre
  876. * new set of Gabor changes: see fixes.txt
  877. Revision 1.20 2000/04/25 08:42:36 pierre
  878. * New Gabor changes : see fixes.txt
  879. Revision 1.19 2000/04/18 11:42:39 pierre
  880. lot of Gabor changes : see fixes.txt
  881. Revision 1.18 2000/03/21 23:19:13 pierre
  882. + TrimEndSlash and CompareText by Gabor
  883. Revision 1.17 2000/03/20 19:19:45 pierre
  884. * LFN support in streams
  885. Revision 1.16 2000/03/14 13:36:12 pierre
  886. * error for unexistant file in GetFileTime fixed
  887. Revision 1.15 2000/02/07 11:45:11 pierre
  888. + TUnsortedStringCollection CreateFrom/Assign/GetItem/PutItem from Gabor
  889. Revision 1.14 2000/01/20 00:30:32 pierre
  890. * Result of GetShortPathName is checked
  891. Revision 1.13 2000/01/17 12:20:03 pierre
  892. * uses windows needed for GetShortName
  893. Revision 1.12 2000/01/14 15:36:43 pierre
  894. + GetShortFileName used for tcodeeditor file opening
  895. Revision 1.11 2000/01/05 17:27:20 pierre
  896. + linecomplete arg for ReadlnFromStream
  897. Revision 1.10 2000/01/03 11:38:35 michael
  898. Changes from Gabor
  899. Revision 1.9 1999/12/01 16:19:46 pierre
  900. + GetFileTime moved here
  901. Revision 1.8 1999/10/25 16:39:03 pierre
  902. + GetPChar to avoid nil pointer problems
  903. Revision 1.7 1999/09/13 11:44:00 peter
  904. * fixes from gabor, idle event, html fix
  905. Revision 1.6 1999/08/24 22:01:48 pierre
  906. * readlnfromstream length check added
  907. Revision 1.5 1999/08/03 20:22:45 peter
  908. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  909. + Desktop saving should work now
  910. - History saved
  911. - Clipboard content saved
  912. - Desktop saved
  913. - Symbol info saved
  914. * syntax-highlight bug fixed, which compared special keywords case sensitive
  915. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  916. * with 'whole words only' set, the editor didn't found occourences of the
  917. searched text, if the text appeared previously in the same line, but didn't
  918. satisfied the 'whole-word' condition
  919. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  920. (ie. the beginning of the selection)
  921. * when started typing in a new line, but not at the start (X=0) of it,
  922. the editor inserted the text one character more to left as it should...
  923. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  924. * Shift shouldn't cause so much trouble in TCodeEditor now...
  925. * Syntax highlight had problems recognizing a special symbol if it was
  926. prefixed by another symbol character in the source text
  927. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  928. Revision 1.4 1999/04/07 21:56:06 peter
  929. + object support for browser
  930. * html help fixes
  931. * more desktop saving things
  932. * NODEBUG directive to exclude debugger
  933. Revision 1.2 1999/03/08 14:58:22 peter
  934. + prompt with dialogs for tools
  935. Revision 1.1 1999/03/01 15:51:43 peter
  936. + Log
  937. }