wutils.pas 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit WUtils;
  11. {$ifdef cpullvm}
  12. {$modeswitch nestedprocvars}
  13. {$endif}
  14. {$H-}
  15. interface
  16. uses
  17. {$ifdef Windows}
  18. windows,
  19. {$endif Windows}
  20. {$ifdef netwlibc}
  21. libc,
  22. {$else}
  23. {$ifdef netware}
  24. nwserv,
  25. {$endif}
  26. {$endif}
  27. {$ifdef Unix}
  28. baseunix,
  29. unix,
  30. {$endif Unix}
  31. Dos,Objects;
  32. const
  33. kbCtrlGrayPlus = $9000;
  34. kbCtrlGrayMinus = $8e00;
  35. kbCtrlGrayMul = $9600;
  36. TempFirstChar = {$ifndef Unix}'~'{$else}'_'{$endif};
  37. TempExt = '.tmp';
  38. TempNameLen = 8;
  39. { Get DirSep and EOL from System unit, instead of redefining
  40. here with tons of $ifdefs (KB) }
  41. DirSep : AnsiChar = System.DirectorySeparator;
  42. EOL : String[2] = System.LineEnding;
  43. type
  44. Sw_AString = AnsiString; { long lines in editor }
  45. {Sw_AString = ShortString;} { 255 char lines in editor }
  46. type
  47. PByteArray = ^TByteArray;
  48. TByteArray = array[0..MaxBytes] of byte;
  49. PNoDisposeCollection = ^TNoDisposeCollection;
  50. TNoDisposeCollection = object(TCollection)
  51. procedure FreeItem(Item: Pointer); virtual;
  52. end;
  53. PUnsortedStringCollection = ^TUnsortedStringCollection;
  54. TUnsortedStringCollection = object(TCollection)
  55. constructor CreateFrom(ALines: PUnsortedStringCollection);
  56. procedure Assign(ALines: PUnsortedStringCollection);
  57. function At(Index: Sw_Integer): PString;
  58. procedure FreeItem(Item: Pointer); virtual;
  59. function GetItem(var S: TStream): Pointer; virtual;
  60. procedure PutItem(var S: TStream; Item: Pointer); virtual;
  61. procedure InsertStr(const S: string);
  62. end;
  63. PNulStream = ^TNulStream;
  64. TNulStream = object(TStream)
  65. constructor Init;
  66. function GetPos: Longint; virtual;
  67. function GetSize: Longint; virtual;
  68. procedure Read(var Buf; Count: longint); virtual;
  69. procedure Seek(Pos: Longint); virtual;
  70. procedure Write(var Buf; Count: longint); virtual;
  71. end;
  72. PSubStream = ^TSubStream;
  73. TSubStream = object(TStream)
  74. constructor Init(AStream: PStream; AStartPos, ASize: longint);
  75. function GetPos: Longint; virtual;
  76. function GetSize: Longint; virtual;
  77. procedure Read(var Buf; Count: longint); virtual;
  78. procedure Seek(Pos: Longint); virtual;
  79. procedure Write(var Buf; Count: longint); virtual;
  80. private
  81. StartPos: longint;
  82. S : PStream;
  83. end;
  84. PFastBufStream = ^TFastBufStream;
  85. TFastBufStream = object(TBufStream)
  86. constructor Init (FileName: FNameStr; Mode, Size: Word);
  87. procedure Seek(Pos: Longint); virtual;
  88. procedure Readline(var S:ShortString;var linecomplete,hasCR : boolean);
  89. procedure Readline(var S:AnsiString;var linecomplete,hasCR : boolean);
  90. private
  91. BasePos: longint;
  92. end;
  93. PTextCollection = ^TTextCollection;
  94. TTextCollection = object(TStringCollection)
  95. function LookUp(const S: string; var Idx: sw_integer): string;
  96. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  97. end;
  98. PIntCollection = ^TIntCollection;
  99. TIntCollection = object(TSortedCollection)
  100. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  101. procedure FreeItem(Item: Pointer); virtual;
  102. procedure Add(Item: ptrint);
  103. function Contains(Item: ptrint): boolean;
  104. function AtInt(Index: sw_integer): ptrint;
  105. end;
  106. procedure ReadlnFromStream(Stream: PStream; var s:ShortString;var linecomplete,hasCR : boolean);
  107. procedure ReadlnFromStream(Stream: PStream; var s:AnsiString;var linecomplete,hasCR : boolean);
  108. function eofstream(s: pstream): boolean;
  109. procedure ReadlnFromFile(var f : file; var S:string;
  110. var linecomplete,hasCR : boolean;
  111. BreakOnSpacesOnly : boolean);
  112. function Min(A,B: longint): longint;
  113. function Max(A,B: longint): longint;
  114. function CharStr(C: AnsiChar; Count: sw_integer): Sw_AString;
  115. function UpcaseStr(const S: string): string;
  116. function UpcaseStr(const S: AnsiString): AnsiString;
  117. function LowCase(C: AnsiChar): AnsiChar;
  118. function LowcaseStr(S: string): string;
  119. function LowcaseStr(S: AnsiString): AnsiString;
  120. function RExpand(const S: Sw_AString; MinLen: sw_integer): Sw_AString;
  121. function LExpand(const S: string; MinLen: byte): string;
  122. function LTrim(const S: string): string;
  123. function LTrim(const S: AnsiString): AnsiString;
  124. function RTrim(const S: string): string;
  125. function RTrim(const S: AnsiString): AnsiString;
  126. function Trim(const S: string): string;
  127. function Trim(const S: AnsiString): AnsiString;
  128. function IntToStr(L: longint): string;
  129. function IntToStrL(L: longint; MinLen: sw_integer): string;
  130. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  131. function StrToInt(const S: string): longint;
  132. function StrToCard(const S: string): cardinal;
  133. function FloatToStr(D: Double; Decimals: byte): string;
  134. function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
  135. function GetStr(P: PString): string;
  136. function GetPChar(P: PAnsiChar): string;
  137. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  138. function LExtendString(S: string; MinLen: byte): string;
  139. function DirOf(const S: string): string;
  140. function ExtOf(const S: string): string;
  141. function NameOf(const S: string): string;
  142. function NameAndExtOf(const S: string): string;
  143. function DirAndNameOf(const S: string): string;
  144. { return Dos GetFTime value or -1 if the file does not exist }
  145. function GetFileTime(const FileName: string): longint;
  146. { copied from compiler global unit }
  147. function GetShortName(const n:string):string;
  148. function GetLongName(const n:string):string;
  149. function TrimEndSlash(const Path: string): string;
  150. function CompleteDir(const Path: string): string;
  151. function GetCurDir: string;
  152. function OptimizePath(Path: string; MaxLen: integer): string;
  153. function CompareText(S1, S2: string): integer;
  154. function ExistsDir(const DirName: string): boolean;
  155. function ExistsFile(const FileName: string): boolean;
  156. function SizeOfFile(const FileName: string): longint;
  157. function DeleteFile(const FileName: string): integer;
  158. function CopyFile(const SrcFileName, DestFileName: string): boolean;
  159. function GenTempFileName: string;
  160. function FormatPath(Path: string): string;
  161. function CompletePath(const Base, InComplete: string): string;
  162. function CompleteURL(const Base, URLRef: string): string;
  163. function EatIO: integer;
  164. function Now: longint;
  165. function FormatDateTimeL(L: longint; const Format: string): string;
  166. function FormatDateTime(const D: DateTime; const Format: string): string;
  167. function MemToStr(var B; Count: byte): string;
  168. procedure StrToMem(S: string; var B);
  169. const LastStrToIntResult : integer = 0;
  170. LastHexToIntResult : integer = 0;
  171. LastStrToCardResult : integer = 0;
  172. LastHexToCardResult : integer = 0;
  173. UseOldBufStreamMethod : boolean = false;
  174. procedure RegisterWUtils;
  175. Procedure DebugMessage(AFileName, AText : string; ALine, APos : sw_word); // calls DebugMessage
  176. Procedure WUtilsDebugMessage(AFileName, AText : string; ALine, APos : string; nrLine, nrPos : sw_word);
  177. type
  178. TDebugMessage = procedure(AFileName, AText : string; ALine, APos : String; nrLine, nrPos : sw_word);
  179. Const
  180. DebugMessageS : TDebugMessage = @WUtilsDebugMessage;
  181. implementation
  182. uses
  183. {$IFDEF OS2}
  184. DosCalls,
  185. {$ENDIF OS2}
  186. Strings;
  187. {$ifndef NOOBJREG}
  188. const
  189. SpaceStr = ' '+
  190. ' '+
  191. ' '+
  192. ' ' ;
  193. RUnsortedStringCollection: TStreamRec = (
  194. ObjType: 22500;
  195. VmtLink: Ofs(TypeOf(TUnsortedStringCollection)^);
  196. Load: @TUnsortedStringCollection.Load;
  197. Store: @TUnsortedStringCollection.Store
  198. );
  199. {$endif}
  200. function eofstream(s: pstream): boolean;
  201. begin
  202. eofstream:=(s^.getpos>=s^.getsize);
  203. end;
  204. procedure ReadlnFromStream(Stream: PStream; var S:ShortString;var linecomplete,hasCR : boolean);
  205. var
  206. c : AnsiChar;
  207. i,pos : longint;
  208. CurLen : longword;
  209. begin
  210. linecomplete:=false;
  211. c:=#0;
  212. i:=0;
  213. { this created problems for lines longer than 255 characters
  214. now those lines are cutted into pieces without warning PM }
  215. { changed implicit 255 to High(S), so it will be automatically extended
  216. when longstrings eventually become default - Gabor }
  217. while (not eofstream(stream)) and (c<>#10) and (i<High(S)) do
  218. begin
  219. stream^.read(c,sizeof(c));
  220. if c<>#10 then
  221. begin
  222. inc(i);
  223. s[i]:=c;
  224. end;
  225. end;
  226. { if there was a CR LF then remove the CR Dos newline style }
  227. if (i>0) and (s[i]=#13) then
  228. begin
  229. dec(i);
  230. end;
  231. if (c=#13) and (not eofstream(stream)) then
  232. stream^.read(c,sizeof(c));
  233. if (i=High(S)) and not eofstream(stream) then
  234. begin
  235. pos:=stream^.getpos;
  236. stream^.read(c,sizeof(c));
  237. if (c=#13) and not eofstream(stream) then
  238. stream^.read(c,sizeof(c));
  239. if c<>#10 then
  240. stream^.seek(pos);
  241. end;
  242. if (c=#10) or eofstream(stream) then
  243. linecomplete:=true;
  244. if (c=#10) then
  245. hasCR:=true;
  246. setlength(s,i);
  247. end;
  248. procedure ReadlnFromStream(Stream: PStream; var S:AnsiString;var linecomplete,hasCR : boolean);
  249. var
  250. c : AnsiChar;
  251. i,pos : longint;
  252. CurLen : longword;
  253. begin
  254. linecomplete:=false;
  255. c:=#0;
  256. i:=0;
  257. CurLen:=256;
  258. SetLength(S,CurLen);
  259. { this created problems for lines longer than 255 characters
  260. now those lines are cutted into pieces without warning PM }
  261. { changed implicit 255 to High(S), so it will be automatically extended
  262. when longstrings eventually become default - Gabor }
  263. while (not eofstream(stream)) and (c<>#10) {and (i<High(S))} do
  264. begin
  265. stream^.read(c,sizeof(c));
  266. if c<>#10 then
  267. begin
  268. inc(i);
  269. s[i]:=c;
  270. if (i mod 256)=0 then
  271. begin
  272. CurLen:=CurLen+256;
  273. SetLength(S,CurLen);
  274. end;
  275. end;
  276. end;
  277. { if there was a CR LF then remove the CR Dos newline style }
  278. if (i>0) and (s[i]=#13) then
  279. begin
  280. dec(i);
  281. end;
  282. if (c=#13) and (not eofstream(stream)) then
  283. stream^.read(c,sizeof(c));
  284. if (c=#10) or eofstream(stream) then
  285. linecomplete:=true;
  286. if (c=#10) then
  287. hasCR:=true;
  288. setlength(s,i);
  289. end;
  290. procedure ReadlnFromFile(var f : file; var S:string;
  291. var linecomplete,hasCR : boolean;
  292. BreakOnSpacesOnly : boolean);
  293. var
  294. c : AnsiChar;
  295. i,pos,
  296. lastspacepos,LastSpaceFilePos : longint;
  297. {$ifdef DEBUG}
  298. filename: string;
  299. {$endif DEBUG}
  300. begin
  301. LastSpacePos:=0;
  302. linecomplete:=false;
  303. c:=#0;
  304. i:=0;
  305. { this created problems for lines longer than 255 characters
  306. now those lines are cutted into pieces without warning PM }
  307. { changed implicit 255 to High(S), so it will be automatically extended
  308. when longstrings eventually become default - Gabor }
  309. while (not eof(f)) and (c<>#10) and (i<High(S)) do
  310. begin
  311. system.blockread(f,c,sizeof(c));
  312. if c<>#10 then
  313. begin
  314. inc(i);
  315. s[i]:=c;
  316. end;
  317. if BreakOnSpacesOnly and (c=' ') then
  318. begin
  319. LastSpacePos:=i;
  320. LastSpaceFilePos:=system.filepos(f);
  321. end;
  322. end;
  323. { if there was a CR LF then remove the CR Dos newline style }
  324. if (i>0) and (s[i]=#13) then
  325. begin
  326. dec(i);
  327. end;
  328. if (c=#13) and (not eof(f)) then
  329. system.blockread(f,c,sizeof(c));
  330. if (i=High(S)) and not eof(f) then
  331. begin
  332. pos:=system.filepos(f);
  333. system.blockread(f,c,sizeof(c));
  334. if (c=#13) and not eof(f) then
  335. system.blockread(f,c,sizeof(c));
  336. if c<>#10 then
  337. system.seek(f,pos);
  338. if (c<>' ') and (c<>#10) and BreakOnSpacesOnly and
  339. (LastSpacePos>1) then
  340. begin
  341. {$ifdef DEBUG}
  342. setlength(s,i);
  343. filename:=strpas(@(filerec(f).Name));
  344. DebugMessage(filename,'s='+s,1,1);
  345. {$endif DEBUG}
  346. i:=LastSpacePos;
  347. {$ifdef DEBUG}
  348. setlength(s,i);
  349. DebugMessage(filename,'reduced to '+s,1,1);
  350. {$endif DEBUG}
  351. system.seek(f,LastSpaceFilePos);
  352. end;
  353. end;
  354. if (c=#10) or eof(f) then
  355. linecomplete:=true;
  356. if (c=#10) then
  357. hasCR:=true;
  358. setlength(s,i);
  359. end;
  360. function MemToStr(var B; Count: byte): string;
  361. var S: string;
  362. begin
  363. setlength(s,count);
  364. if Count>0 then Move(B,S[1],Count);
  365. MemToStr:=S;
  366. end;
  367. procedure StrToMem(S: string; var B);
  368. begin
  369. if length(S)>0 then Move(S[1],B,length(S));
  370. end;
  371. function Max(A,B: longint): longint;
  372. begin
  373. if A>B then Max:=A else Max:=B;
  374. end;
  375. function Min(A,B: longint): longint;
  376. begin
  377. if A<B then Min:=A else Min:=B;
  378. end;
  379. function CharStr(C: AnsiChar; Count: sw_integer): Sw_AString;
  380. begin
  381. if Count<=0 then
  382. begin
  383. CharStr:='';
  384. exit;
  385. end
  386. {$if sizeof(sw_astring)>8 only if ShortString}
  387. else if Count>255 then
  388. Count:=255;
  389. {$endif};
  390. SetLength(CharStr,Count);
  391. FillChar(CharStr[1],Count,C);
  392. end;
  393. function UpcaseStr(const S: string): string;
  394. var
  395. I: Longint;
  396. begin
  397. for I:=1 to length(S) do
  398. if S[I] in ['a'..'z'] then
  399. UpCaseStr[I]:=chr(ord(S[I])-32)
  400. else
  401. UpCaseStr[I]:=S[I];
  402. Setlength(UpcaseStr,length(s));
  403. end;
  404. function UpcaseStr(const S: AnsiString): AnsiString;
  405. var
  406. I: Longint;
  407. begin
  408. Setlength(UpcaseStr,length(s));
  409. for I:=1 to length(S) do
  410. if S[I] in ['a'..'z'] then
  411. UpCaseStr[I]:=chr(ord(S[I])-32)
  412. else
  413. UpCaseStr[I]:=S[I];
  414. end;
  415. function RExpand(const S: Sw_AString; MinLen: sw_integer): Sw_AString;
  416. begin
  417. if length(S)<MinLen then
  418. RExpand:=S+CharStr(' ',MinLen-length(S))
  419. else
  420. RExpand:=S;
  421. end;
  422. function LExpand(const S: string; MinLen: byte): string;
  423. begin
  424. if length(S)<MinLen then
  425. LExpand:=CharStr(' ',MinLen-length(S))+S
  426. else
  427. LExpand:=S;
  428. end;
  429. function LTrim(const S: string): string;
  430. var
  431. i : longint;
  432. begin
  433. i:=1;
  434. while (i<length(s)) and (s[i]=' ') do
  435. inc(i);
  436. LTrim:=Copy(s,i,High(S));
  437. end;
  438. function RTrim(const S: string): string;
  439. var
  440. i : longint;
  441. begin
  442. i:=length(s);
  443. while (i>0) and (s[i]=' ') do
  444. dec(i);
  445. RTrim:=Copy(s,1,i);
  446. end;
  447. function Trim(const S: string): string;
  448. var
  449. i,j : longint;
  450. begin
  451. i:=1;
  452. while (i<length(s)) and (s[i]=' ') do
  453. inc(i);
  454. j:=length(s);
  455. while (j>0) and (s[j]=' ') do
  456. dec(j);
  457. Trim:=Copy(S,i,j-i+1);
  458. end;
  459. function LTrim(const S: AnsiString): AnsiString;
  460. var
  461. i : longint;
  462. begin
  463. i:=1;
  464. while (i<length(s)) and (s[i]=' ') do
  465. inc(i);
  466. LTrim:=Copy(s,i,length(S));
  467. end;
  468. function RTrim(const S: AnsiString): AnsiString;
  469. var
  470. i : longint;
  471. begin
  472. i:=length(s);
  473. while (i>0) and (s[i]=' ') do
  474. dec(i);
  475. RTrim:=Copy(s,1,i);
  476. end;
  477. function Trim(const S: AnsiString): AnsiString;
  478. var
  479. i,j : longint;
  480. begin
  481. i:=1;
  482. while (i<length(s)) and (s[i]=' ') do
  483. inc(i);
  484. j:=length(s);
  485. while (j>0) and (s[j]=' ') do
  486. dec(j);
  487. Trim:=Copy(S,i,j-i+1);
  488. end;
  489. function IntToStr(L: longint): string;
  490. var S: string;
  491. begin
  492. Str(L,S);
  493. IntToStr:=S;
  494. end;
  495. function IntToStrL(L: longint; MinLen: sw_integer): string;
  496. begin
  497. IntToStrL:=LExpand(IntToStr(L),MinLen);
  498. end;
  499. function IntToStrZ(L: longint; MinLen: sw_integer): string;
  500. var S: string;
  501. begin
  502. S:=IntToStr(L);
  503. if length(S)<MinLen then
  504. S:=CharStr('0',MinLen-length(S))+S;
  505. IntToStrZ:=S;
  506. end;
  507. function StrToInt(const S: string): longint;
  508. var L: longint;
  509. C: integer;
  510. begin
  511. Val(S,L,C); if C<>0 then L:=-1;
  512. LastStrToIntResult:=C;
  513. StrToInt:=L;
  514. end;
  515. function StrToCard(const S: string): cardinal;
  516. var L: cardinal;
  517. C: integer;
  518. begin
  519. Val(S,L,C); if C<>0 then L:=$ffffffff;
  520. LastStrToCardResult:=C;
  521. StrToCard:=L;
  522. end;
  523. function FloatToStr(D: Double; Decimals: byte): string;
  524. var S: string;
  525. L: byte;
  526. begin
  527. Str(D:0:Decimals,S);
  528. if length(S)>0 then
  529. while (S[1]=' ') do Delete(S,1,1);
  530. FloatToStr:=S;
  531. end;
  532. function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
  533. begin
  534. FloatToStrL:=LExtendString(FloatToStr(D,Decimals),MinLen);
  535. end;
  536. function LExtendString(S: string; MinLen: byte): string;
  537. begin
  538. LExtendString:=copy(SpaceStr,1,MinLen-length(S))+S;
  539. end;
  540. function GetStr(P: PString): string;
  541. begin
  542. if P=nil then GetStr:='' else GetStr:=P^;
  543. end;
  544. function GetPChar(P: PAnsiChar): string;
  545. begin
  546. if P=nil then GetPChar:='' else GetPChar:=StrPas(P);
  547. end;
  548. function DirOf(const S: string): string;
  549. var D: DirStr; E: ExtStr; N: NameStr;
  550. begin
  551. FSplit(S,D,N,E);
  552. if (D<>'') and (D[Length(D)]<>DirSep)
  553. {$ifdef HASAMIGA}
  554. and (D[Length(D)]<>DriveSeparator)
  555. {$endif}
  556. then
  557. DirOf:=D+DirSep
  558. else
  559. DirOf:=D;
  560. end;
  561. function ExtOf(const S: string): string;
  562. var D: DirStr; E: ExtStr; N: NameStr;
  563. begin
  564. FSplit(S,D,N,E);
  565. ExtOf:=E;
  566. end;
  567. function NameOf(const S: string): string;
  568. var D: DirStr; E: ExtStr; N: NameStr;
  569. begin
  570. FSplit(S,D,N,E);
  571. NameOf:=N;
  572. end;
  573. function NameAndExtOf(const S: string): string;
  574. var D: DirStr; E: ExtStr; N: NameStr;
  575. begin
  576. FSplit(S,D,N,E);
  577. NameAndExtOf:=N+E;
  578. end;
  579. function DirAndNameOf(const S: string): string;
  580. var D: DirStr; E: ExtStr; N: NameStr;
  581. begin
  582. FSplit(S,D,N,E);
  583. DirAndNameOf:=D+N;
  584. end;
  585. { return Dos GetFTime value or -1 if the file does not exist }
  586. function GetFileTime(const FileName: string): longint;
  587. var T: longint;
  588. f: file;
  589. FM: integer;
  590. begin
  591. if FileName='' then
  592. T:=-1
  593. else
  594. begin
  595. FM:=FileMode; FileMode:=0;
  596. EatIO; Dos.DosError:=0;
  597. Assign(f,FileName);
  598. {$I-}
  599. Reset(f);
  600. if InOutRes=0 then
  601. begin
  602. GetFTime(f,T);
  603. Close(f);
  604. end;
  605. {$I+}
  606. if (EatIO<>0) or (Dos.DosError<>0) then T:=-1;
  607. FileMode:=FM;
  608. end;
  609. GetFileTime:=T;
  610. end;
  611. function GetShortName(const n:string):string;
  612. {$ifdef Windows}
  613. var
  614. hs,hs2 : string;
  615. i : longint;
  616. {$endif}
  617. {$ifdef go32v2}
  618. var
  619. hs : string;
  620. {$endif}
  621. begin
  622. GetShortName:=n;
  623. {$ifdef Windows}
  624. hs:=n+#0;
  625. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  626. if (i>0) and (i<=high(hs2)) then
  627. begin
  628. setlength(hs2,strlen(@hs2[1]));
  629. GetShortName:=hs2;
  630. end;
  631. {$endif}
  632. {$ifdef go32v2}
  633. hs:=n;
  634. if Dos.GetShortName(hs) then
  635. GetShortName:=hs;
  636. {$endif}
  637. end;
  638. function GetLongName(const n:string):string;
  639. {$ifdef Windows}
  640. var
  641. hs : string;
  642. hs2 : Array [0..255] of AnsiChar;
  643. i : longint;
  644. j : PAnsiChar;
  645. {$endif}
  646. {$ifdef go32v2}
  647. var
  648. hs : string;
  649. {$endif}
  650. begin
  651. GetLongName:=n;
  652. {$ifdef Windows}
  653. hs:=n+#0;
  654. i:=Windows.GetFullPathNameA(@hs[1],256,hs2,j);
  655. if (i>0) and (i<=high(hs)) then
  656. begin
  657. hs:=strpas(hs2);
  658. GetLongName:=hs;
  659. end;
  660. {$endif}
  661. {$ifdef go32v2}
  662. hs:=n;
  663. if Dos.GetLongName(hs) then
  664. GetLongName:=hs;
  665. {$endif}
  666. end;
  667. function EatIO: integer;
  668. begin
  669. EatIO:=IOResult;
  670. end;
  671. function LowCase(C: AnsiChar): AnsiChar;
  672. begin
  673. if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
  674. LowCase:=C;
  675. end;
  676. function LowcaseStr(S: string): string;
  677. var I: Longint;
  678. begin
  679. for I:=1 to length(S) do
  680. S[I]:=Lowcase(S[I]);
  681. LowcaseStr:=S;
  682. end;
  683. function LowcaseStr(S: AnsiString): AnsiString;
  684. var I: Longint;
  685. begin
  686. SetLength(LowcaseStr,length(S));
  687. for I:=1 to length(S) do
  688. LowcaseStr[I]:=Lowcase(S[I]);
  689. end;
  690. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  691. begin
  692. if B then BoolToStr:=TrueS else BoolToStr:=FalseS;
  693. end;
  694. procedure TNoDisposeCollection.FreeItem(Item: Pointer);
  695. begin
  696. { don't do anything here }
  697. end;
  698. constructor TUnsortedStringCollection.CreateFrom(ALines: PUnsortedStringCollection);
  699. begin
  700. if Assigned(ALines)=false then Fail;
  701. inherited Init(ALines^.Count,ALines^.Count div 10);
  702. Assign(ALines);
  703. end;
  704. procedure TUnsortedStringCollection.Assign(ALines: PUnsortedStringCollection);
  705. procedure AddIt(P: PString);
  706. begin
  707. Insert(NewStr(GetStr(P)));
  708. end;
  709. begin
  710. FreeAll;
  711. if Assigned(ALines) then
  712. ALines^.ForEach(TCallbackProcParam(@AddIt));
  713. end;
  714. procedure TUnsortedStringCollection.InsertStr(const S: string);
  715. begin
  716. Insert(NewStr(S));
  717. end;
  718. function TUnsortedStringCollection.At(Index: Sw_Integer): PString;
  719. begin
  720. At:=inherited At(Index);
  721. end;
  722. procedure TUnsortedStringCollection.FreeItem(Item: Pointer);
  723. begin
  724. if Item<>nil then DisposeStr(Item);
  725. end;
  726. function TUnsortedStringCollection.GetItem(var S: TStream): Pointer;
  727. begin
  728. GetItem:=S.ReadStr;
  729. end;
  730. procedure TUnsortedStringCollection.PutItem(var S: TStream; Item: Pointer);
  731. begin
  732. S.WriteStr(Item);
  733. end;
  734. function TIntCollection.Contains(Item: ptrint): boolean;
  735. var Index: sw_integer;
  736. begin
  737. Contains:=Search(pointer(Item),Index);
  738. end;
  739. function TIntCollection.AtInt(Index: sw_integer): ptrint;
  740. begin
  741. AtInt:=longint(At(Index));
  742. end;
  743. procedure TIntCollection.Add(Item: ptrint);
  744. begin
  745. Insert(pointer(Item));
  746. end;
  747. function TIntCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  748. var K1: longint absolute Key1;
  749. K2: longint absolute Key2;
  750. R: integer;
  751. begin
  752. if K1<K2 then R:=-1 else
  753. if K1>K2 then R:= 1 else
  754. R:=0;
  755. Compare:=R;
  756. end;
  757. procedure TIntCollection.FreeItem(Item: Pointer);
  758. begin
  759. { do nothing here }
  760. end;
  761. constructor TNulStream.Init;
  762. begin
  763. inherited Init;
  764. Position:=0;
  765. end;
  766. function TNulStream.GetPos: Longint;
  767. begin
  768. GetPos:=Position;
  769. end;
  770. function TNulStream.GetSize: Longint;
  771. begin
  772. GetSize:=Position;
  773. end;
  774. procedure TNulStream.Read(var Buf; Count: longint);
  775. begin
  776. Error(stReadError,0);
  777. end;
  778. procedure TNulStream.Seek(Pos: Longint);
  779. begin
  780. if Pos<=Position then
  781. Position:=Pos;
  782. end;
  783. procedure TNulStream.Write(var Buf; Count: longint);
  784. begin
  785. Inc(Position,Count);
  786. end;
  787. constructor TSubStream.Init(AStream: PStream; AStartPos, ASize: longint);
  788. begin
  789. inherited Init;
  790. if Assigned(AStream)=false then Fail;
  791. S:=AStream; StartPos:=AStartPos; StreamSize:=ASize;
  792. Seek(0);
  793. end;
  794. function TSubStream.GetPos: Longint;
  795. var Pos: longint;
  796. begin
  797. Pos:=S^.GetPos; Dec(Pos,StartPos);
  798. GetPos:=Pos;
  799. end;
  800. function TSubStream.GetSize: Longint;
  801. begin
  802. GetSize:=StreamSize;
  803. end;
  804. procedure TSubStream.Read(var Buf; Count: longint);
  805. var Pos: longint;
  806. RCount: longint;
  807. begin
  808. Pos:=GetPos;
  809. if Pos+Count>StreamSize then RCount:=StreamSize-Pos else RCount:=Count;
  810. S^.Read(Buf,RCount);
  811. if RCount<Count then
  812. Error(stReadError,0);
  813. end;
  814. procedure TSubStream.Seek(Pos: Longint);
  815. var RPos: longint;
  816. begin
  817. if (Pos<=StreamSize) then RPos:=Pos else RPos:=StreamSize;
  818. S^.Seek(StartPos+RPos);
  819. end;
  820. procedure TSubStream.Write(var Buf; Count: longint);
  821. begin
  822. S^.Write(Buf,Count);
  823. end;
  824. constructor TFastBufStream.Init (FileName: FNameStr; Mode, Size: Word);
  825. begin
  826. Inherited Init(FileName,Mode,Size);
  827. BasePos:=0;
  828. end;
  829. procedure TFastBufStream.Seek(Pos: Longint);
  830. var RelOfs: longint;
  831. begin
  832. RelOfs:=Pos-BasePos;
  833. if (RelOfs<0) or (RelOfs>=BufEnd) or (BufEnd=0) then
  834. begin
  835. inherited Seek(Pos);
  836. BasePos:=Pos-BufPtr;
  837. end
  838. else
  839. begin
  840. BufPtr:=RelOfs;
  841. Position:=Pos;
  842. end;
  843. end;
  844. procedure TFastBufStream.Readline(var S:ShortString;var linecomplete,hasCR : boolean);
  845. var
  846. c : AnsiChar;
  847. i,pos,StartPos : longint;
  848. charsInS : boolean;
  849. begin
  850. linecomplete:=false;
  851. c:=#0;
  852. i:=0;
  853. { this created problems for lines longer than 255 characters
  854. now those lines are cutted into pieces without warning PM }
  855. { changed implicit 255 to High(S), so it will be automatically extended
  856. when longstrings eventually become default - Gabor }
  857. if (bufend-bufptr>=High(S)) and (getpos+High(S)<getsize) then
  858. begin
  859. StartPos:=GetPos;
  860. //read(S[1],High(S));
  861. system.move(buffer^[bufptr],S[1],High(S));
  862. charsInS:=true;
  863. end
  864. else
  865. CharsInS:=false;
  866. while (CharsInS or not (getpos>=getsize)) and
  867. (c<>#10) and (i<High(S)) do
  868. begin
  869. if CharsInS then
  870. c:=s[i+1]
  871. else
  872. read(c,sizeof(c));
  873. if c<>#10 then
  874. begin
  875. inc(i);
  876. if not CharsInS then
  877. s[i]:=c;
  878. end;
  879. end;
  880. if CharsInS then
  881. begin
  882. if c=#10 then
  883. Seek(StartPos+i+1)
  884. else
  885. Seek(StartPos+i);
  886. end;
  887. { if there was a CR LF then remove the CR Dos newline style }
  888. if (i>0) and (s[i]=#13) then
  889. begin
  890. dec(i);
  891. end;
  892. if (c=#13) and (not (getpos>=getsize)) then
  893. begin
  894. read(c,sizeof(c));
  895. end;
  896. if (i=High(S)) and not (getpos>=getsize) then
  897. begin
  898. pos:=getpos;
  899. read(c,sizeof(c));
  900. if (c=#13) and not (getpos>=getsize) then
  901. read(c,sizeof(c));
  902. if c<>#10 then
  903. seek(pos);
  904. end;
  905. if (c=#10) or (getpos>=getsize) then
  906. linecomplete:=true;
  907. if (c=#10) then
  908. hasCR:=true;
  909. setlength(s,i);
  910. end;
  911. procedure TFastBufStream.Readline(var S:AnsiString;var linecomplete,hasCR : boolean);
  912. var
  913. c : char;
  914. i,pos,StartPos : longint;
  915. charsInS : boolean;
  916. Len,Idx : sw_integer;
  917. begin
  918. linecomplete:=false;
  919. c:=#0;
  920. i:=0;
  921. CharsInS:=false;
  922. Len:=bufend-bufptr;
  923. Idx:=-1;
  924. if Len>0 then
  925. Idx:=IndexByte(buffer^[bufptr],Len, 10)+1; {find end of line}
  926. Len:=Min(Idx,Len);
  927. SetLength(S,Len);
  928. if (Len > 0) and (GetPos+Len<GetSize) then
  929. begin
  930. StartPos:=GetPos;
  931. system.move(buffer^[bufptr],S[1],Len); {get full line}
  932. charsInS:=true;
  933. end;
  934. while (CharsInS or not (getpos>=getsize)) and (c<>#10) do
  935. begin
  936. if CharsInS then
  937. c:=s[i+1]
  938. else
  939. read(c,sizeof(c));
  940. if c<>#10 then
  941. begin
  942. inc(i);
  943. if not CharsInS then
  944. begin
  945. if i > Len then
  946. begin
  947. Len:=Len+256; {constant grow}
  948. SetLength(S,Len);
  949. end;
  950. s[i]:=c;
  951. end;
  952. end;
  953. end;
  954. if CharsInS then
  955. begin
  956. if c=#10 then
  957. Seek(StartPos+i+1)
  958. else
  959. Seek(StartPos+i);
  960. end;
  961. { if there was a CR LF then remove the CR Dos newline style }
  962. if (i>0) and (s[i]=#13) then
  963. begin
  964. dec(i);
  965. end;
  966. if (c=#13) and (not (getpos>=getsize)) then
  967. begin
  968. read(c,sizeof(c));
  969. end;
  970. if (c=#10) or (getpos>=getsize) then
  971. linecomplete:=true;
  972. if (c=#10) then
  973. hasCR:=true;
  974. setlength(s,i);
  975. end;
  976. function TTextCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  977. var K1: PString absolute Key1;
  978. K2: PString absolute Key2;
  979. R: Sw_integer;
  980. S1,S2: string;
  981. begin
  982. S1:=UpCaseStr(K1^);
  983. S2:=UpCaseStr(K2^);
  984. if S1<S2 then R:=-1 else
  985. if S1>S2 then R:=1 else
  986. R:=0;
  987. Compare:=R;
  988. end;
  989. function TTextCollection.LookUp(const S: string; var Idx: sw_integer): string;
  990. var OLI,ORI,Left,Right,Mid: integer;
  991. {LeftP,RightP,}MidP: PString;
  992. {LeftS,}MidS{,RightS}: string;
  993. FoundS: string;
  994. UpS : string;
  995. begin
  996. Idx:=-1; FoundS:='';
  997. Left:=0; Right:=Count-1;
  998. UpS:=UpCaseStr(S);
  999. while Left<=Right do
  1000. begin
  1001. OLI:=Left; ORI:=Right;
  1002. Mid:=Left+(Right-Left) div 2;
  1003. MidP:=At(Mid);
  1004. MidS:=UpCaseStr(MidP^);
  1005. if copy(MidS,1,length(UpS))=UpS then
  1006. begin
  1007. Idx:=Mid; FoundS:=GetStr(MidP);
  1008. { exit immediately if exact match PM }
  1009. If Length(MidS)=Length(UpS) then
  1010. break;
  1011. end;
  1012. if UpS<MidS then
  1013. Right:=Mid
  1014. else
  1015. Left:=Mid;
  1016. if (OLI=Left) and (ORI=Right) then
  1017. begin
  1018. if (Left<Right) then
  1019. Left:=Right
  1020. else
  1021. Break;
  1022. end;
  1023. end;
  1024. LookUp:=FoundS;
  1025. end;
  1026. function TrimEndSlash(const Path: string): string;
  1027. var S: string;
  1028. begin
  1029. S:=Path;
  1030. if (length(S)>0) and (S<>DirSep) and (copy(S,length(S),1)=DirSep) and
  1031. (S[length(S)-1]<>':') then
  1032. S:=copy(S,1,length(S)-1);
  1033. TrimEndSlash:=S;
  1034. end;
  1035. function CompareText(S1, S2: string): integer;
  1036. var R: integer;
  1037. begin
  1038. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  1039. if S1<S2 then R:=-1 else
  1040. if S1>S2 then R:= 1 else
  1041. R:=0;
  1042. CompareText:=R;
  1043. end;
  1044. function FormatPath(Path: string): string;
  1045. var P: sw_integer;
  1046. SC: AnsiChar;
  1047. begin
  1048. if ord(DirSep)=ord('/') then
  1049. SC:='\'
  1050. else
  1051. SC:='/';
  1052. repeat
  1053. P:=Pos(SC,Path);
  1054. if P>0 then Path[P]:=DirSep;
  1055. until P=0;
  1056. FormatPath:=Path;
  1057. end;
  1058. function CompletePath(const Base, InComplete: string): string;
  1059. var Drv,BDrv: string[40]; D,BD: DirStr; N,BN: NameStr; E,BE: ExtStr;
  1060. P: sw_integer;
  1061. Complete: string;
  1062. begin
  1063. Complete:=FormatPath(InComplete);
  1064. FSplit(FormatPath(InComplete),D,N,E);
  1065. P:=Pos(':',D); if P=0 then Drv:='' else begin Drv:=copy(D,1,P); Delete(D,1,P); end;
  1066. FSplit(FormatPath(Base),BD,BN,BE);
  1067. P:=Pos(':',BD); if P=0 then BDrv:='' else begin BDrv:=copy(BD,1,P); Delete(BD,1,P); end;
  1068. if copy(D,1,1)<>DirSep then
  1069. Complete:=BD+D+N+E;
  1070. if Drv='' then
  1071. Complete:=BDrv+Complete;
  1072. Complete:=FExpand(Complete);
  1073. CompletePath:=Complete;
  1074. end;
  1075. function CompleteURL(const Base, URLRef: string): string;
  1076. var P: integer;
  1077. Drive: string[20];
  1078. IsComplete: boolean;
  1079. S: string;
  1080. Ref: string;
  1081. Bookmark: string;
  1082. begin
  1083. IsComplete:=false; Ref:=URLRef;
  1084. P:=Pos(':',Ref);
  1085. if P=0 then Drive:='' else Drive:=UpcaseStr(copy(Ref,1,P-1));
  1086. if Drive<>'' then
  1087. if (Drive='MAILTO') or (Drive='FTP') or (Drive='HTTP') or
  1088. (Drive='GOPHER') or (Drive='FILE') then
  1089. IsComplete:=true;
  1090. if IsComplete then S:=Ref else
  1091. begin
  1092. P:=Pos('#',Ref);
  1093. if P=0 then
  1094. Bookmark:=''
  1095. else
  1096. begin
  1097. Bookmark:=copy(Ref,P+1,length(Ref));
  1098. Ref:=copy(Ref,1,P-1);
  1099. end;
  1100. S:=CompletePath(Base,Ref);
  1101. if Bookmark<>'' then
  1102. S:=S+'#'+Bookmark;
  1103. end;
  1104. CompleteURL:=S;
  1105. end;
  1106. function OptimizePath(Path: string; MaxLen: integer): string;
  1107. var i : integer;
  1108. BackSlashs : array[1..20] of integer;
  1109. BSCount : integer;
  1110. Jobbra : boolean;
  1111. Jobb, Bal : byte;
  1112. Hiba : boolean;
  1113. begin
  1114. if length(Path)>MaxLen then
  1115. begin
  1116. BSCount:=0; Jobbra:=true;
  1117. for i:=1 to length(Path) do if Path[i]=DirSep then
  1118. begin
  1119. Inc(BSCount);
  1120. BackSlashs[BSCount]:=i;
  1121. end;
  1122. i:=BSCount div 2;
  1123. Hiba:=false;
  1124. Bal:=i; Jobb:=i+1;
  1125. case i of 0 : ;
  1126. 1 : Path:=copy(Path, 1, BackSlashs[1])+'..'+
  1127. copy(Path, BackSlashs[2], length(Path));
  1128. else begin
  1129. while (BackSlashs[Bal]+(length(Path)-BackSlashs[Jobb]) >=
  1130. MaxLen) and not Hiba do
  1131. begin
  1132. if Jobbra then begin
  1133. if Jobb<BSCount then inc(Jobb)
  1134. else Hiba:=true;
  1135. Jobbra:=false;
  1136. end
  1137. else begin
  1138. if Bal>1 then dec(Bal)
  1139. else Hiba:=true;
  1140. Jobbra:=true;
  1141. end;
  1142. end;
  1143. Path:=copy(Path, 1, BackSlashs[Bal])+'..'+
  1144. copy(Path, BackSlashs[Jobb], length(Path));
  1145. end;
  1146. end;
  1147. end;
  1148. if length(Path)>MaxLen then
  1149. begin
  1150. i:=Pos('\..\',Path);
  1151. if i>0 then Path:=copy(Path,1,i-1)+'..'+copy(Path,i+length('\..\'),length(Path));
  1152. end;
  1153. OptimizePath:=Path;
  1154. end;
  1155. function Now: longint;
  1156. var D: DateTime;
  1157. W: word;
  1158. L: longint;
  1159. begin
  1160. FillChar(D,sizeof(D),0);
  1161. GetDate(D.Year,D.Month,D.Day,W);
  1162. GetTime(D.Hour,D.Min,D.Sec,W);
  1163. PackTime(D,L);
  1164. Now:=L;
  1165. end;
  1166. function FormatDateTimeL(L: longint; const Format: string): string;
  1167. var D: DateTime;
  1168. begin
  1169. UnpackTime(L,D);
  1170. FormatDateTimeL:=FormatDateTime(D,Format);
  1171. end;
  1172. function FormatDateTime(const D: DateTime; const Format: string): string;
  1173. var I: sw_integer;
  1174. CurCharStart: sw_integer;
  1175. CurChar: AnsiChar;
  1176. CurCharCount: integer;
  1177. DateS: string;
  1178. C: AnsiChar;
  1179. procedure FlushChars;
  1180. var S: string;
  1181. I: sw_integer;
  1182. begin
  1183. S:='';
  1184. for I:=1 to CurCharCount do
  1185. S:=S+CurChar;
  1186. case CurChar of
  1187. 'y' : S:=IntToStrL(D.Year,length(S));
  1188. 'm' : S:=IntToStrZ(D.Month,length(S));
  1189. 'd' : S:=IntToStrZ(D.Day,length(S));
  1190. 'h' : S:=IntToStrZ(D.Hour,length(S));
  1191. 'n' : S:=IntToStrZ(D.Min,length(S));
  1192. 's' : S:=IntToStrZ(D.Sec,length(S));
  1193. end;
  1194. DateS:=DateS+S;
  1195. end;
  1196. begin
  1197. DateS:='';
  1198. CurCharStart:=-1; CurCharCount:=0; CurChar:=#0;
  1199. for I:=1 to length(Format) do
  1200. begin
  1201. C:=Format[I];
  1202. if (C<>CurChar) or (CurCharStart=-1) then
  1203. begin
  1204. if CurCharStart<>-1 then FlushChars;
  1205. CurCharCount:=1; CurCharStart:=I;
  1206. end
  1207. else
  1208. Inc(CurCharCount);
  1209. CurChar:=C;
  1210. end;
  1211. FlushChars;
  1212. FormatDateTime:=DateS;
  1213. end;
  1214. function DeleteFile(const FileName: string): integer;
  1215. var f: file;
  1216. begin
  1217. {$I-}
  1218. Assign(f,FileName);
  1219. Erase(f);
  1220. DeleteFile:=EatIO;
  1221. {$I+}
  1222. end;
  1223. function ExistsFile(const FileName: string): boolean;
  1224. var
  1225. Dir : SearchRec;
  1226. begin
  1227. Dos.FindFirst(FileName,Archive+ReadOnly,Dir);
  1228. ExistsFile:=(Dos.DosError=0);
  1229. Dos.FindClose(Dir);
  1230. end;
  1231. { returns zero for empty and non existant files }
  1232. function SizeOfFile(const FileName: string): longint;
  1233. var
  1234. Dir : SearchRec;
  1235. begin
  1236. Dos.FindFirst(FileName,Archive+ReadOnly,Dir);
  1237. if (Dos.DosError=0) then
  1238. SizeOfFile:=Dir.Size
  1239. else
  1240. SizeOfFile:=0;
  1241. Dos.FindClose(Dir);
  1242. end;
  1243. function ExistsDir(const DirName: string): boolean;
  1244. var
  1245. Dir : SearchRec;
  1246. begin
  1247. Dos.FindFirst(TrimEndSlash(DirName),anyfile,Dir);
  1248. { if a file is found it is also reported
  1249. at least for some Dos version
  1250. so we need to check the attributes PM }
  1251. ExistsDir:=(Dos.DosError=0) and ((Dir.attr and Directory) <> 0);
  1252. Dos.FindClose(Dir);
  1253. end;
  1254. function CompleteDir(const Path: string): string;
  1255. begin
  1256. { keep c: untouched PM }
  1257. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  1258. (Path[Length(Path)]<>':') then
  1259. CompleteDir:=Path+DirSep
  1260. else
  1261. CompleteDir:=Path;
  1262. end;
  1263. function GetCurDir: string;
  1264. var S: string;
  1265. begin
  1266. GetDir(0,S);
  1267. {$ifdef HASAMIGA}
  1268. if (copy(S,length(S),1)<>DirSep) and (copy(S,length(S),1)<>DriveSeparator) then S:=S+DirSep;
  1269. {$else}
  1270. if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
  1271. {$endif}
  1272. GetCurDir:=S;
  1273. end;
  1274. function GenTempFileName: string;
  1275. var Dir: string;
  1276. Name: string;
  1277. I: integer;
  1278. OK: boolean;
  1279. Path: string;
  1280. begin
  1281. Dir:=GetEnv('TEMP');
  1282. if Dir='' then Dir:=GetEnv('TMP');
  1283. {$ifdef HASAMIGA}
  1284. if Dir='' then Dir:='T:';
  1285. {$endif}
  1286. if (Dir<>'') then if not ExistsDir(Dir) then Dir:='';
  1287. if Dir='' then Dir:=GetCurDir;
  1288. repeat
  1289. Name:=TempFirstChar;
  1290. for I:=2 to TempNameLen do
  1291. Name:=Name+chr(ord('a')+random(ord('z')-ord('a')+1));
  1292. Name:=Name+TempExt;
  1293. Path:=CompleteDir(Dir)+Name;
  1294. OK:=not ExistsFile(Path);
  1295. until OK;
  1296. GenTempFileName:=Path;
  1297. end;
  1298. function CopyFile(const SrcFileName, DestFileName: string): boolean;
  1299. var SrcF,DestF: PBufStream;
  1300. OK: boolean;
  1301. begin
  1302. SrcF:=nil; DestF:=nil;
  1303. New(SrcF, Init(SrcFileName,stOpenRead,4096));
  1304. OK:=Assigned(SrcF) and (SrcF^.Status=stOK);
  1305. if OK then
  1306. begin
  1307. New(DestF, Init(DestFileName,stCreate,1024));
  1308. OK:=Assigned(DestF) and (DestF^.Status=stOK);
  1309. end;
  1310. if OK then DestF^.CopyFrom(SrcF^,SrcF^.GetSize);
  1311. if Assigned(DestF) then Dispose(DestF, Done);
  1312. if Assigned(SrcF) then Dispose(SrcF, Done);
  1313. CopyFile:=OK;
  1314. end;
  1315. procedure RegisterWUtils;
  1316. begin
  1317. {$ifndef NOOBJREG}
  1318. RegisterType(RUnsortedStringCollection);
  1319. {$endif}
  1320. end;
  1321. Procedure DebugMessage(AFileName, AText : string; ALine, APos : sw_word); // calls DebugMessage
  1322. begin
  1323. DebugMessageS(Afilename,AText,'','',aline,apos);
  1324. end;
  1325. Procedure WUtilsDebugMessage(AFileName, AText : string; ALine, APos : string;nrLine, nrPos : sw_word);
  1326. begin
  1327. writeln(stderr,AFileName,' (',ALine,',',APos,') ',AText);
  1328. flush(stderr);
  1329. end;
  1330. BEGIN
  1331. Randomize;
  1332. END.