2c2
<    Copyright (C) 1992, 2010 Free Software Foundation, Inc.
---
>    Copyright (C) 1992 Free Software Foundation, Inc.
4,5d3
<    Per-character diff mode added 2010 by 
<    Georgios Zarkadas <georgios.zarkadas@gmail.com>
9c7
<    the Free Software Foundation; either version 3, or (at your option)
---
>    the Free Software Foundation; either version 2, or (at your option)
18,19c16,17
<    along with this program; if not, write to the Free Software Foundation, 
<    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA   */
---
>    along with this program; if not, write to the Free Software
>    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
118d115
<   {"char"        , 0, NULL, 'c'},
131c128
<   "Copyright (C) 1992, 2010 Free Software Foundation, Inc.";
---
>   "Copyright (C) 1992 Free Software Foundation, Inc.";
165,171d161
< enum diff_mode
< {
<   MODE_WORD, 			/* diff by words (default) */
<   MODE_CHAR 			/* diff by chars */
< }
< diff_mode;        
< 
186c176
<   int position;			/* number of words|chars read so far */
---
>   int position;			/* number of words read so far */
211d200
< 
425,459d413
< static void
< skip_char (SIDE *side)
< {
<   if (interrupted)
<     longjmp (signal_label, 1);
< 
<   /* skip one non-space char; we are called *after* skip_whitespace */
< 
<   if (side->character != EOF)
<     {
<       /* Simple UTF-8 support:
<        * Since this is a pass-through utility, do not interpret/transform
<        * invalid sequences. Just group bytes in a sensible manner. 
<        */
<       unsigned char test = side->character;
<       if ((test & 0xc0) == 0xc0)
< 	{
< 	  /* Start of multibyte sequence. Consume all continuation bytes 
< 	   * up to the maximum allowed by original UTF-8 specification.
< 	   */
< 	  int count;
< 	  for (count = 0; count < 6; ++count)
< 	    {
< 	      side->character = getc (side->file);
< 	      test = side->character;
< 	      if (test == EOF || (test & 0xc0) != 0x80)
< 		break;
< 	    }
< 	}
<       else 					/* ASCII or non UTF-8 */
< 	side->character = getc (side->file);
<     }
<   side->position++;
< }
< 
595,677d548
< /* Get a UTF-8 character from side->file and store it in *buf (buf must hold
<  * at least 8 chars, the 8th for the terminating null)
<  * Return the mumber of bytes extracted (also updates both side->character 
<  * and side->position).
<  */
< static int
< get_char (SIDE *side, char *buf)
< {
<   int count = 0;
<   if (side->character != EOF)
<     {
<       buf[count] = side->character;
<       ++count;
<       unsigned char test = side->character;
<       if ((test & 0xc0) == 0xc0)
< 	{
< 	  /* Start of multibyte sequence. Consume all continuation bytes 
< 	   * up to the maximum allowed by original UTF-8 specification.
< 	   */
< 	  for ( /* count=1 */ ; count < 7; ++count)
< 	    {
< 	      side->character = getc (side->file);
< 	      test = side->character;
< 	      buf[count] = side->character;
< 	      if (test == EOF || (test & 0xc0) != 0x80)
< 		break;
< 	    }
< 	}
<       else 					/* ASCII or non UTF-8 */
< 	side->character = getc (side->file);
<     }
<   side->position++;
<   buf[count] = '\0';
<   return count;
< }
< 
< static void
< copy_char (SIDE *side, FILE *file)
< {
<   char buf[8];
< 
<   if (interrupted)
<     longjmp (signal_label, 1);
< 
<   /* copy one non-space char; we are called *after* (skip|copy)_whitespace */
< 
<   if (side->character != EOF)
<     {
<       get_char(side, (char *) &buf);
< 
<       /* In printer mode, act according to copy_mode.  If copy_mode is not
< 	 COPY_NORMAL, we know that file is necessarily output_file.  */
< 
<       if (overstrike)
< 	switch (copy_mode)
< 	  {
< 	  case COPY_NORMAL:
< 	    fputs ((const char *) &buf, file);
< 	    break;
< 
< 	  case COPY_DELETED:
< 	    putc ('_', output_file);
< 
< 	    /* Avoid underlining an underscore.  */
< 
< 	    if (side->character != '_')
< 	      {
< 		putc ('\b', output_file);
< 		fputs ((const char *) &buf, output_file);
< 	      }
< 	    break;
< 	  
< 	  case COPY_INSERTED:
< 	    fputs ((const char *) &buf, output_file);
< 	    putc ('\b', output_file);
< 	    fputs ((const char *) &buf, output_file);
< 	    break;
< 	  }
<       else
< 	fputs ((const char *) &buf, file);
<     }
< }
< 
684c555
< split_file_common (SIDE *side)
---
> split_file_into_words (SIDE *side)
729,739d599
< }
< 
< /* Only the copy_xxxx line differs in the two functions below. 
<  * However, they were chosen to be implemented separately because 
<  * they constitute 'tight' loops. 
<  */
< 
< static void
< split_file_into_words (SIDE *side)
< {
<   split_file_common (side);
757,777d616
< static void
< split_file_into_chars (SIDE *side)
< {
<   split_file_common (side);
< 
<   /* Complete splitting input file into chars on output.  */
< 
<   while (side->character != EOF)
<     {
<       if (interrupted)
< 	longjmp (signal_label, 1);
< 
<       skip_whitespace (side);
<       if (side->character == EOF)
< 	break;
<       copy_char (side, side->temp_file);
<       putc ('\n', side->temp_file);
<     }
<   fclose (side->temp_file);
< }
< 
856,858c695,697
< /*---------------------------------------------------.
< | Skip SIDE until some word/char ORDINAL, included.  |
< `---------------------------------------------------*/
---
> /*----------------------------------------------.
> | Skip SIDE until some word ORDINAL, included.  |
> `----------------------------------------------*/
863,874c702,706
<   if (diff_mode == MODE_WORD)
<     while (side->position < ordinal)
<       {
<         skip_whitespace (side);
<         skip_word (side);
<       }
<   else
<     while (side->position < ordinal)
<       {
<         skip_whitespace (side);
<         skip_char (side);
<       }
---
>   while (side->position < ordinal)
>     {
>       skip_whitespace (side);
>       skip_word (side);
>     }
877,879c709,711
< /*---------------------------------------------------.
< | Copy SIDE until some word/char ORDINAL, included.  |
< `---------------------------------------------------*/
---
> /*----------------------------------------------.
> | Copy SIDE until some word ORDINAL, included.  |
> `----------------------------------------------*/
884,895c716,720
<   if (diff_mode == MODE_WORD)
<     while (side->position < ordinal)
<       {
<         copy_whitespace (side, output_file);
<         copy_word (side, output_file);
<       }
<   else
<     while (side->position < ordinal)
<       {
<         copy_whitespace (side, output_file);
<         copy_char (side, output_file);
<       }
---
>   while (side->position < ordinal)
>     {
>       copy_whitespace (side, output_file);
>       copy_word (side, output_file);
>     }
978,983c803,806
< 	    {
< 	      if (!inhibit_common && inhibit_right)
< 		copy_until_ordinal (left_side, resync_left);
< 	      else
< 		skip_until_ordinal (left_side, resync_left);
< 	    }
---
> 	    if (!inhibit_common && inhibit_right)
> 	      copy_until_ordinal (left_side, resync_left);
> 	    else
> 	      skip_until_ordinal (left_side, resync_left);
986,991c809,812
< 	    {
< 	      if (inhibit_common)
< 		skip_until_ordinal (right_side, resync_right);
< 	      else
< 		copy_until_ordinal (right_side, resync_right);
< 	    }
---
> 	    if (inhibit_common)
> 	      skip_until_ordinal (right_side, resync_right);
> 	    else
> 	      copy_until_ordinal (right_side, resync_right);
1012,1015c833
< 	      if (diff_mode == MODE_WORD)
< 		copy_word (left_side, output_file);
< 	      else
< 		copy_char (left_side, output_file);
---
> 	      copy_word (left_side, output_file);
1024,1043c842,856
< 	    {
< 	      if (inhibit_right)
< 		{
< 		  if (!inhibit_common && inhibit_left)
< 		    skip_until_ordinal (right_side, argument[3]);
< 		}
< 	      else
< 		{
< 		  copy_whitespace (right_side, output_file);
< 		  start_of_insert ();
< 		  if (diff_mode == MODE_WORD)
< 		    copy_word (right_side, output_file);
< 		  else
< 		    copy_char (right_side, output_file);
< 		  copy_until_ordinal (right_side, argument[3]);
< 		  end_of_insert ();
< 		}
< 	    }
< 	}	/* decode_directive_line */
<     }		/* while (1) */
---
> 	    if (inhibit_right)
> 	      {
> 		if (!inhibit_common && inhibit_left)
> 		  skip_until_ordinal (right_side, argument[3]);
> 	      }
> 	    else
> 	      {
> 		copy_whitespace (right_side, output_file);
> 		start_of_insert ();
> 		copy_word (right_side, output_file);
> 		copy_until_ordinal (right_side, argument[3]);
> 		end_of_insert ();
> 	      }
> 	}
>     }
1083c896
<     input_file = readpipe (DIFF_PROGRAM, "-i", left_side->temp_name,
---
>     input_file = readpipe (DIFF_PROGRAM, "-c", left_side->temp_name,
1307d1119
<   -c, --char                 diff by character instead by word\n\
1356d1167
<   diff_mode = MODE_WORD;        /* word diff is default */
1365c1176
<   while (option_char = getopt_long (argc, argv, "123CVahcidlnpstw:x:y:z:",
---
>   while (option_char = getopt_long (argc, argv, "123CVahidlnpstw:x:y:z:",
1397,1400d1207
<       case 'c':
< 	diff_mode = MODE_CHAR;
< 	break;
< 
1490,1503c1297,1300
<       if (diff_mode == MODE_WORD)
< 	{
< 	  split_file_into_words (left_side);
< 	  count_total_left = left_side->position;
< 	  split_file_into_words (right_side);
< 	  count_total_right = right_side->position;
< 	}
<       else
< 	{
< 	  split_file_into_chars (left_side);
< 	  count_total_left = left_side->position;
< 	  split_file_into_chars (right_side);
< 	  count_total_right = right_side->position;
< 	}
---
>       split_file_into_words (left_side);
>       count_total_left = left_side->position;
>       split_file_into_words (right_side);
>       count_total_right = right_side->position;
1507a1305
>       fclose (input_file);
