| | @@ -32,10 +32,11 @@ |
| 32 | 32 | #define DIFF_IGNORE_EOLWS 0x01000000 /* Ignore end-of-line whitespace */ |
| 33 | 33 | #define DIFF_SIDEBYSIDE 0x02000000 /* Generate a side-by-side diff */ |
| 34 | 34 | #define DIFF_NEWFILE 0x04000000 /* Missing files are as empty files */ |
| 35 | 35 | #define DIFF_INLINE 0x08000000 /* Inline (not side-by-side) diff */ |
| 36 | 36 | #define DIFF_HTML 0x10000000 /* Render for HTML */ |
| 37 | +#define DIFF_LINENO 0x20000000 /* Show line numbers in context diff */ |
| 37 | 38 | |
| 38 | 39 | #endif /* INTERFACE */ |
| 39 | 40 | |
| 40 | 41 | /* |
| 41 | 42 | ** Maximum length of a line in a text file. (8192) |
| | @@ -153,10 +154,27 @@ |
| 153 | 154 | static void appendDiffLine(Blob *pOut, char *zPrefix, DLine *pLine){ |
| 154 | 155 | blob_append(pOut, zPrefix, 1); |
| 155 | 156 | blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK); |
| 156 | 157 | blob_append(pOut, "\n", 1); |
| 157 | 158 | } |
| 159 | + |
| 160 | +/* |
| 161 | +** Append line numbers to the context diff output. Zero or negative numbers |
| 162 | +** are blanks. |
| 163 | +*/ |
| 164 | +static void appendDiffLineno(Blob *pOut, int lnA, int lnB){ |
| 165 | + if( lnA>0 ){ |
| 166 | + blob_appendf(pOut, "%6d ", lnA); |
| 167 | + }else{ |
| 168 | + blob_append(pOut, " ", 7); |
| 169 | + } |
| 170 | + if( lnB>0 ){ |
| 171 | + blob_appendf(pOut, "%6d ", lnB); |
| 172 | + }else{ |
| 173 | + blob_append(pOut, " ", 8); |
| 174 | + } |
| 175 | +} |
| 158 | 176 | |
| 159 | 177 | /* |
| 160 | 178 | ** Expand the size of aEdit[] array to hold nEdit elements. |
| 161 | 179 | */ |
| 162 | 180 | static void expandEdit(DContext *p, int nEdit){ |
| | @@ -200,11 +218,11 @@ |
| 200 | 218 | |
| 201 | 219 | /* |
| 202 | 220 | ** Given a diff context in which the aEdit[] array has been filled |
| 203 | 221 | ** in, compute a context diff into pOut. |
| 204 | 222 | */ |
| 205 | | -static void contextDiff(DContext *p, Blob *pOut, int nContext){ |
| 223 | +static void contextDiff(DContext *p, Blob *pOut, int nContext, int showLn){ |
| 206 | 224 | DLine *A; /* Left side of the diff */ |
| 207 | 225 | DLine *B; /* Right side of the diff */ |
| 208 | 226 | int a = 0; /* Index of next line in A[] */ |
| 209 | 227 | int b = 0; /* Index of next line in B[] */ |
| 210 | 228 | int *R; /* Array of COPY/DELETE/INSERT triples */ |
| | @@ -254,39 +272,44 @@ |
| 254 | 272 | /* |
| 255 | 273 | * If the patch changes an empty file or results in an empty file, |
| 256 | 274 | * the block header must use 0,0 as position indicator and not 1,0. |
| 257 | 275 | * Otherwise, patch would be confused and may reject the diff. |
| 258 | 276 | */ |
| 277 | + if( showLn ) blob_appendf(pOut, "%*s", 15, ""); |
| 259 | 278 | blob_appendf(pOut,"@@ -%d,%d +%d,%d @@\n", |
| 260 | 279 | na ? a+skip+1 : 0, na, |
| 261 | 280 | nb ? b+skip+1 : 0, nb); |
| 262 | 281 | |
| 263 | 282 | /* Show the initial common area */ |
| 264 | 283 | a += skip; |
| 265 | 284 | b += skip; |
| 266 | 285 | m = R[r] - skip; |
| 267 | 286 | for(j=0; j<m; j++){ |
| 287 | + if( showLn ) appendDiffLineno(pOut, a+j, b+j); |
| 268 | 288 | appendDiffLine(pOut, " ", &A[a+j]); |
| 269 | 289 | } |
| 270 | 290 | a += m; |
| 271 | 291 | b += m; |
| 272 | 292 | |
| 273 | 293 | /* Show the differences */ |
| 274 | 294 | for(i=0; i<nr; i++){ |
| 275 | 295 | m = R[r+i*3+1]; |
| 276 | 296 | for(j=0; j<m; j++){ |
| 297 | + if( showLn ) appendDiffLineno(pOut, a+j, 0); |
| 277 | 298 | appendDiffLine(pOut, "-", &A[a+j]); |
| 278 | 299 | } |
| 279 | 300 | a += m; |
| 280 | 301 | m = R[r+i*3+2]; |
| 281 | 302 | for(j=0; j<m; j++){ |
| 303 | + if( showLn ) appendDiffLineno(pOut, 0, b+j); |
| 282 | 304 | appendDiffLine(pOut, "+", &B[b+j]); |
| 283 | 305 | } |
| 284 | 306 | b += m; |
| 285 | 307 | if( i<nr-1 ){ |
| 286 | 308 | m = R[r+i*3+3]; |
| 287 | 309 | for(j=0; j<m; j++){ |
| 310 | + if( showLn ) appendDiffLineno(pOut, a+j, b+j); |
| 288 | 311 | appendDiffLine(pOut, " ", &B[b+j]); |
| 289 | 312 | } |
| 290 | 313 | b += m; |
| 291 | 314 | a += m; |
| 292 | 315 | } |
| | @@ -295,10 +318,11 @@ |
| 295 | 318 | /* Show the final common area */ |
| 296 | 319 | assert( nr==i ); |
| 297 | 320 | m = R[r+nr*3]; |
| 298 | 321 | if( m>nContext ) m = nContext; |
| 299 | 322 | for(j=0; j<m; j++){ |
| 323 | + if( showLn ) appendDiffLineno(pOut, a+j, b+j); |
| 300 | 324 | appendDiffLine(pOut, " ", &B[b+j]); |
| 301 | 325 | } |
| 302 | 326 | } |
| 303 | 327 | } |
| 304 | 328 | |
| | @@ -334,11 +358,11 @@ |
| 334 | 358 | ** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters |
| 335 | 359 | ** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set. |
| 336 | 360 | */ |
| 337 | 361 | static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){ |
| 338 | 362 | int n = pLine->h & LENGTH_MASK; |
| 339 | | - int i, j, k; |
| 363 | + int i, j; |
| 340 | 364 | const char *zIn = pLine->z; |
| 341 | 365 | char *z = &p->zLine[p->n]; |
| 342 | 366 | int w = p->width; |
| 343 | 367 | if( n>w ) n = w; |
| 344 | 368 | for(i=j=0; i<n; i++){ |
| | @@ -868,11 +892,12 @@ |
| 868 | 892 | if( diffFlags & DIFF_SIDEBYSIDE ){ |
| 869 | 893 | int width = diff_width(diffFlags); |
| 870 | 894 | int escHtml = (diffFlags & DIFF_HTML)!=0; |
| 871 | 895 | sbsDiff(&c, pOut, nContext, width, escHtml); |
| 872 | 896 | }else{ |
| 873 | | - contextDiff(&c, pOut, nContext); |
| 897 | + int showLn = (diffFlags & DIFF_LINENO)!=0; |
| 898 | + contextDiff(&c, pOut, nContext, showLn); |
| 874 | 899 | } |
| 875 | 900 | free(c.aFrom); |
| 876 | 901 | free(c.aTo); |
| 877 | 902 | free(c.aEdit); |
| 878 | 903 | return 0; |
| | @@ -913,10 +938,12 @@ |
| 913 | 938 | ** "diffFlags" integer. |
| 914 | 939 | ** |
| 915 | 940 | ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE |
| 916 | 941 | ** --context|-c N N lines of context. DIFF_CONTEXT_MASK |
| 917 | 942 | ** --width|-W N N character lines. DIFF_WIDTH_MASK |
| 943 | +** --html Format for HTML DIFF_HTML |
| 944 | +** --linenum|-n Show line numbers DIFF_LINENO |
| 918 | 945 | */ |
| 919 | 946 | int diff_options(void){ |
| 920 | 947 | int diffFlags = 0; |
| 921 | 948 | const char *z; |
| 922 | 949 | int f; |
| | @@ -929,10 +956,11 @@ |
| 929 | 956 | f *= DIFF_CONTEXT_MASK+1; |
| 930 | 957 | if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK; |
| 931 | 958 | diffFlags |= f; |
| 932 | 959 | } |
| 933 | 960 | if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML; |
| 961 | + if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO; |
| 934 | 962 | return diffFlags; |
| 935 | 963 | } |
| 936 | 964 | |
| 937 | 965 | /* |
| 938 | 966 | ** COMMAND: test-udiff |
| 939 | 967 | |