You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.9 KiB
240 lines
5.9 KiB
-------------------------------------------------------------------------------
|
|
Alignment thresholds:
|
|
|
|
Alignment threshold are used to prevent aligning of certain text.
|
|
|
|
Consider this example when aligning assignments:
|
|
|
|
a = 2;
|
|
gld.settings[somevariable] = 5;
|
|
|
|
Without thresholds, this would result in:
|
|
|
|
a = 2;
|
|
gld.settings[somevariable] = 5;
|
|
|
|
However, this is likely not desired.
|
|
|
|
So to handle this, we set a limit on the number of columns that a alignment
|
|
may move a token. If we set the threshold to, say, 3 characters, then
|
|
the two would not be aligned together because 'a = 2' would have to be moved
|
|
by 25 columns.
|
|
|
|
Here's a more complicated case:
|
|
|
|
a = 1;
|
|
bb = 2;
|
|
ccc = 3;
|
|
dddd = 4;
|
|
eeeee = 5;
|
|
ffffff = 6;
|
|
|
|
In this case, we may want this output:
|
|
|
|
a = 1;
|
|
bb = 2;
|
|
ccc = 3;
|
|
dddd = 4;
|
|
eeeee = 5;
|
|
ffffff = 6;
|
|
|
|
But, with a threshold of 3, 'a' and 'ffffff' cannot be aligned together.
|
|
|
|
So how should these thresholds be implemented?
|
|
|
|
One approach is to use the threshold as the maximum difference between the
|
|
current maximum and the new maximum. Using this approach, all 6 lines above
|
|
are aligned, because the change for each is 1 column.
|
|
|
|
Consider this with a line-span of 3 and a column-threshold of 3.
|
|
Note that we'll now need to keep track of the last line processed.
|
|
(line and column numbers added for clarity)
|
|
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | eeeee = 5;
|
|
3 | ffffff = 6;
|
|
|
|
On line 1, the maxcol is set to 3.
|
|
On line 2, the maxcol would be set to 7, except that exceeds the threshold.
|
|
On line 3, the maxcol would be set to 8, except that exceeds the threshold.
|
|
|
|
So, it ends up with one item in the align stack - line 1.
|
|
Then we pick up from where we left off - on line 2.
|
|
On line 2, the maxcol is set to 7.
|
|
On line 3, the maxcol is set to 8.
|
|
|
|
End result:
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | eeeee = 5;
|
|
3 | ffffff = 6;
|
|
|
|
|
|
Now lets get tricky.
|
|
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | eeeee = 5;
|
|
3 | ccc = 3;
|
|
4 | ffffff = 6;
|
|
|
|
How should this be aligned?
|
|
I think we need to add another list - a 'skipped' list, that runs in parallel
|
|
with the 'aligned' list.
|
|
|
|
On line 1, the maxcol is set to 3, added to the aligned list.
|
|
On line 2, col exceeds the threshold, so it is added to the skipped list.
|
|
On line 3, the maxcol is set to 5, added to the aligned list.
|
|
Now, after an item is added to the aligned list, the skipped list must be re-scanned.
|
|
We now see that line 2 is only 2 columns different, so it is added and maxcol = 7.
|
|
The skipped list is now empty.
|
|
On line 4, the maxcol is set to 8, added to the aligned list.
|
|
|
|
So the output is:
|
|
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | eeeee = 5;
|
|
3 | ccc = 3;
|
|
4 | ffffff = 6;
|
|
|
|
|
|
Now for a case where the skipped list is not absorbed:
|
|
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | iiiiiiiiiiiiieeeee = 5;
|
|
3 | ccc = 3;
|
|
4 | ffffff = 6;
|
|
|
|
On line 1, the maxcol is set to 3, added to the aligned list.
|
|
On line 2, col exceeds the threshold, so it is added to the skipped list.
|
|
On line 3, the maxcol is set to 5, added to the aligned list.
|
|
Skipped list is scanned, nothing moved from the skipped list to the aligned list.
|
|
On line 4, the maxcol is set to 8, added to the aligned list.
|
|
|
|
So the output is:
|
|
|
|
111111
|
|
123456789012345
|
|
---------------
|
|
1 | a = 1;
|
|
2 | iiiiiiiiiiiiieeeee = 5;
|
|
3 | ccc = 3;
|
|
4 | ffffff = 6;
|
|
|
|
As a reminder, the old system would have produced:
|
|
|
|
1 | a = 1;
|
|
2 | iiiiiiiiiiiiieeeee = 5;
|
|
3 | ccc = 3;
|
|
4 | ffffff = 6;
|
|
|
|
Which is probably not wanted.
|
|
|
|
|
|
--===---===---===---===--
|
|
Absolute thresholds
|
|
To get a better grip on what thresholds do the absolute thresholds were introduced.
|
|
An absolute threshold means that the item, in this case the assign statement, is never
|
|
moved more than the threshold value.
|
|
|
|
See the below example:
|
|
Relative threshold = 10
|
|
000000000111111111122222222223
|
|
123456789012345678901234567890
|
|
1| a = 1
|
|
2| aaaaa = 1
|
|
3| bbbbbbbbbbb = 2
|
|
4| ccccccccccccccccccccc = 3
|
|
|
|
Absolute threshold:
|
|
000000000111111111122222222223
|
|
123456789012345678901234567890
|
|
1| a = 1
|
|
2| aaaaa = 1
|
|
3| bbbbbbbbbbb = 2
|
|
4| cccccccccccccccccccc = 3
|
|
|
|
--===---===---===---===--
|
|
How to do this generically in the code...
|
|
|
|
Easy case - one item per line.
|
|
|
|
Here's the functions and what each do:
|
|
align_start(line_span, col_thresh)
|
|
align_add(pc)
|
|
align_flush()
|
|
align_newline(count)
|
|
align_end()
|
|
|
|
For each entry, a sequence number is kept.
|
|
|
|
align_start(line_span, col_thresh)
|
|
- initializes the align and skipped lists
|
|
- zero max_column
|
|
- zero cur_seqnum
|
|
- zero nl_count
|
|
|
|
align_add(pc)
|
|
- update cur_seqnum, assign to item
|
|
- if item column is within threshold
|
|
- zero nl_count
|
|
- add to the aligned list
|
|
- if item column is > max_col
|
|
- update max_col
|
|
- re-adds all items on the skipped list
|
|
- if item column is not within threshold, add to skipped list
|
|
|
|
align_newline(count)
|
|
- adds count to nl_count
|
|
- if nl_count > line_span, call align_flush()
|
|
|
|
align_flush()
|
|
- step through all the items in aligned list and align the items to max_column
|
|
- keep the seq_num of the last aligned item
|
|
- zero max_column
|
|
- remove all items with a seq_num < last aligned seq_num
|
|
- call align_add on all remaining items in the skipped list
|
|
|
|
align_end()
|
|
- call align_flush
|
|
- clear the lists
|
|
- free resources, etc
|
|
|
|
Example usage: Aligning trailing comments
|
|
|
|
void align_trailing_comments(void)
|
|
{
|
|
chunk_t *pc;
|
|
|
|
align_start(cpd.settings[UO_align_right_cmt_span],
|
|
cpd.settings[UO_align_right_cmt_thresh]);
|
|
|
|
for(pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
|
|
{
|
|
if ((pc->flags & PCF_RIGHT_COMMENT) != 0)
|
|
{
|
|
align_add(pc);
|
|
}
|
|
else if (chunk_is_newline(pc))
|
|
{
|
|
align_newline(pc->nl_count);
|
|
}
|
|
}
|
|
|
|
align_end();
|
|
}
|
|
|