Subject: bug#22067: [bug-diffutils] bug#22067: bug#20062: bug#20062: [PATCH] diff: add support for --color

From: Gisle Vanem <[email-masked]>
Date: Mon, 8 Feb 2016 14:29:11 +0100

Giuseppe Scrivano wrote:

> thanks for your patches.  Is it fine for you if we keep bug-diffutils in
> the loop?

Sure. I forgot it was in the CC-list.
Attached again; wincolor.c + diff-1.txt.
Excused my diff format; I'm a "git n00b". Hope you figure it out.

-- 
--gv

--- a/src/diff.h  2016-01-30 20:29:29
+++ b/src/diff.h 2016-01-30 20:35:34
@@ -378,6 +378,18 @@
 extern void print_sdiff_script (struct change *);

 /* util.c */
+
+struct bin_str
+  {
+    size_t len;			/* Number of bytes */
+    const char *string;		/* Pointer to the same */
+  };
+
+extern struct bin_str color_indicator [8];
+extern const char *const indicator_name[9];
+extern char const *color_palette;
+extern bool colors_enabled;
+
 extern char const change_letter[4];
 extern char const pr_program[];
 extern char *concat (char const *, char const *, char const *);
@@ -419,3 +431,20 @@

 extern void set_color_context (enum color_context color_context);
 extern void set_color_palette (char const *palette);
+
+/* wincolor.c */
+
+#ifdef WIN32
+  #include <signal.h>
+
+  #ifndef SIGSTOP
+  #define SIGSTOP SIGTERM
+  #endif
+
+  #ifndef ARRAY_SIZE
+  #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+  #endif
+
+  extern void init_wincon (void);
+  extern void set_color (int index);
+#endif
--- a/src/util.c  2016-01-30 20:29:29
+++ b/src/util.c 2016-01-30 20:38:12
@@ -208,7 +208,11 @@
       int stops;
       sigset_t oldset;

+#ifdef WIN32
+      set_color (-1);
+#else
       set_color_context (RESET_CONTEXT);
+#endif
       fflush (stdout);

       sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
@@ -245,10 +249,20 @@
   static int const sig[] =
     {
       /* This one is handled specially.  */
+#ifdef SIGTSTP
       SIGTSTP,
-
+#endif
+#ifdef SIGALRM
+      SIGALRM,
+#endif
+#ifdef SIGQUIT
+      SIGQUIT,
+#endif
       /* The usual suspects.  */
-      SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
+      SIGHUP, SIGINT, SIGPIPE,
+#ifdef SIGTERM
+      SIGTERM,
+#endif
 #ifdef SIGPOLL
       SIGPOLL,
 #endif
@@ -298,7 +312,11 @@
         caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
         if (caught_sig[j])
           {
+#ifdef SIGTSTP
             signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
+#else
+            signal (sig[j], sighandler);
+#endif
             siginterrupt (sig[j], 0);
           }
       }
@@ -309,16 +327,10 @@
 static char const *current_name0;
 static char const *current_name1;
 static bool currently_recursive;
-static bool colors_enabled;
+bool colors_enabled;

 static struct color_ext_type *color_ext_list = NULL;

-struct bin_str
-  {
-    size_t len;			/* Number of bytes */
-    const char *string;		/* Pointer to the same */
-  };
-
 struct color_ext_type
   {
     struct bin_str ext;		/* The extension we're looking for */
@@ -546,7 +558,7 @@

 #define LEN_STR_PAIR(s) sizeof (s) - 1, s

-static struct bin_str color_indicator[] =
+struct bin_str color_indicator[8] =
   {
     { LEN_STR_PAIR ("\033[") },		/* lc: Left of color sequence */
     { LEN_STR_PAIR ("m") },		/* rc: Right of color sequence */
@@ -558,13 +570,13 @@
     { LEN_STR_PAIR ("36") },		/* ln: Line number */
   };

-static const char *const indicator_name[] =
+const char *const indicator_name[9] =
   {
     "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL
   };
 ARGMATCH_VERIFY (indicator_name, color_indicator);

-static char const *color_palette;
+char const *color_palette;

 void
 set_color_palette (char const *palette)
@@ -714,9 +726,12 @@

   colors_enabled = (colors_style == ALWAYS
                     || (colors_style == AUTO && output_is_tty));
-
-  if (colors_enabled)
+  if (colors_enabled) {
     parse_diff_color ();
+#ifdef WIN32
+     init_wincon();
+#endif
+  }

   if (output_is_tty)
     install_signal_handlers ();
@@ -1341,7 +1356,40 @@
 static void
 put_indicator (const struct bin_str *ind)
 {
+#ifdef WIN32
+#define IND_TO_ADDR(x)  ((const char*)ind == (const char*)&color_indicator[x])
+
+  if (IND_TO_ADDR(C_LEFT) || IND_TO_ADDR(C_RIGHT))
+     return;
+
+  if (IND_TO_ADDR(C_RESET) || interrupt_signal)
+  {
+    fflush (outfile);
+    set_color (-1);
+  }
+  else if (IND_TO_ADDR(C_HEADER))
+  {
+    fflush (outfile);
+    set_color (C_HEADER);
+  }
+  else if (IND_TO_ADDR(C_LINE))
+  {
+    fflush (outfile);
+    set_color (C_LINE);
+  }
+  else if (IND_TO_ADDR(C_ADD))
+  {
+    fflush (outfile);
+    set_color (C_ADD);
+  }
+  else if (IND_TO_ADDR(C_DELETE))
+  {
+    fflush (outfile);
+    set_color (C_DELETE);
+  }
+#else
   fwrite (ind->string, ind->len, 1, outfile);
+#endif
 }

 static enum color_context last_context = RESET_CONTEXT;