@@ -183,6 +183,16 @@ struct Item
183
183
items.back ().AddTokenToLastAtom (token);
184
184
}
185
185
186
+ void AddTokenToLastStringComponent (const InstructionTextToken& token)
187
+ {
188
+ if (!tokens.empty ())
189
+ tokens.push_back (token);
190
+ else if (items.empty ())
191
+ items.push_back (Item {StringComponent, {}, {token}, 0 });
192
+ else
193
+ items.back ().AddTokenToLastStringComponent (token);
194
+ }
195
+
186
196
void CalculateWidth ()
187
197
{
188
198
width = 0 ;
@@ -204,7 +214,6 @@ struct ItemLayoutStackEntry
204
214
size_t desiredWidth;
205
215
size_t desiredContinuationWidth;
206
216
size_t desiredStringWidth;
207
- size_t desiredStringContinuationWidth;
208
217
bool newLineOnReenteringScope;
209
218
};
210
219
@@ -355,6 +364,16 @@ static vector<InstructionTextToken> ParseStringToken(
355
364
356
365
static vector<Item> CreateStringGroups (const vector<Item>& items)
357
366
{
367
+ // We handle strings mostly the same as other types except the introduction
368
+ // of the StringComponent and StringWhitespace types.
369
+ //
370
+ // The reason we introduce these is for the specific behaviors when formatting multiline
371
+ // string annotations. String annotations have a different desired width than tokens
372
+ // like arguments, comments, etc.
373
+ //
374
+ // Additionally, we don't wrap trailing whitespace until the preceding token is within
375
+ // the wrapping width, unlike other token types.
376
+
358
377
vector<Item> result, pending;
359
378
bool hasStrings = false ;
360
379
for (auto & i : items)
@@ -370,7 +389,7 @@ static vector<Item> CreateStringGroups(const vector<Item>& items)
370
389
else
371
390
{
372
391
for (auto & j : i.tokens )
373
- pending.back ().AddTokenToLastAtom (j);
392
+ pending.back ().AddTokenToLastStringComponent (j);
374
393
result.push_back (Item {StringComponent, pending, {}, 0 });
375
394
}
376
395
pending.clear ();
@@ -385,18 +404,18 @@ static vector<Item> CreateStringGroups(const vector<Item>& items)
385
404
result.push_back (Item {StringComponent, pending, {}, 0 });
386
405
pending.clear ();
387
406
}
388
- result.push_back (Item {StringWhitespace, i.items , i.tokens , i. width });
407
+ result.push_back (Item {StringWhitespace, i.items , i.tokens , 0 });
389
408
}
390
409
else if (i.type == FormatSpecifier || i.type == EscapeSequence)
391
410
{
392
411
// Flush previous tokens before special sequences like format specifiers or
393
412
// escape sequences
394
413
if (!pending.empty ())
395
414
{
396
- result.push_back (Item {StringComponent, pending, {}, 0 });
415
+ result.push_back (Item {StringComponent, pending, {}, 0 });
397
416
pending.clear ();
398
417
}
399
- result.push_back (Item { StringComponent, i.items , i.tokens , i. width });
418
+ result.push_back (Item { StringComponent, i.items , i.tokens , 0 });
400
419
}
401
420
else if (i.type == StartOfContainer && pending.empty ())
402
421
{
@@ -750,19 +769,10 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
750
769
if (indentation < settings.desiredLineLength )
751
770
{
752
771
size_t remainingStringWidth = settings.desiredLineLength - indentation;
753
- if (remainingStringWidth > desiredWidth )
772
+ if (remainingStringWidth > desiredStringWidth )
754
773
desiredStringWidth = remainingStringWidth;
755
774
}
756
775
757
- // Compute target width for continuation string wrapping lines
758
- size_t desiredStringContinuationWidth = settings.stringWrappingWidth ;
759
- if (continuationIndentation < settings.desiredLineLength )
760
- {
761
- size_t remainingStringWidth = settings.desiredLineLength - continuationIndentation;
762
- if (remainingStringWidth > desiredStringContinuationWidth)
763
- desiredStringContinuationWidth = remainingStringWidth;
764
- }
765
-
766
776
// Gather the indentation tokens at the beginning of the line
767
777
vector<InstructionTextToken> indentationTokens = currentLine.GetAddressAndIndentationTokens ();
768
778
size_t tokenIndex = indentationTokens.size ();
@@ -927,7 +937,7 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
927
937
bool firstTokenOfLine = true ;
928
938
929
939
stack<ItemLayoutStackEntry> layoutStack;
930
- layoutStack.push ({items, additionalContinuationIndentation, desiredWidth, desiredContinuationWidth, desiredStringWidth, desiredStringContinuationWidth, false });
940
+ layoutStack.push ({items, additionalContinuationIndentation, desiredWidth, desiredContinuationWidth, desiredStringWidth, false });
931
941
932
942
auto newLine = [&]() {
933
943
if (!firstTokenOfLine)
@@ -952,7 +962,6 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
952
962
outputLine.tokens .emplace_back (TextToken, string (additionalContinuationIndentation, ' ' ));
953
963
currentWidth = 0 ;
954
964
desiredWidth = desiredContinuationWidth;
955
- desiredStringWidth = desiredStringContinuationWidth;
956
965
firstTokenOfLine = true ;
957
966
};
958
967
@@ -966,7 +975,6 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
966
975
desiredWidth = layoutStackEntry.desiredWidth ;
967
976
desiredContinuationWidth = layoutStackEntry.desiredContinuationWidth ;
968
977
desiredStringWidth = layoutStackEntry.desiredStringWidth ;
969
- desiredStringContinuationWidth = layoutStackEntry.desiredStringContinuationWidth ;
970
978
971
979
// Check to see if the scope we are returning to needs a new line. This is used when an argument
972
980
// spans multiple lines. The rest of the arguments are placed on separate lines from the long argument.
@@ -979,10 +987,11 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
979
987
{
980
988
// If a string is too wide to fit on the current line, create a newline
981
989
// without additional indentation
990
+ LogError (" Line length vs. desired %zu vs %zu" , currentWidth + item->width , desiredStringWidth);
982
991
newLine ();
983
992
continue ;
984
993
}
985
- if (currentWidth + item->width > desiredWidth && item->type != StringWhitespace)
994
+ if (currentWidth + item->width > desiredWidth && item->type != StringWhitespace && item-> type != StringComponent )
986
995
{
987
996
// Current item is too wide to fit on the current line, will need to start a new line.
988
997
// Whitespace is allowed to be too wide; we push it on as the preceding word is wrapped.
@@ -1001,7 +1010,7 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
1001
1010
if (next != items.end ())
1002
1011
{
1003
1012
layoutStack.push ({vector (next, items.end ()), additionalContinuationIndentation,
1004
- desiredWidth, desiredContinuationWidth, desiredStringWidth, desiredStringContinuationWidth, true });
1013
+ desiredWidth, desiredContinuationWidth, desiredStringWidth, true });
1005
1014
}
1006
1015
1007
1016
newLine ();
@@ -1012,13 +1021,8 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
1012
1021
else
1013
1022
desiredContinuationWidth -= settings.tabWidth ;
1014
1023
1015
- if (desiredStringContinuationWidth < settings.minimumContentLength + settings.tabWidth )
1016
- desiredStringContinuationWidth = settings.minimumContentLength ;
1017
- else
1018
- desiredStringContinuationWidth -= settings.tabWidth ;
1019
-
1020
1024
layoutStack.push ({item->items , additionalContinuationIndentation, desiredWidth,
1021
- desiredContinuationWidth, desiredStringWidth, desiredStringContinuationWidth, false });
1025
+ desiredContinuationWidth, desiredStringWidth, false });
1022
1026
break ;
1023
1027
}
1024
1028
@@ -1028,10 +1032,10 @@ vector<DisassemblyTextLine> GenericLineFormatter::FormatLines(
1028
1032
if (next != items.end ())
1029
1033
{
1030
1034
layoutStack.push ({vector (next, items.end ()), additionalContinuationIndentation,
1031
- desiredWidth, desiredContinuationWidth, desiredStringWidth, desiredStringContinuationWidth, false });
1035
+ desiredWidth, desiredContinuationWidth, desiredStringWidth, false });
1032
1036
}
1033
1037
layoutStack.push ({item->items , additionalContinuationIndentation, desiredWidth,
1034
- desiredContinuationWidth, desiredStringWidth, desiredStringContinuationWidth, false });
1038
+ desiredContinuationWidth, desiredStringWidth, false });
1035
1039
break ;
1036
1040
}
1037
1041
0 commit comments