wutils.pas 34 KB

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