3 This file is part of the Free Pascal run time library.
4 Copyright (c) 1999-2000 by the Free Pascal development team
6 See the file COPYING.FPC, included in this distribution,
7 for details about the copyright.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 **********************************************************************}
15 {****************************************************************************
16 subroutines for string handling
17 ****************************************************************************}
21 function copy(const s : shortstring;index : StrLenInt;count : StrLenInt): shortstring;
29 if index>length(s) then
32 if count>length(s)-index then
33 count:=length(s)-index;
35 Move(s[Index+1],Copy[1],Count);
39 procedure delete(var s : shortstring;index : StrLenInt;count : StrLenInt);
46 if (Index<=Length(s)) and (Count>0) then
48 if Count>length(s)-Index then
49 Count:=length(s)-Index+1;
50 s[0]:=Chr(length(s)-Count);
51 if Index<=Length(s) then
52 Move(s[Index+Count],s[Index],Length(s)-Index+1);
57 procedure insert(const source : shortstring;var s : shortstring;index : StrLenInt);
59 cut,srclen,indexlen : longint;
63 if index>length(s) then
65 indexlen:=Length(s)-Index+1;
66 srclen:=length(Source);
67 if length(source)+length(s)>=sizeof(s) then
69 cut:=length(source)+length(s)-sizeof(s)+1;
72 dec(srclen,cut-indexlen);
78 move(s[Index],s[Index+srclen],indexlen);
79 move(Source[1],s[Index],srclen);
80 s[0]:=chr(index+srclen+indexlen-1);
84 procedure insert(source : Char;var s : shortstring;index : StrLenInt);
90 if index>length(s) then
92 indexlen:=Length(s)-Index+1;
93 if (length(s)+1=sizeof(s)) and (indexlen>0) then
95 move(s[Index],s[Index+1],indexlen);
97 s[0]:=chr(index+indexlen);
101 function pos(const substr : shortstring;const s : shortstring):StrLenInt;
108 e:=(length(SubStr)>0);
109 while e and (i<=Length(s)-Length(SubStr)) do
112 if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then
122 {Faster when looking for a single char...}
123 function pos(c:char;const s:shortstring):StrLenInt;
127 for i:=1 to length(s) do
137 procedure SetLength(var s:shortstring;len:StrLenInt);
145 function copy(c:char;index : StrLenInt;count : StrLenInt): shortstring;
147 if (index=1) and (Count>0) then
154 function pos(const substr : shortstring;c:char): StrLenInt;
156 if (length(substr)=1) and (substr[1]=c) then
163 { removed must be internal to be accepted in const expr !! PM
164 function length(c:char):StrLenInt;
170 {$ifdef IBM_CHAR_SET}
172 UpCaseTbl : shortstring[7]=#154#142#153#144#128#143#165;
173 LoCaseTbl : shortstring[7]=#129#132#148#130#135#134#164;
176 function upcase(c : char) : char;
177 {$IFDEF IBM_CHAR_SET}
182 if (c in ['a'..'z']) then
183 upcase:=char(byte(c)-32)
185 {$IFDEF IBM_CHAR_SET}
199 function upcase(const s : shortstring) : shortstring;
204 for i := 1 to length (s) do
205 upcase[i] := upcase (s[i]);
211 function lowercase(c : char) : char;
212 {$IFDEF IBM_CHAR_SET}
217 if (c in ['A'..'Z']) then
218 lowercase:=char(byte(c)+32)
220 {$IFDEF IBM_CHAR_SET}
224 lowercase:=LoCaseTbl[i]
234 function lowercase(const s : shortstring) : shortstring;
239 for i:=1 to length(s) do
240 lowercase[i]:=lowercase (s[i]);
244 function hexstr(val : longint;cnt : byte) : shortstring;
246 HexTbl : array[0..15] of char='0123456789ABCDEF';
250 hexstr[0]:=char(cnt);
251 for i:=cnt downto 1 do
253 hexstr[i]:=hextbl[val and $f];
259 function binstr(val : longint;cnt : byte) : shortstring;
263 binstr[0]:=char(cnt);
264 for i:=cnt downto 1 do
266 binstr[i]:=char(48+val and 1);
274 function space (b : byte): shortstring;
277 FillChar (Space[1],b,' ');
281 {*****************************************************************************
283 *****************************************************************************}
285 procedure ShortStr_Float(d : ValReal;len,fr,rt : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_FLOAT'];
287 str_real(len,fr,d,treal_type(rt),s);
291 procedure int_str_longint(v : longint;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGINT'];
294 if length(s)<len then
295 s:=space(len-length(s))+s;
299 procedure int_str_cardinal(v : cardinal;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_CARDINAL'];
302 if length(s)<len then
303 s:=space(len-length(s))+s;
307 {*****************************************************************************
309 *****************************************************************************}
311 Function InitVal(const s:shortstring;var negativ:boolean;var base:byte):ValSInt;
315 {Skip Spaces and Tab}
317 while (code<=length(s)) and (s[code] in [' ',#9]) do
330 if code<=length(s) then
337 until (code>=length(s)) or (s[code]<>'0');
349 Function ValSignedInt(DestSize: longint; Const S: ShortString; var Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR'];
351 u, temp, prev: ValUInt;
357 Code:=InitVal(s,negative,base);
358 if Code>length(s) then
360 while Code<=Length(s) do
363 '0'..'9' : u:=Ord(S[Code])-Ord('0');
364 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
365 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
370 Temp := Temp*ValUInt(base);
373 (MaxSIntValue-temp+ord(negative) < u)) or
375 (ValUInt(MaxUIntValue-Temp) < u)) or
376 (prev > ValUInt(MaxUIntValue) div ValUInt(Base)) Then
385 ValSignedInt := ValSInt(Temp);
387 ValSignedInt := -ValSignedInt;
388 If Not(Negative) and (base <> 10) Then
389 {sign extend the result to allow proper range checking}
391 1: If (ValSignedInt > High(ShortInt)) and (ValSignedInt <= High(Byte)) Then
392 ValSignedInt := ValSignedInt or (MaxUIntValue xor High(Byte));
393 2: If (ValSignedInt > High(Integer)) and (ValSignedInt <= High(Word)) Then
394 ValSignedInt := ValSignedInt or (MaxUIntValue xor High(Word));
395 { Uncomment the folling once full 64bit support is in place
396 4: If (ValSignedInt > High(Longint)) and (ValSignedInt <= High(Cardinal)) Then
397 ValSignedInt := ValSignedInt or (MaxUIntValue xor High(Cardinal));}
402 Function ValUnsignedInt(Const S: ShortString; var Code: ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_SHORTSTR'];
409 Code:=InitVal(s,negative,base);
410 If Negative or (Code>length(s)) Then
412 while Code<=Length(s) do
415 '0'..'9' : u:=Ord(S[Code])-Ord('0');
416 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
417 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
421 prev := ValUnsignedInt;
423 (ValUInt(MaxUIntValue-u) div ValUInt(Base)<prev) then
428 ValUnsignedInt:=ValUnsignedInt*ValUInt(base) + u;
435 Function ValFloat(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR'];
438 esign,sign : valreal;
439 exponent,i : longint;
448 while (code<=length(s)) and (s[code] in [' ',#9]) do
457 while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
459 { Read integer part }
461 valfloat:=valfloat*10+(ord(s[code])-ord('0'));
465 if (s[code]='.') and (length(s)>=code) then
469 while (s[code] in ['0'..'9']) and (length(s)>=code) do
471 { Read fractional part. }
473 valfloat:=valfloat*10+(ord(s[code])-ord('0'));
477 valfloat:=valfloat/hd;
479 { Again, read integer and fractional part}
486 if (upcase(s[code])='E') and (length(s)>=code) then
497 if not(s[code] in ['0'..'9']) or (length(s)<code) then
502 while (s[code] in ['0'..'9']) and (length(s)>=code) do
504 exponent:=exponent*10;
505 exponent:=exponent+ord(s[code])-ord('0');
509 { Calculate Exponent }
512 for i:=1 to exponent do
513 valfloat:=valfloat*10
515 for i:=1 to exponent do
516 valfloat:=valfloat/10; }
518 for i:=1 to exponent do
521 valfloat:=valfloat*hd
523 valfloat:=valfloat/hd;
524 { Not all characters are read ? }
525 if length(s)>=code then
531 valfloat:=valfloat*sign;
537 {$ifdef SUPPORT_FIXED}
538 Function ValFixed(const s : shortstring;var code : ValSInt): Fixed; [public, alias:'FPC_VAL_FIXED_SHORTSTR'];
540 ValFixed := Fixed(ValFloat(s,code));
542 {$endif SUPPORT_FIXED}
545 Procedure SetString (Var S : Shortstring; Buf : PChar; Len : Longint);
547 Move (Buf[0],S[1],Len);
553 Revision 1.1 2002/02/19 08:25:28 sasu
556 Revision 1.1.2.4 2000/12/09 20:49:34 florian
557 * val for dword and qword didn't handle the max values
559 * val for qword works again
560 + val with int64/qword and ansistring implemented
562 Revision 1.1.2.3 2000/11/23 11:40:34 jonas
563 * fix for web bug 1265 by Peter
565 Revision 1.1.2.2 2000/11/17 16:56:42 jonas
566 * fixed bug for val when processing -2147483648 and low(int64)
568 Revision 1.1.2.1 2000/07/28 12:19:21 jonas
570 * fixed similar (and other) problems in val() for int64 and qword
572 Revision 1.1 2000/07/13 06:30:48 michael
575 Revision 1.35 2000/04/06 11:51:47 pierre
576 * fix for extended constants
578 Revision 1.34 2000/02/09 16:59:31 peter
581 Revision 1.33 2000/01/07 16:41:36 daniel
584 Revision 1.32 2000/01/07 16:32:25 daniel
585 * copyright 2000 added
587 Revision 1.31 1999/12/11 19:07:44 jonas
588 * avoid unwanted type conversion from cardinal to longint in val for
589 signed and unsigned 32bit int
591 Revision 1.30 1999/11/06 14:35:39 peter