[Lazarus] TStringList : how should it behave on Delimiter = ' ' ?

Bogusław Brandys brandys at o2.pl
Wed Sep 8 13:41:02 CEST 2010


W dniu 2010-09-08 12:03, Lukasz Sokol pisze:
> On 07/09/2010 18:20, Vincent Snijders wrote:
>> 2010/9/7 Lukasz Sokol<el.es.cr at gmail.com>:
>>> Hi Group,
>>>
>>> How should the TStringList behave when
>>>
>>> Delimiter := ' ';
>>> QuoteChar := '"';
>>>
>>> ?
>>>
>>> On my
>>>
>>> Lazarus 0.9.28.2 r22279 FPC 2.2.4 i386-win32-win32/win64
>>>
>>> when reading a line like this
>>>
>>> Sep  3 16:27:32 router_ip src="internal IP:46987" dst="external_ip:64880" msg="Traffic Log" note="Traffic Log" devID="0019CBDF94A3" cat="Traffic Log" duration=300 send=168 rcvd=48 dir="LAN:WAN" protoID=17 proto="others" trans="Normal"
>>>
>>> {the above should be one line}
>>>
>>> I will obviously get the date split in 3 different Strings[],
>>> !but! it also splits the 'msg="Traffic' and 'Log"' - is this correct ?
>>>
>>
>> Maybe StrictDelimiter is true?
>> http://www.freepascal.org/docs-html/rtl/classes/tstrings.strictdelimiter.html
>>
>> Vincent
>>
> No, after forcing it to false, it still behaves the same (splits 'msg="Traffic' and 'Log"').
>
> I know this is possibly a corner case, when Delimiter = ' ';  but there seems something
> wrong with the logic in SetDelimitedText... ? (stringl.inc)
> It fails on things like 'msg="Traffic Log"'... because it does not understand that a string
> can be composed of plain and quoted part and should then be treated as one:
>
>
> 	// next string is not quoted
>         j:=i;
>         while (j<=length(AValue)) and
>               (Ord(AValue[j])>Ord(' ')) and
>               (AValue[j]<>FDelimiter) do inc(j);
>         Add( Copy(AValue,i,j-i));
>         i:=j;
>
> maybe could become
>
>    while (j<=length(AValue)) do
>      begin
>        // we might find QuoteChar in string that begins unquoted
>        if (AValue[j]<>FDelimiter) then inc(j)
> 	else
>        if (AValue[j]=FQuoteChar) then
>          begin
>            repeat
>              inc(j);	// carry on until you find another quote, regardless of what is quoted
> 	  until (AValue[j]=FQuoteChar) or (j=length(AValue));
>          end
>        else
>        // do we really have to have a special case for ' ' ? for backward compatibility maybe
>        // but then be it lower priority than quotechar and delimiter
>        if (Ord(AValue[j])>Ord(' ')) then inc(j)
> 	else break;
>      end;
>
> This should be enough to support 'name="some value"' separated by spaces... and also
> "some name"="some value" too... - comments ?
>
> (the if...then...else...if maybe isn't optimal, but shows the idea)
>
> HTH,
> Lukasz


I think TStringList expects at this situation items like "msg=Traffic 
Log". What you need is extended list with support to Keyword=Value for 
example having property Values[Item : string] : string returning left 
side of equation. Something I used in KOL but not sure if it can cope 
with " quote char.


Bogusław





More information about the Lazarus mailing list