Jump to content
emileverh

String literals more then 255 chars

Recommended Posts

Hey guys!

 

I need a little help, I created a ticket. We live in 2023, talking about 64-bit compilers, FMX, and other high-tech stuff, and a string literal can not be longer then 255 chars? for use with resourcestrings, consts. Come on.....

 

Please vote! https://quality.embarcadero.com/browse/RSP-41138

Edited by emileverh
  • Like 1

Share this post


Link to post
1 hour ago, emileverh said:

Hey guys!

 

I need a little help, I created a ticket. We live in 2023, talking about 64-bit compilers, FMX, and other high-tech stuff, and a string literal can not be longer then 255 chars? for use with resourcestrings, consts. Come on.....

 

Please vote! https://quality.embarcadero.com/browse/RSP-41138

The compiler accepts this without problems:

const
  CTest =
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ;

 

  • Like 2

Share this post


Link to post
8 minutes ago, PeterBelow said:

The compiler accepts this without problems:


const
  CTest =
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'+
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ;

 

Yes I know you can use the '+' sign. But we have all seen this issue sooner or later. 255 chars is something for Delphi 1 or Delphi 2, not for Delphi 11 in 2023!

 

I have third party tools for my mutli-language app. And if the string is too long everything stucks.  The only thing I ask for EMB, why can't they change 'const' or 'resourcestring' from 'shortstring' to string?

Edited by emileverh
  • Like 1

Share this post


Link to post
22 hours ago, emileverh said:

I have third party tools for my mutli-language app. And if the string is too long everything stucks.  The only thing I ask for EMB, why can't they change 'const' or 'resourcestring' from 'shortstring' to string?

They are of type String already. The limitation seems to be in the parser which cannot deal with lines longer than 255 characters in the source. But there is an easy workaround, which your third-party tool should use for long string literals: split it into several shorter literals concatenated by '+' plus linebreaks.  Much easier to read for you as well if you need to manually correct stuff later.

  • Like 1

Share this post


Link to post

I wrote a small method to convert any text (even multiple lines) to a "Delphi source file string". I'm sure there are limitations but does it's job just fine for me:

Function ToDelphiString(Const outString: String): String;
Const
  ADDITION = #39' + '#39;
  BREAKAT = 80;
Var
  line, a, max: Integer;
  sb: TStringBuilder;
  strarr: TArray<String>;
