View Issue Details

IDProjectCategoryView StatusLast Update
0035660FPCRTLpublic2019-12-16 11:05
ReporterCudaText man Assigned ToMichael Van Canneyt  
Status closedResolutionfixed 
Product Version3.3.1 
Fixed in Version3.3.1 
Summary0035660: TStringList ValueFromIndex incomatible with Delphi
  l: tstringlist;
  l:= tstringlist.create;
  caption:= l.ValueFromIndex[0]+', '+l.ValueFromIndex[1];
FPC trunk, Win32, gives: 111, bb
Delphi 10.3 gives: 111,
(ie, Delphi gets empty string for item[1])
TagsNo tags attached.
Fixed in Revision42153
Attached Files


jamie philbrook

2019-05-31 16:28

reporter   ~0116481

Last edited: 2019-05-31 16:34

View 2 revisions

Please Read Bellow, at the bottom, its an LCL issue, it is doing what the help states, being it's correct or not.

[Overview][Constants][Types][Classes][Procedures and functions][Variables][Index] Reference for unit 'Classes' (#rtl)


Return the value part of a string based on it's index.


Source position: line 702

public property TStrings.ValueFromIndex[Index: Integer] : string

  read GetValueFromIndex

  write SetValueFromIndex;


ValueFromIndex returns the value part of a string based on the string index. The value part are all characters in the string after the
NameValueSeparator character, or all characters if the NameValueSeparator character is not present.

That has to be a Lazarus (LCL) issue because it also fails with 2.0.2 release using 3.0.4
So maybe a change is needed

CudaText man

2019-05-31 17:35

reporter   ~0116488

no, it is FPC issue, unit Classes belongs to fpcsrc/ folder.

Don Siders

2019-05-31 17:59

reporter   ~0116489

IMO, the FPC behavior is correct. You asked for a value... it gives you a value.

The bug is in Delphi.


2019-05-31 18:29

reporter   ~0116490

But if you're in {$mode Delphi} it should behave exactly as Delphi.
IMO its not a bug in Delphi as the syntax is key=value and you don't give it a value...

CudaText man

2019-05-31 19:35

reporter   ~0116495

It is code in Classes- it has bad logic.
Delphi logic is fully ok - if an item don't have "=" then VALUE of item is empty.

jamie philbrook

2019-05-31 19:56

reporter   ~0116498

Looking at the code it appears the code that is getting executed is not the code that I see in the sources.
why I say this is because I looked the sources and from what I can see it should be working like Delphi,
if you don't have a "=" in the string, it should return an empty string, it does not, it returns the complete string.
 So who ever wrote the docs are claiming it should be this way but its not that way with Delphi and since the behavior does
not match the source I looked at, something is strange here.

procedure TStrings.GetNameValue(Index : Integer; Out AName,AValue : String);
Var L : longint;
  L:=Pos(FNameValueSeparator,AValue); << a test is done here for the "=" or what ever it is at the time.
  If L<>0 then
    begin // this always gets executed.!

As you can see, the behavior does not match the source because from what is in the source should work.
now I guess if one was to recompile the RTL, it just make work but what other changes were there that are not showing in the source code?


2019-05-31 22:08

reporter   ~0116503

Not sure whats stored exactly in AValue:=Strings[Index]; but seems it does not contain the '=' if you only do l.add('bb');

Therefore I guess it should be like this

If L<>0 then

jamie philbrook

2019-05-31 23:49

reporter   ~0116505

Looks reasonable...

Michael Van Canneyt

2019-06-01 09:48

administrator   ~0116512

I Introduced a property PreferValuesToNames.

In absence of a NameValueSeparator character this property decides whether the line is considered a name or a value.
By default it is False, so you will get by default the same behaviour as Delphi.
Set to true to get the old FPC behaviour.

Note that Delphi is inconsistent in its treatment of such case:

program stringsnamevalue;


{$R *.res}


  l: tstringlist;
  l:= tstringlist.create;
  Writeln(l.ValueFromIndex[0]+', '+l.ValueFromIndex[1]);
  Writeln(L.Names[0]+', '+L.Names[1]);

You would expect that if the value is empty, the name is not empty. This is the default behaviour of FPC:
aa, bb
Instead, for Delphi, the name is also empty:
I don't consider this correct, but I am not going to change FPC to make this compatible.

Michael Van Canneyt

2019-06-04 07:04

administrator   ~0116558

Problems popped up. I implemented a different solution in rev. 42170.

The PreferValuesToNames property has been replaced by
    Property MissingNameValueSeparatorAction : TMissingNameValueSeparatorAction;
  TMissingNameValueSeparatorAction = (mnvaValue,mnvaName,mnvaEmpty,mnvaError);
which decides what will be done when getnamevalue (used by Names[i] ValueByIndex[i]) will do if there is no separator:
mnvaValue : Return line as value (backwards compatible default of FPC)
mnvaName : Return line as name
mnvaEmpty : Return empty for both name and value
mnvaError : Raise an exception.

Delphi compatible would probably be mnvaEmpty.

Issue History

Date Modified Username Field Change
2019-05-31 16:08 CudaText man New Issue
2019-05-31 16:28 jamie philbrook Note Added: 0116481
2019-05-31 16:34 jamie philbrook Note Edited: 0116481 View Revisions
2019-05-31 17:14 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-05-31 17:14 Michael Van Canneyt Status new => assigned
2019-05-31 17:35 CudaText man Note Added: 0116488
2019-05-31 17:59 Don Siders Note Added: 0116489
2019-05-31 18:29 rd0x Note Added: 0116490
2019-05-31 19:35 CudaText man Note Added: 0116495
2019-05-31 19:56 jamie philbrook Note Added: 0116498
2019-05-31 22:08 rd0x Note Added: 0116503
2019-05-31 23:49 jamie philbrook Note Added: 0116505
2019-06-01 09:48 Michael Van Canneyt Status assigned => resolved
2019-06-01 09:48 Michael Van Canneyt Resolution open => fixed
2019-06-01 09:48 Michael Van Canneyt Fixed in Version => 3.3.1
2019-06-01 09:48 Michael Van Canneyt Fixed in Revision => 42153
2019-06-01 09:48 Michael Van Canneyt FPCTarget => 3.2.0
2019-06-01 09:48 Michael Van Canneyt Note Added: 0116512
2019-06-04 07:04 Michael Van Canneyt Note Added: 0116558
2019-12-16 11:05 CudaText man Status resolved => closed