Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fluff: started adding basic ANSI color support to text-mode diffs. Only context diffs for the time being. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
41e6280df78d9ce59c452e92243910f8 |
User & Date: | stephan 2014-03-26 15:48:03.378 |
Context
2014-03-26
| ||
15:50 | removed extraneous newlines. check-in: 30eaf1465a user: stephan tags: trunk | |
15:48 | Fluff: started adding basic ANSI color support to text-mode diffs. Only context diffs for the time being. check-in: 41e6280df7 user: stephan tags: trunk | |
15:42 | minor internal cleanups. Nothing functional. check-in: fbf48bc585 user: stephan tags: trunk | |
Changes
Changes to f-apps/f-adiff.c.
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <stdlib.h> /* atoi() */ static void fcli_local_help(){ printf("Usage:\n\t%s [options] fromArtifactUuid toArtifactUuid\n\n", fcli.appName); puts("Generates diff of individual blobs (not checkin versions!). Options:"); puts("\n\t--context-lines|-c=### Specifies the number of context lines around differences.\n"); puts("\n\t--html|-h Specifies HTML-format output, marked for styling via CSS.\n"); puts("\n\t--invert|-v Inverts the to/from arguments for diff purposes.\n"); puts("\n\t--sbs-width|-w=### specifies a side-by-side diff with the given column width.\n"); puts("\nResults may be weird if specifying conflicting options (-i and -w).\n"); puts("The two versions to compare may be specified as non-flag arguments or " "via the -v1=x and -v2=y flags.\n"); } struct ADiffOpt { int diffFlags; short sbsWidth; short contextLines; }; typedef struct ADiffOpt ADiffOpt; /** */ static int f_adiff(fsl_id_t v1, fsl_id_t v2, const ADiffOpt * opt){ | > > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include <stdlib.h> /* atoi() */ static void fcli_local_help(){ printf("Usage:\n\t%s [options] fromArtifactUuid toArtifactUuid\n\n", fcli.appName); puts("Generates diff of individual blobs (not checkin versions!). Options:"); puts("\n\t--no-color Disables color output.\n"); puts("\n\t--context-lines|-c=### Specifies the number of context lines around differences.\n"); puts("\n\t--html|-h Specifies HTML-format output, marked for styling via CSS.\n"); puts("\n\t--invert|-v Inverts the to/from arguments for diff purposes.\n"); puts("\n\t--sbs-width|-w=### specifies a side-by-side diff with the given column width.\n"); puts("\nResults may be weird if specifying conflicting options (-i and -w).\n"); puts("The two versions to compare may be specified as non-flag arguments or " "via the -v1=x and -v2=y flags.\n"); } struct ADiffOpt { int diffFlags; short sbsWidth; short contextLines; char ansiColor; }; typedef struct ADiffOpt ADiffOpt; /** */ static int f_adiff(fsl_id_t v1, fsl_id_t v2, const ADiffOpt * opt){ |
︙ | ︙ | |||
73 74 75 76 77 78 79 | char * vTo = NULL; char * tmpVal = NULL; fsl_cx * f; fsl_id_t idFrom = 0, idTo = 0; ADiffOpt diffOpt = { 0/*diffFlags*/, 0/*sbsWidth*/, | | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | char * vTo = NULL; char * tmpVal = NULL; fsl_cx * f; fsl_id_t idFrom = 0, idTo = 0; ADiffOpt diffOpt = { 0/*diffFlags*/, 0/*sbsWidth*/, 0/*contextLines*/, 0/*ansiColor*/ }; fcli.appHelp = fcli_local_help; rc = fcli_setup(argc, argv); if(FSL_RC_BREAK==rc) /* --help */ return 0; else if(rc) goto end; |
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | } if(fcli_flag2("l", "line-numbers", NULL)){ diffOpt.diffFlags |= FSL_DIFF_LINENO; } if(fcli_flag2("h", "html", NULL)){ diffOpt.diffFlags |= FSL_DIFF_HTML; } if(fcli_flag2("w", "sbs-width", &tmpVal)){ diffOpt.diffFlags |= FSL_DIFF_SIDEBYSIDE; diffOpt.sbsWidth = atoi(tmpVal); fsl_free(tmpVal); tmpVal = NULL; } if(fcli_flag2("c", "context-lines", &tmpVal)){ | > > > > | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | } if(fcli_flag2("l", "line-numbers", NULL)){ diffOpt.diffFlags |= FSL_DIFF_LINENO; } if(fcli_flag2("h", "html", NULL)){ diffOpt.diffFlags |= FSL_DIFF_HTML; } if(isatty(STDOUT_FILENO) && !fcli_flag("no-color", NULL)){ diffOpt.diffFlags |= FSL_DIFF_ANSI_COLOR; } if(fcli_flag2("w", "sbs-width", &tmpVal)){ diffOpt.diffFlags |= FSL_DIFF_SIDEBYSIDE; diffOpt.sbsWidth = atoi(tmpVal); fsl_free(tmpVal); tmpVal = NULL; } if(fcli_flag2("c", "context-lines", &tmpVal)){ |
︙ | ︙ |
Changes to f-apps/test.c.
︙ | ︙ | |||
220 221 222 223 224 225 226 | assert(!rc); rc = fsl_buffer_append( &rhs, lhs.mem, lhs.used ); assert(!rc); for( rc = 0; rc < 20; ++rc ){ rhs.mem[rc + 100] = '*'; } | | > | | | > | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | assert(!rc); rc = fsl_buffer_append( &rhs, lhs.mem, lhs.used ); assert(!rc); for( rc = 0; rc < 20; ++rc ){ rhs.mem[rc + 100] = '*'; } rc = fsl_diff_text_to_buffer( &lhs, &rhs, &diff, context, 0, FSL_DIFF_ANSI_COLOR); f_out("diff rc=%s, output len=%"FSL_SIZE_T_PFMT"\n", fsl_rc_cstr(rc), diff.used); f_out("Diff from this file and a mangled copy:\n%b", &diff); fsl_buffer_clear(&diff); f_out("\nInverted...\n"); rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 0, FSL_DIFF_INVERT | FSL_DIFF_ANSI_COLOR); f_out("\nWith line numbers...\n"); rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 0, FSL_DIFF_LINENO | FSL_DIFF_ANSI_COLOR); f_out("\nSide-by-side...\n"); rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 30, 0 /*FSL_DIFF_SIDEBYSIDE is implicit when sbsWidth>0*/ | FSL_DIFF_ANSI_COLOR); f_out("\nInverted...\n"); rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 30, FSL_DIFF_INVERT | FSL_DIFF_ANSI_COLOR); if(0){ f_out("\nAnd using HTML...\n"); rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, 3, 80, FSL_DIFF_SIDEBYSIDE | FSL_DIFF_HTML); } fsl_buffer_clear(&lhs); |
︙ | ︙ |
Changes to include/fossil-scm/fossil-cli.h.
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #if defined(NDEBUG) #undef NDEBUG #define DEBUG 1 #endif #include "fossil-scm/fossil.h" #include <assert.h> /* for the benefit of test apps */ #include <stdlib.h> /* EXIT_SUCCESS and friends */ /** @page page_fcli fcli (formerly FossilApp) ::fcli (formerly FossilApp) provides a small framework for bootstrapping simple libfossil applications. It is primarily intended for use with CLI apps implementing features similar to those in fossil(1). It provides the following basic services to | > > > > > > > > > > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #if defined(NDEBUG) #undef NDEBUG #define DEBUG 1 #endif #include "fossil-scm/fossil.h" #include <assert.h> /* for the benefit of test apps */ #include <stdlib.h> /* EXIT_SUCCESS and friends */ #if defined(_WIN32) || defined(WIN32) # include <io.h> #define isatty(h) _isatty(h) #else # include <unistd.h> /* isatty() */ #if 0 extern int isatty(int); #endif #endif /** @page page_fcli fcli (formerly FossilApp) ::fcli (formerly FossilApp) provides a small framework for bootstrapping simple libfossil applications. It is primarily intended for use with CLI apps implementing features similar to those in fossil(1). It provides the following basic services to |
︙ | ︙ |
Changes to include/fossil-scm/fossil-util.h.
︙ | ︙ | |||
2929 2930 2931 2932 2933 2934 2935 | /** Suppress optimizations (debug). */ FSL_DIFF_NOOPT = 0x0100, /** Invert the diff (debug). */ FSL_DIFF_INVERT = 0x0200, /** Only display if not "too big." */ FSL_DIFF_NOTTOOBIG = 0x0800, /** Strip trailing CR */ | | > > > > > > > > > > > > | 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 | /** Suppress optimizations (debug). */ FSL_DIFF_NOOPT = 0x0100, /** Invert the diff (debug). */ FSL_DIFF_INVERT = 0x0200, /** Only display if not "too big." */ FSL_DIFF_NOTTOOBIG = 0x0800, /** Strip trailing CR */ FSL_DIFF_STRIP_EOLCR = 0x1000, /** This flag tells text-mode diff generation to add ANSI color sequences to some output. The colors are currently hard-coded and non-configurable. This has no effect for HTML output, and that flag trumps this one. Maintenance reminder: this one currently has no counterpart in fossil(1), is not tracked in the same way, and need not map to an internal flag value. That's a good thing, because we'll be out of flags once Jan's done tinkering in fossil(1) ;). */ FSL_DIFF_ANSI_COLOR = 0x2000 }; /** Generates a textual diff from two text inputs and writes it to the given output function. pA and pB are the buffers to diff. |
︙ | ︙ |
Changes to src/fsl_diff.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) */ #define LENGTH_MASK_SZ 13 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1) /** Extract the number of lines of context from diffFlags. */ static int diff_context_lines(fsl_uint64_t diffFlags){ int n = diffFlags & DIFF_CONTEXT_MASK; if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | /** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) */ #define LENGTH_MASK_SZ 13 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1) #define ANSI_COLOR_BLACK(BOLD) ((BOLD) ? "\x1b[30m" : "\x1b[30m") #define ANSI_COLOR_RED(BOLD) ((BOLD) ? "\x1b[31;1m" : "\x1b[31m") #define ANSI_COLOR_GREEN(BOLD) ((BOLD) ? "\x1b[32;1m" : "\x1b[32m") #define ANSI_COLOR_YELLOW(BOLD) ((BOLD) ? "\x1b[33;1m" : "\x1b[33m") #define ANSI_COLOR_BLUE(BOLD) ((BOLD) ? "\x1b[34;1m" : "\x1b[34m") #define ANSI_COLOR_MAGENTA(BOLD) ((BOLD) ? "\x1b[35;1m" : "\x1b[35m") #define ANSI_COLOR_CYAN(BOLD) ((BOLD) ? "\x1b[36;1m" : "\x1b[36m") #define ANSI_COLOR_WHITE(BOLD) ((BOLD) ? "\x1b[37;1m" : "\x1b[37m") #define ANSI_COLOR_ADD(BOLD) ANSI_COLOR_GREEN(BOLD) #define ANSI_COLOR_RM(BOLD) ANSI_COLOR_RED(BOLD) #define ANSI_BG_BLACK(BOLD) ((BOLD) ? "\x1b[40;1m" : "\x1b[40m") #define ANSI_BG_RED(BOLD) ((BOLD) ? "\x1b[41;1m" : "\x1b[41m") #define ANSI_BG_GREEN(BOLD) ((BOLD) ? "\x1b[42;1m" : "\x1b[42m") #define ANSI_BG_YELLOW(BOLD) ((BOLD) ? "\x1b[43;1m" : "\x1b[43m") #define ANSI_BG_BLUE(BOLD) ((BOLD) ? "\x1b[44;1m" : "\x1b[44m") #define ANSI_BG_MAGENTA(BOLD) ((BOLD) ? "\x1b[45;1m" : "\x1b[45m") #define ANSI_BG_CYAN(BOLD) ((BOLD) ? "\x1b[46;1m" : "\x1b[46m") #define ANSI_BG_WHITE(BOLD) ((BOLD) ? "\x1b[47;1m" : "\x1b[47m") #define ANSI_RESET_COLOR "\x1b[39;49m" #define ANSI_RESET_ALL "\x1b[0m" #define ANSI_RESET ANSI_RESET_ALL /*#define ANSI_BOLD ";1m"*/ /* 0x00-0x07: standard colors (as in ESC [ 30..37 m) 0x08-0x0f: high intensity colors (as in ESC [ 90..97 m) */ /** Extract the number of lines of context from diffFlags. */ static int diff_context_lines(fsl_uint64_t diffFlags){ int n = diffFlags & DIFF_CONTEXT_MASK; if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5; |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 | struct DiffOutState { /** Output callback. */ fsl_output_f out; /** State for this->out(). */ void * oState; /** For propagating output errors. */ int rc; }; typedef struct DiffOutState DiffOutState; | > | > > > > > | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | struct DiffOutState { /** Output callback. */ fsl_output_f out; /** State for this->out(). */ void * oState; /** For propagating output errors. */ int rc; char ansiColor; }; typedef struct DiffOutState DiffOutState; static const DiffOutState DiffOutState_empty = { NULL/*out*/, NULL/*oState*/, 0/*rc*/, 0/*useAnsiColor*/ }; /** Internal helper. Sends src to o->out(). If n is negative, fsl_strlen() is used to determine the length. */ static int diff_out( DiffOutState * o, void const * src, fsl_int_t n ){ return o->rc = n |
︙ | ︙ | |||
309 310 311 312 313 314 315 | static int appendDiffLine( DiffOutState *pOut, /* Where to write the line of output */ char cPrefix, /* One of " ", "+", or "-" */ DLine *pLine, /* The line to be output */ int html, /* True if generating HTML. False for plain text */ ReCompiled *pRe /* Colorize only if line matches this Regex */ ){ | | > > > > > > > > | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | static int appendDiffLine( DiffOutState *pOut, /* Where to write the line of output */ char cPrefix, /* One of " ", "+", or "-" */ DLine *pLine, /* The line to be output */ int html, /* True if generating HTML. False for plain text */ ReCompiled *pRe /* Colorize only if line matches this Regex */ ){ int rc = 0; char const * ansiPrefix = !pOut->ansiColor ? NULL : (('+'==cPrefix) ? ANSI_COLOR_ADD(0) : (('-'==cPrefix) ? ANSI_COLOR_RM(0) : NULL)) ; if(ansiPrefix) rc = diff_out(pOut, ansiPrefix, -1 ); if(!rc) rc = diff_out(pOut, &cPrefix, 1); if(rc) return rc; else if( html ){ #if 0 if( pRe /*MISSING: && re_dline_match(pRe, pLine, 1)==0 */ ){ cPrefix = ' '; }else #endif |
︙ | ︙ | |||
332 333 334 335 336 337 338 339 340 341 342 343 344 345 | /* while( n>0 && (pLine->z[n-1]=='\n' || pLine->z[n-1]=='\r') ) n--; */ rc = pOut->rc = fsl_htmlize(pOut->out, pOut->oState, pLine->z, pLine->n); if( !rc && cPrefix!=' ' ){ rc = diff_out(pOut, "</span>", -1); } } }else{ rc = diff_out(pOut, pLine->z, pLine->n); } if(!rc) rc = diff_out(pOut, "\n", 1); return rc; } | > > > | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | /* while( n>0 && (pLine->z[n-1]=='\n' || pLine->z[n-1]=='\r') ) n--; */ rc = pOut->rc = fsl_htmlize(pOut->out, pOut->oState, pLine->z, pLine->n); if( !rc && cPrefix!=' ' ){ rc = diff_out(pOut, "</span>", -1); } } }else if(ansiPrefix){ if(!rc) rc = diff_out(pOut, pLine->z, pLine->n); if(!rc) rc = diff_outf(pOut, ANSI_RESET ); }else{ rc = diff_out(pOut, pLine->z, pLine->n); } if(!rc) rc = diff_out(pOut, "\n", 1); return rc; } |
︙ | ︙ | |||
899 900 901 902 903 904 905 906 907 908 909 910 911 | }else{ rc = diff_outf(pOut, "%.80c\n", '.'); } if( !rc && html ){ rc = diff_outf(pOut, "<span class=\"fsl-diff-chunk-%d\"></span>", nChunk); } }else{ if( html ) rc = diff_outf(pOut, "<span class=\"fsl-diff-lineno\">"); /* * If the patch changes an empty file or results in an empty file, * the block header must use 0,0 as position indicator and not 1,0. * Otherwise, patch would be confused and may reject the diff. */ | > > > > > > > > > | | | > | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 | }else{ rc = diff_outf(pOut, "%.80c\n", '.'); } if( !rc && html ){ rc = diff_outf(pOut, "<span class=\"fsl-diff-chunk-%d\"></span>", nChunk); } }else{ char const * ansi1 = ""; char const * ansi2 = ""; char const * ansi3 = ""; if( html ) rc = diff_outf(pOut, "<span class=\"fsl-diff-lineno\">"); else if(0 && pOut->ansiColor){ /* Turns out this just confuses the output */ ansi1 = ANSI_COLOR_RM(0); ansi2 = ANSI_COLOR_ADD(0); ansi3 = ANSI_RESET; } /* * If the patch changes an empty file or results in an empty file, * the block header must use 0,0 as position indicator and not 1,0. * Otherwise, patch would be confused and may reject the diff. */ if(!rc) rc = diff_outf(pOut,"@@ %s-%d,%d %s+%d,%d%s @@", ansi1, na ? a+skip+1 : 0, na, ansi2, nb ? b+skip+1 : 0, nb, ansi3); if( !rc ){ if( html ) rc = diff_outf(pOut, "</span>"); if(!rc) rc = diff_out(pOut, "\n", 1); } } if(rc) return rc; |
︙ | ︙ | |||
1978 1979 1980 1981 1982 1983 1984 | /* Encode SBS width... */ if(sbsWidth<0 || ((DIFF_SIDEBYSIDE & diffFlags) && !sbsWidth) ) sbsWidth = 80; if(sbsWidth) diffFlags |= DIFF_SIDEBYSIDE; diffFlags |= ((int)(sbsWidth & 0xFF))<<16; dos.out = out; dos.oState = outState; | | | 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 | /* Encode SBS width... */ if(sbsWidth<0 || ((DIFF_SIDEBYSIDE & diffFlags) && !sbsWidth) ) sbsWidth = 80; if(sbsWidth) diffFlags |= DIFF_SIDEBYSIDE; diffFlags |= ((int)(sbsWidth & 0xFF))<<16; dos.out = out; dos.oState = outState; dos.ansiColor = !!(diffFlags_ & FSL_DIFF_ANSI_COLOR); if( diffFlags & DIFF_INVERT ){ fsl_buffer const *pTemp = pA; pA = pB; pB = pTemp; } /* Prepare the input files */ |
︙ | ︙ | |||
2087 2088 2089 2090 2091 2092 2093 | #undef SBS_LNA #undef SBS_TXTA #undef SBS_MKR #undef SBS_LNB #undef SBS_TXTB #undef ANN_FILE_VERS #undef ANN_FILE_ANCEST | > > > > > > > > > > > > > > > > > > > > | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 | #undef SBS_LNA #undef SBS_TXTA #undef SBS_MKR #undef SBS_LNB #undef SBS_TXTB #undef ANN_FILE_VERS #undef ANN_FILE_ANCEST #undef ANSI_COLOR_BLACK #undef ANSI_COLOR_RED #undef ANSI_COLOR_GREEN #undef ANSI_COLOR_YELLOW #undef ANSI_COLOR_BLUE #undef ANSI_COLOR_MAGENTA #undef ANSI_COLOR_CYAN #undef ANSI_COLOR_WHITE #undef ANSI_BG_BLACK #undef ANSI_BG_RED #undef ANSI_BG_GREEN #undef ANSI_BG_YELLOW #undef ANSI_BG_BLUE #undef ANSI_BG_MAGENTA #undef ANSI_BG_CYAN #undef ANSI_BG_WHITE #undef ANSI_RESET_COLOR #undef ANSI_RESET_ALL #undef ANSI_RESET |