Begin
  sb := TStringBuilder.Create;
  Try
    sb.Append(#39);

    strarr := AdjustLineBreaks(outString).Split([sLineBreak]);

    For line := Low(strarr) To High(strarr) Do
    Begin
      max := strarr[line].Length Div BREAKAT;

      For a := 0 To max Do
      Begin
        sb.Append(strarr[line].Substring(a * BREAKAT, BREAKAT).Replace(#39, #39#39));

        sb.Append(#39);

        If a <> max Then
          sb.Append(' +' + sLineBreak + #39);
      End;

      If line <> High(strarr) Then
        sb.Append(' + sLineBreak +' + sLineBreak + #39);
    End;

    Result := sb.ToString;
  Finally
    FreeAndNil(sb);
  End;
End;

You can use it to overcome the 255 character limitation.

Share this post


Link to post

Nice your code... I can not use it! Because of a third party tool.

 

I don't know how many Delphi programmers are here in this world. A few thousand sure, but if we sum all the time spend on this ( for me stupid) limitation lot's of money is thrown away. Is it a show stopper? No. Is it critical? No. Are there workarounds? Yes. The only thing I hope is that EMB changes this old fashion limitation. 

  • Like 1

Share this post


Link to post
24 minutes ago, emileverh said:

if we sum all the time spend on this ( for me stupid) limitation

I for myself have never spent any time on this limitation, because I never had to (and probably never will) write that long string literals. Not only that the style guide is much stricter, it is just way less readable and thus I would never even think of doing that. In addition I would literally slap such code in the face of the developer presenting it to me. So better don't count me in here.

  • Like 6

Share this post


Link to post
3 minutes ago, Uwe Raabe said:

I for myself have never spent any time on this limitation, because I never had to (and probably never will) write that long string literals. Not only that the style guide is much stricter, it is just way less readable and thus I would never even think of doing that. In addition I would literally slap such code in the face of the developer presenting it to me. So better don't count me in here.

One last remark, as said, it's this issue not shocking....

I use DevExpress 'dxFormattedLabels' a lot. So in the string there will be extra markup code for setting text to bold and/or italic or change color. So the string can quickly become quite large. If you use a multi language app ( as I have Dutch and English for now), the string can grow beyond it's limitation.

 

Break; never filed a request to EMB before, but I see they changed the status to OPEN and INTERNAL ASSIGNED. So there is a little hope 😉

 

Have a nice day, to you all. And enjoy D11.3 as much as I do. There are lot's of improvements!!!

  • Thanks 1

Share this post


Link to post

is it not the same than above?

 

procedure TForm1.Button1Click(Sender: TObject);
var
  LText      : string;
  LSubText   : string;
  LFinalText : string;
  LPos       : Integer;
  LTextLength: Integer;
  LLineLenght: Integer;
begin
  // here, there is no-way!!! "const" just 255
  LText := 'They are of type String already. The limitation seems to be in the parser which cannot deal with lines longer ' +              { }
    'than 255 characters in the source. But there is an easy workaround, which your third-party tool should use for long string ' +        { }
    'literals: split it into several shorter literals concatenated by plus linebreaks.  Much easier to read for you as well if you need' + { }
    ' to manually correct stuff later.';
  //
  LFinalText  := #39;
  LLineLenght := 11; // >= 1...
  LPos        := 1;  // >  1..
  LTextLength := LText.Length;
  while LPos <= LTextLength do
    begin
      LSubText := copy(LText, LPos, LLineLenght);
      //
      LFinalText := LFinalText + LSubText + #39;
      //
      LPos := LPos + LLineLenght;
      //
      if (LPos <= LTextLength) then
        LFinalText := LFinalText + '+' + sLineBreak + #39;
    end;
  //
  Memo1.Text := LFinalText;
end;

 

Edited by programmerdelphi2k

Share this post


Link to post
2 hours ago, Uwe Raabe said:

... it is just way less readable and thus I would never even think of doing that. In addition I would literally slap such code in the face of the developer presenting it to me. So better don't count me in here.

I use this in some kind of "not-human-readable" const definitions,. for example as a central, unique definition of some medium complex SVG pathdata icons.

To not confuse anybody I usually put such definitions in a separate unit then, well commented about its purpose.

So I see this use case a little more practical, not just pure black-and-white, I think it can make sense in some situations.

  • Like 1

Share this post


Link to post
On 3/11/2023 at 6:10 AM, emileverh said:

Hey guys!

 

I need a little help, I created a ticket. We live in 2023, talking about 64-bit compilers, FMX, and other high-tech stuff, and a string literal can not be longer then 255 chars? for use with resourcestrings, consts. Come on.....

 

Please vote! https://quality.embarcadero.com/browse/RSP-41138

I first complained about that limitation in November of 2012. 😞 I think I heard it was due to legacy Borland Turbo Pascal code. 😞

 

The ridiculous thing is that FreePascal's Lazarus IDE has the same limitation, like they were striving for bug-for-bug compatibility or something.

Share this post


Link to post
On 3/12/2023 at 8:06 AM, PeterBelow said:

They are of type String already. The limitation seems to be in the parser which cannot deal with lines longer than 255 characters in the source. But there is an easy workaround, which your third-party tool should use for long string literals: split it into several shorter literals concatenated by '+' plus linebreaks.  Much easier to read for you as well if you need to manually correct stuff later.

This is it. What I believe I heard when I complained about this in 2012 (!!!) from Mason Wheeler who got it from Allan Bauer was that it was due to legacy Turbo Pascal code in the IDE that they don't plan on touching.

 

Splitting strings yourself is just ridiculous. It's 2023 and we've got Star Trek computer-grade AI with ChatGPT and BingBot and humanoid robots coming shortly. Way past time to join... well, the 20th century. Forget long strings... this needs to be fixed for multi-line strings to be feasible. This limitation drove me nuts in 2012 when I was trying to help someone parse some nasty HTML and I tried to enter the text into Delphi and realized the limitation was still there. Fine, I'll do it in Lazarus/FreePascal... guess what? They're limited to 255 characters too, which is bizarre. It's like they artificially limited themselves to match Delphi's limitations!

 

It's long past time that one should be able to write

 

HTML := "<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>My test page</title>
  </head>
  <body>
    <img src="images/firefox-icon.png" alt="My test image" />
  </body>
</html>"

 

Share this post


Link to post
On 3/13/2023 at 11:22 AM, Uwe Raabe said:

I for myself have never spent any time on this limitation, because I never had to (and probably never will) write that long string literals. Not only that the style guide is much stricter, it is just way less readable and thus I would never even think of doing that. In addition I would literally slap such code in the face of the developer presenting it to me. So better don't count me in here.

Really? You've never needed a JSON literal, or an HTML literal, or an XML literal, or some template string literal?

 

Heck, what about SQL queries?

 

SELECT
DATE_FORMAT(co.order_date, '%Y-%m') AS order_month,
DATE_FORMAT(co.order_date, '%Y-%m-%d') AS order_day,
COUNT(DISTINCT co.order_id) AS num_orders,
COUNT(ol.book_id) AS num_books,
SUM(ol.price) AS total_price,
SUM(COUNT(ol.book_id)) OVER (
  ORDER BY DATE_FORMAT(co.order_date, '%Y-%m-%d')
) AS running_total_num_books
FROM cust_order co
INNER JOIN order_line ol ON co.order_id = ol.order_id
GROUP BY 
  DATE_FORMAT(co.order_date, '%Y-%m'),
  DATE_FORMAT(co.order_date, '%Y-%m-%d')
ORDER BY co.order_date ASC;

 

 

This limitation has nothing to do with being readable. It has to do with ancient Turbo Pascal code still in the IDE (ultimate source: Allan Bauer via Mason Wheeler).

 

C++, Java, Python, Swift, Javascript, Ruby, Rust (to name a few) all have long/multi-line string support in one form or another. Clearly it's useful.

  • Like 1

Share this post


Link to post

IDK about D11 but D10.3 still is not able to handle multiline literals. This might be not simple TP legacy size limitation but the parser's which is harder to remove.

Share this post


Link to post
6 hours ago, Joseph MItzen said:

Really? You've never needed a JSON literal, or an HTML literal, or an XML literal, or some template string literal?

 

Heck, what about SQL queries?

Actually I use these quite often. In the case of your SQL, which could as well come from the FireDAC query editor, I just copy the whole code, create a string array constant with a simple template, multi-paste the SQL and format the results:

const
  cArr: TArray<string> = [                                    //
    'SELECT',                                                 //
    'DATE_FORMAT(co.order_date, ''%Y-%m'') AS order_month,',  //
    'DATE_FORMAT(co.order_date, ''%Y-%m-%d'') AS order_day,', //
    'COUNT(DISTINCT co.order_id) AS num_orders,',             //
    'COUNT(ol.book_id) AS num_books,',                        //
    'SUM(ol.price) AS total_price,',                          //
    'SUM(COUNT(ol.book_id)) OVER (',                          //
    '  ORDER BY DATE_FORMAT(co.order_date, ''%Y-%m-%d'')',    //
    ') AS running_total_num_books',                           //
    'FROM cust_order co',                                     //
    'INNER JOIN order_line ol ON co.order_id = ol.order_id',  //
    'GROUP BY ',                                              //
    '  DATE_FORMAT(co.order_date, ''%Y-%m''),',               //
    '  DATE_FORMAT(co.order_date, ''%Y-%m-%d'')',             //
    'ORDER BY co.order_date ASC;',                            //
    ''];

procedure UseSQL;
begin
  var qry := TFDQuery.Create(nil);
  try
    qry.SQL.AddStrings(cArr);
//    ...
  finally
    qry.Free;
  end;
end;

The same scheme also works for JSON  or XML.

 

Interesting, that you bring up the SQL text, which is neatly split into multiple lines - probably for better readability.

 

Despite allowing string constants with more than 255 characters in one line, it would be more helpful to have string constants over multiple lines preserving linefeeds. Then it wouldn't even matter if the lines are limited to 255 characters each, although I expect this limit being lifted anyway whenever such a feature will be implemented.

  • Like 3

Share this post


Link to post

See how the human is something very peculiar: When we only had 80 lines on the screen (D.O.S. era), we complained about that (because we would like to be able to visualize more "things" on the same line)...

 

Now, the lucky ones, can have 8K screens (we can display thousands of "things" per line), and still complain, because "it hurts my eyes to have to turn my head to be able to see the whole line)

 

So I ask: Is the "human" still the same as before, or has he evolved?

Edited by programmerdelphi2k

Share this post


Link to post
2 hours ago, programmerdelphi2k said:

Now, the lucky ones, can have 8K screens (we can display thousands of "things" per line), and still complain, because "it hurts my eyes to have to turn my head to be able to see the whole line)

 

So I ask: Is the "human" still the same as before, or has he evolved?

Evolved? No. But sitting in front of the monitor and not turning your head at all leads to stiffness and pain, sooner or later. Our bodies are meant to be in motion.

Share this post


Link to post

I am getting weary of 16/9 screens. 

 

To get by I use the Tmemo.

  object Memo1: TMemo
    Left = 528
    Top = 66
    Width = 701
    Height = 569
    Lines.Strings = (
      'SELECT'#65279
      'DATE_FORMAT(co.order_date, '#39'%Y-%m'#39') AS order_month,'
      'DATE_FORMAT(co.order_date, '#39'%Y-%m-%d'#39') AS order_day,'
      'COUNT(DISTINCT co.order_id) AS num_orders,'
      'COUNT(ol.book_id) AS num_books,'
      'SUM(ol.price) AS total_price,'
      'SUM(COUNT(ol.book_id)) OVER ('
      '  ORDER BY DATE_FORMAT(co.order_date, '#39'%Y-%m-%d'#39')'
      ') AS running_total_num_books'
      'FROM cust_order co'
      'INNER JOIN order_line ol ON co.order_id = ol.order_id'
      'GROUP BY '
      '  DATE_FORMAT(co.order_date, '#39'%Y-%m'#39'),'
      '  DATE_FORMAT(co.order_date, '#39'%Y-%m-%d'#39')'
      'ORDER BY co.order_date ASC;'
      ''
       'end')
    TabOrder = 6
  end

 From the .dfm  
 

Share this post


Link to post
2 hours ago, David Heffernan said:

Why just wish for relaxing the 255 limit? Why not aim for multi line literals and more? 

Isn't that what I just wrote?

15 hours ago, Uwe Raabe said:

Despite allowing string constants with more than 255 characters in one line, it would be more helpful to have string constants over multiple lines preserving linefeeds.

 

Share this post


Link to post
7 hours ago, Uwe Raabe said:

Isn't that what I just wrote?

Yes, but I'd not read your post and was making a general comment to the overall topic.

Share this post


Link to post
On 3/23/2023 at 11:11 AM, Uwe Raabe said:

Actually I use these quite often. In the case of your SQL, which could as well come from the FireDAC query editor, I just copy the whole code, create a string array constant with a simple template, multi-paste the SQL and format the results:

Why the //s at the end?

 

On topic: enlarging only size limit without multiline literals seem nearly useless to me. However, there's another catch - we have those stupid 3 different linebreaks. Which of them multiline literals will have? They either will contain hardcoded linebreak incompatible with 2 of 3 OS's or will depend on target OS or file encoding, thus the value of a constant will differ on various platforms.

Edited by Fr0sT.Brutal

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×