@@ -102,6 +102,10 @@ function show_usage(): void
102
102
seconds. The default value is 60 seconds, or 300 seconds when
103
103
testing for memory leaks.
104
104
105
+ --context [n]
106
+ Sets the number of lines of surrounding context to print for diffs.
107
+ The default value is 3.
108
+
105
109
--show-[all|php|skip|clean|exp|diff|out|mem]
106
110
Show 'all' files, 'php' test file, 'skip' or 'clean' file. You
107
111
can also use this to show the output 'out', the expected result
@@ -146,6 +150,7 @@ function main(): void
146
150
$ user_tests , $ valgrind , $ sum_results , $ shuffle , $ file_cache ;
147
151
// Parallel testing
148
152
global $ workers , $ workerID ;
153
+ global $ context_line_count ;
149
154
150
155
define ('IS_WINDOWS ' , substr (PHP_OS , 0 , 3 ) == "WIN " );
151
156
@@ -400,6 +405,7 @@ function main(): void
400
405
$ file_cache = null ;
401
406
$ shuffle = false ;
402
407
$ workers = null ;
408
+ $ context_line_count = 3 ;
403
409
404
410
$ cfgtypes = ['show ' , 'keep ' ];
405
411
$ cfgfiles = ['skip ' , 'php ' , 'clean ' , 'out ' , 'diff ' , 'exp ' , 'mem ' ];
@@ -568,6 +574,13 @@ function main(): void
568
574
case '--set-timeout ' :
569
575
$ environment ['TEST_TIMEOUT ' ] = $ argv [++$ i ];
570
576
break ;
577
+ case '--context ' :
578
+ $ context_line_count = $ argv [++$ i ] ?? '' ;
579
+ if (!preg_match ('/^\d+$/ ' , $ context_line_count )) {
580
+ error ("' $ context_line_count' is not a valid number of lines of context, try e.g. --context 3 for 3 lines " );
581
+ }
582
+ $ context_line_count = intval ($ context_line_count , 10 );
583
+ break ;
571
584
case '--show-all ' :
572
585
foreach ($ cfgfiles as $ file ) {
573
586
$ cfg ['show ' ][$ file ] = true ;
@@ -2890,15 +2903,22 @@ function count_array_diff(
2890
2903
2891
2904
function generate_array_diff (array $ ar1 , array $ ar2 , bool $ is_reg , array $ w ): array
2892
2905
{
2906
+ global $ context_line_count ;
2893
2907
$ idx1 = 0 ;
2894
2908
$ cnt1 = @count ($ ar1 );
2895
2909
$ idx2 = 0 ;
2896
2910
$ cnt2 = @count ($ ar2 );
2897
2911
$ diff = [];
2898
2912
$ old1 = [];
2899
2913
$ old2 = [];
2914
+ $ number_len = max (3 , strlen ((string )max ($ cnt1 + 1 , $ cnt2 + 1 )));
2915
+ $ line_number_spec = '%0 ' . $ number_len . 'd ' ;
2916
+
2917
+ /** Mapping from $idx2 to $idx1, including indexes of idx2 that are identical to idx1 as well as entries that don't have matches */
2918
+ $ mapping = [];
2900
2919
2901
2920
while ($ idx1 < $ cnt1 && $ idx2 < $ cnt2 ) {
2921
+ $ mapping [$ idx2 ] = $ idx1 ;
2902
2922
if (comp_line ($ ar1 [$ idx1 ], $ ar2 [$ idx2 ], $ is_reg )) {
2903
2923
$ idx1 ++;
2904
2924
$ idx2 ++;
@@ -2908,49 +2928,90 @@ function generate_array_diff(array $ar1, array $ar2, bool $is_reg, array $w): ar
2908
2928
$ c2 = @count_array_diff ($ ar1 , $ ar2 , $ is_reg , $ w , $ idx1 , $ idx2 + 1 , $ cnt1 , $ cnt2 , 10 );
2909
2929
2910
2930
if ($ c1 > $ c2 ) {
2911
- $ old1 [$ idx1 ] = sprintf ("%03d - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2931
+ $ old1 [$ idx1 ] = sprintf ("{ $ line_number_spec } - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2912
2932
} elseif ($ c2 > 0 ) {
2913
- $ old2 [$ idx2 ] = sprintf ("%03d + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2933
+ $ old2 [$ idx2 ] = sprintf ("{ $ line_number_spec } + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2914
2934
} else {
2915
- $ old1 [$ idx1 ] = sprintf ("%03d - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2916
- $ old2 [$ idx2 ] = sprintf ("%03d + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2935
+ $ old1 [$ idx1 ] = sprintf ("{ $ line_number_spec } - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2936
+ $ old2 [$ idx2 ] = sprintf ("{ $ line_number_spec } + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2917
2937
}
2938
+ $ last_printed_context_line = $ idx1 ;
2918
2939
}
2919
2940
}
2941
+ $ mapping [$ idx2 ] = $ idx1 ;
2920
2942
2921
2943
reset ($ old1 );
2922
2944
$ k1 = key ($ old1 );
2923
2945
$ l1 = -2 ;
2924
2946
reset ($ old2 );
2925
2947
$ k2 = key ($ old2 );
2926
2948
$ l2 = -2 ;
2949
+ $ old_k1 = -1 ;
2950
+ $ add_context_lines = function (int $ new_k1 ) use (&$ old_k1 , &$ diff , $ w , $ context_line_count , $ number_len ) {
2951
+ if ($ old_k1 >= $ new_k1 || !$ context_line_count ) {
2952
+ return ;
2953
+ }
2954
+ $ end = $ new_k1 - 1 ;
2955
+ $ range_end = min ($ end , $ old_k1 + $ context_line_count );
2956
+ if ($ old_k1 >= 0 ) {
2957
+ while ($ old_k1 < $ range_end ) {
2958
+ $ diff [] = str_repeat (' ' , $ number_len + 2 ) . $ w [$ old_k1 ++];
2959
+ }
2960
+ }
2961
+ if ($ end - $ context_line_count > $ old_k1 ) {
2962
+ $ old_k1 = $ end - $ context_line_count ;
2963
+ if ($ old_k1 > 0 ) {
2964
+ // Add a '--' to mark sections where the common areas were truncated
2965
+ $ diff [] = '-- ' ;
2966
+ }
2967
+ }
2968
+ $ old_k1 = max ($ old_k1 , 0 );
2969
+ while ($ old_k1 < $ end ) {
2970
+ $ diff [] = str_repeat (' ' , $ number_len + 2 ) . $ w [$ old_k1 ++];
2971
+ }
2972
+ $ old_k1 = $ new_k1 ;
2973
+ };
2927
2974
2928
2975
while ($ k1 !== null || $ k2 !== null ) {
2929
2976
if ($ k1 == $ l1 + 1 || $ k2 === null ) {
2977
+ $ add_context_lines ($ k1 );
2930
2978
$ l1 = $ k1 ;
2931
2979
$ diff [] = current ($ old1 );
2980
+ $ old_k1 = $ k1 ;
2932
2981
$ k1 = next ($ old1 ) ? key ($ old1 ) : null ;
2933
2982
} elseif ($ k2 == $ l2 + 1 || $ k1 === null ) {
2983
+ $ add_context_lines ($ mapping [$ k2 ]);
2934
2984
$ l2 = $ k2 ;
2935
2985
$ diff [] = current ($ old2 );
2936
2986
$ k2 = next ($ old2 ) ? key ($ old2 ) : null ;
2937
- } elseif ($ k1 < $ k2 ) {
2987
+ } elseif ($ k1 < $ mapping [$ k2 ]) {
2988
+ $ add_context_lines ($ k1 );
2938
2989
$ l1 = $ k1 ;
2939
2990
$ diff [] = current ($ old1 );
2940
2991
$ k1 = next ($ old1 ) ? key ($ old1 ) : null ;
2941
2992
} else {
2993
+ $ add_context_lines ($ mapping [$ k2 ]);
2942
2994
$ l2 = $ k2 ;
2943
2995
$ diff [] = current ($ old2 );
2944
2996
$ k2 = next ($ old2 ) ? key ($ old2 ) : null ;
2945
2997
}
2946
2998
}
2947
2999
2948
3000
while ($ idx1 < $ cnt1 ) {
2949
- $ diff [] = sprintf ("%03d- " , $ idx1 + 1 ) . $ w [$ idx1 ++];
3001
+ $ add_context_lines ($ idx1 + 1 );
3002
+ $ diff [] = sprintf ("{$ line_number_spec }- " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2950
3003
}
2951
3004
2952
3005
while ($ idx2 < $ cnt2 ) {
2953
- $ diff [] = sprintf ("%03d+ " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
3006
+ if (isset ($ mapping [$ idx2 ])) {
3007
+ $ add_context_lines ($ mapping [$ idx2 ] + 1 );
3008
+ }
3009
+ $ diff [] = sprintf ("{$ line_number_spec }+ " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
3010
+ }
3011
+ $ add_context_lines (min ($ old_k1 + $ context_line_count + 1 , $ cnt1 + 1 ));
3012
+ if ($ context_line_count && $ old_k1 < $ cnt1 + 1 ) {
3013
+ // Add a '--' to mark sections where the common areas were truncated
3014
+ $ diff [] = '-- ' ;
2954
3015
}
2955
3016
2956
3017
return $ diff ;
0 commit comments