wutils.pas 24 KB

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