emileverh 22 Posted March 11, 2023 (edited) 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 March 11, 2023 by emileverh 1 Share this post Link to post
PeterBelow 239 Posted March 11, 2023 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' ; 2 Share this post Link to post
emileverh 22 Posted March 11, 2023 (edited) 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 March 11, 2023 by emileverh 1 Share this post Link to post
PeterBelow 239 Posted March 12, 2023 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. 1 Share this post Link to post
aehimself 399 Posted March 12, 2023 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
emileverh 22 Posted March 13, 2023 (edited) typo... sorry Edited March 13, 2023 by emileverh Share this post Link to post
emileverh 22 Posted March 13, 2023 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. 1 Share this post Link to post
Uwe Raabe 2064 Posted March 13, 2023 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. 6 Share this post Link to post
emileverh 22 Posted March 13, 2023 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!!! 1 Share this post Link to post
programmerdelphi2k 237 Posted March 13, 2023 (edited) 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 March 13, 2023 by programmerdelphi2k Share this post Link to post
Rollo62 539 Posted March 13, 2023 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. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted March 16, 2023 I usually keep long texts in resources as RCDATA but extending the limits would be nice... 2 Share this post Link to post
Joseph MItzen 252 Posted March 23, 2023 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
Joseph MItzen 252 Posted March 23, 2023 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
Joseph MItzen 252 Posted March 23, 2023 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. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted March 23, 2023 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
Uwe Raabe 2064 Posted March 23, 2023 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. 3 Share this post Link to post
programmerdelphi2k 237 Posted March 23, 2023 (edited) 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 March 23, 2023 by programmerdelphi2k Share this post Link to post
Bill Meyer 337 Posted March 23, 2023 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
Pat Foley 52 Posted March 23, 2023 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
David Heffernan 2353 Posted March 23, 2023 Why just wish for relaxing the 255 limit? Why not aim for multi line literals and more? Share this post Link to post
Uwe Raabe 2064 Posted March 23, 2023 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
David Heffernan 2353 Posted March 24, 2023 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
Fr0sT.Brutal 900 Posted March 24, 2023 (edited) 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 March 24, 2023 by Fr0sT.Brutal Share this post Link to post