wutils.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392
  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. {$ifdef win32}
  18. windows,
  19. {$endif win32}
  20. {$ifdef Unix}
  21. {$ifdef VER1_0}
  22. linux,
  23. {$else}
  24. unix,
  25. {$endif}
  26. {$endif Unix}
  27. Dos,Objects;
  28. const
  29. kbCtrlGrayPlus = $9000;
  30. kbCtrlGrayMinus = $8e00;
  31. kbCtrlGrayMul = $9600;
  32. TempFirstChar = {$ifndef Unix}'~'{$else}'_'{$endif};
  33. TempExt = '.tmp';
  34. TempNameLen = 8;
  35. EOL : String[2] = {$ifdef Unix}#10;{$else}#13#10;{$endif}
  36. type
  37. PByteArray = ^TByteArray;
  38. TByteArray = array[0..MaxBytes] of byte;
  39. PNoDisposeCollection = ^TNoDisposeCollection;
  40. TNoDisposeCollection = object(TCollection)
  41. procedure FreeItem(Item: Pointer); virtual;
  42. end;
  43. PUnsortedStringCollection = ^TUnsortedStringCollection;
  44. TUnsortedStringCollection = object(TCollection)
  45. constructor CreateFrom(ALines: PUnsortedStringCollection);
  46. procedure Assign(ALines: PUnsortedStringCollection);
  47. function At(Index: Integer): PString;
  48. procedure FreeItem(Item: Pointer); virtual;
  49. function GetItem(var S: TStream): Pointer; virtual;
  50. procedure PutItem(var S: TStream; Item: Pointer); virtual;
  51. procedure InsertStr(const S: string);
  52. end;
  53. PNulStream = ^TNulStream;
  54. TNulStream = object(TStream)
  55. constructor Init;
  56. function GetPos: Longint; virtual;
  57. function GetSize: Longint; virtual;
  58. procedure Read(var Buf; Count: Word); virtual;
  59. procedure Seek(Pos: Longint); virtual;
  60. procedure Write(var Buf; Count: Word); virtual;
  61. end;
  62. PSubStream = ^TSubStream;
  63. TSubStream = object(TStream)
  64. constructor Init(AStream: PStream; AStartPos, ASize: longint);
  65. function GetPos: Longint; virtual;
  66. function GetSize: Longint; virtual;
  67. procedure Read(var Buf; Count: Word); virtual;
  68. procedure Seek(Pos: Longint); virtual;
  69. procedure Write(var Buf; Count: Word); virtual;
  70. private
  71. StartPos: longint;
  72. S : PStream;
  73. end;
  74. PFastBufStream = ^TFastBufStream;
  75. TFastBufStream = object(TBufStream)
  76. procedure Seek(Pos: Longint); virtual;
  77. private
  78. BasePos: longint;
  79. end;
  80. PTextCollection = ^TTextCollection;
  81. TTextCollection = object(TStringCollection)
  82. function LookUp(const S: string; var Idx: sw_integer): string;
  83. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  84. end;
  85. PIntCollection = ^TIntCollection;
  86. TIntCollection = object(TSortedCollection)
  87. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  88. procedure FreeItem(Item: Pointer); virtual;
  89. procedure Add(Item: longint);
  90. function Contains(Item: longint): boolean;
  91. function AtInt(Index: sw_integer): longint;
  92. end;
  93. {$ifdef TPUNIXLF}
  94. procedure readln(var t:text;var s:string);
  95. {$endif}
  96. procedure ReadlnFromStream(Stream: PStream; var s:string;var linecomplete,hasCR : boolean);
  97. function eofstream(s: pstream): boolean;
  98. function Min(A,B: longint): longint;
  99. function Max(A,B: longint): longint;
  100. function CharStr(C: char; Count: integer): string;
  101. function UpcaseStr(const S: string): string;
  102. function LowCase(C: char): char;
  103. function LowcaseStr(S: string): string;
  104. function RExpand(const S: string; MinLen: byte): string;
  105. function LExpand(const S: string; MinLen: byte): string;
  106. function LTrim(const S: string): string;
  107. function RTrim(const S: string): string;
  108. function Trim(const S: string): string;
  109. function IntToStr(L: longint): string;
  110. function IntToStrL(L: longint; MinLen: sw_integer): string;
  111. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  112. function StrToInt(const S: string): longint;
  113. function FloatToStr(D: Double; Decimals: byte): string;
  114. function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
  115. function HexToInt(S: string): longint;
  116. function IntToHex(L: longint; MinLen: integer): string;
  117. function GetStr(P: PString): string;
  118. function GetPChar(P: PChar): string;
  119. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  120. function LExtendString(S: string; MinLen: byte): string;
  121. function DirOf(const S: string): string;
  122. function ExtOf(const S: string): string;
  123. function NameOf(const S: string): string;
  124. function NameAndExtOf(const S: string): string;
  125. function DirAndNameOf(const S: string): string;
  126. { return Dos GetFTime value or -1 if the file does not exist }
  127. function GetFileTime(const FileName: string): longint;
  128. { copied from compiler global unit }
  129. function GetShortName(const n:string):string;
  130. function GetLongName(const n:string):string;
  131. function TrimEndSlash(const Path: string): string;
  132. function CompleteDir(const Path: string): string;
  133. function GetCurDir: string;
  134. function OptimizePath(Path: string; MaxLen: integer): string;
  135. function CompareText(S1, S2: string): integer;
  136. function ExistsDir(const DirName: string): boolean;
  137. function ExistsFile(const FileName: string): boolean;
  138. function DeleteFile(const FileName: string): integer;
  139. function CopyFile(const SrcFileName, DestFileName: string): boolean;
  140. function GenTempFileName: string;
  141. function FormatPath(Path: string): string;
  142. function CompletePath(const Base, InComplete: string): string;
  143. function CompleteURL(const Base, URLRef: string): string;
  144. function EatIO: integer;
  145. function Now: longint;
  146. function FormatDateTimeL(L: longint; const Format: string): string;
  147. function FormatDateTime(const D: DateTime; const Format: string): string;
  148. {$ifdef TP}
  149. function StrPas(C: PChar): string;
  150. {$endif}
  151. function MemToStr(var B; Count: byte): string;
  152. procedure StrToMem(S: string; var B);
  153. procedure GiveUpTimeSlice;
  154. const LastStrToIntResult : integer = 0;
  155. LastHexToIntResult : integer = 0;
  156. DirSep : char = {$ifdef Unix}'/'{$else}'\'{$endif};
  157. procedure RegisterWUtils;
  158. implementation
  159. uses
  160. {$IFDEF OS2}
  161. DosCalls,
  162. {$ENDIF OS2}
  163. Strings;
  164. {$ifndef NOOBJREG}
  165. const
  166. SpaceStr = ' '+
  167. ' '+
  168. ' '+
  169. ' ' ;
  170. RUnsortedStringCollection: TStreamRec = (
  171. ObjType: 22500;
  172. VmtLink: Ofs(TypeOf(TUnsortedStringCollection)^);
  173. Load: @TUnsortedStringCollection.Load;
  174. Store: @TUnsortedStringCollection.Store
  175. );
  176. {$endif}
  177. {$ifdef TPUNIXLF}
  178. procedure readln(var t:text;var s:string);
  179. var
  180. c : char;
  181. i : longint;
  182. begin
  183. if TextRec(t).UserData[1]=2 then
  184. system.readln(t,s)
  185. else
  186. begin
  187. c:=#0;
  188. i:=0;
  189. while (not eof(t)) and (c<>#10) and (i<High(S)) do
  190. begin
  191. read(t,c);
  192. if c<>#10 then
  193. begin
  194. inc(i);
  195. s[i]:=c;
  196. end;
  197. end;
  198. if (i>0) and (s[i]=#13) then
  199. begin
  200. dec(i);
  201. TextRec(t).UserData[1]:=2;
  202. end;
  203. s[0]:=chr(i);
  204. end;
  205. end;
  206. {$endif}
  207. function eofstream(s: pstream): boolean;
  208. begin
  209. eofstream:=(s^.getpos>=s^.getsize);
  210. end;
  211. procedure ReadlnFromStream(Stream: PStream; var S:string;var linecomplete,hasCR : boolean);
  212. var
  213. c : char;
  214. i,pos : longint;
  215. begin
  216. linecomplete:=false;
  217. c:=#0;
  218. i:=0;
  219. { this created problems for lines longer than 255 characters
  220. now those lines are cutted into pieces without warning PM }
  221. { changed implicit 255 to High(S), so it will be automatically extended
  222. when longstrings eventually become default - Gabor }
  223. while (not eofstream(stream)) and (c<>#10) and (i<High(S)) do
  224. begin
  225. stream^.read(c,sizeof(c));
  226. if c<>#10 then
  227. begin
  228. inc(i);
  229. s[i]:=c;
  230. end;
  231. end;
  232. { if there was a CR LF then remove the CR Dos newline style }
  233. if (i>0) and (s[i]=#13) then
  234. begin
  235. dec(i);
  236. end;
  237. if (c=#13) and (not eofstream(stream)) then
  238. stream^.read(c,sizeof(c));
  239. if (i=High(S)) and not eofstream(stream) then
  240. begin
  241. pos:=stream^.getpos;
  242. stream^.read(c,sizeof(c));
  243. if (c=#13) and not eofstream(stream) then
  244. stream^.read(c,sizeof(c));
  245. if c<>#10 then
  246. stream^.seek(pos);
  247. end;
  248. if (c=#10) or eofstream(stream) then
  249. linecomplete:=true;
  250. if (c=#10) then
  251. hasCR:=true;
  252. s[0]:=chr(i);
  253. end;
  254. {$ifdef TP}
  255. { TP's own StrPas() is buggy, because it causes GPF with strings longer than
  256. 255 chars }
  257. function StrPas(C: PChar): string;
  258. var S: string;
  259. I: longint;
  260. begin
  261. if Assigned(C)=false then
  262. S:=''
  263. else
  264. begin
  265. I:=StrLen(C); if I>High(S) then I:=High(S);
  266. S[0]:=chr(I); Move(C^,S[1],I);
  267. end;
  268. StrPas:=S;
  269. end;
  270. {$endif}
  271. function MemToStr(var B; Count: byte): string;
  272. var S: string;
  273. begin
  274. S[0]:=chr(Count);
  275. if Count>0 then Move(B,S[1],Count);
  276. MemToStr:=S;
  277. end;
  278. procedure StrToMem(S: string; var B);
  279. begin
  280. if length(S)>0 then Move(S[1],B,length(S));
  281. end;
  282. function Max(A,B: longint): longint;
  283. begin
  284. if A>B then Max:=A else Max:=B;
  285. end;
  286. function Min(A,B: longint): longint;
  287. begin
  288. if A<B then Min:=A else Min:=B;
  289. end;
  290. function CharStr(C: char; Count: integer): string;
  291. {$ifndef FPC}
  292. var S: string;
  293. {$endif}
  294. begin
  295. {$ifdef FPC}
  296. CharStr[0]:=chr(Count);
  297. FillChar(CharStr[1],Count,C);
  298. {$else}
  299. S[0]:=chr(Count);
  300. FillChar(S[1],Count,C);
  301. CharStr:=S;
  302. {$endif}
  303. end;
  304. function UpcaseStr(const S: string): string;
  305. var
  306. I: Longint;
  307. begin
  308. for I:=1 to length(S) do
  309. if S[I] in ['a'..'z'] then
  310. UpCaseStr[I]:=chr(ord(S[I])-32)
  311. else
  312. UpCaseStr[I]:=S[I];
  313. UpcaseStr[0]:=S[0];
  314. end;
  315. function RExpand(const S: string; MinLen: byte): string;
  316. begin
  317. if length(S)<MinLen then
  318. RExpand:=S+CharStr(' ',MinLen-length(S))
  319. else
  320. RExpand:=S;
  321. end;
  322. function LExpand(const S: string; MinLen: byte): string;
  323. begin
  324. if length(S)<MinLen then
  325. LExpand:=CharStr(' ',MinLen-length(S))+S
  326. else
  327. LExpand:=S;
  328. end;
  329. function LTrim(const S: string): string;
  330. var
  331. i : longint;
  332. begin
  333. i:=1;
  334. while (i<length(s)) and (s[i]=' ') do
  335. inc(i);
  336. LTrim:=Copy(s,i,High(S));
  337. end;
  338. function RTrim(const S: string): string;
  339. var
  340. i : longint;
  341. begin
  342. i:=length(s);
  343. while (i>0) and (s[i]=' ') do
  344. dec(i);
  345. RTrim:=Copy(s,1,i);
  346. end;
  347. function Trim(const S: string): string;
  348. var
  349. i,j : longint;
  350. begin
  351. i:=1;
  352. while (i<length(s)) and (s[i]=' ') do
  353. inc(i);
  354. j:=length(s);
  355. while (j>0) and (s[j]=' ') do
  356. dec(j);
  357. Trim:=Copy(S,i,j-i+1);
  358. end;
  359. function IntToStr(L: longint): string;
  360. var S: string;
  361. begin
  362. Str(L,S);
  363. IntToStr:=S;
  364. end;
  365. function IntToStrL(L: longint; MinLen: sw_integer): string;
  366. begin
  367. IntToStrL:=LExpand(IntToStr(L),MinLen);
  368. end;
  369. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  370. var S: string;
  371. begin
  372. S:=IntToStr(L);
  373. if length(S)<MinLen then
  374. S:=CharStr('0',MinLen-length(S))+S;
  375. IntToStrZ:=S;
  376. end;
  377. function StrToInt(const S: string): longint;
  378. var L: longint;
  379. C: integer;
  380. begin
  381. Val(S,L,C); if C<>0 then L:=-1;
  382. LastStrToIntResult:=C;
  383. StrToInt:=L;
  384. end;
  385. function HexToInt(S: string): longint;
  386. var L,I: longint;
  387. C: char;
  388. const HexNums: string[16] = '0123456789ABCDEF';
  389. begin
  390. S:=Trim(S); L:=0; I:=1; LastHexToIntResult:=0;
  391. while (I<=length(S)) and (LastHexToIntResult=0) do
  392. begin
  393. C:=Upcase(S[I]);
  394. if C in['0'..'9','A'..'F'] then
  395. begin
  396. L:=L*16+(Pos(C,HexNums)-1);
  397. end else LastHexToIntResult:=I;
  398. Inc(I);
  399. end;
  400. HexToInt:=L;
  401. end;
  402. function IntToHex(L: longint; MinLen: integer): string;
  403. const HexNums : string[16] = '0123456789ABCDEF';
  404. var S: string;
  405. R: real;
  406. function DivF(Mit,Mivel: real): longint;
  407. begin
  408. DivF:=trunc(Mit/Mivel);
  409. end;
  410. function ModF(Mit,Mivel: real): longint;
  411. begin
  412. ModF:=trunc(Mit-DivF(Mit,Mivel)*Mivel);
  413. end;
  414. begin
  415. S:='';
  416. R:=L; if R<0 then begin R:=R+2147483647+2147483647+2; end;
  417. repeat
  418. Insert(HexNums[ModF(R,16)+1],S,1);
  419. R:=DivF(R,16);
  420. until R=0;
  421. while length(S)<MinLen do
  422. Insert('0',S,1);
  423. IntToHex:=S;
  424. end;
  425. function FloatToStr(D: Double; Decimals: byte): string;
  426. var S: string;
  427. L: byte;
  428. begin
  429. Str(D:0:Decimals,S);
  430. if length(S)>0 then
  431. while (S[1]=' ') do Delete(S,1,1);
  432. FloatToStr:=S;
  433. end;
  434. function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
  435. begin
  436. FloatToStrL:=LExtendString(FloatToStr(D,Decimals),MinLen);
  437. end;
  438. function LExtendString(S: string; MinLen: byte): string;
  439. begin
  440. LExtendString:=copy(SpaceStr,1,MinLen-length(S))+S;
  441. end;
  442. function GetStr(P: PString): string;
  443. begin
  444. if P=nil then GetStr:='' else GetStr:=P^;
  445. end;
  446. function GetPChar(P: PChar): string;
  447. begin
  448. if P=nil then GetPChar:='' else GetPChar:=StrPas(P);
  449. end;
  450. function DirOf(const S: string): string;
  451. var D: DirStr; E: ExtStr; N: NameStr;
  452. begin
  453. FSplit(S,D,N,E);
  454. if (D<>'') and (D[Length(D)]<>DirSep) then
  455. DirOf:=D+DirSep
  456. else
  457. DirOf:=D;
  458. end;
  459. function ExtOf(const S: string): string;
  460. var D: DirStr; E: ExtStr; N: NameStr;
  461. begin
  462. FSplit(S,D,N,E);
  463. ExtOf:=E;
  464. end;
  465. function NameOf(const S: string): string;
  466. var D: DirStr; E: ExtStr; N: NameStr;
  467. begin
  468. FSplit(S,D,N,E);
  469. NameOf:=N;
  470. end;
  471. function NameAndExtOf(const S: string): string;
  472. var D: DirStr; E: ExtStr; N: NameStr;
  473. begin
  474. FSplit(S,D,N,E);
  475. NameAndExtOf:=N+E;
  476. end;
  477. function DirAndNameOf(const S: string): string;
  478. var D: DirStr; E: ExtStr; N: NameStr;
  479. begin
  480. FSplit(S,D,N,E);
  481. DirAndNameOf:=D+N;
  482. end;
  483. { return Dos GetFTime value or -1 if the file does not exist }
  484. function GetFileTime(const FileName: string): longint;
  485. var T: longint;
  486. f: file;
  487. FM: integer;
  488. begin
  489. if FileName='' then
  490. T:=-1
  491. else
  492. begin
  493. FM:=FileMode; FileMode:=0;
  494. EatIO; Dos.DosError:=0;
  495. Assign(f,FileName);
  496. {$I-}
  497. Reset(f);
  498. if InOutRes=0 then
  499. begin
  500. GetFTime(f,T);
  501. Close(f);
  502. end;
  503. {$I+}
  504. if (EatIO<>0) or (Dos.DosError<>0) then T:=-1;
  505. FileMode:=FM;
  506. end;
  507. GetFileTime:=T;
  508. end;
  509. function GetShortName(const n:string):string;
  510. {$ifdef win32}
  511. var
  512. hs,hs2 : string;
  513. i : longint;
  514. {$endif}
  515. {$ifdef go32v2}
  516. var
  517. hs : string;
  518. {$endif}
  519. begin
  520. GetShortName:=n;
  521. {$ifdef win32}
  522. hs:=n+#0;
  523. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  524. if (i>0) and (i<=high(hs2)) then
  525. begin
  526. hs2[0]:=chr(strlen(@hs2[1]));
  527. GetShortName:=hs2;
  528. end;
  529. {$endif}
  530. {$ifdef go32v2}
  531. hs:=n;
  532. if Dos.GetShortName(hs) then
  533. GetShortName:=hs;
  534. {$endif}
  535. end;
  536. function GetLongName(const n:string):string;
  537. {$ifdef win32}
  538. var
  539. hs : string;
  540. hs2 : Array [0..255] of char;
  541. i : longint;
  542. j : pchar;
  543. {$endif}
  544. {$ifdef go32v2}
  545. var
  546. hs : string;
  547. {$endif}
  548. begin
  549. GetLongName:=n;
  550. {$ifdef win32}
  551. hs:=n+#0;
  552. i:=Windows.GetFullPathName(@hs[1],256,hs2,j);
  553. if (i>0) and (i<=high(hs)) then
  554. begin
  555. hs:=strpas(hs2);
  556. GetLongName:=hs;
  557. end;
  558. {$endif}
  559. {$ifdef go32v2}
  560. hs:=n;
  561. if Dos.GetLongName(hs) then
  562. GetLongName:=hs;
  563. {$endif}
  564. end;
  565. function EatIO: integer;
  566. begin
  567. EatIO:=IOResult;
  568. end;
  569. function LowCase(C: char): char;
  570. begin
  571. if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
  572. LowCase:=C;
  573. end;
  574. function LowcaseStr(S: string): string;
  575. var I: Longint;
  576. begin
  577. for I:=1 to length(S) do
  578. S[I]:=Lowcase(S[I]);
  579. LowcaseStr:=S;
  580. end;
  581. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  582. begin
  583. if B then BoolToStr:=TrueS else BoolToStr:=FalseS;
  584. end;
  585. procedure TNoDisposeCollection.FreeItem(Item: Pointer);
  586. begin
  587. { don't do anything here }
  588. end;
  589. constructor TUnsortedStringCollection.CreateFrom(ALines: PUnsortedStringCollection);
  590. begin
  591. if Assigned(ALines)=false then Fail;
  592. inherited Init(ALines^.Count,ALines^.Count div 10);
  593. Assign(ALines);
  594. end;
  595. procedure TUnsortedStringCollection.Assign(ALines: PUnsortedStringCollection);
  596. procedure AddIt(P: PString); {$ifndef FPC}far;{$endif}
  597. begin
  598. Insert(NewStr(GetStr(P)));
  599. end;
  600. begin
  601. FreeAll;
  602. if Assigned(ALines) then
  603. ALines^.ForEach(@AddIt);
  604. end;
  605. procedure TUnsortedStringCollection.InsertStr(const S: string);
  606. begin
  607. Insert(NewStr(S));
  608. end;
  609. function TUnsortedStringCollection.At(Index: Integer): PString;
  610. begin
  611. At:=inherited At(Index);
  612. end;
  613. procedure TUnsortedStringCollection.FreeItem(Item: Pointer);
  614. begin
  615. if Item<>nil then DisposeStr(Item);
  616. end;
  617. function TUnsortedStringCollection.GetItem(var S: TStream): Pointer;
  618. begin
  619. GetItem:=S.ReadStr;
  620. end;
  621. procedure TUnsortedStringCollection.PutItem(var S: TStream; Item: Pointer);
  622. begin
  623. S.WriteStr(Item);
  624. end;
  625. function TIntCollection.Contains(Item: longint): boolean;
  626. var Index: sw_integer;
  627. begin
  628. Contains:=Search(pointer(Item),Index);
  629. end;
  630. function TIntCollection.AtInt(Index: sw_integer): longint;
  631. begin
  632. AtInt:=longint(At(Index));
  633. end;
  634. procedure TIntCollection.Add(Item: longint);
  635. begin
  636. Insert(pointer(Item));
  637. end;
  638. function TIntCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  639. var K1: longint absolute Key1;
  640. K2: longint absolute Key2;
  641. R: integer;
  642. begin
  643. if K1<K2 then R:=-1 else
  644. if K1>K2 then R:= 1 else
  645. R:=0;
  646. Compare:=R;
  647. end;
  648. procedure TIntCollection.FreeItem(Item: Pointer);
  649. begin
  650. { do nothing here }
  651. end;
  652. constructor TNulStream.Init;
  653. begin
  654. inherited Init;
  655. Position:=0;
  656. end;
  657. function TNulStream.GetPos: Longint;
  658. begin
  659. GetPos:=Position;
  660. end;
  661. function TNulStream.GetSize: Longint;
  662. begin
  663. GetSize:=Position;
  664. end;
  665. procedure TNulStream.Read(var Buf; Count: Word);
  666. begin
  667. Error(stReadError,0);
  668. end;
  669. procedure TNulStream.Seek(Pos: Longint);
  670. begin
  671. if Pos<=Position then
  672. Position:=Pos;
  673. end;
  674. procedure TNulStream.Write(var Buf; Count: Word);
  675. begin
  676. Inc(Position,Count);
  677. end;
  678. constructor TSubStream.Init(AStream: PStream; AStartPos, ASize: longint);
  679. begin
  680. inherited Init;
  681. if Assigned(AStream)=false then Fail;
  682. S:=AStream; StartPos:=AStartPos; StreamSize:=ASize;
  683. Seek(0);
  684. end;
  685. function TSubStream.GetPos: Longint;
  686. var Pos: longint;
  687. begin
  688. Pos:=S^.GetPos; Dec(Pos,StartPos);
  689. GetPos:=Pos;
  690. end;
  691. function TSubStream.GetSize: Longint;
  692. begin
  693. GetSize:=StreamSize;
  694. end;
  695. procedure TSubStream.Read(var Buf; Count: Word);
  696. var Pos: longint;
  697. RCount: word;
  698. begin
  699. Pos:=GetPos;
  700. if Pos+Count>StreamSize then RCount:=StreamSize-Pos else RCount:=Count;
  701. S^.Read(Buf,RCount);
  702. if RCount<Count then
  703. Error(stReadError,0);
  704. end;
  705. procedure TSubStream.Seek(Pos: Longint);
  706. var RPos: longint;
  707. begin
  708. if (Pos<=StreamSize) then RPos:=Pos else RPos:=StreamSize;
  709. S^.Seek(StartPos+RPos);
  710. end;
  711. procedure TSubStream.Write(var Buf; Count: Word);
  712. begin
  713. S^.Write(Buf,Count);
  714. end;
  715. procedure TFastBufStream.Seek(Pos: Longint);
  716. function BufStartPos: longint;
  717. begin
  718. BufStartPos:=Position-BufPtr;
  719. end;
  720. var RelOfs: longint;
  721. begin
  722. RelOfs:=Pos-{BufStartPos}BasePos;
  723. if (RelOfs<0) or (RelOfs>=BufEnd) or (BufEnd=0) then
  724. begin
  725. inherited Seek(Pos);
  726. BasePos:=Pos-BufPtr;
  727. end
  728. else
  729. begin
  730. BufPtr:=RelOfs;
  731. Position:=Pos;
  732. end;
  733. end;
  734. function TTextCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  735. var K1: PString absolute Key1;
  736. K2: PString absolute Key2;
  737. R: Sw_integer;
  738. S1,S2: string;
  739. begin
  740. S1:=UpCaseStr(K1^);
  741. S2:=UpCaseStr(K2^);
  742. if S1<S2 then R:=-1 else
  743. if S1>S2 then R:=1 else
  744. R:=0;
  745. Compare:=R;
  746. end;
  747. function TTextCollection.LookUp(const S: string; var Idx: sw_integer): string;
  748. var OLI,ORI,Left,Right,Mid: integer;
  749. {LeftP,RightP,}MidP: PString;
  750. {LeftS,}MidS{,RightS}: string;
  751. FoundS: string;
  752. UpS : string;
  753. begin
  754. Idx:=-1; FoundS:='';
  755. Left:=0; Right:=Count-1;
  756. UpS:=UpCaseStr(S);
  757. while Left<=Right do
  758. begin
  759. OLI:=Left; ORI:=Right;
  760. Mid:=Left+(Right-Left) div 2;
  761. MidP:=At(Mid);
  762. MidS:=UpCaseStr(MidP^);
  763. if copy(MidS,1,length(UpS))=UpS then
  764. begin
  765. Idx:=Mid; FoundS:=GetStr(MidP);
  766. end;
  767. if UpS<MidS then
  768. Right:=Mid
  769. else
  770. Left:=Mid;
  771. if (OLI=Left) and (ORI=Right) then
  772. begin
  773. if (Left<Right) then
  774. Left:=Right
  775. else
  776. Break;
  777. end;
  778. end;
  779. LookUp:=FoundS;
  780. end;
  781. function TrimEndSlash(const Path: string): string;
  782. var S: string;
  783. begin
  784. S:=Path;
  785. if (length(S)>0) and (S<>DirSep) and (copy(S,length(S),1)=DirSep) and
  786. (S[length(S)-1]<>':') then
  787. S:=copy(S,1,length(S)-1);
  788. TrimEndSlash:=S;
  789. end;
  790. function CompareText(S1, S2: string): integer;
  791. var R: integer;
  792. begin
  793. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  794. if S1<S2 then R:=-1 else
  795. if S1>S2 then R:= 1 else
  796. R:=0;
  797. CompareText:=R;
  798. end;
  799. function FormatPath(Path: string): string;
  800. var P: sw_integer;
  801. SC: char;
  802. begin
  803. if ord(DirSep)=ord('/') then
  804. SC:='\'
  805. else
  806. SC:='/';
  807. repeat
  808. P:=Pos(SC,Path);
  809. if P>0 then Path[P]:=DirSep;
  810. until P=0;
  811. FormatPath:=Path;
  812. end;
  813. function CompletePath(const Base, InComplete: string): string;
  814. var Drv,BDrv: string[40]; D,BD: DirStr; N,BN: NameStr; E,BE: ExtStr;
  815. P: sw_integer;
  816. Complete: string;
  817. begin
  818. Complete:=FormatPath(InComplete);
  819. FSplit(FormatPath(InComplete),D,N,E);
  820. P:=Pos(':',D); if P=0 then Drv:='' else begin Drv:=copy(D,1,P); Delete(D,1,P); end;
  821. FSplit(FormatPath(Base),BD,BN,BE);
  822. P:=Pos(':',BD); if P=0 then BDrv:='' else begin BDrv:=copy(BD,1,P); Delete(BD,1,P); end;
  823. if copy(D,1,1)<>DirSep then
  824. Complete:=BD+D+N+E;
  825. if Drv='' then
  826. Complete:=BDrv+Complete;
  827. Complete:=FExpand(Complete);
  828. CompletePath:=Complete;
  829. end;
  830. function CompleteURL(const Base, URLRef: string): string;
  831. var P: integer;
  832. Drive: string[20];
  833. IsComplete: boolean;
  834. S: string;
  835. Ref: string;
  836. Bookmark: string;
  837. begin
  838. IsComplete:=false; Ref:=URLRef;
  839. P:=Pos(':',Ref);
  840. if P=0 then Drive:='' else Drive:=UpcaseStr(copy(Ref,1,P-1));
  841. if Drive<>'' then
  842. if (Drive='MAILTO') or (Drive='FTP') or (Drive='HTTP') or
  843. (Drive='GOPHER') or (Drive='FILE') then
  844. IsComplete:=true;
  845. if IsComplete then S:=Ref else
  846. begin
  847. P:=Pos('#',Ref);
  848. if P=0 then
  849. Bookmark:=''
  850. else
  851. begin
  852. Bookmark:=copy(Ref,P+1,length(Ref));
  853. Ref:=copy(Ref,1,P-1);
  854. end;
  855. S:=CompletePath(Base,Ref);
  856. if Bookmark<>'' then
  857. S:=S+'#'+Bookmark;
  858. end;
  859. CompleteURL:=S;
  860. end;
  861. function OptimizePath(Path: string; MaxLen: integer): string;
  862. var i : integer;
  863. BackSlashs : array[1..20] of integer;
  864. BSCount : integer;
  865. Jobbra : boolean;
  866. Jobb, Bal : byte;
  867. Hiba : boolean;
  868. begin
  869. if length(Path)>MaxLen then
  870. begin
  871. BSCount:=0; Jobbra:=true;
  872. for i:=1 to length(Path) do if Path[i]=DirSep then
  873. begin
  874. Inc(BSCount);
  875. BackSlashs[BSCount]:=i;
  876. end;
  877. i:=BSCount div 2;
  878. Hiba:=false;
  879. Bal:=i; Jobb:=i+1;
  880. case i of 0 : ;
  881. 1 : Path:=copy(Path, 1, BackSlashs[1])+'..'+
  882. copy(Path, BackSlashs[2], length(Path));
  883. else begin
  884. while (BackSlashs[Bal]+(length(Path)-BackSlashs[Jobb]) >=
  885. MaxLen) and not Hiba do
  886. begin
  887. if Jobbra then begin
  888. if Jobb<BSCount then inc(Jobb)
  889. else Hiba:=true;
  890. Jobbra:=false;
  891. end
  892. else begin
  893. if Bal>1 then dec(Bal)
  894. else Hiba:=true;
  895. Jobbra:=true;
  896. end;
  897. end;
  898. Path:=copy(Path, 1, BackSlashs[Bal])+'..'+
  899. copy(Path, BackSlashs[Jobb], length(Path));
  900. end;
  901. end;
  902. end;
  903. if length(Path)>MaxLen then
  904. begin
  905. i:=Pos('\..\',Path);
  906. if i>0 then Path:=copy(Path,1,i-1)+'..'+copy(Path,i+length('\..\'),length(Path));
  907. end;
  908. OptimizePath:=Path;
  909. end;
  910. function Now: longint;
  911. var D: DateTime;
  912. W: word;
  913. L: longint;
  914. begin
  915. FillChar(D,sizeof(D),0);
  916. GetDate(D.Year,D.Month,D.Day,W);
  917. GetTime(D.Hour,D.Min,D.Sec,W);
  918. PackTime(D,L);
  919. Now:=L;
  920. end;
  921. function FormatDateTimeL(L: longint; const Format: string): string;
  922. var D: DateTime;
  923. begin
  924. UnpackTime(L,D);
  925. FormatDateTimeL:=FormatDateTime(D,Format);
  926. end;
  927. function FormatDateTime(const D: DateTime; const Format: string): string;
  928. var I: sw_integer;
  929. CurCharStart: sw_integer;
  930. CurChar: char;
  931. CurCharCount: integer;
  932. DateS: string;
  933. C: char;
  934. procedure FlushChars;
  935. var S: string;
  936. I: sw_integer;
  937. begin
  938. S:='';
  939. for I:=1 to CurCharCount do
  940. S:=S+CurChar;
  941. case CurChar of
  942. 'y' : S:=IntToStrL(D.Year,length(S));
  943. 'm' : S:=IntToStrZ(D.Month,length(S));
  944. 'd' : S:=IntToStrZ(D.Day,length(S));
  945. 'h' : S:=IntToStrZ(D.Hour,length(S));
  946. 'n' : S:=IntToStrZ(D.Min,length(S));
  947. 's' : S:=IntToStrZ(D.Sec,length(S));
  948. end;
  949. DateS:=DateS+S;
  950. end;
  951. begin
  952. DateS:='';
  953. CurCharStart:=-1; CurCharCount:=0; CurChar:=#0;
  954. for I:=1 to length(Format) do
  955. begin
  956. C:=Format[I];
  957. if (C<>CurChar) or (CurCharStart=-1) then
  958. begin
  959. if CurCharStart<>-1 then FlushChars;
  960. CurCharCount:=1; CurCharStart:=I;
  961. end
  962. else
  963. Inc(CurCharCount);
  964. CurChar:=C;
  965. end;
  966. FlushChars;
  967. FormatDateTime:=DateS;
  968. end;
  969. function DeleteFile(const FileName: string): integer;
  970. var f: file;
  971. begin
  972. {$I-}
  973. Assign(f,FileName);
  974. Erase(f);
  975. DeleteFile:=EatIO;
  976. {$I+}
  977. end;
  978. function ExistsFile(const FileName: string): boolean;
  979. var
  980. Dir : SearchRec;
  981. begin
  982. Dos.FindFirst(FileName,Archive+ReadOnly,Dir);
  983. ExistsFile:=(Dos.DosError=0);
  984. {$ifdef FPC}
  985. Dos.FindClose(Dir);
  986. {$endif def FPC}
  987. end;
  988. function ExistsDir(const DirName: string): boolean;
  989. var
  990. Dir : SearchRec;
  991. begin
  992. Dos.FindFirst(TrimEndSlash(DirName),Directory,Dir);
  993. { if a file is found it is also reported
  994. at least for some Dos version
  995. so we need to check the attributes PM }
  996. ExistsDir:=(Dos.DosError=0) and ((Dir.attr and Directory) <> 0);
  997. {$ifdef FPC}
  998. Dos.FindClose(Dir);
  999. {$endif def FPC}
  1000. end;
  1001. function CompleteDir(const Path: string): string;
  1002. begin
  1003. { keep c: untouched PM }
  1004. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  1005. (Path[Length(Path)]<>':') then
  1006. CompleteDir:=Path+DirSep
  1007. else
  1008. CompleteDir:=Path;
  1009. end;
  1010. function GetCurDir: string;
  1011. var S: string;
  1012. begin
  1013. GetDir(0,S);
  1014. if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
  1015. GetCurDir:=S;
  1016. end;
  1017. function GenTempFileName: string;
  1018. var Dir: string;
  1019. Name: string;
  1020. I: integer;
  1021. OK: boolean;
  1022. Path: string;
  1023. begin
  1024. Dir:=GetEnv('TEMP');
  1025. if Dir='' then Dir:=GetEnv('TMP');
  1026. if (Dir<>'') then if not ExistsDir(Dir) then Dir:='';
  1027. if Dir='' then Dir:=GetCurDir;
  1028. repeat
  1029. Name:=TempFirstChar;
  1030. for I:=2 to TempNameLen do
  1031. Name:=Name+chr(ord('a')+random(ord('z')-ord('a')+1));
  1032. Name:=Name+TempExt;
  1033. Path:=CompleteDir(Dir)+Name;
  1034. OK:=not ExistsFile(Path);
  1035. until OK;
  1036. GenTempFileName:=Path;
  1037. end;
  1038. function CopyFile(const SrcFileName, DestFileName: string): boolean;
  1039. var SrcF,DestF: PBufStream;
  1040. OK: boolean;
  1041. begin
  1042. SrcF:=nil; DestF:=nil;
  1043. New(SrcF, Init(SrcFileName,stOpenRead,4096));
  1044. OK:=Assigned(SrcF) and (SrcF^.Status=stOK);
  1045. if OK then
  1046. begin
  1047. New(DestF, Init(DestFileName,stCreate,1024));
  1048. OK:=Assigned(DestF) and (DestF^.Status=stOK);
  1049. end;
  1050. if OK then DestF^.CopyFrom(SrcF^,SrcF^.GetSize);
  1051. if Assigned(DestF) then Dispose(DestF, Done);
  1052. if Assigned(SrcF) then Dispose(SrcF, Done);
  1053. CopyFile:=OK;
  1054. end;
  1055. procedure GiveUpTimeSlice;
  1056. {$ifdef GO32V2}{$define DOS}{$endif}
  1057. {$ifdef TP}{$define DOS}{$endif}
  1058. {$ifdef DOS}
  1059. var r: registers;
  1060. begin
  1061. r.ax:=$1680;
  1062. intr($2f,r);
  1063. end;
  1064. {$endif}
  1065. {$ifdef Unix}
  1066. var
  1067. req,rem : timespec;
  1068. begin
  1069. req.tv_sec:=0;
  1070. req.tv_nsec:=10000000;{ 10 ms }
  1071. nanosleep(req,rem);
  1072. end;
  1073. {$endif}
  1074. {$IFDEF OS2}
  1075. begin
  1076. DosSleep (5);
  1077. end;
  1078. {$ENDIF}
  1079. {$ifdef Win32}
  1080. begin
  1081. { if the return value of this call is non zero then
  1082. it means that a ReadFileEx or WriteFileEx have completed
  1083. unused for now ! }
  1084. { wait for 10 ms }
  1085. if SleepEx(10,true)=WAIT_IO_COMPLETION then
  1086. begin
  1087. { here we should handle the completion of the routines
  1088. if we use them }
  1089. end;
  1090. end;
  1091. {$endif}
  1092. {$undef DOS}
  1093. procedure RegisterWUtils;
  1094. begin
  1095. {$ifndef NOOBJREG}
  1096. RegisterType(RUnsortedStringCollection);
  1097. {$endif}
  1098. end;
  1099. BEGIN
  1100. Randomize;
  1101. END.
  1102. {
  1103. $Log$
  1104. Revision 1.3 2001-08-12 00:04:50 pierre
  1105. * some speed improvements for string operations
  1106. Revision 1.2 2001/08/05 02:01:49 peter
  1107. * FVISION define to compile with fvision units
  1108. Revision 1.1 2001/08/04 11:30:26 peter
  1109. * ide works now with both compiler versions
  1110. Revision 1.1.2.14 2001/06/20 22:56:31 pierre
  1111. * check that the Dir in ExistsDir is really a directory and not a file
  1112. Revision 1.1.2.13 2001/02/05 14:45:42 pierre
  1113. * fix for bug 1370
  1114. Revision 1.1.2.12 2000/11/29 18:28:54 pierre
  1115. + add save to file capability for list boxes
  1116. Revision 1.1.2.11 2000/11/27 12:06:52 pierre
  1117. New bunch of Gabor fixes
  1118. Revision 1.1.2.10 2000/11/14 09:08:51 marco
  1119. * First batch IDE renamefest
  1120. Revision 1.1.2.9 2000/11/13 16:59:10 pierre
  1121. * some function in double removed from fputils unit
  1122. Revision 1.1.2.8 2000/11/12 19:50:36 hajny
  1123. * OS/2 changes from the main branch merged
  1124. Revision 1.1.2.7 2000/11/06 17:19:58 pierre
  1125. * avoid eating of last carriage return
  1126. Revision 1.1.2.6 2000/10/24 12:31:40 pierre
  1127. * fix the last commit for linux
  1128. Revision 1.1.2.5 2000/10/24 12:24:03 pierre
  1129. + GiveUpTimeSlice for linux and win32
  1130. Revision 1.1.2.4 2000/09/18 13:20:56 pierre
  1131. New bunch of Gabor changes
  1132. Revision 1.2 2000/08/22 09:41:42 pierre
  1133. * first big merge from fixes branch
  1134. Revision 1.1.2.3 2000/08/20 15:00:23 peter
  1135. * windows fix
  1136. Revision 1.1.2.2 2000/08/16 18:46:15 peter
  1137. [*] double clicking on a droplistbox caused GPF (due to invalid recurson)
  1138. [*] Make, Build now possible even in Compiler Messages Window
  1139. [+] when started in a new dir the IDE now ask whether to create a local
  1140. config, or to use the one located in the IDE dir
  1141. Revision 1.1.2.1 2000/07/20 11:02:16 michael
  1142. + Fixes from gabor. See fixes.txt
  1143. Revision 1.1 2000/07/13 09:48:37 michael
  1144. + Initial import
  1145. Revision 1.27 2000/07/03 08:54:54 pierre
  1146. * Some enhancements for WinHelp support by G abor
  1147. Revision 1.26 2000/06/26 07:29:23 pierre
  1148. * new bunch of Gabor's changes
  1149. Revision 1.25 2000/06/22 09:07:15 pierre
  1150. * Gabor changes: see fixes.txt
  1151. Revision 1.24 2000/06/16 21:16:41 pierre
  1152. * allow to read until 255 chars per line
  1153. Revision 1.23 2000/06/16 08:50:45 pierre
  1154. + new bunch of Gabor's changes
  1155. Revision 1.22 2000/05/29 11:09:14 pierre
  1156. + New bunch of Gabor's changes: see fixes.txt
  1157. Revision 1.21 2000/05/02 08:42:29 pierre
  1158. * new set of Gabor changes: see fixes.txt
  1159. Revision 1.20 2000/04/25 08:42:36 pierre
  1160. * New Gabor changes : see fixes.txt
  1161. Revision 1.19 2000/04/18 11:42:39 pierre
  1162. lot of Gabor changes : see fixes.txt
  1163. Revision 1.18 2000/03/21 23:19:13 pierre
  1164. + TrimEndSlash and CompareText by Gabor
  1165. Revision 1.17 2000/03/20 19:19:45 pierre
  1166. * LFN support in streams
  1167. Revision 1.16 2000/03/14 13:36:12 pierre
  1168. * error for unexistant file in GetFileTime fixed
  1169. Revision 1.15 2000/02/07 11:45:11 pierre
  1170. + TUnsortedStringCollection CreateFrom/Assign/GetItem/PutItem from Gabor
  1171. Revision 1.14 2000/01/20 00:30:32 pierre
  1172. * Result of GetShortPathName is checked
  1173. Revision 1.13 2000/01/17 12:20:03 pierre
  1174. * uses windows needed for GetShortName
  1175. Revision 1.12 2000/01/14 15:36:43 pierre
  1176. + GetShortFileName used for tcodeeditor file opening
  1177. Revision 1.11 2000/01/05 17:27:20 pierre
  1178. + linecomplete arg for ReadlnFromStream
  1179. Revision 1.10 2000/01/03 11:38:35 michael
  1180. Changes from Gabor
  1181. Revision 1.9 1999/12/01 16:19:46 pierre
  1182. + GetFileTime moved here
  1183. Revision 1.8 1999/10/25 16:39:03 pierre
  1184. + GetPChar to avoid nil pointer problems
  1185. Revision 1.7 1999/09/13 11:44:00 peter
  1186. * fixes from gabor, idle event, html fix
  1187. Revision 1.6 1999/08/24 22:01:48 pierre
  1188. * readlnfromstream length check added
  1189. Revision 1.5 1999/08/03 20:22:45 peter
  1190. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  1191. + Desktop saving should work now
  1192. - History saved
  1193. - Clipboard content saved
  1194. - Desktop saved
  1195. - Symbol info saved
  1196. * syntax-highlight bug fixed, which compared special keywords case sensitive
  1197. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  1198. * with 'whole words only' set, the editor didn't found occourences of the
  1199. searched text, if the text appeared previously in the same line, but didn't
  1200. satisfied the 'whole-word' condition
  1201. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  1202. (ie. the beginning of the selection)
  1203. * when started typing in a new line, but not at the start (X=0) of it,
  1204. the editor inserted the text one character more to left as it should...
  1205. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  1206. * Shift shouldn't cause so much trouble in TCodeEditor now...
  1207. * Syntax highlight had problems recognizing a special symbol if it was
  1208. prefixed by another symbol character in the source text
  1209. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  1210. Revision 1.4 1999/04/07 21:56:06 peter
  1211. + object support for browser
  1212. * html help fixes
  1213. * more desktop saving things
  1214. * NODEBUG directive to exclude debugger
  1215. Revision 1.2 1999/03/08 14:58:22 peter
  1216. + prompt with dialogs for tools
  1217. Revision 1.1 1999/03/01 15:51:43 peter
  1218. + Log
  1219. }