@@ -102,6 +102,10 @@ function show_usage(): void
102102 seconds. The default value is 60 seconds, or 300 seconds when
103103 testing for memory leaks.
104104
105+ --context [n]
106+ Sets the number of lines of surrounding context to print for diffs.
107+ The default value is 3.
108+
105109 --show-[all|php|skip|clean|exp|diff|out|mem]
106110 Show 'all' files, 'php' test file, 'skip' or 'clean' file. You
107111 can also use this to show the output 'out', the expected result
@@ -146,6 +150,7 @@ function main(): void
146150 $ user_tests , $ valgrind , $ sum_results , $ shuffle , $ file_cache ;
147151 // Parallel testing
148152 global $ workers , $ workerID ;
153+ global $ context_line_count ;
149154
150155 define ('IS_WINDOWS ' , substr (PHP_OS , 0 , 3 ) == "WIN " );
151156
@@ -400,6 +405,7 @@ function main(): void
400405 $ file_cache = null ;
401406 $ shuffle = false ;
402407 $ workers = null ;
408+ $ context_line_count = 3 ;
403409
404410 $ cfgtypes = ['show ' , 'keep ' ];
405411 $ cfgfiles = ['skip ' , 'php ' , 'clean ' , 'out ' , 'diff ' , 'exp ' , 'mem ' ];
@@ -568,6 +574,13 @@ function main(): void
568574 case '--set-timeout ' :
569575 $ environment ['TEST_TIMEOUT ' ] = $ argv [++$ i ];
570576 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 ;
571584 case '--show-all ' :
572585 foreach ($ cfgfiles as $ file ) {
573586 $ cfg ['show ' ][$ file ] = true ;
@@ -2884,15 +2897,22 @@ function count_array_diff(
28842897
28852898function generate_array_diff (array $ ar1 , array $ ar2 , bool $ is_reg , array $ w ): array
28862899{
2900+ global $ context_line_count ;
28872901 $ idx1 = 0 ;
28882902 $ cnt1 = @count ($ ar1 );
28892903 $ idx2 = 0 ;
28902904 $ cnt2 = @count ($ ar2 );
28912905 $ diff = [];
28922906 $ old1 = [];
28932907 $ old2 = [];
2908+ $ number_len = max (3 , strlen ((string )max ($ cnt1 + 1 , $ cnt2 + 1 )));
2909+ $ line_number_spec = '%0 ' . $ number_len . 'd ' ;
2910+
2911+ /** Mapping from $idx2 to $idx1, including indexes of idx2 that are identical to idx1 as well as entries that don't have matches */
2912+ $ mapping = [];
28942913
28952914 while ($ idx1 < $ cnt1 && $ idx2 < $ cnt2 ) {
2915+ $ mapping [$ idx2 ] = $ idx1 ;
28962916 if (comp_line ($ ar1 [$ idx1 ], $ ar2 [$ idx2 ], $ is_reg )) {
28972917 $ idx1 ++;
28982918 $ idx2 ++;
@@ -2902,50 +2922,85 @@ function generate_array_diff(array $ar1, array $ar2, bool $is_reg, array $w): ar
29022922 $ c2 = @count_array_diff ($ ar1 , $ ar2 , $ is_reg , $ w , $ idx1 , $ idx2 + 1 , $ cnt1 , $ cnt2 , 10 );
29032923
29042924 if ($ c1 > $ c2 ) {
2905- $ old1 [$ idx1 ] = sprintf ("%03d - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2925+ $ old1 [$ idx1 ] = sprintf ("{ $ line_number_spec } - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
29062926 } elseif ($ c2 > 0 ) {
2907- $ old2 [$ idx2 ] = sprintf ("%03d + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2927+ $ old2 [$ idx2 ] = sprintf ("{ $ line_number_spec } + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
29082928 } else {
2909- $ old1 [$ idx1 ] = sprintf ("%03d - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2910- $ old2 [$ idx2 ] = sprintf ("%03d + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2929+ $ old1 [$ idx1 ] = sprintf ("{ $ line_number_spec } - " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2930+ $ old2 [$ idx2 ] = sprintf ("{ $ line_number_spec } + " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
29112931 }
2932+ $ last_printed_context_line = $ idx1 ;
29122933 }
29132934 }
2935+ $ mapping [$ idx2 ] = $ idx1 ;
29142936
29152937 reset ($ old1 );
29162938 $ k1 = key ($ old1 );
29172939 $ l1 = -2 ;
29182940 reset ($ old2 );
29192941 $ k2 = key ($ old2 );
29202942 $ l2 = -2 ;
2943+ $ old_k1 = -1 ;
2944+ $ add_context_lines = function (int $ new_k1 ) use (&$ old_k1 , &$ diff , $ w , $ context_line_count , $ number_len ) {
2945+ if ($ old_k1 >= $ new_k1 || !$ context_line_count ) {
2946+ return ;
2947+ }
2948+ $ end = $ new_k1 - 1 ;
2949+ $ range_end = min ($ end , $ old_k1 + $ context_line_count );
2950+ if ($ old_k1 >= 0 ) {
2951+ while ($ old_k1 < $ range_end ) {
2952+ $ diff [] = str_repeat (' ' , $ number_len + 2 ) . $ w [$ old_k1 ++];
2953+ }
2954+ }
2955+ if ($ end - $ context_line_count > $ old_k1 ) {
2956+ $ old_k1 = $ end - $ context_line_count ;
2957+ // Add a '--' to mark sections where the common areas were truncated
2958+ $ diff [] = '-- ' ;
2959+ }
2960+ $ old_k1 = max ($ old_k1 , 0 );
2961+ while ($ old_k1 < $ end ) {
2962+ $ diff [] = str_repeat (' ' , $ number_len + 2 ) . $ w [$ old_k1 ++];
2963+ }
2964+ $ old_k1 = $ new_k1 ;
2965+ };
29212966
29222967 while ($ k1 !== null || $ k2 !== null ) {
29232968 if ($ k1 == $ l1 + 1 || $ k2 === null ) {
2969+ $ add_context_lines ($ k1 );
29242970 $ l1 = $ k1 ;
29252971 $ diff [] = current ($ old1 );
2972+ $ old_k1 = $ k1 ;
29262973 $ k1 = next ($ old1 ) ? key ($ old1 ) : null ;
29272974 } elseif ($ k2 == $ l2 + 1 || $ k1 === null ) {
2975+ $ add_context_lines ($ mapping [$ k2 ]);
29282976 $ l2 = $ k2 ;
29292977 $ diff [] = current ($ old2 );
29302978 $ k2 = next ($ old2 ) ? key ($ old2 ) : null ;
2931- } elseif ($ k1 < $ k2 ) {
2979+ } elseif ($ k1 < $ mapping [$ k2 ]) {
2980+ $ add_context_lines ($ k1 );
29322981 $ l1 = $ k1 ;
29332982 $ diff [] = current ($ old1 );
29342983 $ k1 = next ($ old1 ) ? key ($ old1 ) : null ;
29352984 } else {
2985+ $ add_context_lines ($ mapping [$ k2 ]);
29362986 $ l2 = $ k2 ;
29372987 $ diff [] = current ($ old2 );
29382988 $ k2 = next ($ old2 ) ? key ($ old2 ) : null ;
29392989 }
29402990 }
29412991
29422992 while ($ idx1 < $ cnt1 ) {
2943- $ diff [] = sprintf ("%03d- " , $ idx1 + 1 ) . $ w [$ idx1 ++];
2993+ $ add_context_lines ($ idx1 + 1 );
2994+ $ diff [] = sprintf ("{$ line_number_spec }- " , $ idx1 + 1 ) . $ w [$ idx1 ++];
29442995 }
29452996
29462997 while ($ idx2 < $ cnt2 ) {
2947- $ diff [] = sprintf ("%03d+ " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
2998+ if (isset ($ mapping [$ idx2 ])) {
2999+ $ add_context_lines ($ mapping [$ idx2 ] + 1 );
3000+ }
3001+ $ diff [] = sprintf ("{$ line_number_spec }+ " , $ idx2 + 1 ) . $ ar2 [$ idx2 ++];
29483002 }
3003+ $ add_context_lines (min ($ old_k1 + $ context_line_count + 1 , $ cnt1 + 1 ));
29493004
29503005 return $ diff ;
29513006}
0 commit comments