astrings.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { ---------------------------------------------------------------------
  13. This file implements AnsiStrings for FPC
  14. ---------------------------------------------------------------------}
  15. {
  16. This file contains the implementation of the LongString type,
  17. and all things that are needed for it.
  18. AnsiSTring is defined as a 'silent' pchar :
  19. a pchar that points to :
  20. @-12 : Longint for maximum size;
  21. @-8 : Longint for size;
  22. @-4 : Longint for reference count;
  23. @ : String + Terminating #0;
  24. Pchar(Ansistring) is a valid typecast.
  25. So AS[i] is converted to the address @AS+i-1.
  26. Constants should be assigned a reference count of -1
  27. Meaning that they can't be disposed of.
  28. }
  29. Type shortstring=string;
  30. Function NewAnsiString (Len : Longint) : AnsiString; forward;
  31. Procedure DisposeAnsiString (Var S : AnsiString); forward;
  32. Procedure Decr_Ansi_Ref (Var S : AnsiString); forward;
  33. Procedure Incr_Ansi_Ref (Var S : AnsiString); forward;
  34. Procedure AssignAnsiString (Var S1 : AnsiString; S2 : Pointer); forward;
  35. Procedure Ansi_String_Concat (Var S1 : AnsiString; Var S2 : AnsiString); forward;
  36. Procedure Ansi_ShortString_Concat (Var S1: AnsiString; Var S2 : ShortString); forward;
  37. Procedure Ansi_To_ShortString (Var S1 : ShortString; S2 : Pointer; maxlen : longint); forward;
  38. Procedure Short_To_AnsiString (Var S1 : AnsiString; Const S2 : ShortString); forward;
  39. Function AnsiCompare (Var S1,S2 : AnsiString): Longint; forward;
  40. Function AnsiCompare (var S1 : AnsiString; Var S2 : ShortString): Longint; forward;
  41. Procedure SetCharAtIndex (Var S : AnsiString; Index : Longint; C : CHar); forward;
  42. { Public functions, Will end up in systemh.inc }
  43. {$PACKRECORDS 1}
  44. Type TAnsiRec = Record
  45. Maxlen, len, ref : Longint;
  46. First : Char;
  47. end;
  48. PAnsiRec = ^TAnsiRec;
  49. Const AnsiRecLen = SizeOf(TAnsiRec);
  50. FirstOff = SizeOf(TAnsiRec)-1;
  51. { ---------------------------------------------------------------------
  52. Internal functions, not in interface.
  53. ---------------------------------------------------------------------}
  54. Procedure DumpAnsiRec (Var S : Ansistring);
  55. begin
  56. If Pointer(S)=Nil then
  57. Writeln ('String is nil')
  58. Else
  59. Begin
  60. With PAnsiRec(Pointer(S)-Firstoff)^ do
  61. begin
  62. Writeln ('Maxlen : ',maxlen);
  63. Writeln ('Len : ',len);
  64. Writeln ('Ref : ',ref);
  65. end;
  66. end;
  67. end;
  68. Function NewAnsiString (Len : Longint) : AnsiString;
  69. {
  70. Allocate a new AnsiString on the heap.
  71. initialize it to zero length and reference count 1.
  72. }
  73. Var P : Pointer;
  74. begin
  75. GetMem(P,Len+AnsiRecLen);
  76. If P<>Nil then
  77. begin
  78. PAnsiRec(P)^.Maxlen:=Len; { Maximal length }
  79. PAnsiRec(P)^.Len:=0; { Initial length }
  80. PAnsiRec(P)^.Ref:=1; { Set reference count }
  81. PAnsiRec(P)^.First:=#0; { Terminating #0 }
  82. P:=P+FirstOff; { Points to string now }
  83. end;
  84. Pointer(NewAnsiString):=P;
  85. end;
  86. Procedure DisposeAnsiString (Var S : AnsiString);
  87. {
  88. Deallocates a AnsiString From the heap.
  89. }
  90. begin
  91. // Writeln ('In disposeAnsiSTring');
  92. If Pointer(S)=Nil then exit;
  93. Dec (Longint(S),FirstOff);
  94. FreeMem (Pointer(S),PAnsiRec(Pointer(S))^.Maxlen+AnsiRecLen);
  95. Pointer(S):=Nil;
  96. end;
  97. Procedure Decr_Ansi_Ref (Var S : AnsiString);[Alias : 'DECR_ANSI_REF'];
  98. {
  99. Decreases the ReferenceCount of a non constant ansistring;
  100. If the reference count is zero, deallocate the string;
  101. }
  102. Type plongint = ^longint;
  103. Var l : plongint;
  104. Begin
  105. // dumpansirec(s);
  106. If Pointer(S)=Nil then exit; { Zero string }
  107. { check for constant strings ...}
  108. l:=Pointer(S)-FirstOff+8;
  109. If l^<0 then exit;
  110. l^:=l^-1;
  111. // dumpansirec(s);
  112. If l^=0 then
  113. { Ref count dropped to zero }
  114. begin
  115. // Writeln ('CAlling disposestring');
  116. DisposeAnsiString (S); { Remove...}
  117. end
  118. end;
  119. Procedure Incr_Ansi_Ref (Var S : AnsiString);[Alias : 'INCR_ANSI_REF'];
  120. Begin
  121. If Pointer(S)=Nil then exit;
  122. { Let's be paranoid : Constant string ??}
  123. If PansiRec(Pointer(S)-FirstOff)^.Ref<0 then exit;
  124. inc(PAnsiRec(Pointer(S)-FirstOff)^.Ref);
  125. end;
  126. Procedure UniqueAnsiString (Var S : AnsiString);
  127. {
  128. Make sure reference count of S is 1,
  129. using copy-on-write semantics.
  130. }
  131. Var SNew : Pointer;
  132. begin
  133. If Pointer(S)=Nil then exit;
  134. if PAnsiRec(Pointer(S)-Firstoff)^.Ref>1 then
  135. begin
  136. SNew:=Pointer(NewAnsiString (PAnsiRec(Pointer(S)-FirstOff)^.len));
  137. Move (Pointer(S)^,SNew^,PAnsiRec(Pointer(S)-FirstOff)^.len+1);
  138. PAnsiRec(SNew-8)^.len:=PAnsiRec(Pchar(S)-FirstOff)^.len;
  139. Decr_Ansi_Ref (S); { Thread safe }
  140. Pchar(S):=Pchar(SNew);
  141. end;
  142. end;
  143. Procedure AssignAnsiString (Var S1 : AnsiString; S2 : Pointer); [Public, Alias : 'ASSIGN_ANSI_STRING'];
  144. {
  145. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  146. If S2 is a constant string, a new S1 is allocated on the heap.
  147. }
  148. Var Temp : Pointer;
  149. begin
  150. If S2<>nil then
  151. begin
  152. If PAnsiRec(S2-FirstOff)^.Ref<0 then
  153. begin
  154. { S2 is a constant string, Create new string with copy. }
  155. Temp:=Pointer(NewAnsiString(PansiRec(S2-FirstOff)^.Len));
  156. Move (S2^,Temp^,PAnsiRec(S2-FirstOff)^.len+1);
  157. PAnsiRec(Temp-FirstOff)^.Len:=PAnsiRec(S2-FirstOff)^.len;
  158. end
  159. else
  160. begin
  161. Inc(PAnsiRec(S2-FirstOff)^.ref);
  162. Temp:=S2;
  163. end;
  164. end;
  165. { Decrease the reference count on the old S1 }
  166. Decr_Ansi_Ref (S1);
  167. { And finally, have S1 pointing to S2 (or its copy) }
  168. Pointer(S1):=Temp;
  169. end;
  170. Procedure Ansi_String_Concat (Var S1 : AnsiString; Var S2 : AnsiString);
  171. {
  172. Concatenates 2 AnsiStrings : S1+S2.
  173. Result Goes to S1;
  174. }
  175. Var Size,Location : Longint;
  176. begin
  177. if Pointer(S2)=Nil then exit;
  178. if (Pointer(S1)=Nil) then
  179. AssignAnsiString(S1,S2)
  180. else
  181. begin
  182. Size:=PAnsiRec(Pointer(S2)-FirstOff)^.Len;
  183. Location:=Length(S1);
  184. { Setlength takes case of uniqueness
  185. and allocated memory. We need to use length,
  186. to take into account possibility of S1=Nil }
  187. //!! SetLength (S1,Size+Location);
  188. Move (Pointer(S2)^,Pointer(Pointer(S1)+location)^,Size+1);
  189. end;
  190. end;
  191. Procedure Ansi_ShortString_Concat (Var S1: AnsiString; Var S2 : ShortString);
  192. {
  193. Concatenates a Ansi with a short string; : S2 + S2
  194. }
  195. Var Size,Location : Longint;
  196. begin
  197. Size:=byte(S2[0]);
  198. Location:=Length(S1);
  199. If Size=0 then exit;
  200. { Setlength takes case of uniqueness
  201. and alllocated memory. We need to use length,
  202. to take into account possibility of S1=Nil }
  203. SetLength (S1,Size+Length(S1));
  204. Move (S2[1],Pointer(Pointer(S1)+Location)^,Size);
  205. PByte( Pointer(S1)+length(S1) )^:=0; { Terminating Zero }
  206. end;
  207. Procedure Ansi_To_ShortString (Var S1 : ShortString;S2 : Pointer; Maxlen : Longint);
  208. [Public, alias: 'FPC_TO_ANSISTRING_SHORT'];
  209. {
  210. Converts a AnsiString to a ShortString;
  211. }
  212. Var Size : Longint;
  213. begin
  214. Size:=PAnsiRec(S2-FirstOff)^.Len;
  215. If Size>maxlen then Size:=maxlen;
  216. Move (S2^,S1[1],Size);
  217. byte(S1[0]):=Size;
  218. end;
  219. Procedure Short_To_AnsiString (Var S1 : AnsiString; Const S2 : ShortString); [Public, alias: 'FPC_SHORT_TO_ANSISTRING'];
  220. {
  221. Converts a ShortString to a AnsiString;
  222. }
  223. Var Size : Longint;
  224. begin
  225. Size:=Byte(S2[0]);
  226. Setlength (S1,Size);
  227. Move (S2[1],Pointer(S1)^,Size);
  228. { Terminating Zero }
  229. PByte(Pointer(S1)+Size)^:=0;
  230. end;
  231. Const EmptyChar : char = #0;
  232. Function Ansi2pchar (S : Pointer) : Pchar; [Alias : 'ANSI2PCHAR'];
  233. begin
  234. If S<>Nil then
  235. Ansi2Pchar:=S
  236. else
  237. Ansi2Pchar:=@emptychar;
  238. end;
  239. Function AnsiCompare (Var S1,S2 : AnsiString): Longint;
  240. {
  241. Compares 2 AnsiStrings;
  242. The result is
  243. <0 if S1<S2
  244. 0 if S1=S2
  245. >0 if S1>S2
  246. }
  247. Var i,MaxI,Temp : Longint;
  248. begin
  249. Temp:=0;
  250. i:=0;
  251. MaxI:=Length(S1);
  252. if MaxI>Length(S2) then MaxI:=Length(S2);
  253. While (i<MaxI) and (Temp=0) do
  254. begin
  255. Temp:= PByte(Pointer(S1)+I)^ - PByte(Pointer(S2)+i)^;
  256. inc(i);
  257. end;
  258. if temp=0 then temp:=Length(S1)-Length(S2);
  259. AnsiCompare:=Temp;
  260. end;
  261. Function AnsiCompare (Var S1 : AnsiString; Var S2 : ShortString): Longint;
  262. {
  263. Compares a AnsiString with a ShortString;
  264. The result is
  265. <0 if S1<S2
  266. 0 if S1=S2
  267. >0 if S1>S2
  268. }
  269. Var i,MaxI,Temp : Longint;
  270. begin
  271. Temp:=0;
  272. i:=0;
  273. MaxI:=Length(S1);
  274. if MaxI>byte(S2[0]) then MaxI:=Byte(S2[0]);
  275. While (i<MaxI) and (Temp=0) do
  276. begin
  277. Temp:= PByte(Pointer(S1)+I)^ - Byte(S2[i+1]);
  278. inc(i);
  279. end;
  280. AnsiCompare:=Temp;
  281. end;
  282. Procedure SetCharAtIndex (Var S : AnsiString; Index : Longint; C : CHar);
  283. begin
  284. if Index<=Length(S) then
  285. begin
  286. UniqueAnsiString(S);
  287. Pbyte(Pointer(S)+index-1)^:=Byte(C);
  288. end;
  289. end;
  290. { ---------------------------------------------------------------------
  291. Public functions, In interface.
  292. ---------------------------------------------------------------------}
  293. Function Length (Var S : AnsiString) : Longint;
  294. {
  295. Returns the length of an AnsiString.
  296. Takes in acount that zero strings are NIL;
  297. }
  298. begin
  299. If Pointer(S)=Nil then
  300. Length:=0
  301. else
  302. Length:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  303. end;
  304. Procedure SetLength (Var S : AnsiString; l : Longint);
  305. {
  306. Sets The length of string S to L.
  307. Makes sure S is unique, and contains enough room.
  308. }
  309. Var Temp : Pointer;
  310. begin
  311. If (Pointer(S)=Nil) and (l>0) then
  312. begin
  313. { Need a complete new string...}
  314. // S:=NewAnsiString(l);
  315. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  316. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  317. PByte (Pointer(S)+l)^:=0;
  318. end
  319. else if l>0 then
  320. begin
  321. If (PAnsiRec(Pointer(S)-FirstOff)^.Maxlen < L) or
  322. (PAnsiRec(Pointer(S)-FirstOff)^.Ref <> 1) then
  323. begin
  324. { Reallocation is needed... }
  325. Temp:=Pointer(NewAnsiString(L));
  326. if Length(S)>0 then
  327. Move (Pointer(S)^,Temp^,Length(S)+1);
  328. Decr_Ansi_ref (S);
  329. Pointer(S):=Temp;
  330. end;
  331. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l
  332. end
  333. else
  334. { Length=0 }
  335. begin
  336. Decr_Ansi_Ref (S);
  337. S:=Nil;
  338. end;
  339. end;
  340. Function Copy (Var S : AnsiString; Index,Size : Longint) : AnsiString;
  341. var ResultAddress : Pointer;
  342. begin
  343. ResultAddress:=Nil;
  344. dec(index);
  345. { Check Size. Accounts for Zero-length S }
  346. if Length(S)<Index+Size then
  347. Size:=Length(S)-Index;
  348. If Size>0 then
  349. begin
  350. ResultAddress:=Pointer(NewAnsiString (Size));
  351. if ResultAddress<>Nil then
  352. begin
  353. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  354. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  355. PByte(ResultAddress+Size)^:=0;
  356. end;
  357. end;
  358. Copy:=AnsiString(ResultAddress);
  359. end;
  360. Function Pos (Var Substr : AnsiString; Var Source : AnsiString) : Longint;
  361. var i,j : longint;
  362. e : boolean;
  363. s : Pointer;
  364. begin
  365. i := 0;
  366. j := 0;
  367. e := true;
  368. if Plongint(substr)^=0 then e := false;
  369. while (e) and (i <= length (Source) - length (substr)) do
  370. begin
  371. inc (i);
  372. S:=Pointer(copy(Source,i,length(Substr)));
  373. if AnsiCompare(substr,AnsiString(s))=0 then
  374. begin
  375. j := i;
  376. e := false;
  377. end;
  378. DisposeAnsiString(AnsiString(S));
  379. end;
  380. pos := j;
  381. end;
  382. Procedure Val (var S : AnsiString; var R : real; Var Code : Integer);
  383. Var SS : String;
  384. begin
  385. Ansi_To_ShortString (SS,S,255);
  386. Val(SS,R,Code);
  387. end;
  388. {
  389. Procedure Val (var S : AnsiString; var D : Double; Var Code : Integer);
  390. Var SS : ShortString;
  391. begin
  392. Ansi_To_ShortString (SS,S,255);
  393. Val(SS,D,Code);
  394. end;
  395. }
  396. Procedure Val (var S : AnsiString; var E : Extended; Code : Integer);
  397. Var SS : ShortString;
  398. begin
  399. Ansi_To_ShortString (SS,S,255);
  400. Val(SS,E,Code);
  401. end;
  402. Procedure Val (var S : AnsiString; var C : Cardinal; Code : Integer);
  403. Var SS : ShortString;
  404. begin
  405. Ansi_To_ShortString (SS,S,255);
  406. Val(SS,C,Code);
  407. end;
  408. Procedure Val (var S : AnsiString; var L : Longint; Var Code : Integer);
  409. Var SS : ShortString;
  410. begin
  411. Ansi_To_ShortString (SS,S,255);
  412. Val(SS,L,Code);
  413. end;
  414. Procedure Val (var S : AnsiString; var W : Word; Var Code : Integer);
  415. Var SS : ShortString;
  416. begin
  417. Ansi_To_ShortString (SS,S,255);
  418. Val(SS,W,Code);
  419. end;
  420. Procedure Val (var S : AnsiString; var I : Integer; Var Code : Integer);
  421. Var SS : ShortString;
  422. begin
  423. Ansi_To_ShortString (SS,S,255);
  424. Val(SS,I,Code);
  425. end;
  426. Procedure Val (var S : AnsiString; var B : Byte; Var Code : Integer);
  427. Var SS : ShortString;
  428. begin
  429. Ansi_To_ShortString (SS,S,255);
  430. Val(SS,B,Code);
  431. end;
  432. Procedure Val (var S : AnsiString; var SI : ShortInt; Var Code : Integer);
  433. Var SS : ShortString;
  434. begin
  435. Ansi_To_ShortString (SS,S,255);
  436. Val(SS,SI,Code);
  437. end;
  438. {
  439. Procedure Str (Const R : Real;Len,fr : Longint; Const S : AnsiString);
  440. Var SS : ShortString;
  441. begin
  442. {int_Str_Real (R,Len,fr,SS);}
  443. Short_To_AnsiString (S,SS);
  444. end;
  445. {
  446. Procedure Str (Var D : Double;Len,fr: Longint; Var S : AnsiString);
  447. Var SS : ShortString;
  448. begin
  449. {int_Str_Double (D,Len,fr,SS);}
  450. Short_To_AnsiString (S,SS);
  451. end;
  452. }
  453. Procedure Str (Var E : Extended;Lenf,Fr: Longint; Var S : AnsiString);
  454. Var SS : ShortString;
  455. begin
  456. {int_Str_Extended (E,Len,fr,SS);}
  457. Short_To_AnsiString (S,SS);
  458. end;
  459. Procedure Str (Var C : Cardinal;Len : Longint; Var S : AnsiString);
  460. begin
  461. end;
  462. Procedure Str (Var L : Longint; Len : Longint; Var S : AnsiString);
  463. Var SS : ShortString;
  464. begin
  465. {int_Str_Longint (L,Len,fr,SS);}
  466. Short_To_AnsiString (S,SS);
  467. end;
  468. Procedure Str (Var W : Word;Len : Longint; Var S : AnsiString);
  469. begin
  470. end;
  471. Procedure Str (Var I : Integer;Len : Longint; Var S : AnsiString);
  472. begin
  473. end;
  474. Procedure Str (Var B : Byte; Len : Longint; Var S : AnsiString);
  475. begin
  476. end;
  477. Procedure Str (Var SI : ShortInt; Len : Longint; Var S : AnsiString);
  478. begin
  479. end;
  480. }
  481. Procedure Delete (Var S : AnsiString; Index,Size: Longint);
  482. begin
  483. if index<=0 then
  484. begin
  485. Size:=Size+index-1;
  486. index:=1;
  487. end;
  488. if (Index<=length(s)) and (Size>0) then
  489. begin
  490. UniqueAnsiString (S);
  491. if Size+Index>Length(S) then
  492. Size:=Length(s)-Index+1;
  493. Setlength(s,Length(s)-Size);
  494. if Index<=Length(s) then
  495. Move(Pointer(Pointer(S)+Index+Size-1)^,
  496. Pointer(Pointer(s)+Index-1)^,Length(s)-Index+2)
  497. else
  498. Pbyte(Pointer(S)+Length(S))^:=0;
  499. end;
  500. end;
  501. Procedure Insert (Var Source : AnsiString; Var S : AnsiString; Index : Longint);
  502. var s3,s4 : Pointer;
  503. begin
  504. If Length(Source)=0 then exit;
  505. if index <= 0 then index := 1;
  506. s3 := Pointer(copy(s,index,length(s)));
  507. if index > Length(s) then
  508. index := Length(S)+1;
  509. SetLength(s,index - 1);
  510. s4 := Pointer ( NewAnsiString(PansiRec(Pointer(Source)-Firstoff)^.len) );
  511. Ansi_String_Concat(AnsiString(s4),Source);
  512. if S4<>Nil then
  513. Ansi_String_Concat(AnsiString(S4),AnsiString(s3));
  514. Ansi_String_Concat(S,AnsiString(S4));
  515. Decr_ansi_ref (AnsiString(S3));
  516. Decr_ansi_ref (AnsiString(S4));
  517. end;
  518. {
  519. $Log$
  520. Revision 1.13 1998-08-23 20:58:51 florian
  521. + rtti for objects and classes
  522. + TObject.GetClassName implemented
  523. Revision 1.12 1998/08/22 09:32:12 michael
  524. + minor fixes typos, and ansi2pchar
  525. Revision 1.11 1998/08/08 12:28:10 florian
  526. * a lot small fixes to the extended data type work
  527. Revision 1.10 1998/07/29 21:44:34 michael
  528. + Implemented reading/writing of ansistrings
  529. Revision 1.9 1998/07/20 23:36:56 michael
  530. changes for ansistrings
  531. Revision 1.8 1998/07/13 21:19:09 florian
  532. * some problems with ansi string support fixed
  533. Revision 1.7 1998/07/06 14:29:08 michael
  534. + Added Public,Alias directives for some calls
  535. Revision 1.6 1998/06/25 08:41:44 florian
  536. * better rtti
  537. Revision 1.5 1998/06/12 07:39:13 michael
  538. + Added aliases for Incr/Decr ref.
  539. Revision 1.4 1998/06/08 19:35:02 michael
  540. Some changes to integrate in system unit
  541. Revision 1.3 1998/06/08 12:38:22 michael
  542. Implemented rtti, inserted ansistrings again
  543. Revision 1.2 1998/05/12 10:42:44 peter
  544. * moved getopts to inc/, all supported OS's need argc,argv exported
  545. + strpas, strlen are now exported in the systemunit
  546. * removed logs
  547. * removed $ifdef ver_above
  548. }