{ $Id$ This file is part of the Free Pascal run time library. Copyright (c) 1993,97 by the Free Pascal development team See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} {**************************************************************************** subroutines for string handling ****************************************************************************} {$I real2str.inc} function copy(const s : string;index : integer;count : integer): string; begin if count<0 then count:=0; if index>1 then dec(index) else index:=0; if index>length(s) then count:=0 else if index+count>length(s) then count:=length(s)-index; Copy[0]:=chr(Count); Move(s[Index+1],Copy[1],Count); end; procedure delete(var s : string;index : integer;count : integer); begin if index<=0 then begin count:=count+index-1; index:=1; end; if (Index<=Length(s)) and (Count>0) then begin if Count+Index>length(s) then Count:=length(s)-Index+1; s[0]:=Chr(length(s)-Count); if Index<=Length(s) then Move(s[Index+Count],s[Index],Length(s)-Index+1); end; end; procedure insert(const source : string;var s : string;index : integer); begin if index>1 then dec(index) else index:=0; s:=Copy(s,1,Index)+source+Copy(s,Index+1,length(s)); end; function pos(const substr : string;const s : string): byte; var i,j : longint; e : boolean; begin i := 0; j := 0; e:=(length(SubStr)>0); while e and (i<=Length(s)-Length(SubStr)) do begin inc(i); if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then begin j:=i; e:=false; end; end; Pos:=j; end; {Faster when looking for a single char...} function pos(c:char;const s:string):byte; var i:longint; begin for i:=1 to length(s) do if s[i]=c then begin pos:=i; exit; end; pos:=0; end; {$ifdef IBM_CHAR_SET} const UpCaseTbl : string[7]=#154#142#153#144#128#143#165; LoCaseTbl : string[7]=#129#132#148#130#135#134#164; {$endif} function upcase(c : char) : char; {$IFDEF IBM_CHAR_SET} var i : longint; {$ENDIF} begin if (c in ['a'..'z']) then upcase:=char(byte(c)-32) else {$IFDEF IBM_CHAR_SET} begin i:=Pos(c,LoCaseTbl); if i>0 then upcase:=UpCaseTbl[i] else upcase:=c; end; {$ELSE} upcase:=c; {$ENDIF} end; function upcase(const s : string) : string; var i : longint; begin upcase[0]:=s[0]; for i := 1 to length (s) do upcase[i] := upcase (s[i]); end; function lowercase(c : char) : char; {$IFDEF IBM_CHAR_SET} var i : longint; {$ENDIF} begin if (c in ['A'..'Z']) then lowercase:=char(byte(c)+32) else {$IFDEF IBM_CHAR_SET} begin i:=Pos(c,UpCaseTbl); if i>0 then lowercase:=LoCaseTbl[i] else lowercase:=c; end; {$ELSE} lowercase:=c; {$ENDIF} end; function lowercase(const s : string) : string; var i : longint; begin lowercase [0] := s[0]; for i := 1 to length (s) do lowercase[i] := lowercase (s[i]); end; function space (b : byte): string; begin space[0] := chr(b); FillChar (Space[1],b,' '); end; function hexstr(val : longint;cnt : byte) : string; const HexTbl : array[0..15] of char='0123456789ABCDEF'; var i : longint; begin hexstr[0]:=char(cnt); for i:=cnt downto 1 do begin hexstr[i]:=hextbl[val and $f]; val:=val shr 4; end; end; function binstr(val : longint;cnt : byte) : string; var i : longint; begin binstr[0]:=char(cnt); for i:=cnt downto 1 do begin binstr[i]:=char(48+val and 1); val:=val shr 1; end; end; {$ifndef str_intern } procedure str(i : integer;var s : string); begin str(longint(i),s); end; procedure str(si : shortint;var s : string); begin str(longint(si),s); end; procedure str(b : byte;var s : string); begin str(longint(b),s); end; procedure str(w : word;var s : string); begin str(longint(w),s); end; {$ifdef ieee_support} procedure str(d : double;var s : string); begin str_real(-1,-1,d,rt_s64real,s); end; {$endif ieee_support} {$ifndef ieee_support} { REAL TYPE = single type in this case } procedure str(d : real;var s : string); begin str_real(-1,-1,d,rt_s32real,s); end; {$endif ieee_support} {$else not str_intern } procedure int_str_real(d : real;len,fr : longint;var s : string);[public, alias : 'STR_REAL']; begin {$ifdef i386} str_real(len,fr,d,rt_s64real,s); {$else} str_real(len,fr,d,rt_s32real,s); {$endif} end; {$ifdef support_ieee} procedure int_str_single(d : single;len,fr : longint;var s : string);[public, alias : 'STR_SINGLE']; begin str_real(len,fr,d,rt_s32real,s); end; procedure int_str_extended(d : extended;len,fr : longint;var s : string);[public, alias : 'STR_EXTENDED']; begin str_real(len,fr,d,rt_s80real,s); end; {$endif support_ieee} {$ifdef support_comp} procedure int_str_comp(d : comp;len,fr : longint;var s : string);[public, alias : 'STR_COMP']; begin str_real(len,fr,d,rt_s64bit,s); end; {$endif support_comp} procedure int_str_fixed(d : fixed;len,fr : longint;var s : string);[public, alias : 'STR_FIXED']; begin str_real(len,fr,d,rt_f32bit,s); end; procedure int_str_longint(v : longint;len : longint;var s : string);[public, alias : 'STR_LONGINT']; begin int_str(v,s); if length(s)=code) then begin hd:=0.1; inc(code); { After dot, a number is required. } if not(s[code] in ['0'..'9']) or (length(s)=code) do begin { Read fractional part. } flags:=flags or 2; d:=d+hd*(ord(s[code])-ord('0')); hd:=hd/10.0; inc(code); end; end; { Again, read integer and fractional part} if flags=0 then begin d:=0.0; exit; end; { Exponent ? } if (upcase(s[code])='E') and (length(s)>=code) then begin inc(code); if s[code]='+' then inc(code) else if s[code]='-' then begin esign:=-1; inc(code); end; if not(s[code] in ['0'..'9']) or (length(s)=code) do begin exponent:=exponent*10; exponent:=exponent+ord(s[code])-ord('0'); inc(code); end; end; { Calculate Exponent } if esign>0 then for i:=1 to exponent do d:=d*10 else for i:=1 to exponent do d:=d/10; { Not all characters are read ? } if length(s)>=code then begin d:=0.0; exit; end; { evalute sign } d:=d*sign; { success ! } code:=0; end; procedure val(const s : string;var d : real;var code : integer); begin val(s,d,word(code)); end; procedure val(const s : string;var d : real); var code : word; begin val(s,d,code); end; {$ifdef ver_above0_9_2} {$IFDEF ieee_support} procedure val(const s : string;var d : single;var code : word); var e : double; begin val(s,e,code); d:=e; end; procedure val(const s : string;var d : single;var code : integer); var e : double; begin val(s,e,word(code)); d:=e; end; procedure val(const s : string;var d : single); var code : word; e : double; begin val(s,e,code); d:=e; end; {$ENDIF ieee_support} {$endif ver_above0_9_2} {$ifdef ver_above0_9_7} {$ifdef ieee_support} procedure val(const s : string;var d : extended;var code : word); var e : double; begin val(s,e,code); d:=e; end; procedure val(const s : string;var d : extended;var code : integer); var e : double; begin val(s,e,word(code)); d:=e; end; procedure val(const s : string;var d : extended); var code : word; e : double; begin val(s,e,code); d:=e; end; {$endif ieee_support} {$ifdef comp_support} procedure val(const s : string;var d : comp;var code : word); var e : double; begin val(s,e,code); d:=e; end; procedure val(const s : string;var d : comp;var code : integer); var e : double; begin val(s,e,word(code)); d:=e; end; procedure val(const s : string;var d : comp); var code : word; e : double; begin val(s,e,code); d:=e; end; {$endif comp_support} {$endif ver_above0_9_7} Function InitVal(const s:string;var negativ:boolean;var base:byte):Word; var Code : Longint; begin {Skip Spaces and Tab} code:=1; while (code<=length(s)) and (s[code] in [' ',#9]) do inc(code); {Sign} negativ:=false; case s[code] of '-' : begin negativ:=true; inc(code); end; '+' : inc(code); end; {Base} base:=10; if code<=length(s) then begin case s[code] of '$' : begin base:=16; repeat inc(code); until (code>=length(s)) or (s[code]<>'0'); if length(s)-code>7 then inc(code,8); end; '%' : begin base:=2; inc(code); end; end; end; InitVal:=code; end; procedure val(const s : string;var v : longint;var code : word); var base,u : byte; negativ : boolean; begin v:=0; Code:=InitVal(s,negativ,base); if Code>length(s) then exit; if negativ and (s='-2147483648') then begin Code:=0; v:=$80000000; exit; end; while Code<=Length(s) do begin u:=ord(s[code]); case u of 48..57 : dec(u,48); 65..70 : dec(u,55); 97..104 : dec(u,87); else u:=16; end; v:=v*longint(base); if (u>=base) or ((base=10) and (2147483647-vlength(s)) or negativ then exit; while Code<=Length(s) do begin u:=ord(s[code]); case u of 48..57 : dec(u,48); 65..70 : dec(u,55); 97..104 : dec(u,87); else u:=16; end; cardinal(v):=cardinal(v)*cardinal(longint(base)); if (u>base) or (cardinal($ffffffff)-cardinal(v)>cardinal(longint(u))) then begin v:=0; exit; end; inc(v,u); inc(code); end; code:=0; end; procedure val(const s : string;var v : cardinal); var code : word; begin val(s,v,code); end; procedure val(const s : string;var v : cardinal;var code : integer); begin val(s,v,word(code)); end; {$endif ver_above0_9_8} { $Log$ Revision 1.2 1998-03-26 14:41:22 michael + Added comp support for val and read(ln) Revision 1.1.1.1 1998/03/25 11:18:43 root * Restored version Revision 1.8 1998/03/18 15:04:36 pierre * bug in val : a was accepted as 10 in base 10 !! Revision 1.7 1998/02/11 16:55:18 michael fixed cardinal printing. Large cardinals (>0fffffff) not yet working Revision 1.6 1998/02/08 23:57:51 peter * fixed val(longint) so it works again with $80000000+ Revision 1.5 1998/02/08 21:51:40 peter * some optimizes and Val(cardinal) fixed Revision 1.4 1998/01/26 12:00:13 michael + Added log at the end revision 1.3 date: 1998/01/23 12:06:05; author: daniel; state: Exp; lines: +18 -22 * Did some small code tweaks. ---------------------------- revision 1.2 date: 1998/01/12 02:31:44; author: carl; state: Exp; lines: +30 -9 + added generic Floating point support/fixes for m68k port and other ports ---------------------------- revision 1.1 date: 1997/12/22 18:54:25; author: michael; state: Exp; + Initial implementation: moved all strings routines from system.inc to sstrings.inc. ============================================================================= }